@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
@@ -0,0 +1,463 @@
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 resolveProjectIdByPath(rootPath, token) {
138
+ const resp = await apiGet(
139
+ `/api/v1/projects/resolve?rootPath=${encodeURIComponent(rootPath)}`,
140
+ token
141
+ );
142
+ return resp?.projectId ?? null;
143
+ }
144
+ async function getWorkflowStatus(workflowId) {
145
+ const token = await getToken();
146
+ if (!token) return null;
147
+ return apiGet(`/api/v1/workflows/${workflowId}/status`, token);
148
+ }
149
+ async function getWorkflowMode(workflowId) {
150
+ const status = await getWorkflowStatus(workflowId);
151
+ if (!status) return null;
152
+ return status.executionMode ?? status.mode ?? null;
153
+ }
154
+ async function getNextAction(workflowId) {
155
+ const token = await getToken();
156
+ if (!token) return null;
157
+ return apiGet(`/api/v1/workflows/${workflowId}/pending-action`, token);
158
+ }
159
+ var LAST_COMPLETED_FILE = join2(STATE_DIR, "last-completed-workflow.json");
160
+ var LAST_COMPLETED_TTL_MS = 60 * 60 * 1e3;
161
+ var INVOCATIONS_DIR = join2(STATE_DIR, "invocations");
162
+ var INVOCATION_STATE_TTL_MS = 4 * 60 * 60 * 1e3;
163
+ var DISPATCH_INTENT_DIR = join2(STATE_DIR, "dispatch-intent");
164
+ async function getWorkflowTypeAndVariant(workflowId, token) {
165
+ try {
166
+ const resp = await apiGet(`/api/v1/workflows/${workflowId}/status`, token);
167
+ if (!resp) return null;
168
+ const { type, variant } = resp;
169
+ if (!type || !variant) return null;
170
+ return { type, variant };
171
+ } catch {
172
+ return null;
173
+ }
174
+ }
175
+ async function getGateCellMode(typeId, variant, gateKey, token) {
176
+ try {
177
+ const resp = await apiGet(`/api/v1/workflow-definitions/${typeId}`, token);
178
+ if (!resp) return null;
179
+ const cell = resp.modes?.[variant]?.gates?.[gateKey];
180
+ if (cell === "REQ" || cell === "OPT" || cell === "SKIP") return cell;
181
+ return null;
182
+ } catch {
183
+ return null;
184
+ }
185
+ }
186
+ async function getAdversarialVerdict(workflowId, token) {
187
+ try {
188
+ const resp = await apiGet(`/api/v1/artifact-content/${workflowId}/adversarial_review`, token);
189
+ if (!resp) return null;
190
+ const { verdict, iteration } = resp.metadata ?? {};
191
+ if (typeof verdict !== "string" || typeof iteration !== "number") return null;
192
+ return { verdict, iteration };
193
+ } catch {
194
+ return null;
195
+ }
196
+ }
197
+ async function readStdin() {
198
+ const chunks = [];
199
+ for await (const chunk of process.stdin) {
200
+ chunks.push(chunk);
201
+ }
202
+ const raw = Buffer.concat(chunks).toString("utf-8").trim();
203
+ if (!raw) return {};
204
+ try {
205
+ return JSON.parse(raw);
206
+ } catch {
207
+ return {};
208
+ }
209
+ }
210
+ function getField(obj, path) {
211
+ const parts = path.split(".");
212
+ let current = obj;
213
+ for (const part of parts) {
214
+ if (current == null || typeof current !== "object") return "";
215
+ current = current[part];
216
+ }
217
+ return current != null ? String(current) : "";
218
+ }
219
+ function outputPreToolUse(opts) {
220
+ const output = {
221
+ hookSpecificOutput: {
222
+ hookEventName: "PreToolUse",
223
+ permissionDecision: opts.decision,
224
+ ...opts.reason && { permissionDecisionReason: opts.reason },
225
+ ...opts.context && { additionalContext: opts.context }
226
+ }
227
+ };
228
+ console.log(JSON.stringify(output));
229
+ }
230
+
231
+ // hooks/lib/gate-logic.ts
232
+ function classifyRisk(targetPhase) {
233
+ if (/implement|deploy|migrate|delete/i.test(targetPhase)) {
234
+ return "HIGH";
235
+ }
236
+ return "LOW";
237
+ }
238
+ function deriveGateStrategy(ctx) {
239
+ if (ctx.riskLevel === "HIGH") {
240
+ return {
241
+ strategy: "ASK_HUMAN",
242
+ reason: `Phase '${ctx.targetPhase}' is high-risk and requires human approval before proceeding.`
243
+ };
244
+ }
245
+ return {
246
+ strategy: "AUTO_APPROVE",
247
+ reason: `Phase '${ctx.targetPhase}' is low-risk \u2014 auto-approved.`
248
+ };
249
+ }
250
+
251
+ // hooks/gate-guardian.ts
252
+ var HOOK = "GATE-GUARDIAN";
253
+ var PME_HARD_CAP = 3;
254
+ var defaultDeps = {
255
+ readStdin,
256
+ getWorkflowMode,
257
+ getToken,
258
+ getNextAction,
259
+ getWorkflowTypeAndVariant,
260
+ getGateCellMode,
261
+ getAdversarialVerdict,
262
+ output: outputPreToolUse,
263
+ log
264
+ };
265
+ async function mainWithDeps(deps) {
266
+ const {
267
+ readStdin: readStdin2,
268
+ getWorkflowMode: getWorkflowMode2,
269
+ getToken: getToken2,
270
+ getNextAction: getNextAction2,
271
+ getWorkflowTypeAndVariant: getWorkflowTypeAndVariant2,
272
+ getGateCellMode: getGateCellMode2,
273
+ getAdversarialVerdict: getAdversarialVerdict2,
274
+ output,
275
+ log: log2
276
+ } = deps;
277
+ const stdin = await readStdin2();
278
+ log2(HOOK, "PreToolUse advancePhase triggered");
279
+ const workflowId = getField(stdin, "tool_input.workflowId") || getField(stdin, "workflowId");
280
+ const targetPhase = getField(stdin, "tool_input.targetPhase") || getField(stdin, "targetPhase");
281
+ log2(HOOK, `workflow=${workflowId} targetPhase=${targetPhase}`);
282
+ if (workflowId) {
283
+ const mode = await getWorkflowMode2(workflowId);
284
+ log2(HOOK, `workflow=${workflowId} mode=${mode ?? "legacy"}`);
285
+ if (mode === "quick") {
286
+ output({
287
+ decision: "allow",
288
+ context: `[GATE] AUTO_APPROVE: quick mode skips gate evaluation for '${targetPhase}'.`
289
+ });
290
+ log2(HOOK, `ALLOW quick mode phase=${targetPhase}`);
291
+ return;
292
+ }
293
+ if (mode === "interactive") {
294
+ output({
295
+ decision: "allow",
296
+ context: `[GATE] AUTO_APPROVE: interactive mode skips artifact gate evaluation for '${targetPhase}'.`
297
+ });
298
+ log2(HOOK, `ALLOW interactive mode phase=${targetPhase}`);
299
+ return;
300
+ }
301
+ }
302
+ if (!workflowId || !targetPhase) {
303
+ log2(HOOK, "DENY (could not parse input)");
304
+ output({
305
+ decision: "deny",
306
+ reason: "Gate Guardian: Could not parse workflowId or targetPhase.",
307
+ context: "Ensure you pass both workflowId and targetPhase to advancePhase."
308
+ });
309
+ return;
310
+ }
311
+ const token = await getToken2();
312
+ if (token === null || token === "") {
313
+ log2(HOOK, "DENY (auth failed)");
314
+ output({
315
+ decision: "deny",
316
+ reason: "Gate Guardian: Authentication failed.",
317
+ context: "Check ORCHESTRATOR_ADMIN_EMAIL, ORCHESTRATOR_ADMIN_PASSWORD, ORCHESTRATOR_PROJECT_ID env vars."
318
+ });
319
+ return;
320
+ }
321
+ {
322
+ const typeVariant = await getWorkflowTypeAndVariant2(workflowId, token);
323
+ if (typeVariant?.type === "project_management_enterprise") {
324
+ const gateMode = await getGateCellMode2(
325
+ typeVariant.type,
326
+ typeVariant.variant,
327
+ "adversarial",
328
+ token
329
+ );
330
+ if (gateMode === "REQ") {
331
+ const verdict = await getAdversarialVerdict2(workflowId, token);
332
+ if (!verdict) {
333
+ log2(
334
+ HOOK,
335
+ `PME Step 5.5: no adversarial artifact found \u2014 fail-open ALLOW wf=${workflowId}`
336
+ );
337
+ output({
338
+ decision: "allow",
339
+ context: `[GATE] PME adversarial gate: no artifact found, fail-open ALLOW for '${targetPhase}'.`
340
+ });
341
+ return;
342
+ }
343
+ if (verdict.iteration >= PME_HARD_CAP) {
344
+ log2(
345
+ HOOK,
346
+ `PME Step 5.5: BLOCKED escalation at hard cap (iteration=${String(verdict.iteration)}) \u2014 ALLOW wf=${workflowId}`
347
+ );
348
+ output({
349
+ decision: "allow",
350
+ context: `[GATE] PME adversarial gate: hard cap reached (iteration=${String(verdict.iteration)}/${String(PME_HARD_CAP)}), escalating.`
351
+ });
352
+ return;
353
+ }
354
+ if (verdict.verdict === "PASS") {
355
+ log2(HOOK, `PME Step 5.5: adversarial verdict=PASS \u2014 ALLOW wf=${workflowId}`);
356
+ output({
357
+ decision: "allow",
358
+ context: `[GATE] PME adversarial gate: verdict=PASS, proceeding to '${targetPhase}'.`
359
+ });
360
+ return;
361
+ }
362
+ log2(
363
+ HOOK,
364
+ `PME Step 5.5: DENY verdict=${verdict.verdict} iteration=${String(verdict.iteration)} wf=${workflowId}`
365
+ );
366
+ output({
367
+ decision: "deny",
368
+ reason: `Gate Guardian: adversarial_review required \u2014 verdict=${verdict.verdict}, iteration=${String(verdict.iteration)}. Resolve adversarial review before advancing.`
369
+ });
370
+ return;
371
+ }
372
+ log2(
373
+ HOOK,
374
+ `PME Step 5.5: gateMode=${gateMode ?? "null"} \u2014 ALLOW (non-REQ gate) wf=${workflowId}`
375
+ );
376
+ output({
377
+ decision: "allow",
378
+ context: `[GATE] PME adversarial gate: mode=${gateMode ?? "none"} (non-REQ), proceeding to '${targetPhase}'.`
379
+ });
380
+ return;
381
+ }
382
+ }
383
+ if (/implement/i.test(targetPhase)) {
384
+ log2(HOOK, "Checking approval for IMPLEMENT-type phase");
385
+ const action = await getNextAction2(workflowId);
386
+ const status = action?.pendingAction?.status ?? "";
387
+ if (status === "approved" || status === "awaiting_agent") {
388
+ output({
389
+ decision: "allow",
390
+ context: `[GATE] IMPLEMENT approved (status=${status}): proceeding to phase '${targetPhase}'.`
391
+ });
392
+ log2(
393
+ HOOK,
394
+ JSON.stringify({
395
+ hook: "gate-guardian",
396
+ strategy: "IMPLEMENT_APPROVED",
397
+ targetPhase,
398
+ workflowId
399
+ })
400
+ );
401
+ return;
402
+ }
403
+ output({
404
+ decision: "deny",
405
+ reason: `Gate Guardian: IMPLEMENT requires human approval. Status: ${status || "not-set"}.`,
406
+ context: "Ask the user for approval first. Then call mcp__orchestrator-tools__approveAction."
407
+ });
408
+ log2(
409
+ HOOK,
410
+ JSON.stringify({
411
+ hook: "gate-guardian",
412
+ strategy: "IMPLEMENT_DENIED",
413
+ targetPhase,
414
+ workflowId,
415
+ reason: "pending-action not approved"
416
+ })
417
+ );
418
+ return;
419
+ }
420
+ const riskLevel = classifyRisk(targetPhase);
421
+ const ctx = {
422
+ workflowId,
423
+ targetPhase,
424
+ // Reserved for Phase 5+6 — will be populated when OLAP integration provides
425
+ // workflow context. Currently unused by deriveGateStrategy().
426
+ currentPhase: "",
427
+ executionMode: null,
428
+ workflowMode: null,
429
+ riskLevel
430
+ };
431
+ const decision = deriveGateStrategy(ctx);
432
+ log2(
433
+ HOOK,
434
+ JSON.stringify({ strategy: decision.strategy, targetPhase, riskLevel, reason: decision.reason })
435
+ );
436
+ switch (decision.strategy) {
437
+ case "AUTO_APPROVE":
438
+ output({
439
+ decision: "allow",
440
+ context: `[GATE] AUTO_APPROVE: ${decision.reason}`
441
+ });
442
+ break;
443
+ case "ASK_HUMAN":
444
+ output({
445
+ decision: "deny",
446
+ reason: `Gate Guardian: ${decision.reason} Ask user for approval.`
447
+ });
448
+ break;
449
+ case "BLOCK_AND_REQUIRE":
450
+ output({
451
+ decision: "deny",
452
+ reason: `Gate Guardian BLOCKED: ${decision.reason}. Required: ${decision.requiredAction ?? "unspecified"}.`
453
+ });
454
+ break;
455
+ }
456
+ }
457
+ async function main() {
458
+ await mainWithDeps(defaultDeps);
459
+ }
460
+ main().catch(() => process.exit(0));
461
+ export {
462
+ mainWithDeps
463
+ };