@williambeto/ai-workflow 2.4.9 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/bin/ai-workflow.d.ts +3 -0
  2. package/bin/ai-workflow.js +2669 -1
  3. package/bin/ai-workflow.js.map +1 -0
  4. package/chunk-2AOV2ATY.js +749 -0
  5. package/chunk-5WRI5ZAA.js +31 -0
  6. package/chunk-6EMG6FAO.js +734 -0
  7. package/chunk-UHLZX2EG.js +1827 -0
  8. package/core/index.d.ts +440 -0
  9. package/core/index.js +32 -0
  10. package/core/index.js.map +1 -0
  11. package/dist-assets/AGENTS.md +23 -6
  12. package/dist-assets/agents/atlas.md +8 -8
  13. package/dist-assets/agents/nexus.md +4 -4
  14. package/dist-assets/agents/orion.md +1 -1
  15. package/dist-assets/agents/phoenix.md +1 -1
  16. package/dist-assets/agents/sage.md +1 -1
  17. package/dist-assets/commands/implement.md +1 -1
  18. package/dist-assets/docs/QUICKSTART.md +8 -8
  19. package/dist-assets/docs/cli-reference.md +7 -7
  20. package/dist-assets/docs/compatibility/provider-usage.md +1 -9
  21. package/dist-assets/docs/compatibility/runtime-matrix.md +5 -6
  22. package/dist-assets/docs/consumer-onboarding.md +2 -2
  23. package/dist-assets/docs/design-patterns-policy.md +1 -1
  24. package/dist-assets/docs/npm-consumer-quickstart.md +70 -109
  25. package/dist-assets/docs/policies/01-BRANCH_GATE.md +1 -1
  26. package/dist-assets/docs/policies/06-FINAL_EVIDENCE_CONTRACT.md +2 -2
  27. package/dist-assets/docs/policies/08-PRODUCT_TRUTHFULNESS_AND_PROJECT_DOCS.md +1 -1
  28. package/dist-assets/docs/policies/10-BEHAVIORAL_CONTRACT_HARDENING.md +1 -1
  29. package/dist-assets/docs/policies/ORCHESTRATION_PROTOCOL.md +8 -9
  30. package/dist-assets/docs/policies/PROCEDURE_DELIVERY_ARTIFACTS.md +4 -10
  31. package/dist-assets/docs/policies/SKILLS_COMMON_GOVERNANCE.md +1 -1
  32. package/dist-assets/docs/profiles/README.md +2 -2
  33. package/dist-assets/docs/specs/runtime-operational-contract.md +12 -12
  34. package/dist-assets/docs/troubleshooting-guide.md +2 -2
  35. package/dist-assets/docs/visual-validation-guide.md +3 -3
  36. package/dist-assets/schemas/evidence.schema.json +109 -0
  37. package/dist-assets/templates/ANTIGRAVITY.md.template +7 -5
  38. package/dist-assets/templates/CLAUDE.md.template +7 -5
  39. package/dist-assets/templates/CODEX.md.template +7 -5
  40. package/evidence-validator-76ZQQYDU.js +6661 -0
  41. package/package.json +7 -64
  42. package/{src/core/workspace/read-only-workspace.js → read-only-workspace-PZBE7KAX.js} +14 -31
  43. package/{src/commands/validate.js → validate-Q2NLLQ5G.js} +30 -22
  44. package/AGENTS.md +0 -34
  45. package/CHANGELOG.md +0 -259
  46. package/LICENSE +0 -21
  47. package/PUBLISH_MANIFEST.json +0 -34
  48. package/README.md +0 -129
  49. package/dist-assets/templates/.geminiignore.template +0 -8
  50. package/dist-assets/templates/GEMINI.md.template +0 -20
  51. package/docs/compatibility/provider-usage.md +0 -46
  52. package/docs/compatibility/runtime-matrix.md +0 -31
  53. package/docs/getting-started/DESKTOP_PROMPT.md +0 -52
  54. package/docs/getting-started/authoring-custom-skills.md +0 -80
  55. package/docs/getting-started/quickstart.md +0 -117
  56. package/docs/getting-started/troubleshooting.md +0 -123
  57. package/docs/getting-started/upgrading-to-v2.md +0 -62
  58. package/src/adapters/index.js +0 -4
  59. package/src/adapters/platforms/antigravity.js +0 -382
  60. package/src/adapters/platforms/claude.js +0 -126
  61. package/src/adapters/platforms/codex.js +0 -113
  62. package/src/adapters/platforms/gemini.js +0 -245
  63. package/src/cli.js +0 -155
  64. package/src/commands/clean.js +0 -106
  65. package/src/commands/collect-evidence.js +0 -25
  66. package/src/commands/doctor.js +0 -202
  67. package/src/commands/execute.js +0 -382
  68. package/src/commands/init.js +0 -359
  69. package/src/commands/run.js +0 -112
  70. package/src/core/backup.js +0 -65
  71. package/src/core/completion-contract.js +0 -35
  72. package/src/core/delegation-controller.js +0 -193
  73. package/src/core/evidence/evidence-ledger.js +0 -98
  74. package/src/core/execution-planner.js +0 -62
  75. package/src/core/filesystem.js +0 -141
  76. package/src/core/finalization/finalizer.js +0 -165
  77. package/src/core/finalization/workspace-snapshot.js +0 -110
  78. package/src/core/gates/branch-gate.js +0 -134
  79. package/src/core/gates/merge-gate.js +0 -74
  80. package/src/core/handoff/handoff-engine.js +0 -104
  81. package/src/core/healing/cli-remediation-executor.js +0 -153
  82. package/src/core/healing/healer-engine.js +0 -212
  83. package/src/core/healing/runtime-remediation-executor.js +0 -136
  84. package/src/core/identity.js +0 -43
  85. package/src/core/install-plan.js +0 -34
  86. package/src/core/opencode-merge.js +0 -150
  87. package/src/core/package-assets.js +0 -141
  88. package/src/core/request-classifier.js +0 -73
  89. package/src/core/request-router.js +0 -289
  90. package/src/core/runtime/opencode-adapter.js +0 -202
  91. package/src/core/sdd/validator.js +0 -67
  92. package/src/core/statuses.js +0 -29
  93. package/src/core/symlink-layout.js +0 -93
  94. package/src/core/templates.js +0 -229
  95. package/src/core/validation/artifact-fidelity-gate.js +0 -445
  96. package/src/core/validation/canonical-finalization.js +0 -43
  97. package/src/core/validation/delivery-decision-engine.js +0 -344
  98. package/src/core/validation/evidence-collector.js +0 -245
  99. package/src/core/validation/quality-guard.js +0 -251
  100. package/src/core/validation/stack-detector.js +0 -65
  101. package/src/core/validation/validation-planner.js +0 -134
  102. package/src/core/validation/visual-verifier.js +0 -175
  103. package/src/core/workflow-profiles.js +0 -107
  104. package/src/core/workflow-state-machine.js +0 -46
@@ -1,382 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { COMPLETION_STATUS_TEXT } from "../../core/statuses.js";
5
-
6
- /**
7
- * Maps OpenCode agent names to primary agent roles.
8
- * @type {Record<string, string>}
9
- */
10
- const PERSONA_MAPPING = {
11
- "atlas": "Atlas",
12
- "orion": "Orion",
13
- "sage": "Sage",
14
- "nexus": "Nexus",
15
- "astra": "Astra",
16
- "sage-validation": "Sage",
17
- "orion-release": "Orion",
18
- "orion-deploy": "Orion",
19
- "nexus-discovery": "Nexus",
20
- "phoenix": "Phoenix"
21
- };
22
-
23
- /**
24
- * Antigravity Adapter - Transforms OpenCode .md to Antigravity Skill format and manages .agents/ integration.
25
- */
26
- export class AntigravityAdapter {
27
- constructor({ cwd }) {
28
- this.cwd = cwd;
29
- }
30
-
31
- /**
32
- * Transforms an OpenCode agent or specialized skill file to an Antigravity Skill.
33
- * @param {string} filePath - Path to the source .md file.
34
- * @returns {Promise<{content: string, name: string}>}
35
- */
36
- async transform(filePath) {
37
- const content = await fs.readFile(filePath, "utf8");
38
- const fileName = path.basename(filePath, ".md") === "SKILL"
39
- ? path.basename(path.dirname(filePath))
40
- : path.basename(filePath, ".md");
41
-
42
- const persona = PERSONA_MAPPING[fileName.toLowerCase()] || "Astra";
43
-
44
- // Check if already has frontmatter
45
- if (content.trim().startsWith("---")) {
46
- return { content, name: fileName };
47
- }
48
-
49
- // Extract description from the first paragraph after the title
50
- const descriptionMatch = content.match(/^# .*\n\n(.*)/m);
51
- const description = descriptionMatch ? descriptionMatch[1].trim() : `Specialized agent for ${fileName}.`;
52
-
53
- const skillContent = `---
54
- name: ${fileName}
55
- description: ${description}
56
- ---
57
- # ${persona} Persona
58
-
59
- ${content}
60
-
61
- ## Completion Contract (Mandatory)
62
- Every task completion MUST provide the following payload:
63
- 1. **Status**: ${COMPLETION_STATUS_TEXT}
64
- 2. **Scope reviewed**: Brief summary of what was analyzed.
65
- 3. **Findings**: Evidence-based discoveries.
66
- 4. **Files affected**: List of all concrete paths modified or created.
67
- 5. **Validation/evidence**: Commands run and their results.
68
- 6. **Risks/notes**: Any caveats or technical debt introduced.
69
- 7. **Required manager action**: Clear next step for the orchestrator.
70
- 8. **Can manager continue**: [yes/no]
71
- `;
72
-
73
- return {
74
- content: skillContent,
75
- name: fileName
76
- };
77
- }
78
-
79
- /**
80
- * Deploys transformed skills and agents to their respective directories.
81
- * Also orchestrates the .antigravity/ native integration.
82
- */
83
- async deploy(transformedItems, installRoot = ".ai-workflow") {
84
- const agentsDir = path.join(this.cwd, installRoot, "opencode/agents");
85
- const skillsDir = path.join(this.cwd, installRoot, "opencode/skills");
86
-
87
- await fs.mkdir(agentsDir, { recursive: true });
88
- await fs.mkdir(skillsDir, { recursive: true });
89
-
90
- for (const item of transformedItems) {
91
- const isAgent = PERSONA_MAPPING[item.name.toLowerCase()];
92
- const targetDir = isAgent ? agentsDir : path.join(skillsDir, item.name);
93
- const fileName = isAgent ? `${item.name}.md` : "SKILL.md";
94
-
95
- const absoluteTargetDir = isAgent ? agentsDir : targetDir;
96
- await fs.mkdir(absoluteTargetDir, { recursive: true });
97
- await fs.writeFile(path.join(absoluteTargetDir, fileName), item.content);
98
- }
99
-
100
- // Deploy native Antigravity extensions (.antigravity/)
101
- await this.deployNativeExtensions(installRoot);
102
-
103
- // Also deploy root ANTIGRAVITY.md if it doesn't exist
104
- await this.deployInstructions();
105
- }
106
-
107
- /**
108
- * Orchestrates the .agents/ directory with copies of .ai-workflow/ assets.
109
- * Using hard copies instead of symlinks ensures native discovery across all platforms.
110
- */
111
- async deployNativeExtensions(installRoot = ".ai-workflow") {
112
- const antigravityDir = path.join(this.cwd, ".agents");
113
- const antigravityAgents = path.join(antigravityDir, "agents");
114
- const antigravitySkills = path.join(antigravityDir, "skills");
115
- const antigravityCommands = path.join(antigravityDir, "commands");
116
-
117
- await fs.mkdir(antigravityAgents, { recursive: true });
118
- await fs.mkdir(antigravitySkills, { recursive: true });
119
- await fs.mkdir(antigravityCommands, { recursive: true });
120
-
121
- const getUrls = (targetPath) => {
122
- const linuxUrl = pathToFileURL(targetPath).href;
123
- const urls = [linuxUrl];
124
-
125
- if (process.platform === "linux" && process.env.WSL_DISTRO_NAME) {
126
- const distro = process.env.WSL_DISTRO_NAME;
127
- const normalizedPath = targetPath.replaceAll("\\", "/");
128
- urls.push(`file://wsl.localhost/${distro}${normalizedPath}`);
129
- urls.push(`file:///wsl.localhost/${distro}${normalizedPath}`);
130
- }
131
-
132
- return urls.join("\n");
133
- };
134
-
135
- const toolNames = [
136
- "send_message",
137
- "find_by_name",
138
- "grep_search",
139
- "view_file",
140
- "list_dir",
141
- "read_url_content",
142
- "search_web",
143
- "schedule",
144
- "multi_replace_file_content",
145
- "replace_file_content",
146
- "write_to_file",
147
- "run_command",
148
- "manage_task",
149
- "define_subagent",
150
- "invoke_subagent",
151
- "manage_subagents",
152
- "call_mcp_tool"
153
- ];
154
-
155
- const systemPromptConfig = {
156
- "includeSections": [
157
- "user_information",
158
- "mcp_servers",
159
- "skills",
160
- "subagent_reminder",
161
- "messaging",
162
- "artifacts",
163
- "user_rules"
164
- ]
165
- };
166
-
167
- // 1. Deploy Primary Agents to .agents/agents/{agent_name}/
168
- const sourceAgentsDir = path.join(this.cwd, installRoot, "opencode/agents");
169
- const agentFiles = await fs.readdir(sourceAgentsDir).catch(() => []);
170
-
171
- const AGENTS_INFO = {
172
- "atlas": { name: "Atlas", description: "Router and workflow coordinator for AI Workflow Kit" },
173
- "nexus": { name: "Nexus", description: "Discovery, requirement, scope, and specification owner" },
174
- "orion": { name: "Orion", description: "Planning, PR sequencing, release, and deployment strategy owner" },
175
- "astra": { name: "Astra", description: "Implementation owner for incremental, scoped changes" },
176
- "sage": { name: "Sage", description: "Audit, validation, evidence, and quality gate owner" },
177
- "phoenix": { name: "Phoenix", description: "Remediation and regression recovery owner" }
178
- };
179
-
180
- for (const file of agentFiles) {
181
- if (!file.endsWith(".md")) continue;
182
- const lowercaseName = path.basename(file, ".md").toLowerCase();
183
- const info = AGENTS_INFO[lowercaseName];
184
- if (!info) continue;
185
-
186
- const agentFolder = path.join(antigravityAgents, lowercaseName);
187
- await fs.mkdir(agentFolder, { recursive: true });
188
-
189
- // Copy Markdown file to the agent's folder
190
- const content = await fs.readFile(path.join(sourceAgentsDir, file), "utf8");
191
- const mdTarget = path.join(agentFolder, `${lowercaseName}.md`);
192
- await fs.writeFile(mdTarget, content);
193
-
194
- // Generate agent.json
195
- const agentJson = {
196
- name: lowercaseName,
197
- description: info.description,
198
- hidden: false,
199
- config: {
200
- customAgent: {
201
- systemPromptSections: [
202
- {
203
- title: "Agent System Instructions",
204
- content: `You are ${info.name}, the ${lowercaseName === "astra" ? "implementation" : lowercaseName} owner.\n\nFollow the contract instructions in:\n${getUrls(mdTarget)}`
205
- }
206
- ],
207
- toolNames,
208
- systemPromptConfig
209
- }
210
- }
211
- };
212
- await fs.writeFile(path.join(agentFolder, "agent.json"), JSON.stringify(agentJson, null, 2));
213
- }
214
-
215
- // 2. Deploy Subagents to .agents/agents/{subagent_name}/
216
- const SUBAGENTS_INFO = {
217
- "Architecture-Specialist": { description: "Select the simplest architecture that safely satisfies current requirements", skill: "architecture" },
218
- "Backend-Engineer": { description: "Support safe PHP/Node/Python backend changes for APIs and persistence", skill: "backend-development" },
219
- "Deployment-Specialist": { description: "Plan, review, or validate deployment, release, and production-readiness", skill: "deployment" },
220
- "Design-Specialist": { description: "Apply practical design principles to keep solutions simple and maintainable", skill: "design-principles" },
221
- "Docs-Engineer": { description: "Write or improve project documentation, READMEs, guides, and prompts", skill: "documentation" },
222
- "Frontend-Engineer": { description: "Implement or review frontend changes involving UI, state, routing, and accessibility", skill: "frontend-development" },
223
- "Full-Stack-Engineer": { description: "Coordinate frontend and backend changes as one coherent, testable increment", skill: "full-stack-development" },
224
- "Token-Economist": { description: "Reduce context size while preserving information required for safe execution", skill: "optimize-tokens" },
225
- "PR-Manager": { description: "Plan, implement, review, or validate small pull requests while preserving scope", skill: "pr-workflow" },
226
- "Discovery-Analyst": { description: "Clarify ambiguous requests into actionable problem statements and success outcomes", skill: "product-discovery" },
227
- "Product-Planner": { description: "Turn clarified needs into scoped requirements with acceptance-ready outcomes", skill: "product-planning" },
228
- "Memory-Guardian": { description: "Manage discoverable project memory for durable decisions and recurring corrections", skill: "project-memory" },
229
- "Prompt-Engineer": { description: "Expert in creating and refining prompts for AI agents and workflows", skill: "prompt-engineer" },
230
- "QA-Engineer": { description: "Design, review, or improve tests, acceptance criteria, and validation evidence", skill: "qa-workflow" },
231
- "Refactoring-Specialist": { description: "Improve code/document structure safely while preserving behavior", skill: "refactoring" },
232
- "Release-Specialist": { description: "Prepare release readiness decisions with explicit gates and evidence", skill: "release-workflow" },
233
- "SDD-Specialist": { description: "Convert approved requirements into explicit, testable specification artifacts", skill: "spec-driven-development" },
234
- "Technical-Leader": { description: "Make technical decisions, review architecture, and identify trade-offs", skill: "technical-leadership" },
235
- "UI-UX-Engineer": { description: "Improve usability and interface clarity without introducing unnecessary complexity", skill: "ui-ux-design" }
236
- };
237
-
238
- for (const [name, subInfo] of Object.entries(SUBAGENTS_INFO)) {
239
- const lowercaseSubagentName = name.toLowerCase();
240
- const subagentFolder = path.join(antigravityAgents, lowercaseSubagentName);
241
- await fs.mkdir(subagentFolder, { recursive: true });
242
-
243
- const skillPath = path.join(antigravitySkills, subInfo.skill, "SKILL.md");
244
-
245
- const subagentJson = {
246
- name: lowercaseSubagentName,
247
- description: subInfo.description,
248
- hidden: false,
249
- config: {
250
- customAgent: {
251
- systemPromptSections: [
252
- {
253
- title: "Agent System Instructions",
254
- content: `You are ${name}.\n\nFollow the contract instructions in:\n${getUrls(skillPath)}`
255
- }
256
- ],
257
- toolNames,
258
- systemPromptConfig
259
- }
260
- }
261
- };
262
- await fs.writeFile(path.join(subagentFolder, "agent.json"), JSON.stringify(subagentJson, null, 2));
263
- }
264
-
265
- // 3. Copy Skills
266
- const sourceSkillsDir = path.join(this.cwd, installRoot, "opencode/skills");
267
- const skillFolders = await fs.readdir(sourceSkillsDir).catch(() => []);
268
- for (const folder of skillFolders) {
269
- const skillSource = path.join(sourceSkillsDir, folder, "SKILL.md");
270
- if (await this.exists(skillSource)) {
271
- await fs.mkdir(path.join(antigravitySkills, folder), { recursive: true });
272
- const content = await fs.readFile(skillSource, "utf8");
273
- await fs.writeFile(path.join(antigravitySkills, folder, "SKILL.md"), content);
274
- }
275
- }
276
-
277
- // 4. Copy Commands (from dist-assets/commands)
278
- const sourceCommandsDir = path.join(this.cwd, installRoot, "opencode/commands");
279
- if (await this.exists(sourceCommandsDir)) {
280
- const commandFiles = await fs.readdir(sourceCommandsDir).catch(() => []);
281
- for (const file of commandFiles) {
282
- if (!file.endsWith(".md") && !file.endsWith(".toml")) continue;
283
- const content = await fs.readFile(path.join(sourceCommandsDir, file), "utf8");
284
- await fs.writeFile(path.join(antigravityCommands, file), content);
285
- }
286
- }
287
-
288
- // 5. Copy governance policy into .agents/docs/policies/ so the relative
289
- // link ../../docs/policies/SKILLS_COMMON_GOVERNANCE.md in each
290
- // .agents/skills/{skill}/SKILL.md resolves correctly.
291
- const sourcePoliciesDir = path.join(this.cwd, installRoot, "opencode", "docs", "policies");
292
- const antigravityPolicies = path.join(antigravityDir, "docs", "policies");
293
- if (await this.exists(sourcePoliciesDir)) {
294
- await fs.mkdir(antigravityPolicies, { recursive: true });
295
- const policyFiles = await fs.readdir(sourcePoliciesDir).catch(() => []);
296
- for (const file of policyFiles) {
297
- if (!file.endsWith(".md")) continue;
298
- const content = await fs.readFile(path.join(sourcePoliciesDir, file), "utf8");
299
- await fs.writeFile(path.join(antigravityPolicies, file), content);
300
- }
301
- }
302
-
303
- // 6. Inject project settings.json
304
- const settingsPath = path.join(antigravityDir, "settings.json");
305
- if (!(await this.exists(settingsPath))) {
306
- const settings = {
307
- model: { name: "auto" },
308
- ui: { theme: "Ayu" }
309
- };
310
- await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));
311
- }
312
- }
313
-
314
- async exists(p) {
315
- try {
316
- await fs.access(p);
317
- return true;
318
- } catch {
319
- return false;
320
- }
321
- }
322
-
323
- /**
324
- * Deploys the main ANTIGRAVITY.md and .antigravityignore instructions to the project root.
325
- */
326
- async deployInstructions() {
327
- const targetPath = path.join(this.cwd, "ANTIGRAVITY.md");
328
- const ignorePath = path.join(this.cwd, ".antigravityignore");
329
-
330
- // Deploy ANTIGRAVITY.md if it doesn't exist
331
- try {
332
- await fs.access(targetPath);
333
- } catch {
334
- const instructions = `# AI Workflow Kit - Engineering Governance
335
-
336
- ## Mandate: Atlas Authority Protocol
337
- All architectural changes must align with the specifications issued by the **Specification Authority** (./specs).
338
-
339
- ## Ternary Architecture
340
- - **Root:** Orchestration and config.
341
- - **.ai-workflow/:** Implementation (The Muscle).
342
- - **./specs:** Specifications (The Brain).
343
-
344
- ## Branch Gates
345
- - **main Branch:** READ-ONLY.
346
- - **Validation:** Merges require successful observed validation; full/release workflows may persist EVIDENCE.json.
347
-
348
- ## Primary Agents
349
- - **Atlas (Orchestrator)**
350
- - **Orion (Strategist)**
351
- - **Sage (Auditor)**
352
- - **Nexus (Spec Architect)**
353
- - **Astra (Developer)**
354
- - **Phoenix (Healer)**
355
-
356
- ## Operational Preferences
357
- - Use \`token-economy\` and \`minimal-context\` skills.
358
- - **Native Discovery**: This project uses workspace-specific extensions in \`.agents/\`.
359
- - **Workflow Entry**: Use \`/atlas\` to begin any task.
360
- `;
361
- await fs.writeFile(targetPath, instructions);
362
- }
363
-
364
- // Deploy .antigravityignore if it doesn't exist
365
- try {
366
- await fs.access(ignorePath);
367
- } catch {
368
- const ignoreContent = `.ai-workflow/
369
- .ai-workflow-backups/
370
- node_modules/
371
- .git/
372
- EVIDENCE.json
373
- *.tgz
374
- *.zip
375
- *.tar
376
- .agents/tmp/
377
- .agents/history/
378
- `;
379
- await fs.writeFile(ignorePath, ignoreContent);
380
- }
381
- }
382
- }
@@ -1,126 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { COMPLETION_STATUS_TEXT } from "../../core/statuses.js";
4
-
5
- /**
6
- * Claude Adapter - Transforms OpenCode agents and skills into CLAUDE.md and .claude/rules/.
7
- */
8
- export class ClaudeAdapter {
9
- constructor({ cwd }) {
10
- this.cwd = cwd;
11
- }
12
-
13
- /**
14
- * Transforms an OpenCode agent or skill into a Claude rule with completion contract.
15
- */
16
- async transformToRule(filePath, type = "agent") {
17
- const content = await fs.readFile(filePath, "utf8");
18
- const fileName = path.basename(filePath, ".md") === "SKILL"
19
- ? path.basename(path.dirname(filePath))
20
- : path.basename(filePath, ".md");
21
-
22
- const ruleName = `${type}-${fileName.toLowerCase()}`;
23
-
24
- const hardenedContent = `---
25
- name: ${ruleName}
26
- description: ${type === "agent" ? "Persona" : "Skill"} rule for ${fileName}
27
- ---
28
- # ${fileName} ${type === "agent" ? "Persona" : "Skill"}
29
-
30
- ${content}
31
-
32
- ## Completion Contract (Mandatory)
33
- Every task completion MUST provide the following payload:
34
- 1. **Status**: ${COMPLETION_STATUS_TEXT}
35
- 2. **Scope reviewed**: Brief summary of what was analyzed.
36
- 3. **Findings**: Evidence-based discoveries.
37
- 4. **Files affected**: List of all concrete paths modified or created.
38
- 5. **Validation/evidence**: Commands run and their results.
39
- 6. **Risks/notes**: Any caveats or technical debt introduced.
40
- 7. **Required manager action**: Clear next step for the orchestrator.
41
- 8. **Can manager continue**: [yes/no]
42
- `;
43
-
44
- return {
45
- content: hardenedContent,
46
- name: ruleName
47
- };
48
- }
49
-
50
- /**
51
- * Deploys agents, skills, and root CLAUDE.md.
52
- */
53
- async deploy(installRoot = ".ai-workflow") {
54
- const rulesDir = path.join(this.cwd, ".claude/rules");
55
- await fs.mkdir(rulesDir, { recursive: true });
56
-
57
- const sourceAgentsDir = path.join(this.cwd, installRoot, "opencode/agents");
58
- const sourceSkillsDir = path.join(this.cwd, installRoot, "opencode/skills");
59
- const sourceCommandsDir = path.join(this.cwd, installRoot, "opencode/commands");
60
-
61
- // 1. Deploy Agents to .claude/rules/agent-*.md
62
- const agentFiles = await fs.readdir(sourceAgentsDir).catch(() => []);
63
- for (const file of agentFiles) {
64
- if (!file.endsWith(".md")) continue;
65
- const transformed = await this.transformToRule(path.join(sourceAgentsDir, file), "agent");
66
- await fs.writeFile(path.join(rulesDir, `${transformed.name}.md`), transformed.content);
67
- }
68
-
69
- // 2. Deploy Skills to .claude/rules/skill-*.md
70
- const skillFolders = await fs.readdir(sourceSkillsDir).catch(() => []);
71
- for (const folder of skillFolders) {
72
- const skillSource = path.join(sourceSkillsDir, folder, "SKILL.md");
73
- if (await this.exists(skillSource)) {
74
- const transformed = await this.transformToRule(skillSource, "skill");
75
- await fs.writeFile(path.join(rulesDir, `${transformed.name}.md`), transformed.content);
76
- }
77
- }
78
-
79
- // 3. Create root CLAUDE.md
80
- await this.deployRootClaudeMd(sourceCommandsDir);
81
- }
82
-
83
- async deployRootClaudeMd(sourceCommandsDir) {
84
- const targetPath = path.join(this.cwd, "CLAUDE.md");
85
-
86
- // Collect commands to document them in CLAUDE.md
87
- const commandFiles = await fs.readdir(sourceCommandsDir).catch(() => []);
88
- let commandsDoc = "";
89
- for (const file of commandFiles) {
90
- if (!file.endsWith(".md")) continue;
91
- const name = path.basename(file, ".md");
92
- commandsDoc += `- \`ai-workflow run --spec-path=...\` (Target: ${name})\n`;
93
- }
94
-
95
- const instructions = `# CLAUDE.md - AI Workflow Kit Governance
96
-
97
- This project uses the **AI Workflow Kit** (OpenCode-first) workflow.
98
-
99
- ## Mandate: Atlas Authority Protocol
100
- All architectural changes must align with the specifications issued by the **Specification Authority** (./specs).
101
-
102
- ## Common Commands
103
- ${commandsDoc}
104
- - \`ai-workflow doctor\`: Verify installation.
105
- - \`ai-workflow collect-evidence\`: Generate EVIDENCE.json.
106
-
107
- ## Rules & Personas
108
- Adhere to the specific rules and personas defined in \`.claude/rules/\`.
109
- - Always follow the **Branch Gate** policy (never work on \`main\`).
110
- - Always follow the **SDD Workflow** (Spec -> Plan -> PR -> Evidence).
111
-
112
- ## Completion Contract
113
- Every task completion MUST follow the payload format defined in the individual rule files.
114
- `;
115
- await fs.writeFile(targetPath, instructions);
116
- }
117
-
118
- async exists(p) {
119
- try {
120
- await fs.access(p);
121
- return true;
122
- } catch {
123
- return false;
124
- }
125
- }
126
- }
@@ -1,113 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { COMPLETION_STATUS_TEXT } from "../../core/statuses.js";
4
-
5
- /**
6
- * Codex Adapter - Transforms OpenCode agents, skills, and commands into Codex-native formats.
7
- */
8
- export class CodexAdapter {
9
- constructor({ cwd }) {
10
- this.cwd = cwd;
11
- }
12
-
13
- /**
14
- * Transforms an OpenCode agent into a Codex prompt with completion contract.
15
- */
16
- async transformAgent(filePath) {
17
- const content = await fs.readFile(filePath, "utf8");
18
- const fileName = path.basename(filePath, ".md");
19
-
20
- const hardenedContent = `${content}
21
-
22
- ## Completion Contract (Mandatory)
23
- Every task completion MUST provide the following payload:
24
- 1. **Status**: ${COMPLETION_STATUS_TEXT}
25
- 2. **Scope reviewed**: Brief summary of what was analyzed.
26
- 3. **Findings**: Evidence-based discoveries.
27
- 4. **Files affected**: List of all concrete paths modified or created.
28
- 5. **Validation/evidence**: Commands run and their results.
29
- 6. **Risks/notes**: Any caveats or technical debt introduced.
30
- 7. **Required manager action**: Clear next step for the orchestrator.
31
- 8. **Can manager continue**: [yes/no]
32
- `;
33
-
34
- return {
35
- content: hardenedContent,
36
- name: fileName
37
- };
38
- }
39
-
40
- /**
41
- * Deploys agents, skills, and commands to Codex-native directories.
42
- * Mapping:
43
- * - Agents -> .github/agents/
44
- * - Skills -> .agents/skills/
45
- * - Commands -> .codex/prompts/
46
- */
47
- async deploy(installRoot = ".ai-workflow") {
48
- const sourceAgentsDir = path.join(this.cwd, installRoot, "opencode/agents");
49
- const sourceSkillsDir = path.join(this.cwd, installRoot, "opencode/skills");
50
- const sourceCommandsDir = path.join(this.cwd, installRoot, "opencode/commands");
51
-
52
- // 1. Deploy Agents to .github/agents/
53
- const codexAgentsDir = path.join(this.cwd, ".github/agents");
54
- await fs.mkdir(codexAgentsDir, { recursive: true });
55
-
56
- const agentFiles = await fs.readdir(sourceAgentsDir).catch(() => []);
57
- for (const file of agentFiles) {
58
- if (!file.endsWith(".md")) continue;
59
- const transformed = await this.transformAgent(path.join(sourceAgentsDir, file));
60
- await fs.writeFile(path.join(codexAgentsDir, `${transformed.name}.md`), transformed.content);
61
- }
62
-
63
- // 2. Deploy Skills to .agents/skills/
64
- const codexSkillsDir = path.join(this.cwd, ".agents/skills");
65
- await fs.mkdir(codexSkillsDir, { recursive: true });
66
-
67
- const skillFolders = await fs.readdir(sourceSkillsDir).catch(() => []);
68
- for (const folder of skillFolders) {
69
- const skillSource = path.join(sourceSkillsDir, folder, "SKILL.md");
70
- if (await this.exists(skillSource)) {
71
- const targetDir = path.join(codexSkillsDir, folder);
72
- await fs.mkdir(targetDir, { recursive: true });
73
- const content = await fs.readFile(skillSource, "utf8");
74
- await fs.writeFile(path.join(targetDir, "SKILL.md"), content);
75
- }
76
- }
77
-
78
- // 3. Deploy Commands to .codex/prompts/
79
- const codexPromptsDir = path.join(this.cwd, ".codex/prompts");
80
- await fs.mkdir(codexPromptsDir, { recursive: true });
81
-
82
- const commandFiles = await fs.readdir(sourceCommandsDir).catch(() => []);
83
- for (const file of commandFiles) {
84
- if (!file.endsWith(".md") && !file.endsWith(".toml")) continue;
85
- // Codex prompts work best as .md
86
- const targetFileName = file.endsWith(".toml") ? `${path.basename(file, ".toml")}.md` : file;
87
- const content = await fs.readFile(path.join(sourceCommandsDir, file), "utf8");
88
- await fs.writeFile(path.join(codexPromptsDir, targetFileName), content);
89
- }
90
-
91
- // 4. Copy governance policy into .agents/docs/policies/ so the relative
92
- // link ../../docs/policies/SKILLS_COMMON_GOVERNANCE.md in each
93
- // .agents/skills/{skill}/SKILL.md resolves correctly.
94
- const codexPoliciesDir = path.join(this.cwd, ".agents", "docs", "policies");
95
- await fs.mkdir(codexPoliciesDir, { recursive: true });
96
- const sourcePoliciesDir = path.join(this.cwd, installRoot, "opencode", "docs", "policies");
97
- const policyFiles = await fs.readdir(sourcePoliciesDir).catch(() => []);
98
- for (const file of policyFiles) {
99
- if (!file.endsWith(".md")) continue;
100
- const policyContent = await fs.readFile(path.join(sourcePoliciesDir, file), "utf8");
101
- await fs.writeFile(path.join(codexPoliciesDir, file), policyContent);
102
- }
103
- }
104
-
105
- async exists(p) {
106
- try {
107
- await fs.access(p);
108
- return true;
109
- } catch {
110
- return false;
111
- }
112
- }
113
- }