@williambeto/ai-workflow 2.6.7 โ†’ 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,8 +1,87 @@
1
1
  ## [unreleased]
2
2
 
3
+ ### ๐Ÿš€ Features
4
+
5
+ - *(adapters)* Harden Codex adapter with robust system boundaries
6
+
7
+ ### ๐Ÿ’ผ Other
8
+
9
+ - Merge pull request #125 from williambeto/chore/cleanup
10
+
11
+ chore: clean up obsolete tests, audits, releases, and duplicates
12
+ - Merge pull request #126 from williambeto/refactor/consumer-examples
13
+
14
+ refactor: modernize consumer examples
15
+ - Merge pull request #127 from williambeto/feat/codex-hardening
16
+
17
+ feat(adapters): harden Codex adapter
18
+
19
+ ### ๐Ÿšœ Refactor
20
+
21
+ - Replace outdated examples with modern v2.7 consumer examples
22
+
23
+ ### ๐Ÿ“š Documentation
24
+
25
+ - Translate antigravity system prompt to english
26
+
27
+ ### โš™๏ธ Miscellaneous Tasks
28
+
29
+ - Clean up obsolete tests, audits, releases, and duplicates
30
+ - Merge dependabot PR
31
+ ## [2.7.0] - 2026-07-06
32
+
33
+ ### ๐Ÿš€ Features
34
+
35
+ - *(adapters)* Add copilot-instructions.md for maximum Codex compatibility
36
+
37
+ ### ๐Ÿ› Bug Fixes
38
+
39
+ - *(codex)* Ensure root instructions and proper runtime detection
40
+
41
+ ### ๐Ÿ’ผ Other
42
+
43
+ - Merge pull request #123 from williambeto/feat/codex-compatibility
44
+
45
+ feat: native codex runtime support
46
+
47
+ ### ๐Ÿ“š Documentation
48
+
49
+ - Update CHANGELOG for v2.6.6 and v2.6.7
50
+ - Save publish qa checklist
51
+ - *(qa)* Enforce markdown pattern on github releases
52
+ - Promote Codex to Supported and update assets list
53
+
54
+ ### โš™๏ธ Miscellaneous Tasks
55
+
56
+ - *(release)* V2.7.0
57
+ ## [2.6.7] - 2026-07-04
58
+
59
+ ### ๐Ÿ› Bug Fixes
60
+
61
+ - *(fidelity)* Skip HTML semantic check for non-page components (fixes #122)
62
+
63
+ ### โš™๏ธ Miscellaneous Tasks
64
+
65
+ - *(release)* 2.6.7
66
+ ## [2.6.6] - 2026-07-04
67
+
68
+ ### ๐Ÿšœ Refactor
69
+
70
+ - *(cli)* Reduce cyclomatic complexity in core commands
71
+
72
+ ### โš™๏ธ Miscellaneous Tasks
73
+
74
+ - Cleanup obsolete verification file and sync package-lock
75
+ - *(release)* 2.6.6
76
+ ## [2.6.5] - 2026-07-04
77
+
3
78
  ### ๐Ÿงช Testing
4
79
 
5
80
  - Align E2E assertions with updated requestedActor routing mechanics
81
+
82
+ ### โš™๏ธ Miscellaneous Tasks
83
+
84
+ - *(release)* V2.6.5
6
85
  ## [2.6.4] - 2026-07-04
7
86
 
8
87
  ### ๐Ÿ› Bug Fixes
@@ -193,13 +193,14 @@ function isValidProfile(profile) {
193
193
  function getTemplateFiles(profile = "standard") {
194
194
  return PROFILE_FILES[profile] ?? PROFILE_FILES.standard;
195
195
  }
196
- function buildAiWorkflowConfig({ profile }) {
196
+ function buildAiWorkflowConfig({ profile, runtimes = ["opencode"] }) {
197
197
  const version = getPackageVersion();
198
198
  const now = (/* @__PURE__ */ new Date()).toISOString();
199
+ const primaryRuntime = runtimes.join("+");
199
200
  return {
200
201
  package: "@williambeto/ai-workflow",
201
202
  version,
202
- runtime: "opencode",
203
+ runtime: primaryRuntime,
203
204
  profile,
204
205
  installMode: "project-local",
205
206
  generatedAt: now,
@@ -573,7 +574,8 @@ function normalize(p) {
573
574
  }
574
575
  var LINKABLE_ROOTS = /* @__PURE__ */ new Set([
575
576
  "opencode",
576
- ".agents"
577
+ ".agents",
578
+ "examples"
577
579
  ]);
578
580
  var LINKABLE_FILES = /* @__PURE__ */ new Set([]);
579
581
  function buildSymlinkEntries({ templateFiles, installRoot = ".ai-workflow" }) {
@@ -756,6 +758,11 @@ var CodexAdapter = class {
756
758
  const fileName = path7.basename(filePath, ".md");
757
759
  const hardenedContent = `${content}
758
760
 
761
+ ## System Directives for Codex
762
+ - **No Conversational Filler**: Output only the requested artifact or analysis. Do not apologize or add filler text.
763
+ - **Explicit Paths**: Always specify the exact, absolute or relative file path before making edits.
764
+ - **Read-Only First**: Do not invent or assume file contents. Always read the workspace first.
765
+
759
766
  ## Completion Contract (Mandatory)
760
767
  Every task completion MUST provide the following payload:
761
768
  1. **Status**: ${COMPLETION_STATUS_TEXT}
@@ -779,7 +786,7 @@ Every task completion MUST provide the following payload:
779
786
  * - Skills -> .agents/skills/
780
787
  * - Commands -> .codex/prompts/
781
788
  */
782
- async deploy(installRoot = ".ai-workflow") {
789
+ async deploy(installRoot = ".ai-workflow", force) {
783
790
  const sourceAgentsDir = path7.join(this.cwd, installRoot, "opencode/agents");
784
791
  const sourceSkillsDir = path7.join(this.cwd, installRoot, "opencode/skills");
785
792
  const sourceCommandsDir = path7.join(this.cwd, installRoot, "opencode/commands");
@@ -791,7 +798,7 @@ Every task completion MUST provide the following payload:
791
798
  const transformed = await this.transformAgent(path7.join(sourceAgentsDir, file));
792
799
  await fs5.writeFile(path7.join(codexAgentsDir, `${transformed.name}.md`), transformed.content);
793
800
  }
794
- const codexSkillsDir = path7.join(this.cwd, ".agents/skills");
801
+ const codexSkillsDir = path7.join(this.cwd, ".codex/skills");
795
802
  await fs5.mkdir(codexSkillsDir, { recursive: true });
796
803
  const skillFolders = await fs5.readdir(sourceSkillsDir).catch(() => []);
797
804
  for (const folder of skillFolders) {
@@ -812,7 +819,7 @@ Every task completion MUST provide the following payload:
812
819
  const content = await fs5.readFile(path7.join(sourceCommandsDir, file), "utf8");
813
820
  await fs5.writeFile(path7.join(codexPromptsDir, targetFileName), content);
814
821
  }
815
- const codexPoliciesDir = path7.join(this.cwd, ".agents", "docs", "policies");
822
+ const codexPoliciesDir = path7.join(this.cwd, ".codex", "docs", "policies");
816
823
  await fs5.mkdir(codexPoliciesDir, { recursive: true });
817
824
  const sourcePoliciesDir = path7.join(this.cwd, installRoot, "opencode", "docs", "policies");
818
825
  const policyFiles = await fs5.readdir(sourcePoliciesDir).catch(() => []);
@@ -821,6 +828,80 @@ Every task completion MUST provide the following payload:
821
828
  const policyContent = await fs5.readFile(path7.join(sourcePoliciesDir, file), "utf8");
822
829
  await fs5.writeFile(path7.join(codexPoliciesDir, file), policyContent);
823
830
  }
831
+ await this.deployRootCopilotInstructions();
832
+ await this.deployRootCodexMd(force);
833
+ await this.deployRootAgentsMd(force);
834
+ }
835
+ async deployRootCopilotInstructions() {
836
+ const githubDir = path7.join(this.cwd, ".github");
837
+ await fs5.mkdir(githubDir, { recursive: true });
838
+ const targetPath = path7.join(githubDir, "copilot-instructions.md");
839
+ const instructions = `# AI Workflow Kit Governance
840
+
841
+ This repository uses the **AI Workflow Kit** (OpenCode-first) workflow.
842
+
843
+ ## Mandate: Atlas Authority Protocol
844
+ All architectural changes must align with the specifications issued by the **Specification Authority**.
845
+
846
+ ## Rules & Personas
847
+ - Always follow the **Branch Gate** policy (never work on \`main\`).
848
+ - Always follow the **SDD Workflow** (Spec -> Plan -> PR -> Evidence).
849
+ - When acting as an agent, consult the instructions in \`.github/agents/\`.
850
+ - When utilizing skills, consult the files in \`.codex/skills/\`.
851
+
852
+ ## System Boundaries
853
+ - **No Conversational Filler**: Do not apologize or add filler text.
854
+ - **Strict Evidence**: You must provide the Completion Contract payload when finishing a task.
855
+ - **Immutable Core**: Do not modify files inside \`.ai-workflow/\`, \`.agents/\`, \`.claude/\`, or \`.codex/\` unless explicitly requested.
856
+
857
+ ## Completion Contract
858
+ Every task completion MUST follow the payload format defined in the individual agent files.
859
+ `;
860
+ await fs5.writeFile(targetPath, instructions);
861
+ }
862
+ async deployRootCodexMd(force) {
863
+ const targetPath = path7.join(this.cwd, "CODEX.md");
864
+ if (!force && await this.exists(targetPath)) return;
865
+ const templatePath = path7.join(this.cwd, ".ai-workflow", "templates", "CODEX.md.template");
866
+ if (await this.exists(templatePath)) {
867
+ const content = await fs5.readFile(templatePath, "utf8");
868
+ await fs5.writeFile(targetPath, content);
869
+ return;
870
+ }
871
+ const instructions = `# AI Workflow Kit Governance
872
+
873
+ This repository uses the **AI Workflow Kit** (OpenCode-first) workflow.
874
+
875
+ ## Mandate: Atlas Authority Protocol
876
+ All architectural changes must align with the specifications issued by the **Specification Authority**.
877
+
878
+ ## Rules & Personas
879
+ - Always follow the **Branch Gate** policy (never work on \`main\`).
880
+ - Always follow the **SDD Workflow** (Spec -> Plan -> PR -> Evidence).
881
+ - When acting as an agent, consult the instructions in \`.github/agents/\`.
882
+ - When utilizing skills, consult the files in \`.codex/skills/\`.
883
+
884
+ ## System Boundaries
885
+ - **No Conversational Filler**: Do not apologize or add filler text.
886
+ - **Strict Evidence**: You must provide the Completion Contract payload when finishing a task.
887
+ - **Immutable Core**: Do not modify files inside \`.ai-workflow/\`, \`.agents/\`, \`.claude/\`, or \`.codex/\` unless explicitly requested.
888
+
889
+ ## Completion Contract
890
+ Every task completion MUST follow the payload format defined in the individual agent files.
891
+ `;
892
+ await fs5.writeFile(targetPath, instructions);
893
+ }
894
+ async deployRootAgentsMd(force) {
895
+ const targetPath = path7.join(this.cwd, "AGENTS.md");
896
+ if (!force && await this.exists(targetPath)) return;
897
+ const templatePath = path7.join(this.cwd, ".ai-workflow", "AGENTS.md");
898
+ if (await this.exists(templatePath)) {
899
+ let content = await fs5.readFile(templatePath, "utf8");
900
+ content = content.replace(/\.agents\/skills/g, ".codex/skills");
901
+ content = content.replace(/opencode\/commands/g, ".codex/prompts");
902
+ content = content.replace(/opencode\/docs\/policies/g, ".codex/docs/policies");
903
+ await fs5.writeFile(targetPath, content);
904
+ }
824
905
  }
825
906
  async exists(p) {
826
907
  try {
@@ -1256,7 +1337,7 @@ function resolveProfile(profile) {
1256
1337
  }
1257
1338
  return selectedProfile;
1258
1339
  }
1259
- async function writeInstallFiles(cwd, actions, selectedProfile, force, noOverwrite, backupRoot = ".ai-workflow-backups") {
1340
+ async function writeInstallFiles(cwd, actions, selectedProfile, platforms, force, noOverwrite, backupRoot = ".ai-workflow-backups") {
1260
1341
  const skipped = [];
1261
1342
  const backups = [];
1262
1343
  for (const action of actions) {
@@ -1272,7 +1353,7 @@ async function writeInstallFiles(cwd, actions, selectedProfile, force, noOverwri
1272
1353
  });
1273
1354
  backups.push(backupPath);
1274
1355
  }
1275
- const content = action.relativePath === ".ai-workflow/config.json" ? `${JSON.stringify(buildAiWorkflowConfig({ profile: selectedProfile }), null, 2)}
1356
+ const content = action.relativePath === ".ai-workflow/config.json" ? `${JSON.stringify(buildAiWorkflowConfig({ profile: selectedProfile, runtimes: platforms.length > 0 ? platforms : ["opencode"] }), null, 2)}
1276
1357
  ` : action.content;
1277
1358
  await writeFileSafe(action.absolutePath, content || "");
1278
1359
  }
@@ -1319,7 +1400,7 @@ async function writeSymlinks(cwd, linkEntries, force, backupRoot = ".ai-workflow
1319
1400
  }
1320
1401
  return { linkBackups, linkCreated };
1321
1402
  }
1322
- async function executePlatformMigrations(cwd, installRoot, platforms, claude, codex, antigravity) {
1403
+ async function executePlatformMigrations(cwd, installRoot, platforms, claude, codex, antigravity, force) {
1323
1404
  if (platforms.length === 0) return;
1324
1405
  console.log("ai-workflow: migrating to native platforms...");
1325
1406
  const agentsDir = path9.join(cwd, installRoot, "opencode/agents");
@@ -1332,7 +1413,7 @@ async function executePlatformMigrations(cwd, installRoot, platforms, claude, co
1332
1413
  }
1333
1414
  if (codex) {
1334
1415
  const adapter = new CodexAdapter({ cwd });
1335
- await adapter.deploy(installRoot);
1416
+ await adapter.deploy(installRoot, force);
1336
1417
  console.log("- codex: deployed AI Workflow Kit agents to .agents/, .codex/, and .github/ (native discovery enabled)");
1337
1418
  }
1338
1419
  if (antigravity) {
@@ -1433,7 +1514,7 @@ async function runInit({
1433
1514
  }
1434
1515
  return;
1435
1516
  }
1436
- const { skipped, backups } = await writeInstallFiles(cwd, actions, selectedProfile, force, noOverwrite, backupRoot);
1517
+ const { skipped, backups } = await writeInstallFiles(cwd, actions, selectedProfile, platforms, force, noOverwrite, backupRoot);
1437
1518
  const { linkBackups, linkCreated } = await writeSymlinks(cwd, linkEntries, force, backupRoot);
1438
1519
  await setupInternalSymlinks(cwd, installRoot);
1439
1520
  const opencodeResult = await mergeOpencodeConfig(cwd, { force, backupRoot });
@@ -1457,7 +1538,7 @@ async function runInit({
1457
1538
  }
1458
1539
  const gitignoreResult = await upsertGitignoreBlock(cwd, generatedIgnoreEntries);
1459
1540
  const scriptInjected = await injectScripts(cwd);
1460
- await executePlatformMigrations(cwd, installRoot, platforms, claude, codex, antigravity);
1541
+ await executePlatformMigrations(cwd, installRoot, platforms, claude, codex, antigravity, force);
1461
1542
  printInstallationSummary({
1462
1543
  selectedProfile,
1463
1544
  opencodeResult,
@@ -1542,8 +1623,10 @@ async function checkAiWorkflowConfig(cwd, state) {
1542
1623
  }
1543
1624
  if (config.runtime) {
1544
1625
  console.log(`PASS runtime: ${config.runtime}`);
1626
+ state.runtimes = config.runtime.split("+");
1545
1627
  } else {
1546
1628
  console.log(`NOTE runtime field not present in ${basename}`);
1629
+ state.runtimes = ["opencode"];
1547
1630
  }
1548
1631
  if (Array.isArray(config.managedBlocks)) {
1549
1632
  state.managedBlocks = config.managedBlocks;
@@ -1640,17 +1723,50 @@ async function checkPackageJson(cwd, state) {
1640
1723
  }
1641
1724
  }
1642
1725
  }
1726
+ async function checkCodexRuntime(cwd, state) {
1727
+ const checks = [
1728
+ { name: "root AGENTS.md exists", path: "AGENTS.md" },
1729
+ { name: ".codex/skills exists", path: ".codex/skills" },
1730
+ { name: ".codex prompts detected", path: ".codex/prompts" },
1731
+ { name: ".codex policies detected", path: ".codex/docs/policies" }
1732
+ ];
1733
+ for (const check of checks) {
1734
+ const ok = await exists(path10.join(cwd, check.path));
1735
+ if (ok) {
1736
+ console.log(`PASS ${check.name}`);
1737
+ } else {
1738
+ state.hasFailure = true;
1739
+ console.log(`FAIL ${check.name}`);
1740
+ }
1741
+ }
1742
+ const codexMdOk = await exists(path10.join(cwd, "CODEX.md"));
1743
+ if (codexMdOk) {
1744
+ console.log(`PASS root CODEX.md exists`);
1745
+ }
1746
+ if (state.runtimes.includes("codex")) {
1747
+ console.log("PASS config runtime includes codex");
1748
+ } else {
1749
+ state.hasFailure = true;
1750
+ console.log("FAIL config runtime includes codex");
1751
+ }
1752
+ }
1643
1753
  async function runDoctor({ cwd }) {
1644
1754
  const state = {
1645
1755
  hasFailure: false,
1646
1756
  hasWarning: false,
1647
- managedBlocks: []
1757
+ managedBlocks: [],
1758
+ runtimes: ["opencode"]
1648
1759
  };
1649
1760
  console.log("Doctor report:");
1650
- await checkOpenCodeRuntime(cwd, state);
1651
1761
  await checkRequiredFiles(cwd, state);
1652
1762
  await checkAiWorkflowConfig(cwd, state);
1653
- await checkOpencodeJson(cwd, state);
1763
+ if (state.runtimes.includes("opencode")) {
1764
+ await checkOpenCodeRuntime(cwd, state);
1765
+ await checkOpencodeJson(cwd, state);
1766
+ }
1767
+ if (state.runtimes.includes("codex")) {
1768
+ await checkCodexRuntime(cwd, state);
1769
+ }
1654
1770
  await checkPackageJson(cwd, state);
1655
1771
  const finalStatus = state.hasFailure ? "FAIL" : state.hasWarning ? "PASS_WITH_NOTES" : "PASS";
1656
1772
  console.log(`Final status: ${finalStatus}`);