feat(org): kvb-org-radio and kvb-org-queue replace chair and peer messages
kvb-org-radio is the default channel to other agents: broadcast and direct reach the receiver on its next prompt, security and pan-pan mid-turn through a PostToolBatch hook, and only mayday or direct --wake wake a session, through the receiver's own asyncRewake Stop hook (a SendMessage fallback is printed for sessions without a listener). It keeps the news.jsonl store and lock, so news.py stays a forwarding shim. A mayday holds radio silence for two hours: watch.py blocks new heavy commands and the operator gets a desktop notice. hotfix.py announces merged hotfixes as security items. kvb-org-queue grants heavy jobs by rule instead of chair messages: queue.py hold waits under a flock with disk reservation, hotfix-first and register rank order, slot limits, stage and silence checks, then runs the command and releases. Every job is recorded; history.py learns disk need per command and slot limits per kind (p90, five runs), watch.py mirrors the history to ~/.local/state. enable-plugins.js registers the new hooks behind a file check so a missing script never blocks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed5bb074c5
commit
27559dabc4
18 files changed
+2607
-225
No files matched your search
+16
-10
@@ -33,6 +33,7 @@ const RENAMED = {
|
||||
"democracy/scripts/council.py": "kvb-org-organize/scripts/council.py",
|
||||
"democracy/scripts/watch.py": "kvb-org-organize/scripts/watch.py",
|
||||
"subagent-model/scripts/log.py": "kvb-org-perform/scripts/log.py",
|
||||
"kvb-org-organize/scripts/news.py": "kvb-org-radio/scripts/radio.py",
|
||||
};
|
||||
|
||||
let data = {};
|
||||
@@ -109,23 +110,28 @@ if (!JSON.stringify(data.hooks.PreToolUse).includes("kvb-org-organize/scripts/co
|
||||
}
|
||||
|
||||
const SCRIPT_HOOKS = [
|
||||
["kvb-org-organize/scripts/watch.py", "UserPromptSubmit", null, "watch"],
|
||||
["kvb-org-organize/scripts/news.py", "UserPromptSubmit", null, "hook"],
|
||||
["kvb-org-organize/scripts/watch.py", "PostToolUse", "Bash", "watch"],
|
||||
["kvb-org-organize/scripts/watch.py", "PreToolUse", "Bash", "block"],
|
||||
["kvb-org-perform/scripts/log.py", "PreToolUse", "Agent|Task", "spawn"],
|
||||
["kvb-org-perform/scripts/log.py", "PostToolUse", "Bash", "persist"],
|
||||
["kvb-org-organize/scripts/watch.py", "UserPromptSubmit", null, "watch", {}],
|
||||
["kvb-org-radio/scripts/radio.py", "UserPromptSubmit", null, "hook", {}],
|
||||
["kvb-org-radio/scripts/radio.py", "PostToolBatch", null, "tool", {}],
|
||||
["kvb-org-radio/scripts/radio.py", "Stop", null, "listen", { asyncRewake: true, timeout: 21600 }],
|
||||
["kvb-org-organize/scripts/watch.py", "PostToolUse", "Bash", "watch", {}],
|
||||
["kvb-org-organize/scripts/watch.py", "PreToolUse", "Bash", "block", {}],
|
||||
["kvb-org-queue/scripts/queue.py", "PreToolUse", "Bash", "block", {}],
|
||||
["kvb-org-perform/scripts/log.py", "PreToolUse", "Agent|Task", "spawn", {}],
|
||||
["kvb-org-perform/scripts/log.py", "PostToolUse", "Bash", "persist", {}],
|
||||
];
|
||||
for (const [script, event, matcher, sub] of SCRIPT_HOOKS) {
|
||||
for (const [script, event, matcher, sub, extra] of SCRIPT_HOOKS) {
|
||||
data.hooks[event] = data.hooks[event] || [];
|
||||
const registered = data.hooks[event].some((entry) =>
|
||||
(entry.hooks || []).some((hook) =>
|
||||
String(hook.command).includes(script) && String(hook.command).endsWith(` ${sub}`)));
|
||||
if (registered) continue;
|
||||
const file = path.join(path.dirname(settingsPath), "skills", ...script.split("/"));
|
||||
const entry = { hooks: [{ type: "command", command: `python3 ${JSON.stringify(file)} ${sub}` }] };
|
||||
const file = JSON.stringify(path.join(path.dirname(settingsPath), "skills", ...script.split("/")));
|
||||
// Trip-wire: python3 on a missing file exits 2, which blocks every prompt or tool call; the test makes it exit 1.
|
||||
const command = `[ -f ${file} ] && python3 ${file} ${sub}`;
|
||||
const entry = { hooks: [{ type: "command", command, ...extra }] };
|
||||
data.hooks[event].push(matcher ? { matcher, ...entry } : entry);
|
||||
}
|
||||
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(data, null, 2) + "\n");
|
||||
console.log(`skills: enabled the caveman and ponytail plugins (plugin skill copies dropped from this .claude), the ${REMINDERS.join(" + ")} reminders, the kvb-org-organize claim gate, news hook and resource watch, and the kvb-org-perform log in ${settingsPath}`);
|
||||
console.log(`skills: enabled the caveman and ponytail plugins (plugin skill copies dropped from this .claude), the ${REMINDERS.join(" + ")} reminders, the kvb-org-organize claim gate and resource watch, the kvb-org-radio hooks, the kvb-org-queue gate, and the kvb-org-perform log in ${settingsPath}`);
|
||||
Reference in new issue
Block a user