mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
Persist shared instruction restart intent
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -192,7 +192,13 @@ with a TypeScript lookup table or an id comparison in a component.
|
||||
its assignment. Dirty Title, When to use it, or Instructions fields must
|
||||
confirm before Cancel or the enclosing dialog close discards them. The
|
||||
primary create action is **Publish**, and the footer discloses that anyone
|
||||
in the community can read the instruction.
|
||||
in the community can read the instruction. The `sharedInstructions`
|
||||
experiment gates execution, not only this UI: local prospective restart
|
||||
snapshots and remote deployment payloads must both omit assignments while
|
||||
disabled. A successful toggle records the running value until the user
|
||||
restarts agents (or toggles back), so the restart affordance survives
|
||||
leaving and reopening Settings without claiming a restart is needed when
|
||||
runtime context is unchanged.
|
||||
14. **Profile runtime sections render only reported agent data.** Missing
|
||||
runtime, model, status, command, MCP, advanced, or diagnostics values stay
|
||||
absent in every build mode. Do not fill profile or agent-panel gaps with
|
||||
|
||||
@@ -15,10 +15,19 @@ import { Button } from "@/shared/ui/button";
|
||||
import { Switch } from "@/shared/ui/switch";
|
||||
import { SettingsOptionGroup, SettingsOptionRow } from "./SettingsOptionGroup";
|
||||
import { SettingsSectionHeader } from "./SettingsSectionHeader";
|
||||
import {
|
||||
clearSharedInstructionsRestartPending,
|
||||
isSharedInstructionsRestartPending,
|
||||
recordSharedInstructionsToggle,
|
||||
} from "./sharedInstructionsRestartPending";
|
||||
|
||||
function FeatureRow({ feature }: { feature: FeatureDefinition }) {
|
||||
const [enabled, toggle] = useFeatureToggle(feature.id);
|
||||
const [restartPending, setRestartPending] = React.useState(false);
|
||||
const [restartPending, setRestartPending] = React.useState(() =>
|
||||
feature.id === "sharedInstructions"
|
||||
? isSharedInstructionsRestartPending(enabled)
|
||||
: false,
|
||||
);
|
||||
const [restarting, setRestarting] = React.useState(false);
|
||||
const switchId = `feature-toggle-${feature.id}`;
|
||||
|
||||
@@ -40,6 +49,7 @@ function FeatureRow({ feature }: { feature: FeatureDefinition }) {
|
||||
);
|
||||
return;
|
||||
}
|
||||
clearSharedInstructionsRestartPending();
|
||||
setRestartPending(false);
|
||||
toast.success(
|
||||
running.length === 0
|
||||
@@ -99,7 +109,10 @@ function FeatureRow({ feature }: { feature: FeatureDefinition }) {
|
||||
}
|
||||
if (feature.id === "sharedInstructions") {
|
||||
void setSharedInstructionsEnabled(value)
|
||||
.then(() => setRestartPending(true))
|
||||
.then(() => {
|
||||
const pending = recordSharedInstructionsToggle(value);
|
||||
setRestartPending(pending);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
"Failed to apply shared instructions setting:",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
const values = new Map();
|
||||
globalThis.window = {
|
||||
sessionStorage: {
|
||||
getItem(key) {
|
||||
return values.get(key) ?? null;
|
||||
},
|
||||
removeItem(key) {
|
||||
values.delete(key);
|
||||
},
|
||||
setItem(key, value) {
|
||||
values.set(key, value);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const {
|
||||
clearSharedInstructionsRestartPending,
|
||||
isSharedInstructionsRestartPending,
|
||||
recordSharedInstructionsToggle,
|
||||
} = await import("./sharedInstructionsRestartPending.ts");
|
||||
|
||||
test.beforeEach(() => values.clear());
|
||||
|
||||
test("pending state survives remount until restart", () => {
|
||||
assert.equal(recordSharedInstructionsToggle(true), true);
|
||||
assert.equal(isSharedInstructionsRestartPending(true), true);
|
||||
|
||||
clearSharedInstructionsRestartPending();
|
||||
assert.equal(isSharedInstructionsRestartPending(true), false);
|
||||
});
|
||||
|
||||
test("toggling back to the running value clears pending state", () => {
|
||||
assert.equal(recordSharedInstructionsToggle(true), true);
|
||||
assert.equal(recordSharedInstructionsToggle(false), false);
|
||||
assert.equal(isSharedInstructionsRestartPending(false), false);
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
export const SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY =
|
||||
"buzz.sharedInstructionsRestartBaseline";
|
||||
|
||||
function storage(): Storage | null {
|
||||
return typeof window === "undefined" ? null : window.sessionStorage;
|
||||
}
|
||||
|
||||
export function isSharedInstructionsRestartPending(current: boolean): boolean {
|
||||
const baseline = storage()?.getItem(SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY);
|
||||
return baseline !== null && baseline !== String(current);
|
||||
}
|
||||
|
||||
export function recordSharedInstructionsToggle(current: boolean): boolean {
|
||||
const store = storage();
|
||||
if (!store) return false;
|
||||
|
||||
const baseline = store.getItem(SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY);
|
||||
if (baseline === null) {
|
||||
store.setItem(SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY, String(!current));
|
||||
return true;
|
||||
}
|
||||
if (baseline === String(current)) {
|
||||
store.removeItem(SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function clearSharedInstructionsRestartPending(): void {
|
||||
storage()?.removeItem(SHARED_INSTRUCTIONS_RESTART_BASELINE_KEY);
|
||||
}
|
||||
Reference in New Issue
Block a user