@windyroad/architect 1.0.0-preview.1297 → 1.0.1-preview.1299
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.
|
@@ -63,7 +63,7 @@ if messages:
|
|
|
63
63
|
[ -z "$detect_output" ] || printf '%s\n' "$detect_output"
|
|
64
64
|
[ -z "$stale_output" ] || printf '%s\n' "$stale_output"
|
|
65
65
|
;;
|
|
66
|
-
subagent-stop)
|
|
66
|
+
subagent-start|subagent-stop)
|
|
67
67
|
printf '%s' "$INPUT" | node "$SCRIPT_DIR/codex-agent-completion.mjs"
|
|
68
68
|
;;
|
|
69
69
|
pre-tool)
|
|
@@ -23,6 +23,8 @@ function statePath(sessionId, target, suffix = "") {
|
|
|
23
23
|
return join(riskDir(sessionId), `codex-architect-${Buffer.from(target).toString("base64url")}${suffix}`);
|
|
24
24
|
}
|
|
25
25
|
function registrationPath(sessionId, target) { return join(transportDir(), `registration-${id(sessionId, target)}.json`); }
|
|
26
|
+
function registeredPath(value) { return registrationPath(value.parentSession, value.source === "subagent-start" ? `native:${value.target}` : value.target); }
|
|
27
|
+
function nativePath(sessionId) { return join(riskDir(sessionId), "native-architect-transport"); }
|
|
26
28
|
function receiptPath(sessionId, target, suffix = "") { return join(transportDir(), `receipt-${id(sessionId, target)}.json${suffix}`); }
|
|
27
29
|
|
|
28
30
|
function checkout(cwd) {
|
|
@@ -87,7 +89,30 @@ function clear(sessionId, target) {
|
|
|
87
89
|
for (const suffix of ["", ".claim", ".done"]) rmSync(receiptPath(sessionId, target, suffix), { force: true });
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
function rememberNative(input) {
|
|
93
|
+
if (input.agent_type !== role || typeof input.agent_id !== "string" || !/^[A-Za-z0-9-]+$/.test(input.agent_id)) return;
|
|
94
|
+
const bound = checkout(input.cwd);
|
|
95
|
+
const hash = bound && policyHash(bound.root);
|
|
96
|
+
if (!bound || !hash) return diagnostic("invalid-native-binding", input);
|
|
97
|
+
const target = input.agent_id;
|
|
98
|
+
if (existsSync(receiptPath(input.session_id, target, ".done")) || existsSync(statePath(input.session_id, target, ".done"))) return;
|
|
99
|
+
const registered = { source: "subagent-start", parentSession: input.session_id, role, target, ...bound, policyHash: hash, createdAt: Date.now() };
|
|
100
|
+
mkdirSync(transportDir(), { recursive: true, mode: 0o700 });
|
|
101
|
+
try { writeFileSync(registeredPath(registered), JSON.stringify(registered), { flag: "wx", mode: 0o600 }); }
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error?.code !== "EEXIST") throw error;
|
|
104
|
+
const previous = JSON.parse(readFileSync(registeredPath(registered), "utf8"));
|
|
105
|
+
for (const key of ["source", "parentSession", "role", "target", "root", "physical", "policyHash"]) {
|
|
106
|
+
if (previous[key] !== registered[key]) return diagnostic("native-registration-conflict", input);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
mkdirSync(riskDir(input.session_id), { recursive: true });
|
|
110
|
+
try { writeFileSync(nativePath(input.session_id), "", { flag: "wx", mode: 0o600 }); }
|
|
111
|
+
catch (error) { if (error?.code !== "EEXIST") throw error; }
|
|
112
|
+
}
|
|
113
|
+
|
|
90
114
|
function remember(input) {
|
|
115
|
+
if (existsSync(nativePath(input.session_id))) return;
|
|
91
116
|
reapTransport();
|
|
92
117
|
const result = response(input);
|
|
93
118
|
const target = normalizeTarget(result.agent_id ?? result.task_name);
|
|
@@ -125,7 +150,7 @@ function writeMarker(input, registered, target, output, completedAt, claim, done
|
|
|
125
150
|
}
|
|
126
151
|
renameSync(claim, done);
|
|
127
152
|
rmSync(statePath(registered.parentSession, target), { force: true });
|
|
128
|
-
rmSync(
|
|
153
|
+
rmSync(registeredPath(registered), { force: true });
|
|
129
154
|
const assessedAt = new Date(completedAt);
|
|
130
155
|
for (const marker of [`/tmp/architect-reviewed-${registered.parentSession}`, `/tmp/architect-reviewed-${registered.parentSession}.hash`, `/tmp/architect-plan-reviewed-${registered.parentSession}`]) {
|
|
131
156
|
if (existsSync(marker)) utimesSync(marker, assessedAt, assessedAt);
|
|
@@ -134,6 +159,7 @@ function writeMarker(input, registered, target, output, completedAt, claim, done
|
|
|
134
159
|
}
|
|
135
160
|
|
|
136
161
|
function complete(input, rawTarget, output) {
|
|
162
|
+
if (existsSync(nativePath(input.session_id))) return;
|
|
137
163
|
const target = completionTarget(rawTarget, riskDir(input.session_id), "codex-architect-");
|
|
138
164
|
if (!target || typeof output !== "string" || !output) return;
|
|
139
165
|
const state = statePath(input.session_id, target);
|
|
@@ -171,8 +197,11 @@ function persist(input) {
|
|
|
171
197
|
if (!target || typeof output !== "string" || !output) return;
|
|
172
198
|
if (parsedVerdict(output) !== "PASS") return diagnostic("non-pass-output", input);
|
|
173
199
|
const registrationsForCheckout = registrations(input, target);
|
|
174
|
-
const
|
|
175
|
-
const
|
|
200
|
+
const native = registrationsForCheckout.filter(({ registered }) => registered.source === "subagent-start");
|
|
201
|
+
const nativeExact = native.filter(({ registered }) => registered.parentSession === input.session_id && registered.target === input.agent_id);
|
|
202
|
+
const legacy = registrationsForCheckout.filter(({ registered }) => registered.source !== "subagent-start");
|
|
203
|
+
const exact = legacy.filter(({ registered }) => registered.target === target);
|
|
204
|
+
const candidates = existsSync(nativePath(input.session_id)) || nativeExact.length ? nativeExact : exact.length ? exact : legacy.filter(({ registered }) => registered.parentSession === input.session_id);
|
|
176
205
|
if (candidates.length !== 1) return diagnostic(candidates.length ? "ambiguous-parent-registration" : "missing-parent-registration", input);
|
|
177
206
|
const { registered, age } = candidates[0];
|
|
178
207
|
target = registered.target;
|
|
@@ -191,6 +220,7 @@ function consume(input) {
|
|
|
191
220
|
let pending;
|
|
192
221
|
try { pending = JSON.parse(readFileSync(path, "utf8")); } catch { diagnostic("malformed-receipt", input); continue; }
|
|
193
222
|
if (pending.parentSession !== input.session_id || pending.role !== role) continue;
|
|
223
|
+
if (existsSync(nativePath(input.session_id)) && pending.source !== "subagent-start") continue;
|
|
194
224
|
if (!valid(pending, input, pending.target, Date.now() - pending.completedAt)) continue;
|
|
195
225
|
const claim = `${path}.claim`;
|
|
196
226
|
try { writeFileSync(claim, "", { flag: "wx", mode: 0o600 }); }
|
|
@@ -215,13 +245,14 @@ if (!/^[A-Za-z0-9-]+$/.test(input.session_id || "")) process.exit(0);
|
|
|
215
245
|
if (!/^[0-9]+$/.test(ttlText) || !Number.isSafeInteger(ttl) || ttl <= 0) process.exit(0);
|
|
216
246
|
|
|
217
247
|
try {
|
|
248
|
+
if (input.hook_event_name === "SubagentStart") rememberNative(input);
|
|
218
249
|
if (SPAWN_TOOLS.has(input.tool_name)) remember(input);
|
|
219
250
|
if (CLOSE_TOOLS.has(input.tool_name)) close(input);
|
|
220
251
|
if (WAIT_TOOLS.has(input.tool_name)) wait(input);
|
|
221
252
|
if (input.hook_event_name === "UserPromptSubmit" || input.hook_event_name === "PreToolUse" || ["Bash", "Edit", "Write", "ExitPlanMode"].includes(input.tool_name)) consume(input);
|
|
222
253
|
if (input.hook_event_name === "SubagentStop") {
|
|
223
254
|
if (input.agent_type !== role) diagnostic("unrelated-subagent-stop", input);
|
|
224
|
-
else if (existsSync(statePath(input.session_id, normalizeTarget(input.agent_id)))) complete(input, input.agent_id, input.last_assistant_message);
|
|
255
|
+
else if (!existsSync(nativePath(input.session_id)) && existsSync(statePath(input.session_id, normalizeTarget(input.agent_id)))) complete(input, input.agent_id, input.last_assistant_message);
|
|
225
256
|
else persist(input);
|
|
226
257
|
}
|
|
227
258
|
} catch {
|
package/hooks/hooks.json
CHANGED
|
@@ -1,21 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"hooks": {
|
|
3
3
|
"SessionStart": [
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh session-start"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
7
13
|
],
|
|
8
14
|
"UserPromptSubmit": [
|
|
9
|
-
{
|
|
15
|
+
{
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh user-prompt"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
10
23
|
],
|
|
11
24
|
"PreToolUse": [
|
|
12
|
-
{
|
|
25
|
+
{
|
|
26
|
+
"matcher": "Bash|Edit|Write|ExitPlanMode",
|
|
27
|
+
"hooks": [
|
|
28
|
+
{
|
|
29
|
+
"type": "command",
|
|
30
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh pre-tool"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
13
34
|
],
|
|
14
35
|
"PostToolUse": [
|
|
15
|
-
{
|
|
36
|
+
{
|
|
37
|
+
"matcher": "Agent|Bash|Edit|Skill|Write|collaboration.spawn_agent|collaboration.wait_agent|collaboration.interrupt_agent|collaborationspawn_agent|collaborationwait_agent|collaborationinterrupt_agent|spawn_agent|wait_agent|interrupt_agent|close_agent|multi_agent_v1__spawn_agent|multi_agent_v1__wait_agent|multi_agent_v1__close_agent",
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh post-tool"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
16
45
|
],
|
|
17
46
|
"SubagentStop": [
|
|
18
|
-
{
|
|
47
|
+
{
|
|
48
|
+
"matcher": "^wr-architect:agent$",
|
|
49
|
+
"hooks": [
|
|
50
|
+
{
|
|
51
|
+
"type": "command",
|
|
52
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh subagent-stop"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"SubagentStart": [
|
|
58
|
+
{
|
|
59
|
+
"matcher": "^wr-architect:agent$",
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/architect-dispatch.sh subagent-start"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
19
67
|
]
|
|
20
68
|
}
|
|
21
69
|
}
|