@polderlabs/bizar 10.10.0 → 10.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,48 +1,95 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* .claude/hooks/control-inbox.mjs
|
|
4
|
+
*
|
|
5
|
+
* Bizar OpenKan — UserPromptSubmit / SessionStart hook.
|
|
6
|
+
*
|
|
7
|
+
* On UserPromptSubmit: reads queued control messages and injects them as
|
|
8
|
+
* additional context so the primary session processes durable directives from
|
|
9
|
+
* OpenKan before taking any action.
|
|
10
|
+
*
|
|
11
|
+
* On SessionStart: primes the session with the same control-inbox context so
|
|
12
|
+
* agents see queued messages at session open.
|
|
13
|
+
*
|
|
14
|
+
* Uses import.meta.url + dynamic import() to resolve the sibling CLI module so
|
|
15
|
+
* the hook works regardless of install path (fixes ERR_MODULE_NOT_FOUND after
|
|
16
|
+
* installation when the repo source lived at a non-default location).
|
|
17
|
+
* Lazy import inside the stdin handler avoids top-level-await issues in the
|
|
18
|
+
* transitive dependency chain (control-store.mjs → task-ledger.mjs → better-sqlite3).
|
|
19
|
+
*
|
|
20
|
+
* Claude Code stdin shape (UserPromptSubmit / SessionStart):
|
|
21
|
+
* { session_id, cwd, hook_event_name }
|
|
22
|
+
*
|
|
23
|
+
* Claude Code stdout shape (hookSpecificOutput):
|
|
24
|
+
* { hookSpecificOutput: { hookEventName, additionalContext } }
|
|
25
|
+
*/
|
|
2
26
|
|
|
3
|
-
|
|
27
|
+
'use strict';
|
|
4
28
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let raw = '';
|
|
8
|
-
for await (const chunk of process.stdin) raw += chunk;
|
|
9
|
-
input = raw.trim() ? JSON.parse(raw) : {};
|
|
10
|
-
} catch {
|
|
11
|
-
process.stdout.write(JSON.stringify({ continue: true }) + '\n');
|
|
12
|
-
process.exit(0);
|
|
13
|
-
}
|
|
29
|
+
import { dirname, join } from 'node:path';
|
|
30
|
+
import { fileURLToPath } from 'node:url';
|
|
14
31
|
|
|
15
|
-
const
|
|
16
|
-
const messages = claimControlMessages(cwd, {
|
|
17
|
-
sessionId: input.session_id || '',
|
|
18
|
-
agentType: input.agent_type || input.agent_id || '',
|
|
19
|
-
});
|
|
32
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
33
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
async function main() {
|
|
35
|
+
let input = {};
|
|
36
|
+
try {
|
|
37
|
+
let raw = '';
|
|
38
|
+
for await (const chunk of process.stdin) raw += chunk;
|
|
39
|
+
input = raw.trim() ? JSON.parse(raw) : {};
|
|
40
|
+
} catch {
|
|
41
|
+
process.stdout.write(JSON.stringify({ continue: true }) + '\n');
|
|
42
|
+
process.exit(0);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Dynamic import so the hook resolves correctly regardless of install path.
|
|
47
|
+
// Uses import.meta.url to anchor relative resolution.
|
|
48
|
+
let claimControlMessages;
|
|
49
|
+
try {
|
|
50
|
+
({ claimControlMessages } = await import(join(__dirname, '..', '..', 'cli', 'control-store.mjs')));
|
|
51
|
+
} catch (err) {
|
|
52
|
+
process.stderr.write(`[bizar.control] WARN: could not load control-store: ${err && err.message ? err.message : String(err)}\n`);
|
|
53
|
+
process.stdout.write(JSON.stringify({ continue: true }) + '\n');
|
|
54
|
+
process.exit(0);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
25
57
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
58
|
+
const cwd = input.cwd || process.cwd();
|
|
59
|
+
const messages = claimControlMessages(cwd, {
|
|
60
|
+
sessionId: input.session_id || '',
|
|
61
|
+
agentType: input.agent_type || input.agent_id || '',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (messages.length === 0) {
|
|
65
|
+
process.stdout.write(JSON.stringify({ continue: true }) + '\n');
|
|
66
|
+
process.exit(0);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const context = [
|
|
71
|
+
'# Bizar control messages',
|
|
35
72
|
'',
|
|
36
|
-
|
|
73
|
+
'Process these durable messages in order. They were sent through OpenKan/Bizar.',
|
|
37
74
|
'',
|
|
38
|
-
|
|
39
|
-
|
|
75
|
+
...messages.flatMap((message) => [
|
|
76
|
+
`## Message ${message.id}`,
|
|
77
|
+
`From: ${message.from}`,
|
|
78
|
+
message.taskId ? `Task: ${message.taskId}` : null,
|
|
79
|
+
'',
|
|
80
|
+
message.text,
|
|
81
|
+
'',
|
|
82
|
+
].filter(Boolean)),
|
|
83
|
+
].join('\n');
|
|
40
84
|
|
|
41
|
-
process.stdout.write(JSON.stringify({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}) + '\n');
|
|
85
|
+
process.stdout.write(JSON.stringify({
|
|
86
|
+
continue: true,
|
|
87
|
+
hookSpecificOutput: {
|
|
88
|
+
hookEventName: input.hook_event_name || 'SessionStart',
|
|
89
|
+
additionalContext: context,
|
|
90
|
+
},
|
|
91
|
+
}) + '\n');
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
48
94
|
|
|
95
|
+
main();
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
* skill/agent suggestions. Emits suggestions to stderr (stdout is reserved for
|
|
10
10
|
* Claude Code's hook protocol).
|
|
11
11
|
*
|
|
12
|
+
* Uses import.meta.url + dynamic import() to resolve the sibling CLI module so
|
|
13
|
+
* the hook works regardless of install path (fixes ERR_MODULE_NOT_FOUND after
|
|
14
|
+
* installation when the repo source lived at a non-default location).
|
|
15
|
+
* Lazy import inside the stdin handler avoids top-level-await issues in any
|
|
16
|
+
* transitive dependency chain.
|
|
17
|
+
*
|
|
12
18
|
* Claude Code stdin shape (UserPromptSubmit):
|
|
13
19
|
* {
|
|
14
20
|
* "session_id": "...",
|
|
@@ -29,12 +35,15 @@
|
|
|
29
35
|
*/
|
|
30
36
|
'use strict';
|
|
31
37
|
|
|
32
|
-
import {
|
|
38
|
+
import { dirname, join } from 'node:path';
|
|
39
|
+
import { fileURLToPath } from 'node:url';
|
|
40
|
+
|
|
41
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
33
42
|
|
|
34
43
|
let raw = '';
|
|
35
44
|
process.stdin.setEncoding('utf8');
|
|
36
45
|
process.stdin.on('data', (chunk) => { raw += chunk; });
|
|
37
|
-
process.stdin.on('end', () => {
|
|
46
|
+
process.stdin.on('end', async () => {
|
|
38
47
|
let input = {};
|
|
39
48
|
try {
|
|
40
49
|
input = JSON.parse(raw || '{}');
|
|
@@ -65,6 +74,25 @@ process.stdin.on('end', () => {
|
|
|
65
74
|
'- If you are already running as a Bizar custom agent, follow your assigned role and do not recursively dispatch yourself.',
|
|
66
75
|
].join('\n');
|
|
67
76
|
|
|
77
|
+
let dispatch;
|
|
78
|
+
try {
|
|
79
|
+
({ dispatch } = await import(join(__dirname, '..', '..', 'cli', 'worker-dispatcher.mjs')));
|
|
80
|
+
} catch (err) {
|
|
81
|
+
process.stderr.write(
|
|
82
|
+
`[bizar.workers] WARN: dispatch failed (import): ${
|
|
83
|
+
err && err.message ? err.message : String(err)
|
|
84
|
+
}\n`,
|
|
85
|
+
);
|
|
86
|
+
process.stdout.write(JSON.stringify({
|
|
87
|
+
hookSpecificOutput: {
|
|
88
|
+
hookEventName: 'UserPromptSubmit',
|
|
89
|
+
additionalContext: routePolicy,
|
|
90
|
+
},
|
|
91
|
+
}) + '\n');
|
|
92
|
+
process.exit(0);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
68
96
|
let suggestions;
|
|
69
97
|
try {
|
|
70
98
|
suggestions = dispatch(prompt, { maxSuggestions: 3 });
|
package/.claude/settings.json
CHANGED
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
"mcp__bizar__plan_action", "mcp__bizar__loop_list", "mcp__bizar__loop_status",
|
|
12
12
|
"mcp__bizar__loop_start", "mcp__bizar__loop_stop", "mcp__bizar__graph_query",
|
|
13
13
|
"mcp__bizar__graph_path", "mcp__bizar__list_instincts", "mcp__bizar__list_decisions",
|
|
14
|
-
"mcp__semble__*", "mcp__agent-browser__*"
|
|
15
|
-
],
|
|
16
|
-
"ask": [
|
|
14
|
+
"mcp__semble__*", "mcp__agent-browser__*",
|
|
17
15
|
"Bash(git commit *)", "Bash(git push *)", "Bash(gh pr create *)", "Bash(gh pr edit *)",
|
|
18
16
|
"Bash(gh pr merge *)", "Bash(gh release *)", "Bash(npm publish *)", "Bash(bun publish *)",
|
|
19
17
|
"Bash(vercel deploy *)", "Bash(wrangler deploy *)"
|
package/package.json
CHANGED