runtime: route notifications through worker inbox

This commit is contained in:
2026-08-05 01:44:57 +09:00
parent dd2ca54874
commit f98a123e40
15 changed files with 614 additions and 811 deletions
@@ -1,4 +1,7 @@
import { parseSigilSegments } from "./composer-command.ts";
import {
buildComposerRequest,
parseSigilSegments,
} from "./composer-command.ts";
declare const Deno: { test(name: string, fn: () => void): void };
@@ -21,3 +24,14 @@ Deno.test("parseSigilSegments leaves hash sigils as plain text", () => {
content: "ask #memory",
}]);
});
Deno.test("notify command exposes the operation instead of a System-role input", () => {
assertEquals(buildComposerRequest(":notify reread the Ticket"), {
ok: true,
request: { kind: "notify", content: "reread the Ticket" },
});
assertEquals(buildComposerRequest(":system reread the Ticket"), {
ok: false,
message: "Unknown command: system. Type :help for available commands.",
});
});
@@ -2,7 +2,7 @@ import type { Segment } from "$lib/generated/protocol";
export type WorkerConsoleInputKind =
| "user"
| "system"
| "notify"
| "compact"
| "list_rewind_targets"
| "register_peer";
@@ -53,9 +53,9 @@ const COMMANDS: Record<string, CommandSpec> = {
description:
"Register another existing Worker as a reciprocal metadata peer.",
},
system: {
usage: ":system <message>",
description: "Send an agent-visible system notification to the Worker.",
notify: {
usage: ":notify <message>",
description: "Send an agent-visible notification to the Worker.",
},
};
@@ -125,12 +125,12 @@ function buildColonCommand(commandLine: string): ComposerCommandResult {
request: { kind: "register_peer", content: argv[0] },
notice: `peer metadata registration requested with \`${argv[0]}\``,
};
case "system": {
case "notify": {
const message = commandLine.trim().slice(name.length).trimStart();
if (!message) {
return invalidUsage("system");
return invalidUsage("notify");
}
return { ok: true, request: { kind: "system", content: message } };
return { ok: true, request: { kind: "notify", content: message } };
}
default:
return {
@@ -158,7 +158,7 @@ function helpCommand(argv: string[]): ComposerCommandResult {
notice: `command: ${name} — usage: ${spec.usage}. ${spec.description}`,
};
}
const list = ["help", "noop", "compact", "rewind", "peer", "system"]
const list = ["help", "noop", "compact", "rewind", "peer", "notify"]
.map((command) => `${command} (${COMMANDS[command].usage})`)
.join(", ");
return {
@@ -26,7 +26,7 @@ export const COLON_COMMAND_COMPLETIONS: ComposerCompletionEntry[] = [
{ value: "rewind", description: "List rewind targets" },
{ value: "rollback", description: "Alias for rewind" },
{ value: "peer", description: "Register metadata peer" },
{ value: "system", description: "Send system notification" },
{ value: "notify", description: "Send Worker notification" },
];
export function completionTokenAt(
@@ -428,7 +428,7 @@
],
},
};
case "system":
case "notify":
return {
method: "notify",
params: { message: request.content, auto_run: true },