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