@camilyos/codex-antigravity-kit 0.1.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.
package/dist/cli.cjs ADDED
@@ -0,0 +1,1808 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/cli.ts
5
+ var import_commander = require("commander");
6
+ var import_node_path6 = require("path");
7
+
8
+ // src/commands/brainstorm.ts
9
+ var import_node_fs3 = require("fs");
10
+
11
+ // src/core/agent-router.ts
12
+ var import_node_fs = require("fs");
13
+ var import_node_path = require("path");
14
+ var KNOWN_AGENTS = {
15
+ "web-engineer": {
16
+ id: "web-engineer",
17
+ name: "Web Engineer",
18
+ agentFile: "web-engineer.md",
19
+ skillFile: "web-engineering.md",
20
+ description: "Modern web fullstack architecture, frontend, APIs, CSS, and performance",
21
+ keywords: [
22
+ "web",
23
+ "frontend",
24
+ "backend",
25
+ "html",
26
+ "css",
27
+ "react",
28
+ "next.js",
29
+ "nextjs",
30
+ "vue",
31
+ "svelte",
32
+ "angular",
33
+ "rest api",
34
+ "graphql",
35
+ "websocket",
36
+ "http",
37
+ "endpoint",
38
+ "tailwind",
39
+ "responsive",
40
+ "core web vitals",
41
+ "lcp",
42
+ "inp",
43
+ "browser",
44
+ "dom"
45
+ ],
46
+ repoIndicators: [
47
+ "next.config.js",
48
+ "next.config.mjs",
49
+ "next.config.ts",
50
+ "vite.config.ts",
51
+ "vite.config.js",
52
+ "svelte.config.js",
53
+ "angular.json",
54
+ "tsconfig.json"
55
+ ]
56
+ },
57
+ "mobile-engineer": {
58
+ id: "mobile-engineer",
59
+ name: "Mobile Engineer",
60
+ agentFile: "mobile-engineer.md",
61
+ skillFile: "mobile-engineering.md",
62
+ description: "Mobile applications across Native (iOS/Android) and Cross-Platform (Flutter, React Native)",
63
+ keywords: [
64
+ "mobile",
65
+ "ios",
66
+ "android",
67
+ "flutter",
68
+ "dart",
69
+ "react native",
70
+ "react-native",
71
+ "expo",
72
+ "swift",
73
+ "swiftui",
74
+ "uikit",
75
+ "kotlin",
76
+ "jetpack compose",
77
+ "apk",
78
+ "ipa",
79
+ "push notification",
80
+ "biometrics",
81
+ "app store",
82
+ "play store",
83
+ "offline-first",
84
+ "sqlite"
85
+ ],
86
+ repoIndicators: [
87
+ "pubspec.yaml",
88
+ "Podfile",
89
+ "android/build.gradle",
90
+ "ios/Podfile",
91
+ "build.gradle",
92
+ "build.gradle.kts"
93
+ ]
94
+ },
95
+ "game-engineer": {
96
+ id: "game-engineer",
97
+ name: "Game Engineer",
98
+ agentFile: "game-engineer.md",
99
+ skillFile: "game-engineering.md",
100
+ description: "Game architecture and mechanics across Unity, Godot, and Cocos Creator",
101
+ keywords: [
102
+ "game",
103
+ "gameplay",
104
+ "game loop",
105
+ "unity",
106
+ "godot",
107
+ "cocos",
108
+ "cocos creator",
109
+ "physics",
110
+ "rigidbody",
111
+ "collider",
112
+ "collision",
113
+ "sprite",
114
+ "tilemap",
115
+ "prefab",
116
+ "shader",
117
+ "draw call",
118
+ "fps",
119
+ "ecs",
120
+ "fixedupdate",
121
+ "_physics_process",
122
+ "player controller"
123
+ ],
124
+ repoIndicators: [
125
+ "project.godot",
126
+ "ProjectSettings/ProjectVersion.txt",
127
+ "Assets",
128
+ "cocos.config.json",
129
+ "project.json"
130
+ ]
131
+ },
132
+ "researcher": {
133
+ id: "researcher",
134
+ name: "Technical Researcher",
135
+ agentFile: "researcher.md",
136
+ skillFile: "research.md",
137
+ description: "Deep technical research, feasibility studies, spikes, and architecture trade-offs",
138
+ keywords: [
139
+ "research",
140
+ "spike",
141
+ "feasibility",
142
+ "investigate",
143
+ "benchmark",
144
+ "comparison",
145
+ "trade-off",
146
+ "tradeoff",
147
+ "evaluate library",
148
+ "proof of concept",
149
+ "poc",
150
+ "state-of-the-art",
151
+ "options analysis",
152
+ "architectural evaluation"
153
+ ],
154
+ repoIndicators: []
155
+ },
156
+ "business-analyst": {
157
+ id: "business-analyst",
158
+ name: "Business Analyst",
159
+ agentFile: "business-analyst.md",
160
+ skillFile: "requirements-analysis.md",
161
+ description: "Requirements elicitation, user stories, domain modeling, and Gherkin acceptance criteria",
162
+ keywords: [
163
+ "requirements",
164
+ "requirement",
165
+ "user story",
166
+ "user stories",
167
+ "acceptance criteria",
168
+ "given ",
169
+ "when ",
170
+ "then ",
171
+ "persona",
172
+ "personas",
173
+ "business logic",
174
+ "prd",
175
+ "functional requirement",
176
+ "non-functional",
177
+ "workflow diagram",
178
+ "user journey"
179
+ ],
180
+ repoIndicators: []
181
+ },
182
+ "codex": {
183
+ id: "codex",
184
+ name: "Codex Lead",
185
+ agentFile: "codex.md",
186
+ skillFile: "codex-workflow.md",
187
+ description: "General technical lead, architect, and orchestrator",
188
+ keywords: ["orchestration", "workflow", "general", "architecture"],
189
+ repoIndicators: []
190
+ }
191
+ };
192
+ function detectAgent(options) {
193
+ const { root, content = "", explicitAgent } = options;
194
+ if (explicitAgent && explicitAgent.trim().length > 0) {
195
+ const normalized = explicitAgent.trim().toLowerCase();
196
+ const match = KNOWN_AGENTS[normalized];
197
+ if (!match) {
198
+ const valid = Object.keys(KNOWN_AGENTS).join(", ");
199
+ throw new Error(`Unknown agent: "${explicitAgent}". Available agents: ${valid}`);
200
+ }
201
+ return {
202
+ agent: match,
203
+ isExplicit: true,
204
+ confidence: 1,
205
+ reason: `Explicitly requested via --agent ${match.id}`,
206
+ instructions: loadAgentInstructions(root, match.agentFile),
207
+ skillInstructions: loadSkillInstructions(root, match.skillFile)
208
+ };
209
+ }
210
+ const normalizedText = ` ${content.toLowerCase()} `;
211
+ const candidateScores = {
212
+ "game-engineer": { score: 0, reasons: [] },
213
+ "mobile-engineer": { score: 0, reasons: [] },
214
+ "web-engineer": { score: 0, reasons: [] },
215
+ "researcher": { score: 0, reasons: [] },
216
+ "business-analyst": { score: 0, reasons: [] }
217
+ };
218
+ for (const [id, candidate] of Object.entries(candidateScores)) {
219
+ const def = KNOWN_AGENTS[id];
220
+ if (!def) continue;
221
+ for (const kw of def.keywords) {
222
+ if (normalizedText.includes(kw)) {
223
+ candidate.score += 2;
224
+ if (candidate.reasons.length < 3) {
225
+ candidate.reasons.push(`keyword "${kw}"`);
226
+ }
227
+ }
228
+ }
229
+ }
230
+ for (const [id, candidate] of Object.entries(candidateScores)) {
231
+ const def = KNOWN_AGENTS[id];
232
+ if (!def) continue;
233
+ for (const fileIndicator of def.repoIndicators) {
234
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(root, fileIndicator))) {
235
+ candidate.score += 3;
236
+ if (candidate.reasons.length < 4) {
237
+ candidate.reasons.push(`repo file "${fileIndicator}"`);
238
+ }
239
+ }
240
+ }
241
+ }
242
+ const packageJsonPath = (0, import_node_path.join)(root, "package.json");
243
+ if ((0, import_node_fs.existsSync)(packageJsonPath)) {
244
+ try {
245
+ const rawPkg = (0, import_node_fs.readFileSync)(packageJsonPath, "utf8");
246
+ if (rawPkg.includes("react-native") || rawPkg.includes("expo")) {
247
+ candidateScores["mobile-engineer"].score += 3;
248
+ candidateScores["mobile-engineer"].reasons.push("package.json (react-native)");
249
+ } else if (rawPkg.includes("react") || rawPkg.includes("next") || rawPkg.includes("vue") || rawPkg.includes("svelte")) {
250
+ candidateScores["web-engineer"].score += 2;
251
+ candidateScores["web-engineer"].reasons.push("package.json (web framework)");
252
+ }
253
+ } catch {
254
+ }
255
+ }
256
+ let bestCandidateId = "codex";
257
+ let maxScore = 0;
258
+ let matchReasons = [];
259
+ for (const [id, data] of Object.entries(candidateScores)) {
260
+ if (data.score > maxScore) {
261
+ maxScore = data.score;
262
+ bestCandidateId = id;
263
+ matchReasons = data.reasons;
264
+ }
265
+ }
266
+ const selectedDef = KNOWN_AGENTS[bestCandidateId] ?? KNOWN_AGENTS["codex"];
267
+ const confidence = Math.min(1, maxScore / 6);
268
+ const reason = maxScore > 0 ? `Auto-detected based on ${matchReasons.join(", ")}` : "Defaulted to Codex General Lead (no specific domain signals found)";
269
+ return {
270
+ agent: selectedDef,
271
+ isExplicit: false,
272
+ confidence,
273
+ reason,
274
+ instructions: loadAgentInstructions(root, selectedDef.agentFile),
275
+ skillInstructions: loadSkillInstructions(root, selectedDef.skillFile)
276
+ };
277
+ }
278
+ function loadAgentInstructions(root, fileName) {
279
+ const customPath = (0, import_node_path.join)(root, ".codex", "agents", fileName);
280
+ if ((0, import_node_fs.existsSync)(customPath)) {
281
+ return (0, import_node_fs.readFileSync)(customPath, "utf8");
282
+ }
283
+ return "";
284
+ }
285
+ function loadSkillInstructions(root, fileName) {
286
+ const customPath = (0, import_node_path.join)(root, ".codex", "skills", fileName);
287
+ if ((0, import_node_fs.existsSync)(customPath)) {
288
+ return (0, import_node_fs.readFileSync)(customPath, "utf8");
289
+ }
290
+ return "";
291
+ }
292
+
293
+ // src/core/state-machine.ts
294
+ var WorkflowState = /* @__PURE__ */ ((WorkflowState2) => {
295
+ WorkflowState2["IDLE"] = "IDLE";
296
+ WorkflowState2["DISCOVERY"] = "DISCOVERY";
297
+ WorkflowState2["CLARIFICATION_REQUIRED"] = "CLARIFICATION_REQUIRED";
298
+ WorkflowState2["BRAINSTORMING"] = "BRAINSTORMING";
299
+ WorkflowState2["PLANNING"] = "PLANNING";
300
+ WorkflowState2["READY"] = "READY";
301
+ WorkflowState2["IMPLEMENTING"] = "IMPLEMENTING";
302
+ WorkflowState2["VERIFYING"] = "VERIFYING";
303
+ WorkflowState2["REVIEWING"] = "REVIEWING";
304
+ WorkflowState2["REPAIR_REQUIRED"] = "REPAIR_REQUIRED";
305
+ WorkflowState2["COMPLETED"] = "COMPLETED";
306
+ WorkflowState2["BLOCKED"] = "BLOCKED";
307
+ WorkflowState2["ESCALATION_REQUIRED"] = "ESCALATION_REQUIRED";
308
+ return WorkflowState2;
309
+ })(WorkflowState || {});
310
+ var transitions = {
311
+ ["IDLE" /* IDLE */]: ["DISCOVERY" /* DISCOVERY */],
312
+ ["DISCOVERY" /* DISCOVERY */]: [
313
+ "CLARIFICATION_REQUIRED" /* CLARIFICATION_REQUIRED */,
314
+ "BRAINSTORMING" /* BRAINSTORMING */
315
+ ],
316
+ ["CLARIFICATION_REQUIRED" /* CLARIFICATION_REQUIRED */]: [
317
+ "BRAINSTORMING" /* BRAINSTORMING */,
318
+ "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */
319
+ ],
320
+ ["BRAINSTORMING" /* BRAINSTORMING */]: ["PLANNING" /* PLANNING */],
321
+ ["PLANNING" /* PLANNING */]: ["READY" /* READY */],
322
+ ["READY" /* READY */]: ["IMPLEMENTING" /* IMPLEMENTING */],
323
+ ["IMPLEMENTING" /* IMPLEMENTING */]: [
324
+ "VERIFYING" /* VERIFYING */,
325
+ "BLOCKED" /* BLOCKED */,
326
+ "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */
327
+ ],
328
+ ["VERIFYING" /* VERIFYING */]: ["REVIEWING" /* REVIEWING */, "BLOCKED" /* BLOCKED */],
329
+ ["REVIEWING" /* REVIEWING */]: [
330
+ "COMPLETED" /* COMPLETED */,
331
+ "REPAIR_REQUIRED" /* REPAIR_REQUIRED */,
332
+ "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */,
333
+ "BLOCKED" /* BLOCKED */
334
+ ],
335
+ ["REPAIR_REQUIRED" /* REPAIR_REQUIRED */]: ["IMPLEMENTING" /* IMPLEMENTING */],
336
+ ["COMPLETED" /* COMPLETED */]: ["IDLE" /* IDLE */],
337
+ ["BLOCKED" /* BLOCKED */]: ["ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */],
338
+ ["ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */]: ["IDLE" /* IDLE */]
339
+ };
340
+ function canTransition(from, to) {
341
+ return transitions[from].includes(to);
342
+ }
343
+ function transitionOrThrow(from, to) {
344
+ if (!canTransition(from, to)) {
345
+ throw new Error(`Invalid state transition: ${from} -> ${to}`);
346
+ }
347
+ return to;
348
+ }
349
+
350
+ // src/fs/workflow-store.ts
351
+ var import_node_fs2 = require("fs");
352
+ var import_node_path2 = require("path");
353
+ var WorkflowStore = class {
354
+ root;
355
+ workflowDir;
356
+ tasksDir;
357
+ statePath;
358
+ configPath;
359
+ constructor(root) {
360
+ this.root = root;
361
+ this.workflowDir = (0, import_node_path2.join)(root, ".agent-workflow");
362
+ this.tasksDir = (0, import_node_path2.join)(this.workflowDir, "tasks");
363
+ this.statePath = (0, import_node_path2.join)(this.workflowDir, "STATE.md");
364
+ this.configPath = (0, import_node_path2.join)(this.workflowDir, "config.json");
365
+ }
366
+ ensureBaseStructure() {
367
+ (0, import_node_fs2.mkdirSync)(this.workflowDir, { recursive: true });
368
+ (0, import_node_fs2.mkdirSync)(this.tasksDir, { recursive: true });
369
+ }
370
+ ensureTask(taskId) {
371
+ const taskDir = (0, import_node_path2.join)(this.tasksDir, taskId);
372
+ (0, import_node_fs2.mkdirSync)(taskDir, { recursive: true });
373
+ return taskDir;
374
+ }
375
+ writeTaskFile(taskId, fileName, content) {
376
+ const taskDir = this.ensureTask(taskId);
377
+ const path = (0, import_node_path2.join)(taskDir, fileName);
378
+ (0, import_node_fs2.writeFileSync)(path, content, "utf8");
379
+ return path;
380
+ }
381
+ readTaskFile(taskId, fileName) {
382
+ const path = (0, import_node_path2.join)(this.tasksDir, taskId, fileName);
383
+ return (0, import_node_fs2.readFileSync)(path, "utf8");
384
+ }
385
+ hasTaskFile(taskId, fileName) {
386
+ const path = (0, import_node_path2.join)(this.tasksDir, taskId, fileName);
387
+ return (0, import_node_fs2.existsSync)(path);
388
+ }
389
+ writeConfig(config) {
390
+ this.ensureBaseStructure();
391
+ (0, import_node_fs2.writeFileSync)(this.configPath, `${JSON.stringify(config, null, 2)}
392
+ `, "utf8");
393
+ }
394
+ readConfig() {
395
+ const raw = (0, import_node_fs2.readFileSync)(this.configPath, "utf8");
396
+ return JSON.parse(raw);
397
+ }
398
+ writeState(snapshot) {
399
+ this.ensureBaseStructure();
400
+ const content = toStateMarkdown(snapshot);
401
+ (0, import_node_fs2.writeFileSync)(this.statePath, content, "utf8");
402
+ }
403
+ readState() {
404
+ if (!(0, import_node_fs2.existsSync)(this.statePath)) {
405
+ return defaultState();
406
+ }
407
+ const raw = (0, import_node_fs2.readFileSync)(this.statePath, "utf8");
408
+ return parseStateMarkdown(raw);
409
+ }
410
+ };
411
+ function defaultState() {
412
+ return {
413
+ state: "IDLE" /* IDLE */,
414
+ currentPhase: "none",
415
+ currentTask: "none",
416
+ reviewAttempt: 0,
417
+ repairAttempt: 0,
418
+ nextAction: "Run init",
419
+ blockingIssues: [],
420
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
421
+ };
422
+ }
423
+ function toStateMarkdown(snapshot) {
424
+ const issues = snapshot.blockingIssues.length === 0 ? "- None" : snapshot.blockingIssues.map((issue) => `- ${issue}`).join("\n");
425
+ return [
426
+ "# Current State",
427
+ "",
428
+ `State: ${snapshot.state}`,
429
+ `Current phase: ${snapshot.currentPhase}`,
430
+ `Current task: ${snapshot.currentTask}`,
431
+ `Review attempt: ${snapshot.reviewAttempt}`,
432
+ `Repair attempt: ${snapshot.repairAttempt}`,
433
+ "",
434
+ "## Blocking Issues",
435
+ issues,
436
+ "",
437
+ "## Next",
438
+ snapshot.nextAction,
439
+ "",
440
+ `Updated at: ${snapshot.updatedAt}`,
441
+ ""
442
+ ].join("\n");
443
+ }
444
+ function parseStateMarkdown(markdown) {
445
+ const line = (prefix) => markdown.split(/\r?\n/).find((item) => item.startsWith(prefix))?.slice(prefix.length).trim();
446
+ const stateValue = line("State: ");
447
+ const currentPhase = line("Current phase: ") ?? "none";
448
+ const currentTask = line("Current task: ") ?? "none";
449
+ const reviewAttempt = Number(line("Review attempt: ") ?? "0");
450
+ const repairAttempt = Number(line("Repair attempt: ") ?? "0");
451
+ const updatedAt = line("Updated at: ") ?? (/* @__PURE__ */ new Date()).toISOString();
452
+ const state = Object.values(WorkflowState).find((value) => value === stateValue) ?? "IDLE" /* IDLE */;
453
+ const nextSection = markdown.split("## Next\n")[1] ?? "";
454
+ const nextAction = (nextSection.split(/\r?\n/)[0] ?? "Run init").trim();
455
+ const blockingSection = markdown.split("## Blocking Issues\n")[1] ?? "";
456
+ const blockingRaw = blockingSection.split("\n## Next")[0] ?? "";
457
+ const blockingIssues = blockingRaw.split(/\r?\n/).map((item) => item.trim()).filter((item) => item.startsWith("- ") && item !== "- None").map((item) => item.slice(2));
458
+ return {
459
+ state,
460
+ currentPhase,
461
+ currentTask,
462
+ reviewAttempt,
463
+ repairAttempt,
464
+ nextAction,
465
+ blockingIssues,
466
+ updatedAt
467
+ };
468
+ }
469
+
470
+ // src/commands/brainstorm.ts
471
+ function runBrainstorm(options) {
472
+ const store = new WorkflowStore(options.root);
473
+ store.ensureBaseStructure();
474
+ let spec = "";
475
+ if (options.spec && (0, import_node_fs3.existsSync)(options.spec)) {
476
+ spec = (0, import_node_fs3.readFileSync)(options.spec, "utf8");
477
+ store.writeTaskFile(options.task, "SPEC.md", spec);
478
+ } else if (options.prompt) {
479
+ spec = options.prompt;
480
+ store.writeTaskFile(options.task, "SPEC.md", spec);
481
+ } else if (store.hasTaskFile(options.task, "SPEC.md")) {
482
+ spec = store.readTaskFile(options.task, "SPEC.md");
483
+ } else {
484
+ throw new Error(
485
+ `Missing spec for task ${options.task}. Provide --spec <path>, --prompt <text>, or create .agent-workflow/tasks/${options.task}/SPEC.md`
486
+ );
487
+ }
488
+ const agentResolution = detectAgent({
489
+ root: options.root,
490
+ content: spec,
491
+ explicitAgent: options.agent
492
+ });
493
+ console.log(`[Agent Router] Assigned: ${agentResolution.agent.name} (${agentResolution.agent.id})`);
494
+ console.log(`[Agent Router] Reason: ${agentResolution.reason}`);
495
+ const brainstorm = buildBrainstormMarkdown(options.task, spec, agentResolution);
496
+ store.writeTaskFile(options.task, "BRAINSTORM.md", brainstorm);
497
+ const state = store.readState();
498
+ state.state = "DISCOVERY" /* DISCOVERY */;
499
+ state.state = "BRAINSTORMING" /* BRAINSTORMING */;
500
+ state.currentTask = options.task;
501
+ state.currentPhase = "brainstorming";
502
+ state.nextAction = "Run plan command to convert brainstorm into phases and tasks";
503
+ state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
504
+ store.writeState(state);
505
+ console.log(brainstorm);
506
+ }
507
+ function buildBrainstormMarkdown(task, spec, agentResolution) {
508
+ return [
509
+ "# Brainstorm",
510
+ "",
511
+ `Task: ${task}`,
512
+ `Assigned Agent: ${agentResolution.agent.name} (${agentResolution.agent.id})`,
513
+ `Agent Selection: ${agentResolution.reason}`,
514
+ "",
515
+ "## Goal",
516
+ `Task ${task}`,
517
+ "",
518
+ "## Current System",
519
+ "Repository contains an orchestration kit with Codex planning and Antigravity execution boundaries.",
520
+ "",
521
+ "## Requirements",
522
+ spec.trim(),
523
+ "",
524
+ "## Constraints",
525
+ "- Keep context small and deterministic",
526
+ "- Use filesystem artifacts as durable state",
527
+ "- Do not invent requirements",
528
+ "",
529
+ "## Relevant Existing Architecture",
530
+ "- Codex owns clarification, planning, review, and verification",
531
+ "- Antigravity owns implementation",
532
+ "- Agy is the worker CLI bridge",
533
+ "",
534
+ "## Options Considered",
535
+ "### Option A",
536
+ "Pros: Simple artifact-first workflow",
537
+ "Cons: Requires explicit commands",
538
+ "",
539
+ "### Option B",
540
+ "Pros: More automation",
541
+ "Cons: Higher complexity and harder debugging",
542
+ "",
543
+ "## Recommended Approach",
544
+ "Use an artifact-first command flow: brainstorm -> plan -> execute -> review.",
545
+ "",
546
+ "## Why",
547
+ "This keeps the workflow small, inspectable, and easy to recover.",
548
+ "",
549
+ "## Risks",
550
+ "- Incomplete specs can still block execution",
551
+ "- Worker output may need repair",
552
+ "",
553
+ "## Open Questions",
554
+ "None",
555
+ ""
556
+ ].join("\n");
557
+ }
558
+
559
+ // src/commands/execute.ts
560
+ var import_node_fs4 = require("fs");
561
+ var import_node_path3 = require("path");
562
+
563
+ // src/bridge/shell-agy-adapter.ts
564
+ var import_node_child_process = require("child_process");
565
+ var ShellAgyAdapter = class {
566
+ command;
567
+ baseArgs;
568
+ constructor(options) {
569
+ this.command = options.command;
570
+ this.baseArgs = options.baseArgs ?? [];
571
+ }
572
+ async run(request) {
573
+ return new Promise((resolve2) => {
574
+ const startedAt = Date.now();
575
+ const args = [
576
+ ...this.baseArgs,
577
+ "--add-dir",
578
+ request.repoPath,
579
+ "--print",
580
+ request.prompt,
581
+ "--output-format",
582
+ "text",
583
+ "--print-timeout",
584
+ `${Math.ceil(request.timeoutMs / 1e3)}s`
585
+ ];
586
+ const child = (0, import_node_child_process.spawn)(this.command, args, {
587
+ cwd: request.repoPath,
588
+ stdio: ["ignore", "pipe", "pipe"]
589
+ });
590
+ let stdout = "";
591
+ let stderr = "";
592
+ let timedOut = false;
593
+ const timer = setTimeout(() => {
594
+ timedOut = true;
595
+ child.kill("SIGTERM");
596
+ }, request.timeoutMs);
597
+ child.stdout.on("data", (chunk) => {
598
+ stdout += chunk.toString("utf8");
599
+ });
600
+ child.stderr.on("data", (chunk) => {
601
+ stderr += chunk.toString("utf8");
602
+ });
603
+ child.on("error", (error) => {
604
+ clearTimeout(timer);
605
+ resolve2({
606
+ ok: false,
607
+ timedOut,
608
+ exitCode: null,
609
+ stdout,
610
+ stderr: `${stderr}
611
+ ${error.message}`.trim(),
612
+ durationMs: Date.now() - startedAt
613
+ });
614
+ });
615
+ child.on("close", (exitCode) => {
616
+ clearTimeout(timer);
617
+ resolve2({
618
+ ok: !timedOut && exitCode === 0,
619
+ timedOut,
620
+ exitCode,
621
+ stdout,
622
+ stderr,
623
+ durationMs: Date.now() - startedAt
624
+ });
625
+ });
626
+ });
627
+ }
628
+ };
629
+
630
+ // src/core/result-parser.ts
631
+ var knownStatuses = ["DONE", "BLOCKED", "FAILED"];
632
+ function parseWorkerResult(raw) {
633
+ const lines = raw.split(/\r?\n/).map((line) => line.trim());
634
+ const statusLine = lines.find(
635
+ (line) => knownStatuses.some((status2) => line.toUpperCase().includes(status2))
636
+ );
637
+ const status = knownStatuses.find((value) => statusLine?.toUpperCase().includes(value)) ?? "FAILED";
638
+ const summary = lines.find((line) => line.length > 0 && !line.startsWith("#")) ?? "No summary provided by worker.";
639
+ return { status, summary };
640
+ }
641
+
642
+ // src/commands/execute.ts
643
+ async function runExecute(options) {
644
+ const store = new WorkflowStore(options.root);
645
+ if (!(0, import_node_fs4.existsSync)(store.configPath)) {
646
+ throw new Error("Missing .agent-workflow/config.json. Run init first.");
647
+ }
648
+ const config = store.readConfig();
649
+ const adapter = new ShellAgyAdapter({
650
+ command: config.agyCommand,
651
+ baseArgs: config.agyArgs
652
+ });
653
+ await runExecuteWithAdapter(options, adapter);
654
+ }
655
+ async function runExecuteWithAdapter(options, adapter) {
656
+ const store = new WorkflowStore(options.root);
657
+ store.ensureBaseStructure();
658
+ const current = store.readState();
659
+ let contextSource = "";
660
+ let contextContent = "";
661
+ if (options.file && (0, import_node_fs4.existsSync)(options.file)) {
662
+ contextSource = options.file;
663
+ contextContent = (0, import_node_fs4.readFileSync)(options.file, "utf8");
664
+ store.writeTaskFile(options.task, "PLAN.md", contextContent);
665
+ } else if (options.plan && (0, import_node_fs4.existsSync)(options.plan)) {
666
+ contextSource = options.plan;
667
+ contextContent = (0, import_node_fs4.readFileSync)(options.plan, "utf8");
668
+ store.writeTaskFile(options.task, "PLAN.md", contextContent);
669
+ } else if (store.hasTaskFile(options.task, "PLAN.md")) {
670
+ contextSource = (0, import_node_path3.join)(store.tasksDir, options.task, "PLAN.md");
671
+ contextContent = store.readTaskFile(options.task, "PLAN.md");
672
+ } else if (options.spec && (0, import_node_fs4.existsSync)(options.spec)) {
673
+ contextSource = options.spec;
674
+ contextContent = (0, import_node_fs4.readFileSync)(options.spec, "utf8");
675
+ store.writeTaskFile(options.task, "SPEC.md", contextContent);
676
+ } else if (store.hasTaskFile(options.task, "SPEC.md")) {
677
+ contextSource = (0, import_node_path3.join)(store.tasksDir, options.task, "SPEC.md");
678
+ contextContent = store.readTaskFile(options.task, "SPEC.md");
679
+ } else {
680
+ throw new Error(
681
+ `No context markdown file found to execute for task ${options.task}. Run 'plan' or provide --plan, --file, or --spec.`
682
+ );
683
+ }
684
+ let repairContent = "";
685
+ if (options.repairRequest && (0, import_node_fs4.existsSync)(options.repairRequest)) {
686
+ repairContent = (0, import_node_fs4.readFileSync)(options.repairRequest, "utf8");
687
+ store.writeTaskFile(options.task, "REPAIR_REQUEST.md", repairContent);
688
+ } else if (store.hasTaskFile(options.task, "REPAIR_REQUEST.md")) {
689
+ repairContent = store.readTaskFile(options.task, "REPAIR_REQUEST.md");
690
+ }
691
+ const agentResolution = detectAgent({
692
+ root: options.root,
693
+ content: contextContent,
694
+ explicitAgent: options.agent
695
+ });
696
+ console.log(`[Agent Router] Assigned: ${agentResolution.agent.name} (${agentResolution.agent.id})`);
697
+ console.log(`[Agent Router] Reason: ${agentResolution.reason}`);
698
+ const executeArtifact = buildExecuteMarkdown(options.task, contextSource, contextContent, agentResolution);
699
+ store.writeTaskFile(options.task, "EXECUTE.md", executeArtifact);
700
+ advanceStateToImplementing(current);
701
+ current.currentTask = options.task;
702
+ current.currentPhase = "implementation";
703
+ current.nextAction = "Wait for worker execution result";
704
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
705
+ store.writeState(current);
706
+ const workerRulesPath = (0, import_node_path3.join)(options.root, ".antigravity", "WORKER_RULES.md");
707
+ const workerRules = (0, import_node_fs4.existsSync)(workerRulesPath) ? (0, import_node_fs4.readFileSync)(workerRulesPath, "utf8") : "";
708
+ const prompt = buildWorkerPrompt({
709
+ taskId: options.task,
710
+ workerRules,
711
+ context: contextContent,
712
+ repairRequest: repairContent,
713
+ agentResolution
714
+ });
715
+ const timeoutMs = options.timeoutMs ?? 6e5;
716
+ const execution = await adapter.run({
717
+ repoPath: options.root,
718
+ taskId: options.task,
719
+ prompt,
720
+ timeoutMs
721
+ });
722
+ const resultContent = toResultMarkdown(
723
+ execution.stdout,
724
+ execution.stderr,
725
+ execution.exitCode,
726
+ execution.durationMs
727
+ );
728
+ store.writeTaskFile(options.task, "RESULT.md", resultContent);
729
+ current.state = transitionOrThrow(current.state, "VERIFYING" /* VERIFYING */);
730
+ if (!execution.ok) {
731
+ current.state = "BLOCKED" /* BLOCKED */;
732
+ current.blockingIssues = [
733
+ execution.timedOut ? "Worker execution timed out" : `Worker failed with exit code ${execution.exitCode}`
734
+ ];
735
+ current.nextAction = "Inspect RESULT.md and decide escalation or retry";
736
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
737
+ store.writeState(current);
738
+ console.log("Worker execution failed or timed out. See RESULT.md");
739
+ return;
740
+ }
741
+ const parsed = parseWorkerResult(execution.stdout);
742
+ applyParsedResultState(current, parsed);
743
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
744
+ store.writeState(current);
745
+ console.log(`Worker status: ${parsed.status}`);
746
+ console.log(`Summary: ${parsed.summary}`);
747
+ }
748
+ function advanceStateToImplementing(snapshot) {
749
+ if (snapshot.state === "IMPLEMENTING" /* IMPLEMENTING */) {
750
+ return;
751
+ }
752
+ if (snapshot.state === "REPAIR_REQUIRED" /* REPAIR_REQUIRED */) {
753
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
754
+ return;
755
+ }
756
+ if (snapshot.state === "READY" /* READY */) {
757
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
758
+ return;
759
+ }
760
+ if (snapshot.state === "PLANNING" /* PLANNING */) {
761
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
762
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
763
+ return;
764
+ }
765
+ if (snapshot.state === "BRAINSTORMING" /* BRAINSTORMING */) {
766
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
767
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
768
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
769
+ return;
770
+ }
771
+ if (snapshot.state === "DISCOVERY" /* DISCOVERY */) {
772
+ snapshot.state = transitionOrThrow(snapshot.state, "BRAINSTORMING" /* BRAINSTORMING */);
773
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
774
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
775
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
776
+ return;
777
+ }
778
+ snapshot.state = transitionOrThrow(snapshot.state, "DISCOVERY" /* DISCOVERY */);
779
+ snapshot.state = transitionOrThrow(snapshot.state, "BRAINSTORMING" /* BRAINSTORMING */);
780
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
781
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
782
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
783
+ }
784
+ function buildWorkerPrompt(input) {
785
+ const parts = [
786
+ "You are Antigravity implementation worker.",
787
+ "",
788
+ input.workerRules,
789
+ "",
790
+ `# Task ID
791
+ ${input.taskId}`,
792
+ "",
793
+ `# Assigned Role
794
+ Agent: ${input.agentResolution.agent.name} (${input.agentResolution.agent.id})
795
+ Reason: ${input.agentResolution.reason}`
796
+ ];
797
+ if (input.agentResolution.instructions) {
798
+ parts.push("# Agent Operational Guidelines\n" + input.agentResolution.instructions);
799
+ }
800
+ if (input.agentResolution.skillInstructions) {
801
+ parts.push("# Recommended Skill Practices\n" + input.agentResolution.skillInstructions);
802
+ }
803
+ parts.push("# Implementation Context & Specification\n" + input.context);
804
+ if (input.repairRequest) {
805
+ parts.push("# REPAIR REQUEST\n" + input.repairRequest);
806
+ }
807
+ parts.push("Return only concise Implementation Result markdown with status DONE | BLOCKED | FAILED.");
808
+ return parts.filter(Boolean).join("\n\n");
809
+ }
810
+ function applyParsedResultState(state, result) {
811
+ state.state = transitionOrThrow(state.state, "REVIEWING" /* REVIEWING */);
812
+ if (result.status === "DONE") {
813
+ state.nextAction = "Run review and record PASS/FAIL";
814
+ state.blockingIssues = [];
815
+ return;
816
+ }
817
+ if (result.status === "FAILED") {
818
+ state.state = "REPAIR_REQUIRED" /* REPAIR_REQUIRED */;
819
+ state.repairAttempt += 1;
820
+ state.nextAction = "Create repair request and execute again";
821
+ return;
822
+ }
823
+ state.state = "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */;
824
+ state.blockingIssues = ["Worker returned BLOCKED status"];
825
+ state.nextAction = "Resolve blocking decision with user";
826
+ }
827
+ function buildExecuteMarkdown(task, source, context, agentResolution) {
828
+ return [
829
+ "# Execute",
830
+ "",
831
+ `Task: ${task}`,
832
+ `Source: ${source}`,
833
+ `Assigned Agent: ${agentResolution.agent.name} (${agentResolution.agent.id})`,
834
+ `Agent Selection: ${agentResolution.reason}`,
835
+ "",
836
+ "## Context & Plan Package",
837
+ context.trim(),
838
+ "",
839
+ "## Expected Worker Result",
840
+ "- DONE when implementation and tests complete",
841
+ "- FAILED when implementation needs repair",
842
+ "- BLOCKED when missing context/decision",
843
+ ""
844
+ ].join("\n");
845
+ }
846
+ function toResultMarkdown(stdout, stderr, exitCode, durationMs) {
847
+ return [
848
+ "# Implementation Result",
849
+ "",
850
+ "## Execution",
851
+ `- Exit code: ${String(exitCode)}`,
852
+ `- Duration ms: ${durationMs}`,
853
+ "",
854
+ "## Stdout",
855
+ "```text",
856
+ stdout.trim() || "(empty)",
857
+ "```",
858
+ "",
859
+ "## Stderr",
860
+ "```text",
861
+ stderr.trim() || "(empty)",
862
+ "```",
863
+ ""
864
+ ].join("\n");
865
+ }
866
+
867
+ // src/commands/delegate.ts
868
+ var import_node_fs5 = require("fs");
869
+ var import_node_path4 = require("path");
870
+ async function runDelegate(options) {
871
+ const store = new WorkflowStore(options.root);
872
+ if (!(0, import_node_fs5.existsSync)(store.configPath)) {
873
+ throw new Error("Missing .agent-workflow/config.json. Run init first.");
874
+ }
875
+ const config = store.readConfig();
876
+ const adapter = new ShellAgyAdapter({
877
+ command: config.agyCommand,
878
+ baseArgs: config.agyArgs
879
+ });
880
+ await runDelegateWithAdapter(options, adapter);
881
+ }
882
+ async function runDelegateWithAdapter(options, adapter) {
883
+ const store = new WorkflowStore(options.root);
884
+ store.ensureBaseStructure();
885
+ const current = store.readState();
886
+ const specContent = (0, import_node_fs5.readFileSync)(options.spec, "utf8");
887
+ store.writeTaskFile(options.task, "SPEC.md", specContent);
888
+ let repairContent = "";
889
+ if (options.repairRequest) {
890
+ repairContent = (0, import_node_fs5.readFileSync)(options.repairRequest, "utf8");
891
+ store.writeTaskFile(options.task, "REPAIR_REQUEST.md", repairContent);
892
+ }
893
+ advanceStateToImplementing2(current);
894
+ current.currentTask = options.task;
895
+ current.currentPhase = "implementation";
896
+ current.nextAction = "Wait for worker execution result";
897
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
898
+ store.writeState(current);
899
+ const workerRulesPath = (0, import_node_path4.join)(options.root, ".antigravity", "WORKER_RULES.md");
900
+ const workerRules = (0, import_node_fs5.existsSync)(workerRulesPath) ? (0, import_node_fs5.readFileSync)(workerRulesPath, "utf8") : "";
901
+ const prompt = buildWorkerPrompt2({
902
+ taskId: options.task,
903
+ workerRules,
904
+ spec: specContent,
905
+ repairRequest: repairContent
906
+ });
907
+ const execution = await adapter.run({
908
+ repoPath: options.root,
909
+ taskId: options.task,
910
+ prompt,
911
+ timeoutMs: options.timeoutMs
912
+ });
913
+ const resultContent = toResultMarkdown2(execution.stdout, execution.stderr, execution.exitCode, execution.durationMs);
914
+ store.writeTaskFile(options.task, "RESULT.md", resultContent);
915
+ current.state = transitionOrThrow(current.state, "VERIFYING" /* VERIFYING */);
916
+ if (!execution.ok) {
917
+ current.state = "BLOCKED" /* BLOCKED */;
918
+ current.blockingIssues = [
919
+ execution.timedOut ? "Worker execution timed out" : `Worker failed with exit code ${execution.exitCode}`
920
+ ];
921
+ current.nextAction = "Inspect RESULT.md and decide escalation or retry";
922
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
923
+ store.writeState(current);
924
+ console.log("Worker execution failed or timed out. See RESULT.md");
925
+ return;
926
+ }
927
+ const parsed = parseWorkerResult(execution.stdout);
928
+ applyParsedResultState2(current, parsed);
929
+ current.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
930
+ store.writeState(current);
931
+ console.log(`Worker status: ${parsed.status}`);
932
+ console.log(`Summary: ${parsed.summary}`);
933
+ }
934
+ function buildWorkerPrompt2(input) {
935
+ return [
936
+ "You are Antigravity implementation worker.",
937
+ "",
938
+ input.workerRules,
939
+ "",
940
+ `# Task ID
941
+ ${input.taskId}`,
942
+ "",
943
+ "# SPEC",
944
+ input.spec,
945
+ input.repairRequest ? "# REPAIR REQUEST\n" + input.repairRequest : "",
946
+ "",
947
+ "Return only concise Implementation Result markdown with status DONE | BLOCKED | FAILED."
948
+ ].filter(Boolean).join("\n");
949
+ }
950
+ function applyParsedResultState2(state, result) {
951
+ state.state = transitionOrThrow(state.state, "REVIEWING" /* REVIEWING */);
952
+ if (result.status === "DONE") {
953
+ state.nextAction = "Run review and record PASS/FAIL";
954
+ state.blockingIssues = [];
955
+ return;
956
+ }
957
+ if (result.status === "FAILED") {
958
+ state.state = "REPAIR_REQUIRED" /* REPAIR_REQUIRED */;
959
+ state.repairAttempt += 1;
960
+ state.nextAction = "Create repair request and delegate again";
961
+ return;
962
+ }
963
+ state.state = "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */;
964
+ state.blockingIssues = ["Worker returned BLOCKED status"];
965
+ state.nextAction = "Resolve blocking decision with user";
966
+ }
967
+ function toResultMarkdown2(stdout, stderr, exitCode, durationMs) {
968
+ return [
969
+ "# Implementation Result",
970
+ "",
971
+ "## Execution",
972
+ `- Exit code: ${String(exitCode)}`,
973
+ `- Duration ms: ${durationMs}`,
974
+ "",
975
+ "## Stdout",
976
+ "```text",
977
+ stdout.trim() || "(empty)",
978
+ "```",
979
+ "",
980
+ "## Stderr",
981
+ "```text",
982
+ stderr.trim() || "(empty)",
983
+ "```",
984
+ ""
985
+ ].join("\n");
986
+ }
987
+ function advanceStateToImplementing2(snapshot) {
988
+ if (snapshot.state === "IMPLEMENTING" /* IMPLEMENTING */) {
989
+ return;
990
+ }
991
+ if (snapshot.state === "REPAIR_REQUIRED" /* REPAIR_REQUIRED */) {
992
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
993
+ return;
994
+ }
995
+ if (snapshot.state === "READY" /* READY */) {
996
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
997
+ return;
998
+ }
999
+ if (snapshot.state === "PLANNING" /* PLANNING */) {
1000
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
1001
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
1002
+ return;
1003
+ }
1004
+ if (snapshot.state === "BRAINSTORMING" /* BRAINSTORMING */) {
1005
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
1006
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
1007
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
1008
+ return;
1009
+ }
1010
+ if (snapshot.state === "DISCOVERY" /* DISCOVERY */) {
1011
+ snapshot.state = transitionOrThrow(snapshot.state, "BRAINSTORMING" /* BRAINSTORMING */);
1012
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
1013
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
1014
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
1015
+ return;
1016
+ }
1017
+ snapshot.state = transitionOrThrow(snapshot.state, "DISCOVERY" /* DISCOVERY */);
1018
+ snapshot.state = transitionOrThrow(snapshot.state, "BRAINSTORMING" /* BRAINSTORMING */);
1019
+ snapshot.state = transitionOrThrow(snapshot.state, "PLANNING" /* PLANNING */);
1020
+ snapshot.state = transitionOrThrow(snapshot.state, "READY" /* READY */);
1021
+ snapshot.state = transitionOrThrow(snapshot.state, "IMPLEMENTING" /* IMPLEMENTING */);
1022
+ }
1023
+
1024
+ // src/commands/doctor.ts
1025
+ var import_node_fs6 = require("fs");
1026
+ var import_node_child_process2 = require("child_process");
1027
+ function runDoctor(options) {
1028
+ const store = new WorkflowStore(options.root);
1029
+ const checks = [];
1030
+ const agyCheck = (0, import_node_child_process2.spawnSync)("sh", ["-lc", "command -v agy"], {
1031
+ cwd: options.root,
1032
+ encoding: "utf8"
1033
+ });
1034
+ checks.push({
1035
+ name: "agy command",
1036
+ ok: agyCheck.status === 0,
1037
+ detail: agyCheck.stdout.trim() || agyCheck.stderr.trim()
1038
+ });
1039
+ checks.push({
1040
+ name: ".agent-workflow directory",
1041
+ ok: (0, import_node_fs6.existsSync)(store.workflowDir)
1042
+ });
1043
+ checks.push({
1044
+ name: "STATE.md",
1045
+ ok: (0, import_node_fs6.existsSync)(store.statePath)
1046
+ });
1047
+ checks.push({
1048
+ name: "config.json",
1049
+ ok: (0, import_node_fs6.existsSync)(store.configPath)
1050
+ });
1051
+ checks.push({
1052
+ name: "AGENTS.md",
1053
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/AGENTS.md`)
1054
+ });
1055
+ checks.push({
1056
+ name: ".codex/agents/codex.md",
1057
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/codex.md`)
1058
+ });
1059
+ checks.push({
1060
+ name: ".codex/agents/brainstormer.md",
1061
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/brainstormer.md`)
1062
+ });
1063
+ checks.push({
1064
+ name: ".codex/agents/planner.md",
1065
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/planner.md`)
1066
+ });
1067
+ checks.push({
1068
+ name: ".codex/agents/researcher.md",
1069
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/researcher.md`)
1070
+ });
1071
+ checks.push({
1072
+ name: ".codex/agents/business-analyst.md",
1073
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/business-analyst.md`)
1074
+ });
1075
+ checks.push({
1076
+ name: ".codex/agents/web-engineer.md",
1077
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/web-engineer.md`)
1078
+ });
1079
+ checks.push({
1080
+ name: ".codex/agents/mobile-engineer.md",
1081
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/mobile-engineer.md`)
1082
+ });
1083
+ checks.push({
1084
+ name: ".codex/agents/game-engineer.md",
1085
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/agents/game-engineer.md`)
1086
+ });
1087
+ checks.push({
1088
+ name: ".codex/skills/codex-workflow.md",
1089
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/codex-workflow.md`)
1090
+ });
1091
+ checks.push({
1092
+ name: ".codex/skills/brainstorming.md",
1093
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/brainstorming.md`)
1094
+ });
1095
+ checks.push({
1096
+ name: ".codex/skills/planning.md",
1097
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/planning.md`)
1098
+ });
1099
+ checks.push({
1100
+ name: ".codex/skills/research.md",
1101
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/research.md`)
1102
+ });
1103
+ checks.push({
1104
+ name: ".codex/skills/requirements-analysis.md",
1105
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/requirements-analysis.md`)
1106
+ });
1107
+ checks.push({
1108
+ name: ".codex/skills/web-engineering.md",
1109
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/web-engineering.md`)
1110
+ });
1111
+ checks.push({
1112
+ name: ".codex/skills/mobile-engineering.md",
1113
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/mobile-engineering.md`)
1114
+ });
1115
+ checks.push({
1116
+ name: ".codex/skills/game-engineering.md",
1117
+ ok: (0, import_node_fs6.existsSync)(`${options.root}/.codex/skills/game-engineering.md`)
1118
+ });
1119
+ for (const check of checks) {
1120
+ console.log(`${check.ok ? "PASS" : "FAIL"} - ${check.name}`);
1121
+ if (check.detail) {
1122
+ console.log(` ${check.detail}`);
1123
+ }
1124
+ }
1125
+ const hasFailure = checks.some((check) => !check.ok);
1126
+ if (hasFailure) {
1127
+ process.exitCode = 1;
1128
+ }
1129
+ }
1130
+
1131
+ // src/commands/init.ts
1132
+ var import_node_fs7 = require("fs");
1133
+ var import_node_path5 = require("path");
1134
+ var defaultConfig = {
1135
+ agyCommand: "agy",
1136
+ agyArgs: [],
1137
+ maxRepairAttempts: 3
1138
+ };
1139
+ var defaultAgents = `# Codex Runtime Contract
1140
+
1141
+ Codex role: Technical Lead, Architect, Planner, Orchestrator, Reviewer, Verifier.
1142
+
1143
+ Execution order:
1144
+ Understand -> Inspect -> Clarify -> Brainstorm -> Plan -> Delegate -> Review -> Repair -> Verify -> Complete.
1145
+
1146
+ Rules:
1147
+ 1. Search before asking.
1148
+ 2. If missing context affects architecture/behavior/security/compatibility, stop and ask.
1149
+ 3. Do not invent requirements.
1150
+ 4. Do not delegate before task spec is complete.
1151
+ 5. PASS only after verification and independent review.
1152
+ `;
1153
+ var defaultWorkerRules = `# Antigravity Worker Contract
1154
+
1155
+ You are the implementation worker.
1156
+
1157
+ 1. SPEC is the contract.
1158
+ 2. REPAIR request is the correction contract.
1159
+ 3. Inspect relevant code before editing.
1160
+ 4. Implement minimal correct scope.
1161
+ 5. Add or update tests.
1162
+ 6. Run verification commands.
1163
+ 7. Report using Implementation Result contract.
1164
+ 8. Return BLOCKED if missing decision/context prevents safe completion.
1165
+ `;
1166
+ var defaultCodexAgent = `# Codex Agent Template
1167
+
1168
+ Role: Technical Lead / Planner / Reviewer
1169
+
1170
+ Use this agent for:
1171
+ - clarifying requirements
1172
+ - decomposing work into phases
1173
+ - reviewing implementation output
1174
+ - deciding PASS / FAIL / BLOCKED
1175
+
1176
+ Rules:
1177
+ 1. Keep decisions in markdown artifacts.
1178
+ 2. Do not delegate before the spec is complete.
1179
+ 3. Prefer the smallest safe next action.
1180
+ `;
1181
+ var brainstormAgent = `# Brainstormer Agent
1182
+
1183
+ Role: Discovery and problem framing.
1184
+
1185
+ Use this agent for:
1186
+ - turning a rough request into a clear problem statement
1187
+ - identifying constraints, assumptions, and unknowns
1188
+ - comparing solution options before planning
1189
+ - preparing the input for planning
1190
+
1191
+ Operating rules:
1192
+ 1. Stay in discovery; do not implement.
1193
+ 2. Capture only evidence-backed assumptions.
1194
+ 3. Prefer short, explicit notes.
1195
+ 4. End with concrete questions or a recommendation.
1196
+
1197
+ Output format:
1198
+ - Goal
1199
+ - Context
1200
+ - Constraints
1201
+ - Options
1202
+ - Risks
1203
+ - Open questions
1204
+ - Recommended next step
1205
+ `;
1206
+ var plannerAgent = `# Planner Agent
1207
+
1208
+ Role: Convert a validated brainstorm into an execution plan.
1209
+
1210
+ Use this agent for:
1211
+ - breaking work into phases and tasks
1212
+ - defining acceptance criteria
1213
+ - identifying dependencies and sequencing
1214
+ - preparing the handoff to execution
1215
+
1216
+ Operating rules:
1217
+ 1. Use the brainstorm as the source of truth.
1218
+ 2. Split work into small, ordered steps.
1219
+ 3. Keep the plan testable and recoverable.
1220
+ 4. Call out blockers explicitly.
1221
+
1222
+ Output format:
1223
+ - Objective
1224
+ - Scope
1225
+ - Phases
1226
+ - Tasks
1227
+ - Acceptance criteria
1228
+ - Verification
1229
+ - Blockers
1230
+ `;
1231
+ var defaultCodexSkill = `# Codex Skill Template
1232
+
1233
+ Use this skill when the task must be executed through the Codex flow in this kit.
1234
+
1235
+ Workflow:
1236
+ 1. Brainstorm
1237
+ 2. Plan
1238
+ 3. Execute
1239
+ 4. Delegate
1240
+ 5. Review
1241
+
1242
+ Output artifacts:
1243
+ - BRAINSTORM.md
1244
+ - PLAN.md
1245
+ - EXECUTE.md
1246
+ - RESULT.md
1247
+ - REVIEW.md
1248
+ `;
1249
+ var brainstormingSkill = `# Brainstorming Skill
1250
+
1251
+ Use this skill when you need to transform a vague request into a decision-ready problem statement.
1252
+
1253
+ Workflow:
1254
+ 1. Read the spec or request.
1255
+ 2. Identify goals, constraints, unknowns, and risks.
1256
+ 3. Compare at least two viable approaches.
1257
+ 4. Recommend the safest next step.
1258
+
1259
+ Outputs:
1260
+ - BRAINSTORM.md
1261
+ - Decision notes
1262
+ - Open questions
1263
+
1264
+ Do not implement code in this phase.
1265
+ `;
1266
+ var planningSkill = `# Planning Skill
1267
+
1268
+ Use this skill when the request is ready to be turned into an execution plan.
1269
+
1270
+ Workflow:
1271
+ 1. Consume the brainstorm output.
1272
+ 2. Break the work into phases.
1273
+ 3. Add acceptance criteria and verification steps.
1274
+ 4. Prepare a clear execution handoff.
1275
+
1276
+ Outputs:
1277
+ - PLAN.md
1278
+ - Task breakdown
1279
+ - Verification checklist
1280
+ - Handoff notes
1281
+
1282
+ Do not delegate implementation until the plan is complete.
1283
+ `;
1284
+ var researcherAgent = `# Researcher Agent
1285
+
1286
+ Role: Deep Technical Research, Spikes, Architecture Benchmarks & Feasibility.
1287
+
1288
+ Use this agent for:
1289
+ - investigating unknown technical domains, new libraries, or unfamiliar APIs
1290
+ - conducting technical spikes and feasibility studies before architectural commitment
1291
+ - comparing competing frameworks, protocols, and third-party services
1292
+ - identifying hidden constraints, license obligations, deprecations, and performance bottlenecks
1293
+ - analyzing state-of-the-art implementations and industry best practices
1294
+
1295
+ Operating rules:
1296
+ 1. Search code and documentation before speculating.
1297
+ 2. Provide concrete evidence, benchmarks, or citations for claims.
1298
+ 3. Compare at least 2 viable approaches with explicit trade-offs (pros/cons/risks).
1299
+ 4. Never assume third-party API contracts without verifying current versions.
1300
+ 5. Conclude with a definitive, actionable recommendation and a risk mitigation strategy.
1301
+
1302
+ Output format:
1303
+ - Research Objective & Scope
1304
+ - Background & Current State
1305
+ - Evaluated Options (Trade-off Matrix)
1306
+ - Spike / Proof of Concept Findings
1307
+ - Risks & Breaking Changes
1308
+ - Recommended Architecture / Path Forward
1309
+ `;
1310
+ var businessAnalystAgent = `# Business Analyst (BA) Agent
1311
+
1312
+ Role: Requirements Elicitation, User Story Breakdown, Domain Modeling & Acceptance Criteria Engineering.
1313
+
1314
+ Use this agent for:
1315
+ - turning unstructured business requirements or user requests into precise functional specifications
1316
+ - identifying distinct user personas, user journeys, and role-based permissions
1317
+ - uncovering non-obvious edge cases, error scenarios, and business boundary rules
1318
+ - authoring testable acceptance criteria using Gherkin (Given / When / Then) syntax
1319
+ - mapping domain entities, data dictionaries, and state transition lifecycles
1320
+
1321
+ Operating rules:
1322
+ 1. Do not invent requirements; clarify ambiguities with explicit questions or assumptions.
1323
+ 2. Separate business logic and user intent from technical implementation details.
1324
+ 3. Every functional requirement must have at least one testable acceptance criterion.
1325
+ 4. Always specify happy path, alternative paths, and negative/failure paths.
1326
+ 5. Highlight all dependencies on external systems, legal/compliance rules, and business limits.
1327
+
1328
+ Output format:
1329
+ - Feature Summary & Business Value
1330
+ - User Personas & Permissions
1331
+ - User Stories & Workflows
1332
+ - Functional & Non-Functional Requirements
1333
+ - Edge Cases & Negative Scenarios
1334
+ - Acceptance Criteria (Given/When/Then)
1335
+ - Open Questions & Assumptions
1336
+ `;
1337
+ var webEngineerAgent = `# Web Engineer Agent
1338
+
1339
+ Role: Modern Web Architecture & Engineering Specialist (Frontend, Backend, APIs, Performance).
1340
+
1341
+ Use this agent for:
1342
+ - designing responsive frontend architectures (React, Next.js, Vue, Svelte, Vanilla HTML/CSS/JS)
1343
+ - building resilient backend services and APIs (Node.js/TypeScript, Go, Python, REST, GraphQL, WebSocket)
1344
+ - defining state management, data caching, optimistic UI updates, and server components
1345
+ - enforcing modern web performance (Core Web Vitals: LCP, INP, CLS) and responsive design
1346
+ - securing web applications against XSS, CSRF, SSRF, CORS misconfigurations, and injection attacks
1347
+ - establishing SEO, accessibility (WCAG 2.1 AA, ARIA roles), and progressive enhancement standards
1348
+
1349
+ Operating rules:
1350
+ 1. Adhere to repository coding patterns and modern framework idioms (prefer web standards and composable patterns).
1351
+ 2. Never hardcode sensitive tokens or environment secrets into client-side bundles.
1352
+ 3. Design UI components for responsiveness across mobile, tablet, and desktop breakpoints.
1353
+ 4. Keep network waterfalls minimal: optimize bundle size, leverage code splitting and caching headers.
1354
+ 5. All interactive UI elements must have unique test identifiers and valid keyboard focus management.
1355
+
1356
+ Output format:
1357
+ - Web Architecture & Tech Stack Details
1358
+ - Component Hierarchy & State Flow
1359
+ - API Contracts & Data Schemas
1360
+ - Routing & Navigation Structure
1361
+ - Performance & Security Constraints
1362
+ - Verification & Test Matrix (Unit, Integration, E2E)
1363
+ `;
1364
+ var mobileEngineerAgent = `# Mobile Engineer Agent
1365
+
1366
+ Role: Mobile Application Architecture & Engineering Specialist (Cross-Platform & Native).
1367
+
1368
+ Use this agent for:
1369
+ - architecting cross-platform apps using Flutter/Dart or React Native/Expo
1370
+ - engineering native iOS applications (Swift, SwiftUI, UIKit, Combine/Async-Await)
1371
+ - engineering native Android applications (Kotlin, Jetpack Compose, Coroutines/Flow)
1372
+ - managing mobile lifecycle states (foreground, background, suspended, terminated)
1373
+ - designing offline-first local storage, SQLite/Room/CoreData/WatermelonDB/Hive, and background sync
1374
+ - handling device hardware integrations: Push notifications, Biometrics, Camera, Geolocation, Bluetooth
1375
+ - configuring native build pipelines, signing, permissions, deep linking, and App Store/Play Store readiness
1376
+
1377
+ Operating rules:
1378
+ 1. Respect native operating system guidelines (Apple Human Interface Guidelines and Material Design 3).
1379
+ 2. Handle network flakiness gracefully: implement retries, offline caching, and optimistic local state.
1380
+ 3. Treat app permissions defensively: request at runtime with clear user rationale and fallback states.
1381
+ 4. Avoid main-thread blocking; offload heavy computations and disk I/O to background workers/isolates.
1382
+ 5. Account for device fragmentation: test various screen aspect ratios, safe areas, notches, and dark mode.
1383
+
1384
+ Output format:
1385
+ - Target Platform & Architecture (Native iOS/Android, React Native, or Flutter)
1386
+ - State Management & Navigation Hierarchy
1387
+ - Local Storage & Offline Sync Strategy
1388
+ - Native Capabilities & Permission Handling
1389
+ - Device Lifecycle & Memory Considerations
1390
+ - Build, Verification & Device Testing Strategy
1391
+ `;
1392
+ var gameEngineerAgent = `# Game Engineer Agent
1393
+
1394
+ Role: Game Systems Architecture, Gameplay Mechanics & Engine Specialist (Unity, Godot, Cocos Creator).
1395
+
1396
+ Use this agent for:
1397
+ - architecting game systems across major game engines:
1398
+ - Unity: C#, GameObject/Component lifecycle, ScriptableObjects, DOTS/Burst, Addressables
1399
+ - Godot: GDScript / C#, Node tree hierarchy, Scene inheritance, Signals, Resource system
1400
+ - Cocos Creator: TypeScript, Component lifecycle, Prefabs, Canvas/UI, WebGL/HTML5 packaging
1401
+ - developing core gameplay loops, mechanics, player controllers, and input action maps
1402
+ - designing Entity-Component-System (ECS) and data-driven state machines
1403
+ - configuring 2D/3D physics, collision layers, rigid bodies, raycasting, and triggers
1404
+ - managing asset pipelines: sprites, tilemaps, 3D meshes, particle effects, animations, and audio mixers
1405
+ - profiling and optimizing game performance: frame-rate stability (60/120 FPS), draw calls, texture atlases, garbage collection pauses
1406
+
1407
+ Operating rules:
1408
+ 1. Keep gameplay logic decoupled from rendering and engine-specific editor scripts where feasible.
1409
+ 2. Optimize memory allocations in the hot game loop (Update / _process) to prevent GC spikes.
1410
+ 3. Physics updates must run in fixed timesteps (FixedUpdate / _physics_process).
1411
+ 4. Manage scene and asset lifecycles strictly to eliminate memory leaks and dangling event listeners.
1412
+ 5. Provide deterministic fallback logic and verification tests for core game rules and mathematical calculations.
1413
+
1414
+ Output format:
1415
+ - Game Engine, Version & Render Pipeline Selection
1416
+ - Core Game Loop & Gameplay Mechanics Architecture
1417
+ - Scene / Node Hierarchy & Component Relationships
1418
+ - Physics, Collision Matrix & Input Handling
1419
+ - Asset Management & Performance Budget (Draw calls, Memory, Target FPS)
1420
+ - Verification Checklist & Playtest Strategy
1421
+ `;
1422
+ var researchSkill = `# Technical Research Skill
1423
+
1424
+ Use this skill when tackling technical uncertainty, evaluating new libraries, prototyping spikes, or comparing architectural designs.
1425
+
1426
+ Workflow:
1427
+ 1. Frame the Spike: Define the research question, target hypothesis, constraints, and success criteria.
1428
+ 2. Explore Existing Solutions: Inspect repository codebase, official documentation, ecosystem libraries, and community benchmarks.
1429
+ 3. Compare Alternatives: Benchmark at least 2 distinct approaches across complexity, maintenance, scalability, security, and developer experience.
1430
+ 4. Prototype & Validate: Run minimal proof-of-concept tests or sandbox experiments to verify critical assumptions.
1431
+ 5. Document & Recommend: Synthesize findings into clear architectural guidance, trade-offs, and an actionable implementation path.
1432
+
1433
+ Outputs:
1434
+ - Research findings artifact (RESEARCH.md or section in BRAINSTORM.md)
1435
+ - Technical comparison matrix
1436
+ - Decision record with trade-offs and rationale
1437
+ - Risk assessment and mitigation plan
1438
+ `;
1439
+ var requirementsAnalysisSkill = `# Requirements Analysis Skill
1440
+
1441
+ Use this skill when translating high-level business goals, user feedback, or feature requests into actionable, testable technical requirements.
1442
+
1443
+ Workflow:
1444
+ 1. Clarify Business Intent: Elicit the core user problem, business metrics, and target audience.
1445
+ 2. Deconstruct User Journeys: Map end-to-end flows covering happy path, alternative paths, and error scenarios.
1446
+ 3. Formulate Acceptance Criteria: Write precise, testable criteria using Gherkin syntax (Given [context], When [action], Then [outcome]).
1447
+ 4. Identify Non-Functional Requirements: Specify performance targets, security rules, compliance, and accessibility standards.
1448
+ 5. Surface Unknowns: Flag open questions, unconfirmed business logic, and potential edge cases before planning.
1449
+
1450
+ Outputs:
1451
+ - Business requirements specification (REQUIREMENTS.md or section in SPEC.md)
1452
+ - User stories with Gherkin acceptance criteria
1453
+ - Domain entities & data dictionary definitions
1454
+ - Edge case checklist & business validation rules
1455
+ `;
1456
+ var webEngineeringSkill = `# Web Engineering Skill
1457
+
1458
+ Use this skill when designing, implementing, or optimizing fullstack web applications, frontends, APIs, and modern web architectures.
1459
+
1460
+ Workflow:
1461
+ 1. Analyze Repository & Tech Stack: Inspect active frameworks (React, Next.js, Vue, Node.js, etc.), state stores, design systems, and package dependencies.
1462
+ 2. Design Component & State Flow: Architect clean component boundaries, unidirectional data flow, server/client state segregation, and error boundaries.
1463
+ 3. Specify API Contracts: Define type-safe request/response schemas (TypeScript, Zod, OpenAPI, GraphQL) and error handling codes.
1464
+ 4. Enforce UX, Performance & Accessibility: Apply responsive layouts, Core Web Vitals optimizations (LCP, INP, CLS), keyboard navigation, and ARIA roles.
1465
+ 5. Formulate Verification Matrix: Define unit tests (Vitest/Jest), component tests, and end-to-end integration scenarios (Playwright/Cypress).
1466
+
1467
+ Outputs:
1468
+ - Web implementation plan (PLAN.md with web-specific phase breakdown)
1469
+ - Component hierarchy and data flow diagrams
1470
+ - API schema specifications and endpoint contracts
1471
+ - Performance, security, and accessibility verification checklist
1472
+ `;
1473
+ var mobileEngineeringSkill = `# Mobile Engineering Skill
1474
+
1475
+ Use this skill when developing, refactoring, or optimizing native (iOS Swift, Android Kotlin) and cross-platform (Flutter, React Native) mobile applications.
1476
+
1477
+ Workflow:
1478
+ 1. Target Platform & Framework Audit: Inspect whether the app is Flutter, React Native, Swift/SwiftUI, or Kotlin/Jetpack Compose, plus target SDK versions.
1479
+ 2. Design Navigation & State Hierarchy: Define screen stacks, tabs, modals, deep linking schemes, and application-wide state management.
1480
+ 3. Architect Storage & Offline Capability: Specify local caching, SQLite / Room / CoreData / WatermelonDB schemas, and background sync strategies.
1481
+ 4. Integrate Native Device Capabilities: Structure permission flows, push notifications, hardware access, and platform bridges/plugins defensively.
1482
+ 5. Formulate Verification & Emulation Matrix: Specify unit tests, widget/component tests, and platform-specific simulator/device build commands.
1483
+
1484
+ Outputs:
1485
+ - Mobile technical implementation plan
1486
+ - Screen navigation and state transition map
1487
+ - Local database schema and offline sync rules
1488
+ - Platform permission checklist and native configuration guidelines
1489
+ `;
1490
+ var gameEngineeringSkill = `# Game Engineering Skill
1491
+
1492
+ Use this skill when developing, refactoring, or optimizing games across Unity, Godot, or Cocos Creator engines.
1493
+
1494
+ Workflow:
1495
+ 1. Engine & Architecture Assessment: Identify game engine (Unity C#, Godot GDScript/C#, Cocos Creator TypeScript), rendering pipeline, and target platforms (PC, Mobile, WebGL, Console).
1496
+ 2. Gameplay Loops & Mechanics Design: Structure the primary game loop, player controllers, state machines, and event dispatchers.
1497
+ 3. Scene, Node & Entity Architecture: Establish clean scene hierarchies, prefabs/nodes composition, and decouple gameplay logic from presentation.
1498
+ 4. Physics, Collision & Input Integration: Configure collision layers/masks, rigid body properties, input action maps, and fixed-timestep calculations.
1499
+ 5. Optimization & Performance Profiling: Audit hot loop allocations, draw call batching, texture atlases, object pooling, and target frame rate (60/120 FPS).
1500
+
1501
+ Outputs:
1502
+ - Game architecture & mechanics implementation plan
1503
+ - Scene hierarchy and component relationship specification
1504
+ - Physics collision matrix and input mapping configuration
1505
+ - Object pooling and memory optimization checklist
1506
+ - Verification plan with deterministic math/logic tests and playtest criteria
1507
+ `;
1508
+ function runInit(options) {
1509
+ const store = new WorkflowStore(options.root);
1510
+ store.ensureBaseStructure();
1511
+ const architecturePath = (0, import_node_path5.join)(store.workflowDir, "ARCHITECTURE.md");
1512
+ const projectPath = (0, import_node_path5.join)(store.workflowDir, "PROJECT.md");
1513
+ const decisionsPath = (0, import_node_path5.join)(store.workflowDir, "DECISIONS.md");
1514
+ const agentsPath = (0, import_node_path5.join)(options.root, "AGENTS.md");
1515
+ const codexDir = (0, import_node_path5.join)(options.root, ".codex");
1516
+ const codexAgentsDir = (0, import_node_path5.join)(codexDir, "agents");
1517
+ const codexSkillsDir = (0, import_node_path5.join)(codexDir, "skills");
1518
+ const workerDir = (0, import_node_path5.join)(options.root, ".antigravity");
1519
+ const workerPath = (0, import_node_path5.join)(workerDir, "WORKER_RULES.md");
1520
+ (0, import_node_fs7.mkdirSync)(codexDir, { recursive: true });
1521
+ (0, import_node_fs7.mkdirSync)(codexAgentsDir, { recursive: true });
1522
+ (0, import_node_fs7.mkdirSync)(codexSkillsDir, { recursive: true });
1523
+ if (!(0, import_node_fs7.existsSync)(workerDir)) {
1524
+ (0, import_node_fs7.mkdirSync)(workerDir, { recursive: true });
1525
+ (0, import_node_fs7.writeFileSync)((0, import_node_path5.join)(workerDir, ".gitkeep"), "", "utf8");
1526
+ }
1527
+ writeIfMissing(projectPath, "# Project\n\nDescribe project-level goals and boundaries.\n", options.force);
1528
+ writeIfMissing(
1529
+ architecturePath,
1530
+ "# Architecture\n\nDocument Codex brain, bridge, worker, state, and review loop architecture.\n",
1531
+ options.force
1532
+ );
1533
+ writeIfMissing(decisionsPath, "# Decisions\n\nLog only material architectural/product decisions.\n", options.force);
1534
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "brainstormer.md"), brainstormAgent, options.force);
1535
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "planner.md"), plannerAgent, options.force);
1536
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "codex.md"), defaultCodexAgent, options.force);
1537
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "researcher.md"), researcherAgent, options.force);
1538
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "business-analyst.md"), businessAnalystAgent, options.force);
1539
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "web-engineer.md"), webEngineerAgent, options.force);
1540
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "mobile-engineer.md"), mobileEngineerAgent, options.force);
1541
+ writeIfMissing((0, import_node_path5.join)(codexAgentsDir, "game-engineer.md"), gameEngineerAgent, options.force);
1542
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "brainstorming.md"), brainstormingSkill, options.force);
1543
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "planning.md"), planningSkill, options.force);
1544
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "codex-workflow.md"), defaultCodexSkill, options.force);
1545
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "research.md"), researchSkill, options.force);
1546
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "requirements-analysis.md"), requirementsAnalysisSkill, options.force);
1547
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "web-engineering.md"), webEngineeringSkill, options.force);
1548
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "mobile-engineering.md"), mobileEngineeringSkill, options.force);
1549
+ writeIfMissing((0, import_node_path5.join)(codexSkillsDir, "game-engineering.md"), gameEngineeringSkill, options.force);
1550
+ if (!(0, import_node_fs7.existsSync)(store.statePath) || options.force) {
1551
+ const state = defaultState();
1552
+ state.state = "IDLE" /* IDLE */;
1553
+ state.nextAction = "Start discovery for a feature request";
1554
+ store.writeState(state);
1555
+ }
1556
+ if (!(0, import_node_fs7.existsSync)(store.configPath) || options.force) {
1557
+ store.writeConfig(defaultConfig);
1558
+ }
1559
+ writeIfMissing(agentsPath, defaultAgents, options.force);
1560
+ writeIfMissing(workerPath, defaultWorkerRules, options.force);
1561
+ console.log("Initialized codex-antigravity kit");
1562
+ console.log(`Workflow dir: ${store.workflowDir}`);
1563
+ }
1564
+ function writeIfMissing(path, content, force) {
1565
+ if (!(0, import_node_fs7.existsSync)(path) || force) {
1566
+ (0, import_node_fs7.writeFileSync)(path, content, "utf8");
1567
+ return;
1568
+ }
1569
+ const current = (0, import_node_fs7.readFileSync)(path, "utf8");
1570
+ if (current.trim().length === 0) {
1571
+ (0, import_node_fs7.writeFileSync)(path, content, "utf8");
1572
+ }
1573
+ }
1574
+
1575
+ // src/commands/plan.ts
1576
+ var import_node_fs8 = require("fs");
1577
+ function runPlan(options) {
1578
+ const store = new WorkflowStore(options.root);
1579
+ store.ensureBaseStructure();
1580
+ let spec = "";
1581
+ if (options.spec && (0, import_node_fs8.existsSync)(options.spec)) {
1582
+ spec = (0, import_node_fs8.readFileSync)(options.spec, "utf8");
1583
+ store.writeTaskFile(options.task, "SPEC.md", spec);
1584
+ } else if (store.hasTaskFile(options.task, "SPEC.md")) {
1585
+ spec = store.readTaskFile(options.task, "SPEC.md");
1586
+ } else {
1587
+ spec = `# Task ${options.task}
1588
+ `;
1589
+ }
1590
+ const brainstormContent = store.hasTaskFile(options.task, "BRAINSTORM.md") ? store.readTaskFile(options.task, "BRAINSTORM.md") : "# Brainstorm\n\nRun brainstorm first.\n";
1591
+ const agentResolution = detectAgent({
1592
+ root: options.root,
1593
+ content: `${spec}
1594
+ ${brainstormContent}`,
1595
+ explicitAgent: options.agent
1596
+ });
1597
+ console.log(`[Agent Router] Assigned: ${agentResolution.agent.name} (${agentResolution.agent.id})`);
1598
+ console.log(`[Agent Router] Reason: ${agentResolution.reason}`);
1599
+ const plan = buildPlanMarkdown(options.task, spec, brainstormContent, agentResolution);
1600
+ store.writeTaskFile(options.task, "PLAN.md", plan);
1601
+ const state = store.readState();
1602
+ state.state = "BRAINSTORMING" /* BRAINSTORMING */;
1603
+ state.state = "PLANNING" /* PLANNING */;
1604
+ state.currentTask = options.task;
1605
+ state.currentPhase = "planning";
1606
+ state.nextAction = `Run execute command to implement work described in PLAN.md for task ${options.task}`;
1607
+ state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1608
+ store.writeState(state);
1609
+ console.log(plan);
1610
+ }
1611
+ function buildPlanMarkdown(task, spec, brainstorm, agentResolution) {
1612
+ return [
1613
+ "# Plan",
1614
+ "",
1615
+ `Task: ${task}`,
1616
+ `Assigned Agent: ${agentResolution.agent.name} (${agentResolution.agent.id})`,
1617
+ `Agent Selection: ${agentResolution.reason}`,
1618
+ "",
1619
+ "## Objective",
1620
+ "Convert brainstorm into actionable phases and tasks.",
1621
+ "",
1622
+ "## Context",
1623
+ brainstorm.trim(),
1624
+ "",
1625
+ "## Requirements",
1626
+ spec.trim(),
1627
+ "",
1628
+ "## Phases",
1629
+ "### Phase 1 \u2014 Scope and Contracts",
1630
+ "- Confirm task boundaries",
1631
+ "- Capture expected behavior",
1632
+ "",
1633
+ "### Phase 2 \u2014 Worker Execution",
1634
+ "- Send spec to Antigravity",
1635
+ "- Collect implementation result",
1636
+ "",
1637
+ "### Phase 3 \u2014 Review and Repair",
1638
+ "- Codex reviews diff and output",
1639
+ "- Produce repair request if needed",
1640
+ "",
1641
+ "## Acceptance Criteria",
1642
+ "- Brainstorm artifact exists",
1643
+ "- Plan artifact exists",
1644
+ "- Execute artifact can be generated",
1645
+ "- Workflow remains recoverable from disk",
1646
+ "",
1647
+ "## Verification",
1648
+ "- npm test",
1649
+ "- npm run build",
1650
+ "- npx codex-antigravity-kit doctor",
1651
+ ""
1652
+ ].join("\n");
1653
+ }
1654
+
1655
+ // src/commands/review.ts
1656
+ var import_node_fs9 = require("fs");
1657
+
1658
+ // src/core/repair-loop.ts
1659
+ var RepairLoop = class {
1660
+ constructor(maxAttempts) {
1661
+ this.maxAttempts = maxAttempts;
1662
+ if (maxAttempts < 1) {
1663
+ throw new Error("maxAttempts must be >= 1");
1664
+ }
1665
+ }
1666
+ maxAttempts;
1667
+ canRetry(currentAttempt) {
1668
+ return currentAttempt < this.maxAttempts;
1669
+ }
1670
+ nextAttempt(currentAttempt) {
1671
+ return currentAttempt + 1;
1672
+ }
1673
+ needsEscalation(currentAttempt) {
1674
+ return !this.canRetry(currentAttempt);
1675
+ }
1676
+ };
1677
+
1678
+ // src/commands/review.ts
1679
+ function runReview(options) {
1680
+ const store = new WorkflowStore(options.root);
1681
+ const state = store.readState();
1682
+ const config = store.readConfig();
1683
+ const loop = new RepairLoop(config.maxRepairAttempts);
1684
+ const reviewContent = options.reviewFile ? (0, import_node_fs9.readFileSync)(options.reviewFile, "utf8") : `# Review
1685
+
1686
+ Outcome: ${options.outcome}
1687
+ `;
1688
+ store.writeTaskFile(options.task, "REVIEW.md", reviewContent);
1689
+ state.currentTask = options.task;
1690
+ state.reviewAttempt += 1;
1691
+ if (options.outcome === "PASS") {
1692
+ state.state = "COMPLETED" /* COMPLETED */;
1693
+ state.nextAction = "Task completed. Return to IDLE when ready.";
1694
+ state.blockingIssues = [];
1695
+ } else if (options.outcome === "BLOCKED") {
1696
+ state.state = "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */;
1697
+ state.nextAction = "Escalate blocking issue to user";
1698
+ state.blockingIssues = ["Reviewer marked task as BLOCKED"];
1699
+ } else {
1700
+ state.repairAttempt += 1;
1701
+ if (loop.needsEscalation(state.repairAttempt)) {
1702
+ state.state = "ESCALATION_REQUIRED" /* ESCALATION_REQUIRED */;
1703
+ state.nextAction = "Repair attempts exceeded limit. Escalate to user.";
1704
+ state.blockingIssues = [
1705
+ `Max repair attempts exceeded (${config.maxRepairAttempts})`
1706
+ ];
1707
+ } else {
1708
+ state.state = "REPAIR_REQUIRED" /* REPAIR_REQUIRED */;
1709
+ state.nextAction = "Prepare targeted repair request and delegate again";
1710
+ state.blockingIssues = [];
1711
+ }
1712
+ }
1713
+ state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1714
+ store.writeState(state);
1715
+ console.log(`Review outcome recorded: ${options.outcome}`);
1716
+ console.log(`State is now: ${state.state}`);
1717
+ }
1718
+
1719
+ // src/commands/status.ts
1720
+ function runStatus(options) {
1721
+ const store = new WorkflowStore(options.root);
1722
+ const state = store.readState();
1723
+ console.log("Current workflow status");
1724
+ console.log(`State: ${state.state}`);
1725
+ console.log(`Current phase: ${state.currentPhase}`);
1726
+ console.log(`Current task: ${state.currentTask}`);
1727
+ console.log(`Review attempt: ${state.reviewAttempt}`);
1728
+ console.log(`Repair attempt: ${state.repairAttempt}`);
1729
+ console.log(`Next action: ${state.nextAction}`);
1730
+ console.log(`Updated at: ${state.updatedAt}`);
1731
+ if (state.blockingIssues.length > 0) {
1732
+ console.log("Blocking issues:");
1733
+ for (const issue of state.blockingIssues) {
1734
+ console.log(`- ${issue}`);
1735
+ }
1736
+ }
1737
+ }
1738
+
1739
+ // src/cli.ts
1740
+ var program = new import_commander.Command();
1741
+ program.name("codex-antigravity-kit").description("Codex brain + Antigravity worker orchestration kit").version("0.1.0");
1742
+ program.command("init").option("--root <path>", "Project root", process.cwd()).option("--force", "Overwrite existing kit files", false).action((options) => {
1743
+ runInit({ root: (0, import_node_path6.resolve)(options.root), force: options.force });
1744
+ });
1745
+ program.command("doctor").option("--root <path>", "Project root", process.cwd()).action((options) => {
1746
+ runDoctor({ root: (0, import_node_path6.resolve)(options.root) });
1747
+ });
1748
+ program.command("status").option("--root <path>", "Project root", process.cwd()).action((options) => {
1749
+ runStatus({ root: (0, import_node_path6.resolve)(options.root) });
1750
+ });
1751
+ program.command("brainstorm").requiredOption("--task <id>", "Task ID").option("--spec <path>", "Path to task SPEC markdown file").option("--prompt <text>", "Task specification prompt text").option("--agent <name>", "Explicit agent override (web-engineer, mobile-engineer, game-engineer, researcher, business-analyst, codex)").option("--root <path>", "Project root", process.cwd()).action((options) => {
1752
+ runBrainstorm({
1753
+ root: (0, import_node_path6.resolve)(options.root),
1754
+ task: options.task,
1755
+ spec: options.spec ? (0, import_node_path6.resolve)(options.spec) : void 0,
1756
+ prompt: options.prompt,
1757
+ agent: options.agent
1758
+ });
1759
+ });
1760
+ program.command("plan").requiredOption("--task <id>", "Task ID").option("--spec <path>", "Path to task SPEC markdown file").option("--agent <name>", "Explicit agent override").option("--root <path>", "Project root", process.cwd()).action((options) => {
1761
+ runPlan({
1762
+ root: (0, import_node_path6.resolve)(options.root),
1763
+ task: options.task,
1764
+ spec: options.spec ? (0, import_node_path6.resolve)(options.spec) : void 0,
1765
+ agent: options.agent
1766
+ });
1767
+ });
1768
+ program.command("execute").requiredOption("--task <id>", "Task ID").option("--plan <path>", "Path to plan markdown file").option("--file <path>", "Path to markdown description file to execute").option("--spec <path>", "Path to task SPEC markdown file").option("--agent <name>", "Explicit agent override").option("--repair-request <path>", "Path to repair request markdown").option("--timeout-ms <number>", "Worker timeout in ms", "600000").option("--root <path>", "Project root", process.cwd()).action(
1769
+ async (options) => {
1770
+ await runExecute({
1771
+ root: (0, import_node_path6.resolve)(options.root),
1772
+ task: options.task,
1773
+ plan: options.plan ? (0, import_node_path6.resolve)(options.plan) : void 0,
1774
+ file: options.file ? (0, import_node_path6.resolve)(options.file) : void 0,
1775
+ spec: options.spec ? (0, import_node_path6.resolve)(options.spec) : void 0,
1776
+ agent: options.agent,
1777
+ repairRequest: options.repairRequest ? (0, import_node_path6.resolve)(options.repairRequest) : void 0,
1778
+ timeoutMs: Number(options.timeoutMs)
1779
+ });
1780
+ }
1781
+ );
1782
+ program.command("delegate").requiredOption("--task <id>", "Task ID").requiredOption("--spec <path>", "Path to task SPEC markdown file").option("--repair-request <path>", "Path to repair request markdown").option("--timeout-ms <number>", "Worker timeout in ms", "600000").option("--root <path>", "Project root", process.cwd()).action(
1783
+ async (options) => {
1784
+ await runDelegate({
1785
+ root: (0, import_node_path6.resolve)(options.root),
1786
+ task: options.task,
1787
+ spec: (0, import_node_path6.resolve)(options.spec),
1788
+ repairRequest: options.repairRequest ? (0, import_node_path6.resolve)(options.repairRequest) : void 0,
1789
+ timeoutMs: Number(options.timeoutMs)
1790
+ });
1791
+ }
1792
+ );
1793
+ program.command("review").requiredOption("--task <id>", "Task ID").requiredOption("--outcome <value>", "PASS | FAIL | BLOCKED").option("--review-file <path>", "Path to review markdown").option("--root <path>", "Project root", process.cwd()).action((options) => {
1794
+ const outcome = options.outcome.toUpperCase();
1795
+ if (!["PASS", "FAIL", "BLOCKED"].includes(outcome)) {
1796
+ throw new Error("--outcome must be PASS, FAIL, or BLOCKED");
1797
+ }
1798
+ runReview({
1799
+ root: (0, import_node_path6.resolve)(options.root),
1800
+ task: options.task,
1801
+ outcome,
1802
+ reviewFile: options.reviewFile ? (0, import_node_path6.resolve)(options.reviewFile) : void 0
1803
+ });
1804
+ });
1805
+ program.parseAsync(process.argv).catch((error) => {
1806
+ console.error(error instanceof Error ? error.message : String(error));
1807
+ process.exitCode = 1;
1808
+ });