@orchestrator-claude/definitions 3.32.1 → 3.33.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.
Files changed (87) hide show
  1. package/README.md +113 -0
  2. package/agents/debug-sidecar.md +1 -1
  3. package/agents/doc-sidecar.md +1 -1
  4. package/agents/test-sidecar.md +1 -1
  5. package/dist/cli.js +78 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/DiffCommand.js +1 -1
  8. package/dist/commands/DiffCommand.js.map +1 -1
  9. package/dist/commands/InstallCommand.d.ts +41 -0
  10. package/dist/commands/InstallCommand.d.ts.map +1 -0
  11. package/dist/commands/InstallCommand.js +253 -0
  12. package/dist/commands/InstallCommand.js.map +1 -0
  13. package/dist/http/ApiClient.d.ts +5 -0
  14. package/dist/http/ApiClient.d.ts.map +1 -1
  15. package/dist/http/ApiClient.js.map +1 -1
  16. package/dist/install/DevCheckoutDetector.d.ts +66 -0
  17. package/dist/install/DevCheckoutDetector.d.ts.map +1 -0
  18. package/dist/install/DevCheckoutDetector.js +150 -0
  19. package/dist/install/DevCheckoutDetector.js.map +1 -0
  20. package/dist/install/HooksWirer.d.ts +29 -0
  21. package/dist/install/HooksWirer.d.ts.map +1 -0
  22. package/dist/install/HooksWirer.js +80 -0
  23. package/dist/install/HooksWirer.js.map +1 -0
  24. package/dist/install/LocalDiffReporter.d.ts +25 -0
  25. package/dist/install/LocalDiffReporter.d.ts.map +1 -0
  26. package/dist/install/LocalDiffReporter.js +50 -0
  27. package/dist/install/LocalDiffReporter.js.map +1 -0
  28. package/dist/install/Materializer.d.ts +67 -0
  29. package/dist/install/Materializer.d.ts.map +1 -0
  30. package/dist/install/Materializer.js +196 -0
  31. package/dist/install/Materializer.js.map +1 -0
  32. package/dist/install/McpRegistrar.d.ts +63 -0
  33. package/dist/install/McpRegistrar.d.ts.map +1 -0
  34. package/dist/install/McpRegistrar.js +114 -0
  35. package/dist/install/McpRegistrar.js.map +1 -0
  36. package/dist/install/ProcessRunner.d.ts +25 -0
  37. package/dist/install/ProcessRunner.d.ts.map +1 -0
  38. package/dist/install/ProcessRunner.js +41 -0
  39. package/dist/install/ProcessRunner.js.map +1 -0
  40. package/dist/install/ProjectSettingsNeutralizer.d.ts +39 -0
  41. package/dist/install/ProjectSettingsNeutralizer.d.ts.map +1 -0
  42. package/dist/install/ProjectSettingsNeutralizer.js +100 -0
  43. package/dist/install/ProjectSettingsNeutralizer.js.map +1 -0
  44. package/dist/install/types.d.ts +52 -0
  45. package/dist/install/types.d.ts.map +1 -0
  46. package/dist/install/types.js +8 -0
  47. package/dist/install/types.js.map +1 -0
  48. package/dist/manifest/ManifestLoader.d.ts.map +1 -1
  49. package/dist/manifest/ManifestLoader.js +3 -2
  50. package/dist/manifest/ManifestLoader.js.map +1 -1
  51. package/dist/manifest/types.d.ts +3 -0
  52. package/dist/manifest/types.d.ts.map +1 -1
  53. package/dist/scripts/bundle-hooks.d.ts +39 -0
  54. package/dist/scripts/bundle-hooks.d.ts.map +1 -0
  55. package/dist/scripts/bundle-hooks.js +165 -0
  56. package/dist/scripts/bundle-hooks.js.map +1 -0
  57. package/dist/scripts/generate-manifest.d.ts +22 -3
  58. package/dist/scripts/generate-manifest.d.ts.map +1 -1
  59. package/dist/scripts/generate-manifest.js +78 -35
  60. package/dist/scripts/generate-manifest.js.map +1 -1
  61. package/hooks/dangling-guard.mjs +7426 -0
  62. package/hooks/dangling-guard.ts +223 -6
  63. package/hooks/gate-guardian.mjs +463 -0
  64. package/hooks/lib/additional-directories-sync.ts +295 -0
  65. package/hooks/lib/api-client.ts +388 -7
  66. package/hooks/lib/session-selection.ts +81 -0
  67. package/hooks/mailbox-listener.mjs +259 -0
  68. package/hooks/post-compact.mjs +7931 -0
  69. package/hooks/post-implement.mjs +238 -0
  70. package/hooks/session-start.mjs +8234 -0
  71. package/hooks/session-start.ts +264 -23
  72. package/hooks/sprint-registry.mjs +59 -0
  73. package/hooks/subagent-start.mjs +289 -0
  74. package/hooks/subagent-stop.mjs +7793 -0
  75. package/hooks/subagent-stop.ts +4 -2
  76. package/hooks/user-prompt.mjs +329 -0
  77. package/hooks/workflow-guard.mjs +7805 -0
  78. package/hooks/workflow-guard.ts +360 -119
  79. package/hooks-settings-template.json +63 -0
  80. package/manifest.json +54 -68
  81. package/mcp-servers.json +48 -0
  82. package/package.json +10 -4
  83. package/personas/auditor-compliance.md +104 -0
  84. package/personas/cfo-conservador.md +88 -0
  85. package/personas/designer-perfeccionista.md +104 -0
  86. package/personas/diretor-cetico-fmcg.md +80 -0
  87. package/personas/engenheiro-cetico-construcao.md +107 -0
@@ -18,8 +18,8 @@ import {
18
18
  consumeInvocationState,
19
19
  completeAgentInvocation,
20
20
  isInvocationStateStale,
21
+ resolveAgentMemoryBaseDir,
21
22
  } from './lib/api-client.js';
22
- import { join } from 'node:path';
23
23
  import { createCheckpointIfNeeded } from './lib/git-checkpoint.js';
24
24
  import { appendObservation } from './lib/observations-helper.js';
25
25
 
@@ -98,7 +98,9 @@ async function main(): Promise<void> {
98
98
  // 4. Write Tier B observation (fail-open)
99
99
  try {
100
100
  const sessionId = getField(stdin, 'session_id') || getField(stdin, 'claude_session_id') || '';
101
- const memoryBaseDir = join(process.cwd(), '.claude', 'agent-memory');
101
+ // RFC-040 Operator Multi-Project — Slice 5 (C5): resolves under the
102
+ // project root walked up from cwd (falls back to cwd when unregistered).
103
+ const memoryBaseDir = resolveAgentMemoryBaseDir(process.cwd());
102
104
  appendObservation(memoryBaseDir, agentType, {
103
105
  timestamp: new Date().toISOString(),
104
106
  session_id: sessionId,
@@ -0,0 +1,329 @@
1
+ import { createRequire as __createRequireShim } from 'node:module'; const require = __createRequireShim(import.meta.url);
2
+
3
+ // hooks/lib/api-client.ts
4
+ import { readFileSync, writeFileSync, mkdirSync, statSync, unlinkSync, readdirSync } from "node:fs";
5
+ import { join as join2, dirname as dirname2 } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ // ../project-root-resolver/dist/index.js
9
+ import { existsSync } from "node:fs";
10
+ import { dirname, join } from "node:path";
11
+ function resolveProjectRoot(cwd, sentinel = ".orchestrator") {
12
+ let currentDir = cwd;
13
+ for (; ; ) {
14
+ if (existsSync(join(currentDir, sentinel))) {
15
+ return currentDir;
16
+ }
17
+ const parentDir = dirname(currentDir);
18
+ if (parentDir === currentDir) {
19
+ return null;
20
+ }
21
+ currentDir = parentDir;
22
+ }
23
+ }
24
+
25
+ // hooks/lib/api-client.ts
26
+ var __filename = fileURLToPath(import.meta.url);
27
+ var __dirname = dirname2(__filename);
28
+ var PROJECT_ROOT = join2(__dirname, "..", "..", "..");
29
+ var STATE_DIR = join2(PROJECT_ROOT, ".orchestrator", ".state");
30
+ var JWT_CACHE = join2(STATE_DIR, "jwt-token");
31
+ var DEBUG_LOG = join2(STATE_DIR, "hook-debug.log");
32
+ mkdirSync(STATE_DIR, { recursive: true });
33
+ var API_URL = process.env.ORCHESTRATOR_API_URL || "http://localhost:3001";
34
+ var AUTH_EMAIL = process.env.ORCHESTRATOR_ADMIN_EMAIL || process.env.ORCHESTRATOR_AUTH_EMAIL || "system@orchestrator.local";
35
+ var AUTH_PASSWORD = process.env.ORCHESTRATOR_ADMIN_PASSWORD || process.env.ORCHESTRATOR_AUTH_PASSWORD || "system123";
36
+ var PROJECT_ID = process.env.ORCHESTRATOR_PROJECT_ID || "";
37
+ function resolveHookProjectRoot(cwd) {
38
+ return resolveProjectRoot(cwd);
39
+ }
40
+ var projectIdResolutionAttempted = false;
41
+ async function ensureProjectIdResolved(token) {
42
+ if (PROJECT_ID || projectIdResolutionAttempted) return;
43
+ projectIdResolutionAttempted = true;
44
+ try {
45
+ const rootPath = resolveHookProjectRoot(process.cwd());
46
+ if (rootPath === null) {
47
+ log(
48
+ "API-CLIENT",
49
+ "ensureProjectIdResolved: cwd not registered (.orchestrator sentinel not found) \u2014 skipping"
50
+ );
51
+ return;
52
+ }
53
+ const resolved = await resolveProjectIdByPath(rootPath, token);
54
+ if (resolved) {
55
+ PROJECT_ID = resolved;
56
+ log(
57
+ "API-CLIENT",
58
+ `ensureProjectIdResolved: resolved projectId=${resolved} rootPath=${rootPath}`
59
+ );
60
+ } else {
61
+ log(
62
+ "API-CLIENT",
63
+ `ensureProjectIdResolved: rootPath=${rootPath} not registered to any project \u2014 skipping`
64
+ );
65
+ }
66
+ } catch (err) {
67
+ log(
68
+ "API-CLIENT",
69
+ `ensureProjectIdResolved: unexpected failure \u2014 ${err instanceof Error ? err.message : String(err)}`
70
+ );
71
+ }
72
+ }
73
+ function log(prefix, msg) {
74
+ const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z");
75
+ try {
76
+ const line = `[${ts}] ${prefix}: ${msg}
77
+ `;
78
+ writeFileSync(DEBUG_LOG, line, { flag: "a" });
79
+ } catch {
80
+ }
81
+ }
82
+ function getCachedToken() {
83
+ try {
84
+ const stat = statSync(JWT_CACHE);
85
+ const ageMs = Date.now() - stat.mtimeMs;
86
+ if (ageMs < 35e5) {
87
+ return readFileSync(JWT_CACHE, "utf-8").trim();
88
+ }
89
+ } catch {
90
+ }
91
+ return null;
92
+ }
93
+ async function login() {
94
+ try {
95
+ const resp = await fetch(`${API_URL}/api/v1/auth/login`, {
96
+ method: "POST",
97
+ headers: {
98
+ "Content-Type": "application/json",
99
+ "X-Project-ID": PROJECT_ID
100
+ },
101
+ body: JSON.stringify({ email: AUTH_EMAIL, password: AUTH_PASSWORD }),
102
+ signal: AbortSignal.timeout(5e3)
103
+ });
104
+ if (!resp.ok) return null;
105
+ const data = await resp.json();
106
+ const token = data.accessToken || data.data?.accessToken || "";
107
+ if (token) {
108
+ writeFileSync(JWT_CACHE, token);
109
+ }
110
+ return token || null;
111
+ } catch {
112
+ return null;
113
+ }
114
+ }
115
+ async function getToken() {
116
+ const token = getCachedToken() || await login();
117
+ if (token) {
118
+ await ensureProjectIdResolved(token);
119
+ }
120
+ return token;
121
+ }
122
+ async function apiGet(path, token, timeoutMs = 5e3) {
123
+ try {
124
+ const resp = await fetch(`${API_URL}${path}`, {
125
+ headers: {
126
+ Authorization: `Bearer ${token}`,
127
+ "X-Project-ID": PROJECT_ID
128
+ },
129
+ signal: AbortSignal.timeout(timeoutMs)
130
+ });
131
+ if (!resp.ok) return null;
132
+ return await resp.json();
133
+ } catch {
134
+ return null;
135
+ }
136
+ }
137
+ async function apiPost(path, token, body, timeoutMs = 5e3) {
138
+ try {
139
+ const resp = await fetch(`${API_URL}${path}`, {
140
+ method: "POST",
141
+ headers: {
142
+ "Content-Type": "application/json",
143
+ Authorization: `Bearer ${token}`,
144
+ "X-Project-ID": PROJECT_ID
145
+ },
146
+ body: JSON.stringify(body),
147
+ signal: AbortSignal.timeout(timeoutMs)
148
+ });
149
+ if (!resp.ok) return null;
150
+ return await resp.json();
151
+ } catch {
152
+ return null;
153
+ }
154
+ }
155
+ async function resolveProjectIdByPath(rootPath, token) {
156
+ const resp = await apiGet(
157
+ `/api/v1/projects/resolve?rootPath=${encodeURIComponent(rootPath)}`,
158
+ token
159
+ );
160
+ return resp?.projectId ?? null;
161
+ }
162
+ async function getActiveWorkflow() {
163
+ const token = await getToken();
164
+ if (!token) return null;
165
+ for (const status of ["in_progress", "awaiting_agent", "awaiting_approval"]) {
166
+ const resp = await apiGet(
167
+ `/api/v1/workflows?status=${status}&limit=1`,
168
+ token,
169
+ 3e3
170
+ );
171
+ const list = resp?.data || (Array.isArray(resp) ? resp : null);
172
+ const wf = list?.[0];
173
+ if (wf?.id) return wf;
174
+ }
175
+ return null;
176
+ }
177
+ async function getNextAction(workflowId) {
178
+ const token = await getToken();
179
+ if (!token) return null;
180
+ return apiGet(`/api/v1/workflows/${workflowId}/pending-action`, token);
181
+ }
182
+ async function detectWorkflow(prompt) {
183
+ const token = await getToken();
184
+ if (!token) return null;
185
+ return apiPost(`/api/v1/workflows/detect`, token, { prompt }, 3e3);
186
+ }
187
+ var LAST_COMPLETED_FILE = join2(STATE_DIR, "last-completed-workflow.json");
188
+ var LAST_COMPLETED_TTL_MS = 60 * 60 * 1e3;
189
+ var INVOCATIONS_DIR = join2(STATE_DIR, "invocations");
190
+ var INVOCATION_STATE_TTL_MS = 4 * 60 * 60 * 1e3;
191
+ var DISPATCH_INTENT_DIR = join2(STATE_DIR, "dispatch-intent");
192
+ async function readStdin() {
193
+ const chunks = [];
194
+ for await (const chunk of process.stdin) {
195
+ chunks.push(chunk);
196
+ }
197
+ const raw = Buffer.concat(chunks).toString("utf-8").trim();
198
+ if (!raw) return {};
199
+ try {
200
+ return JSON.parse(raw);
201
+ } catch {
202
+ return {};
203
+ }
204
+ }
205
+ function getField(obj, path) {
206
+ const parts = path.split(".");
207
+ let current = obj;
208
+ for (const part of parts) {
209
+ if (current == null || typeof current !== "object") return "";
210
+ current = current[part];
211
+ }
212
+ return current != null ? String(current) : "";
213
+ }
214
+ function outputContext(hookEvent, context) {
215
+ console.log(
216
+ JSON.stringify({
217
+ hookSpecificOutput: {
218
+ hookEventName: hookEvent,
219
+ additionalContext: context
220
+ }
221
+ })
222
+ );
223
+ }
224
+
225
+ // hooks/lib/sprint-context.ts
226
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "node:fs";
227
+ import { join as join3, dirname as dirname3 } from "node:path";
228
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
229
+ var __filename2 = fileURLToPath2(import.meta.url);
230
+ var __dirname2 = dirname3(__filename2);
231
+ var PROJECT_ROOT2 = join3(__dirname2, "..", "..", "..");
232
+ var SPRINT_CONTEXT_DIR = join3(PROJECT_ROOT2, ".claude", "sprint-context");
233
+ function contextPath(workflowId) {
234
+ return join3(SPRINT_CONTEXT_DIR, `${workflowId}.json`);
235
+ }
236
+ function readSprintContext(workflowId) {
237
+ try {
238
+ const filePath = contextPath(workflowId);
239
+ if (!existsSync2(filePath)) {
240
+ return null;
241
+ }
242
+ const raw = readFileSync2(filePath, "utf-8");
243
+ return JSON.parse(raw);
244
+ } catch {
245
+ return null;
246
+ }
247
+ }
248
+
249
+ // hooks/user-prompt.ts
250
+ var HOOK = "USER-PROMPT";
251
+ async function main() {
252
+ log(HOOK, "UserPromptSubmit triggered");
253
+ const stdin = await readStdin();
254
+ const workflow = await getActiveWorkflow();
255
+ if (!workflow) {
256
+ const prompt2 = getField(stdin, "prompt");
257
+ if (!prompt2) {
258
+ log(HOOK, "empty prompt, silence");
259
+ return;
260
+ }
261
+ const detection = await detectWorkflow(prompt2);
262
+ if (!detection) {
263
+ log(HOOK, "detect API failed/timeout, silence (fail-open)");
264
+ return;
265
+ }
266
+ const { workflowType, confidence, suggestedMode } = detection;
267
+ log(HOOK, `detected type=${workflowType} confidence=${confidence} mode=${suggestedMode}`);
268
+ if (workflowType === "interactive_analysis") {
269
+ outputContext(
270
+ "UserPromptSubmit",
271
+ [
272
+ "[ORCHESTRATOR] This looks like an analytical/design request. How would you like to proceed?",
273
+ "(a) Continue as a free conversation (no workflow)",
274
+ "(b) Start an interactive_analysis workflow for structured exploration (cyclic phases: research \u2192 discuss \u2192 analyze)",
275
+ "",
276
+ 'If you choose (b), I will call: mcp__orchestrator-tools__startWorkflow({ type: "interactive_analysis", prompt: "..." })'
277
+ ].join("\n")
278
+ );
279
+ return;
280
+ }
281
+ if (confidence >= 0.7) {
282
+ const mode = suggestedMode || "standard";
283
+ outputContext(
284
+ "UserPromptSubmit",
285
+ `[ORCHESTRATOR] Detected: ${workflowType} workflow (confidence: ${confidence}, suggested mode: ${mode}).
286
+ To start: mcp__orchestrator-tools__startWorkflow({ type: "${workflowType}", prompt: "...", mode: "${mode}" })
287
+ Or continue without a workflow if this is exploratory.`
288
+ );
289
+ return;
290
+ }
291
+ if (confidence >= 0.5) {
292
+ outputContext(
293
+ "UserPromptSubmit",
294
+ `[ORCHESTRATOR] Hint: this might be a ${workflowType} task. Consider starting a workflow if you plan to write code.`
295
+ );
296
+ return;
297
+ }
298
+ log(HOOK, `Tier 4 silence (confidence=${confidence} < 0.5)`);
299
+ return;
300
+ }
301
+ const prompt = getField(stdin, "prompt");
302
+ if (/brainstorm/i.test(prompt)) {
303
+ try {
304
+ const sprintCtx = readSprintContext(workflow.id);
305
+ if (sprintCtx) {
306
+ const previousSummary = sprintCtx.previousSprints.length === 0 ? "none" : sprintCtx.previousSprints.map((s) => `S${s.index}(${s.status})`).join(", ");
307
+ const brainstormContext = [
308
+ `[PARENT-DOC-CONTEXT] parentDocument=${sprintCtx.parentDocument} | sprint=${sprintCtx.sprintIndex} | scope=${sprintCtx.sprintScope} | previousSprints=${previousSummary}`,
309
+ `[ORCHESTRATOR] Include parent document context in this brainstorm. Read the RFC for background.`
310
+ ].join("\n");
311
+ log(HOOK, `brainstorm detected, injecting sprint context for workflow=${workflow.id}`);
312
+ outputContext("UserPromptSubmit", brainstormContext);
313
+ return;
314
+ }
315
+ } catch {
316
+ log(HOOK, "brainstorm context read failed, falling through to standard injection");
317
+ }
318
+ }
319
+ const action = await getNextAction(workflow.id);
320
+ let context;
321
+ if (action?.hasAction && action.pendingAction) {
322
+ context = `[ORCHESTRATOR] Active workflow: ${workflow.id}. Next: invoke '${action.pendingAction.agent}' (${action.pendingAction.status}).`;
323
+ } else {
324
+ context = `[ORCHESTRATOR] Active workflow: ${workflow.id}. No pending actions.`;
325
+ }
326
+ log(HOOK, `workflow=${workflow.id} hasAction=${action?.hasAction}`);
327
+ outputContext("UserPromptSubmit", context);
328
+ }
329
+ main().catch(() => process.exit(0));