@aperant/framework 0.8.7 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/agents/apt-pr-review-fixer.md +9 -4
  3. package/agents/apt-verifier.md +6 -3
  4. package/dist/cli/commands/init.d.mts.map +1 -1
  5. package/dist/cli/commands/init.mjs +157 -23
  6. package/dist/cli/commands/init.mjs.map +1 -1
  7. package/dist/cli/commands/toolchain-detect.d.mts.map +1 -1
  8. package/dist/cli/commands/toolchain-detect.mjs +44 -0
  9. package/dist/cli/commands/toolchain-detect.mjs.map +1 -1
  10. package/dist/cli/commands/triage.d.mts.map +1 -1
  11. package/dist/cli/commands/triage.mjs +346 -13
  12. package/dist/cli/commands/triage.mjs.map +1 -1
  13. package/dist/cli/commands/uninstall.d.mts.map +1 -1
  14. package/dist/cli/commands/uninstall.mjs +11 -8
  15. package/dist/cli/commands/uninstall.mjs.map +1 -1
  16. package/dist/cli/consistency/parse-review.mjs +5 -3
  17. package/dist/cli/consistency/parse-review.mjs.map +1 -1
  18. package/dist/cli/consistency/rules/r5-verdict-consistency.d.mts.map +1 -1
  19. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs +10 -8
  20. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs.map +1 -1
  21. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  22. package/dist/cli/gate/gates/review-clean.mjs +4 -2
  23. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  24. package/dist/cli/install/mcp-provision.d.mts +26 -0
  25. package/dist/cli/install/mcp-provision.d.mts.map +1 -0
  26. package/dist/cli/install/mcp-provision.mjs +281 -0
  27. package/dist/cli/install/mcp-provision.mjs.map +1 -0
  28. package/dist/cli/install/mcp-server-specs.d.mts +80 -0
  29. package/dist/cli/install/mcp-server-specs.d.mts.map +1 -0
  30. package/dist/cli/install/mcp-server-specs.mjs +102 -0
  31. package/dist/cli/install/mcp-server-specs.mjs.map +1 -0
  32. package/dist/cli/install/runtime-detect.d.mts +27 -0
  33. package/dist/cli/install/runtime-detect.d.mts.map +1 -1
  34. package/dist/cli/install/runtime-detect.mjs +32 -0
  35. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  36. package/dist/cli/install/toml-merge.d.mts +40 -0
  37. package/dist/cli/install/toml-merge.d.mts.map +1 -0
  38. package/dist/cli/install/toml-merge.mjs +134 -0
  39. package/dist/cli/install/toml-merge.mjs.map +1 -0
  40. package/dist/cli/util/aperant-section.d.mts +12 -0
  41. package/dist/cli/util/aperant-section.d.mts.map +1 -1
  42. package/dist/cli/util/aperant-section.mjs +12 -0
  43. package/dist/cli/util/aperant-section.mjs.map +1 -1
  44. package/dist/cli/util/copy.d.mts +27 -0
  45. package/dist/cli/util/copy.d.mts.map +1 -1
  46. package/dist/cli/util/copy.mjs +49 -5
  47. package/dist/cli/util/copy.mjs.map +1 -1
  48. package/dist/cli/util/events-path.d.mts +8 -0
  49. package/dist/cli/util/events-path.d.mts.map +1 -0
  50. package/dist/cli/util/events-path.mjs +23 -0
  51. package/dist/cli/util/events-path.mjs.map +1 -0
  52. package/dist/cli/util/runtime-capabilities.d.mts +30 -0
  53. package/dist/cli/util/runtime-capabilities.d.mts.map +1 -0
  54. package/dist/cli/util/runtime-capabilities.mjs +214 -0
  55. package/dist/cli/util/runtime-capabilities.mjs.map +1 -0
  56. package/dist/cli/verify-proof/audit.d.mts +2 -7
  57. package/dist/cli/verify-proof/audit.d.mts.map +1 -1
  58. package/dist/cli/verify-proof/audit.mjs +11 -17
  59. package/dist/cli/verify-proof/audit.mjs.map +1 -1
  60. package/dist/cli/verify-proof/idl/index.d.mts +12 -1
  61. package/dist/cli/verify-proof/idl/index.d.mts.map +1 -1
  62. package/dist/cli/verify-proof/idl/index.mjs +50 -1
  63. package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
  64. package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
  65. package/dist/cli/verify-proof/resolver.mjs +51 -1
  66. package/dist/cli/verify-proof/resolver.mjs.map +1 -1
  67. package/dist/cli/verify-proof/runtime-detect.d.mts +2 -29
  68. package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
  69. package/dist/cli/verify-proof/runtime-detect.mjs +8 -203
  70. package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
  71. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  72. package/dist/plugin/agents/apt-pr-review-fixer.md +9 -4
  73. package/dist/plugin/agents/apt-verifier.md +6 -3
  74. package/dist/plugin/skills/apt-pr-review/SKILL.md +106 -15
  75. package/dist/plugin/skills/apt-setup/SKILL.md +7 -6
  76. package/dist/plugin/skills/apt-triage/SKILL.md +8 -6
  77. package/dist/plugin/skills/apt-update/SKILL.md +1 -1
  78. package/dist/plugin/skills/apt-verify/SKILL.md +1 -1
  79. package/dist/plugin/skills/apt-verify-proof/SKILL.md +25 -1
  80. package/drivers/browser/skill/agent-browser/SKILL.md +51 -0
  81. package/drivers/tauri/README.md +107 -0
  82. package/drivers/tauri/driver.mjs +88 -0
  83. package/drivers/tauri/manifest.json +37 -0
  84. package/drivers/tauri/scripts/tauri-mcp.sh +41 -0
  85. package/package.json +1 -1
  86. package/skills/apt-pr-review/SKILL.md +106 -15
  87. package/skills/apt-setup/SKILL.md +7 -6
  88. package/skills/apt-triage/SKILL.md +8 -6
  89. package/skills/apt-update/SKILL.md +1 -1
  90. package/skills/apt-verify/SKILL.md +1 -1
  91. package/skills/apt-verify-proof/SKILL.md +25 -1
  92. package/src/cli/commands/init.mjs +163 -19
  93. package/src/cli/commands/toolchain-detect.mjs +44 -0
  94. package/src/cli/commands/triage.mjs +352 -11
  95. package/src/cli/commands/uninstall.mjs +11 -8
  96. package/src/cli/consistency/parse-review.mjs +5 -3
  97. package/src/cli/consistency/rules/r5-verdict-consistency.mjs +14 -9
  98. package/src/cli/gate/gates/review-clean.mjs +4 -2
  99. package/src/cli/install/mcp-provision.mjs +293 -0
  100. package/src/cli/install/mcp-server-specs.mjs +101 -0
  101. package/src/cli/install/runtime-detect.mjs +36 -0
  102. package/src/cli/install/toml-merge.mjs +139 -0
  103. package/src/cli/util/aperant-section.mjs +14 -0
  104. package/src/cli/util/copy.mjs +53 -8
  105. package/src/cli/util/events-path.mjs +24 -0
  106. package/src/cli/util/runtime-capabilities.mjs +216 -0
  107. package/src/cli/verify-proof/audit.mjs +11 -17
  108. package/src/cli/verify-proof/idl/index.mjs +49 -11
  109. package/src/cli/verify-proof/resolver.mjs +49 -2
  110. package/src/cli/verify-proof/runtime-detect.mjs +11 -204
  111. package/templates/config.json +2 -1
@@ -42,6 +42,18 @@ export function detectInstalledRuntimes(targetDir: string): RuntimeDescriptor[];
42
42
  * capitalized form of `id`. Use for runtimes
43
43
  * whose product branding differs from the
44
44
  * internal id (C58: `kilo` → "Kilo Code").
45
+ * @property {string|null} nativeInstructionFile
46
+ * The root-level instruction file this
47
+ * runtime's native CLI reads (e.g. `claude`
48
+ * reads `CLAUDE.md`, `codex` reads
49
+ * `AGENTS.md`). `init` stamps the
50
+ * `<!-- APT:framework-* -->` managed block
51
+ * into every distinct non-null target for the
52
+ * selected runtimes. `null` means the runtime
53
+ * installs to its own surface (e.g. cursor →
54
+ * `.cursor/rules`), NOT a root `.md` — `init`
55
+ * skips null entries. Nullable by design, not
56
+ * a future-work placeholder (ID-01).
45
57
  */
46
58
  /** @type {RuntimeDescriptor[]} */
47
59
  export const RUNTIMES: RuntimeDescriptor[];
@@ -82,5 +94,20 @@ export type RuntimeDescriptor = {
82
94
  * internal id (C58: `kilo` → "Kilo Code").
83
95
  */
84
96
  displayLabel?: string | undefined;
97
+ /**
98
+ * The root-level instruction file this
99
+ * runtime's native CLI reads (e.g. `claude`
100
+ * reads `CLAUDE.md`, `codex` reads
101
+ * `AGENTS.md`). `init` stamps the
102
+ * `<!-- APT:framework-* -->` managed block
103
+ * into every distinct non-null target for the
104
+ * selected runtimes. `null` means the runtime
105
+ * installs to its own surface (e.g. cursor →
106
+ * `.cursor/rules`), NOT a root `.md` — `init`
107
+ * skips null entries. Nullable by design, not
108
+ * a future-work placeholder (ID-01).
109
+ */
110
+ nativeInstructionFile: string | null;
85
111
  };
112
+ export { detectFromPackageJson, loadRuntimeCapabilities } from "../util/runtime-capabilities.mjs";
86
113
  //# sourceMappingURL=runtime-detect.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-detect.d.mts","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"AA4JA;;;;;GAKG;AACH,+BAHW,MAAM,GACJ,iBAAiB,GAAC,IAAI,CAIlC;AAED;;;;;;;;;GASG;AACH,2CAHW,MAAM,GACJ,MAAM,EAAE,CAcpB;AAED;;;;;;GAMG;AACH,mDAHW,MAAM,GACJ,iBAAiB,EAAE,CAc/B;AA7LD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,kCAAkC;AAClC,uBADW,iBAAiB,EAAE,CA+G5B;AAEF,0BAA0B;AAC1B,0BADW,GAAG,CAAC,MAAM,CAAC,CACuC;;;;;QApI/C,MAAM;;;;UACN,MAAM;;;;;iBACN,MAAM;;;;;;aAEN,MAAM,EAAE;;;;;;;WAGR,MAAM,GAAC,IAAI"}
1
+ {"version":3,"file":"runtime-detect.d.mts","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"AAgMA;;;;;GAKG;AACH,+BAHW,MAAM,GACJ,iBAAiB,GAAC,IAAI,CAIlC;AAED;;;;;;;;;GASG;AACH,2CAHW,MAAM,GACJ,MAAM,EAAE,CAcpB;AAED;;;;;;GAMG;AACH,mDAHW,MAAM,GACJ,iBAAiB,EAAE,CAc/B;AAxND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,kCAAkC;AAClC,uBADW,iBAAiB,EAAE,CA8H5B;AAEF,0BAA0B;AAC1B,0BADW,GAAG,CAAC,MAAM,CAAC,CACuC;;;;;QA/J/C,MAAM;;;;UACN,MAAM;;;;;iBACN,MAAM;;;;;;aAEN,MAAM,EAAE;;;;;;;WAGR,MAAM,GAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;2BASX,MAAM,GAAC,IAAI"}
@@ -16,6 +16,11 @@
16
16
  import { existsSync, statSync } from 'node:fs';
17
17
  import { join } from 'node:path';
18
18
  import { MANIFEST_FILENAME } from './manifest.mjs';
19
+ // Package.json-shape capability detection lives in util/ (shared with
20
+ // verify-proof/runtime-detect.mjs). Re-exported here so install-layer callers
21
+ // (e.g. install/mcp-provision.mjs) consume it from their OWN layer instead of
22
+ // reaching across into verify-proof/.
23
+ export { detectFromPackageJson, loadRuntimeCapabilities, } from '../util/runtime-capabilities.mjs';
19
24
  /**
20
25
  * @typedef {Object} RuntimeDescriptor
21
26
  * @property {string} id Stable identifier (`claude`, `cursor`, …).
@@ -34,6 +39,18 @@ import { MANIFEST_FILENAME } from './manifest.mjs';
34
39
  * capitalized form of `id`. Use for runtimes
35
40
  * whose product branding differs from the
36
41
  * internal id (C58: `kilo` → "Kilo Code").
42
+ * @property {string|null} nativeInstructionFile
43
+ * The root-level instruction file this
44
+ * runtime's native CLI reads (e.g. `claude`
45
+ * reads `CLAUDE.md`, `codex` reads
46
+ * `AGENTS.md`). `init` stamps the
47
+ * `<!-- APT:framework-* -->` managed block
48
+ * into every distinct non-null target for the
49
+ * selected runtimes. `null` means the runtime
50
+ * installs to its own surface (e.g. cursor →
51
+ * `.cursor/rules`), NOT a root `.md` — `init`
52
+ * skips null entries. Nullable by design, not
53
+ * a future-work placeholder (ID-01).
37
54
  */
38
55
  /** @type {RuntimeDescriptor[]} */
39
56
  export const RUNTIMES = Object.freeze([
@@ -43,6 +60,7 @@ export const RUNTIMES = Object.freeze([
43
60
  installRoot: '.claude',
44
61
  markers: ['.claude/settings.json', '.claude/settings.local.json'],
45
62
  cliId: 'claude-code',
63
+ nativeInstructionFile: 'CLAUDE.md',
46
64
  },
47
65
  {
48
66
  id: 'codex',
@@ -50,6 +68,7 @@ export const RUNTIMES = Object.freeze([
50
68
  installRoot: '.agents',
51
69
  markers: ['.codex/config.toml'],
52
70
  cliId: 'codex',
71
+ nativeInstructionFile: 'AGENTS.md',
53
72
  },
54
73
  {
55
74
  id: 'cursor',
@@ -57,6 +76,7 @@ export const RUNTIMES = Object.freeze([
57
76
  installRoot: '.cursor',
58
77
  markers: ['.cursor/settings.json'],
59
78
  cliId: 'cursor',
79
+ nativeInstructionFile: null,
60
80
  },
61
81
  {
62
82
  id: 'gemini',
@@ -64,6 +84,7 @@ export const RUNTIMES = Object.freeze([
64
84
  installRoot: '.gemini',
65
85
  markers: ['.gemini/settings.json'],
66
86
  cliId: 'gemini-cli',
87
+ nativeInstructionFile: 'GEMINI.md',
67
88
  },
68
89
  {
69
90
  id: 'opencode',
@@ -71,6 +92,7 @@ export const RUNTIMES = Object.freeze([
71
92
  installRoot: '.opencode',
72
93
  markers: ['.opencode/config.json'],
73
94
  cliId: 'opencode',
95
+ nativeInstructionFile: 'AGENTS.md',
74
96
  },
75
97
  {
76
98
  id: 'pi',
@@ -78,6 +100,7 @@ export const RUNTIMES = Object.freeze([
78
100
  installRoot: '.pi',
79
101
  markers: ['.pi/settings.json', '.pi/skills', '.pi/prompts'],
80
102
  cliId: 'pi',
103
+ nativeInstructionFile: null,
81
104
  },
82
105
  {
83
106
  id: 'kilo',
@@ -89,6 +112,7 @@ export const RUNTIMES = Object.freeze([
89
112
  // migration per spec ID-01). `--kilocode` is also accepted as a
90
113
  // deprecated alias of `--kilo` at the CLI flag parser layer.
91
114
  displayLabel: 'Kilo Code',
115
+ nativeInstructionFile: null,
92
116
  },
93
117
  {
94
118
  id: 'copilot',
@@ -96,6 +120,7 @@ export const RUNTIMES = Object.freeze([
96
120
  installRoot: '.github/copilot',
97
121
  markers: ['.github/copilot-instructions.md'],
98
122
  cliId: 'copilot',
123
+ nativeInstructionFile: null,
99
124
  },
100
125
  {
101
126
  id: 'antigravity',
@@ -103,6 +128,7 @@ export const RUNTIMES = Object.freeze([
103
128
  installRoot: '.antigravity',
104
129
  markers: ['.antigravity/config.json'],
105
130
  cliId: 'antigravity',
131
+ nativeInstructionFile: null,
106
132
  },
107
133
  {
108
134
  id: 'windsurf',
@@ -110,6 +136,7 @@ export const RUNTIMES = Object.freeze([
110
136
  installRoot: '.windsurf',
111
137
  markers: ['.windsurfrules'],
112
138
  cliId: 'windsurf',
139
+ nativeInstructionFile: null,
113
140
  },
114
141
  {
115
142
  id: 'augment',
@@ -117,6 +144,7 @@ export const RUNTIMES = Object.freeze([
117
144
  installRoot: '.augment',
118
145
  markers: ['.augment/config.json'],
119
146
  cliId: 'augment',
147
+ nativeInstructionFile: null,
120
148
  },
121
149
  {
122
150
  id: 'trae',
@@ -124,6 +152,7 @@ export const RUNTIMES = Object.freeze([
124
152
  installRoot: '.trae',
125
153
  markers: ['.trae/config.json'],
126
154
  cliId: 'trae',
155
+ nativeInstructionFile: null,
127
156
  },
128
157
  {
129
158
  id: 'qwen',
@@ -131,6 +160,7 @@ export const RUNTIMES = Object.freeze([
131
160
  installRoot: '.qwen',
132
161
  markers: ['.qwen/config.json'],
133
162
  cliId: 'qwen',
163
+ nativeInstructionFile: null,
134
164
  },
135
165
  {
136
166
  id: 'cline',
@@ -138,6 +168,7 @@ export const RUNTIMES = Object.freeze([
138
168
  installRoot: '.cline',
139
169
  markers: ['.cline/config.json'],
140
170
  cliId: 'cline',
171
+ nativeInstructionFile: null,
141
172
  },
142
173
  {
143
174
  id: 'codebuddy',
@@ -145,6 +176,7 @@ export const RUNTIMES = Object.freeze([
145
176
  installRoot: '.codebuddy',
146
177
  markers: ['.codebuddy/config.json'],
147
178
  cliId: 'codebuddy',
179
+ nativeInstructionFile: null,
148
180
  },
149
181
  ]);
150
182
  /** @type {Set<string>} */
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-detect.mjs","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,kCAAkC;AAClC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC;QACC,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,uBAAuB,EAAE,6BAA6B,CAAC;QACjE,KAAK,EAAE,aAAa;KACpB;IACD;QACC,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,oBAAoB,CAAC;QAC/B,KAAK,EAAE,OAAO;KACd;IACD;QACC,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,uBAAuB,CAAC;QAClC,KAAK,EAAE,QAAQ;KACf;IACD;QACC,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,uBAAuB,CAAC;QAClC,KAAK,EAAE,YAAY;KACnB;IACD;QACC,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,CAAC,uBAAuB,CAAC;QAClC,KAAK,EAAE,UAAU;KACjB;IACD;QACC,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,CAAC,mBAAmB,EAAE,YAAY,EAAE,aAAa,CAAC;QAC3D,KAAK,EAAE,IAAI;KACX;IACD;QACC,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,CAAC,mBAAmB,CAAC;QAC9B,KAAK,EAAE,MAAM;QACb,kEAAkE;QAClE,gEAAgE;QAChE,6DAA6D;QAC7D,YAAY,EAAE,WAAW;KACzB;IACD;QACC,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,iBAAiB;QAC9B,OAAO,EAAE,CAAC,iCAAiC,CAAC;QAC5C,KAAK,EAAE,SAAS;KAChB;IACD;QACC,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,cAAc;QAC3B,OAAO,EAAE,CAAC,0BAA0B,CAAC;QACrC,KAAK,EAAE,aAAa;KACpB;IACD;QACC,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,CAAC,gBAAgB,CAAC;QAC3B,KAAK,EAAE,UAAU;KACjB;IACD;QACC,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,CAAC,sBAAsB,CAAC;QACjC,KAAK,EAAE,SAAS;KAChB;IACD;QACC,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,CAAC,mBAAmB,CAAC;QAC9B,KAAK,EAAE,MAAM;KACb;IACD;QACC,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,CAAC,mBAAmB,CAAC;QAC9B,KAAK,EAAE,MAAM;KACb;IACD;QACC,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,CAAC,oBAAoB,CAAC;QAC/B,KAAK,EAAE,OAAO;KACd;IACD;QACC,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,YAAY;QACzB,OAAO,EAAE,CAAC,wBAAwB,CAAC;QACnC,KAAK,EAAE,WAAW;KAClB;CACD,CAAC,CAAA;AAEF,0BAA0B;AAC1B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE;IAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAA;AACjD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,SAAS;IACxC,MAAM,GAAG,GAAG,EAAE,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YACd,SAAQ;QACT,CAAC;QACD,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACf,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAS;IAChD,MAAM,GAAG,GAAG,EAAE,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAA;QACtE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,SAAQ;QACvC,IAAI,CAAC;YACJ,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC;YACR,0DAA0D;QAC3D,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC"}
1
+ {"version":3,"file":"runtime-detect.mjs","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Whether `existingToml` already declares a `[mcp_servers.<id>]` table.
3
+ * Matches the header at the start of a line (ignoring leading whitespace),
4
+ * permitting an optional TOML trailing comment (` # …`) after the header —
5
+ * a hand-authored `[mcp_servers.tauri] # my server` must still count as
6
+ * present, otherwise the upsert would append a DUPLICATE table and produce
7
+ * an unparseable config (two same-named tables). The id is taken literally
8
+ * (dotted-key TOML ids do not occur for our server ids — electron/tauri are
9
+ * bare) and regex-escaped defensively. A `#`-prefixed comment LINE that
10
+ * merely mentions the header is NOT a match (the header must be the first
11
+ * non-whitespace token).
12
+ *
13
+ * @param {string} existingToml
14
+ * @param {string} serverId
15
+ * @returns {boolean}
16
+ */
17
+ export function hasMcpServerTable(existingToml: string, serverId: string): boolean;
18
+ /**
19
+ * Upsert a `[mcp_servers.<id>]` table into a Codex config.toml string.
20
+ *
21
+ * TOFU (ID-05): if a `[mcp_servers.<id>]` table already exists, returns the
22
+ * input unchanged with `action: 'skipped'`. Otherwise appends the new table
23
+ * (and a nested `[mcp_servers.<id>.env]` table when `env` is non-empty) at
24
+ * EOF, preserving all existing content verbatim, and returns the new
25
+ * content with `action: 'written'`.
26
+ *
27
+ * @param {string} existingToml — current file contents ('' when the file is absent)
28
+ * @param {string} serverId
29
+ * @param {{command: string, args: string[], env?: Record<string, string>}} spec
30
+ * @returns {{content: string, action: 'written'|'skipped'}}
31
+ */
32
+ export function upsertMcpServerToml(existingToml: string, serverId: string, spec: {
33
+ command: string;
34
+ args: string[];
35
+ env?: Record<string, string>;
36
+ }): {
37
+ content: string;
38
+ action: "written" | "skipped";
39
+ };
40
+ //# sourceMappingURL=toml-merge.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-merge.d.mts","sourceRoot":"","sources":["../../../src/cli/install/toml-merge.mjs"],"names":[],"mappings":"AA2DA;;;;;;;;;;;;;;;GAeG;AACH,gDAJW,MAAM,YACN,MAAM,GACJ,OAAO,CAanB;AAED;;;;;;;;;;;;;GAaG;AACH,kDALW,MAAM,YACN,MAAM,QACN;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAC,GAC7D;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAC,SAAS,CAAA;CAAC,CAsC1D"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * install/toml-merge.mjs — dependency-free minimal TOML upsert for the
3
+ * Codex MCP-server config table.
4
+ *
5
+ * Codex's MCP config lives at project-root `.codex/config.toml` as:
6
+ *
7
+ * [mcp_servers.<id>]
8
+ * command = "bash"
9
+ * args = ["./scripts/tauri-mcp.sh"]
10
+ *
11
+ * [mcp_servers.<id>.env]
12
+ * FOO = "bar"
13
+ *
14
+ * No TOML serializer ships in the framework and `@iarna/toml` is not a
15
+ * dependency, so we hand-roll the MINIMAL upsert covering ONLY this shape
16
+ * (string command, string[] args, optional nested env table of
17
+ * string=string). Presence is detected by scanning for the
18
+ * `[mcp_servers.<id>]` header line; if present, we SKIP unchanged (TOFU
19
+ * per ID-05) — never diff/merge/overwrite a hand-authored table. All other
20
+ * content is preserved verbatim; the new table block is appended at EOF.
21
+ *
22
+ * Pure module — string in, string out.
23
+ */
24
+ /**
25
+ * Escape a string for a TOML basic (double-quoted) string. Only the
26
+ * characters that can occur in a command/arg/env value: backslash and
27
+ * double-quote.
28
+ *
29
+ * @param {string} s
30
+ * @returns {string}
31
+ */
32
+ function tomlString(s) {
33
+ return `"${String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
34
+ }
35
+ /**
36
+ * Render a TOML array of double-quoted strings: `["a", "b"]`.
37
+ *
38
+ * @param {string[]} arr
39
+ * @returns {string}
40
+ */
41
+ function tomlStringArray(arr) {
42
+ return `[${arr.map((a) => tomlString(a)).join(', ')}]`;
43
+ }
44
+ /**
45
+ * Render a TOML key. A bare key (TOML `[A-Za-z0-9_-]+`) is emitted verbatim;
46
+ * any other key is quoted as a TOML basic string so a non-bare env name
47
+ * (e.g. one containing `.`, a space, or `"`) cannot break the table or inject
48
+ * extra structure.
49
+ *
50
+ * @param {string} key
51
+ * @returns {string}
52
+ */
53
+ function tomlKey(key) {
54
+ return /^[A-Za-z0-9_-]+$/.test(key) ? key : tomlString(key);
55
+ }
56
+ /**
57
+ * Whether `existingToml` already declares a `[mcp_servers.<id>]` table.
58
+ * Matches the header at the start of a line (ignoring leading whitespace),
59
+ * permitting an optional TOML trailing comment (` # …`) after the header —
60
+ * a hand-authored `[mcp_servers.tauri] # my server` must still count as
61
+ * present, otherwise the upsert would append a DUPLICATE table and produce
62
+ * an unparseable config (two same-named tables). The id is taken literally
63
+ * (dotted-key TOML ids do not occur for our server ids — electron/tauri are
64
+ * bare) and regex-escaped defensively. A `#`-prefixed comment LINE that
65
+ * merely mentions the header is NOT a match (the header must be the first
66
+ * non-whitespace token).
67
+ *
68
+ * @param {string} existingToml
69
+ * @param {string} serverId
70
+ * @returns {boolean}
71
+ */
72
+ export function hasMcpServerTable(existingToml, serverId) {
73
+ if (typeof existingToml !== 'string' || existingToml.length === 0)
74
+ return false;
75
+ const escapedId = serverId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
76
+ // `[mcp_servers.<id>]` at line start (after optional indent), optionally
77
+ // followed by whitespace and/or a `#` trailing comment, to EOL.
78
+ const headerRe = new RegExp(`^\\s*\\[mcp_servers\\.${escapedId}\\]\\s*(#.*)?$`);
79
+ const lines = existingToml.split(/\r?\n/);
80
+ for (const line of lines) {
81
+ if (headerRe.test(line))
82
+ return true;
83
+ }
84
+ return false;
85
+ }
86
+ /**
87
+ * Upsert a `[mcp_servers.<id>]` table into a Codex config.toml string.
88
+ *
89
+ * TOFU (ID-05): if a `[mcp_servers.<id>]` table already exists, returns the
90
+ * input unchanged with `action: 'skipped'`. Otherwise appends the new table
91
+ * (and a nested `[mcp_servers.<id>.env]` table when `env` is non-empty) at
92
+ * EOF, preserving all existing content verbatim, and returns the new
93
+ * content with `action: 'written'`.
94
+ *
95
+ * @param {string} existingToml — current file contents ('' when the file is absent)
96
+ * @param {string} serverId
97
+ * @param {{command: string, args: string[], env?: Record<string, string>}} spec
98
+ * @returns {{content: string, action: 'written'|'skipped'}}
99
+ */
100
+ export function upsertMcpServerToml(existingToml, serverId, spec) {
101
+ const existing = typeof existingToml === 'string' ? existingToml : '';
102
+ if (hasMcpServerTable(existing, serverId)) {
103
+ return { content: existing, action: 'skipped' };
104
+ }
105
+ const lines = [];
106
+ lines.push(`[mcp_servers.${serverId}]`);
107
+ lines.push(`command = ${tomlString(spec.command)}`);
108
+ lines.push(`args = ${tomlStringArray(spec.args ?? [])}`);
109
+ const env = spec.env && typeof spec.env === 'object' ? spec.env : null;
110
+ const envKeys = env ? Object.keys(env) : [];
111
+ if (envKeys.length > 0) {
112
+ lines.push('');
113
+ lines.push(`[mcp_servers.${serverId}.env]`);
114
+ for (const key of envKeys) {
115
+ lines.push(`${tomlKey(key)} = ${tomlString(env[key])}`);
116
+ }
117
+ }
118
+ const block = lines.join('\n');
119
+ // Preserve existing content; separate the new block with exactly one blank
120
+ // line. An empty existing file yields just the block + trailing newline.
121
+ // Strip the existing file's trailing newline run first so a file that
122
+ // already ends in a blank line (`…\n\n`) does not produce a DOUBLE blank
123
+ // line before the appended block.
124
+ let content;
125
+ if (existing.trim().length === 0) {
126
+ content = `${block}\n`;
127
+ }
128
+ else {
129
+ const head = existing.replace(/\n+$/, '');
130
+ content = `${head}\n\n${block}\n`;
131
+ }
132
+ return { content, action: 'written' };
133
+ }
134
+ //# sourceMappingURL=toml-merge.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-merge.mjs","sourceRoot":"","sources":["../../../src/cli/install/toml-merge.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,CAAC;IACpB,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAA;AACpE,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,GAAG;IAC3B,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;AACvD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,OAAO,CAAC,GAAG;IACnB,OAAO,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAY,EAAE,QAAQ;IACvD,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IACjE,yEAAyE;IACzE,gEAAgE;IAChE,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,yBAAyB,SAAS,gBAAgB,CAAC,CAAA;IAC/E,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;IACrC,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI;IAC/D,MAAM,QAAQ,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAA;IACrE,IAAI,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IAChD,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAA;IAChB,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,GAAG,CAAC,CAAA;IACvC,KAAK,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACnD,KAAK,CAAC,IAAI,CAAC,UAAU,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IAExD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;IACtE,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC3C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,OAAO,CAAC,CAAA;QAC3C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;QACxD,CAAC;IACF,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE9B,2EAA2E;IAC3E,yEAAyE;IACzE,sEAAsE;IACtE,yEAAyE;IACzE,kCAAkC;IAClC,IAAI,OAAO,CAAA;IACX,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,GAAG,GAAG,KAAK,IAAI,CAAA;IACvB,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACzC,OAAO,GAAG,GAAG,IAAI,OAAO,KAAK,IAAI,CAAA;IAClC,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AACtC,CAAC"}
@@ -31,4 +31,16 @@ export function buildAptSection({ canonicalRoot, targetDir, cli }: {
31
31
  * @returns {string[]} Row IDs in file order, e.g. `['/apt', '/apt:quick', …]`.
32
32
  */
33
33
  export function extractAptSectionRowIds(text: string): string[];
34
+ /**
35
+ * Matches the full APT managed block (start marker through end marker,
36
+ * inclusive). Exported so callers in the same package can reference a
37
+ * single source rather than inlining duplicate regex literals.
38
+ *
39
+ * `APT_SECTION_RE` — no trailing newline; used for in-place replace.
40
+ * `APT_SECTION_STRIP_RE` — includes optional trailing newline; used for
41
+ * strip operations that want to remove the newline
42
+ * the block was preceded/followed by.
43
+ */
44
+ export const APT_SECTION_RE: RegExp;
45
+ export const APT_SECTION_STRIP_RE: RegExp;
34
46
  //# sourceMappingURL=aperant-section.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aperant-section.d.mts","sourceRoot":"","sources":["../../../src/cli/util/aperant-section.mjs"],"names":[],"mappings":"AAuDA;;;;;;;;;;;;;;;GAeG;AACH,mEAXG;IAAqB,aAAa,EAA1B,MAAM;IAGO,SAAS,EAAtB,MAAM;IACQ,GAAG;CAGzB,GAAU,MAAM,CAqClB;AAED;;;;;;;;;;GAUG;AACH,8CAHW,MAAM,GACJ,MAAM,EAAE,CAoBpB"}
1
+ {"version":3,"file":"aperant-section.d.mts","sourceRoot":"","sources":["../../../src/cli/util/aperant-section.mjs"],"names":[],"mappings":"AAqEA;;;;;;;;;;;;;;;GAeG;AACH,mEAXG;IAAqB,aAAa,EAA1B,MAAM;IAGO,SAAS,EAAtB,MAAM;IACQ,GAAG;CAGzB,GAAU,MAAM,CAqClB;AAED;;;;;;;;;;GAUG;AACH,8CAHW,MAAM,GACJ,MAAM,EAAE,CAoBpB;AA5HD;;;;;;;;;GASG;AACH,oCAA8F;AAC9F,0CACoE"}
@@ -20,6 +20,18 @@ import { getTrustedSkillSources } from '../config/load.mjs';
20
20
  import { discoverSkills } from '../route/skill-discover.mjs';
21
21
  const SECTION_START = '<!-- APT:framework-start -->';
22
22
  const SECTION_END = '<!-- APT:framework-end -->';
23
+ /**
24
+ * Matches the full APT managed block (start marker through end marker,
25
+ * inclusive). Exported so callers in the same package can reference a
26
+ * single source rather than inlining duplicate regex literals.
27
+ *
28
+ * `APT_SECTION_RE` — no trailing newline; used for in-place replace.
29
+ * `APT_SECTION_STRIP_RE` — includes optional trailing newline; used for
30
+ * strip operations that want to remove the newline
31
+ * the block was preceded/followed by.
32
+ */
33
+ export const APT_SECTION_RE = /<!-- APT:framework-start -->[\s\S]*?<!-- APT:framework-end -->/;
34
+ export const APT_SECTION_STRIP_RE = /<!-- APT:framework-start -->[\s\S]*?<!-- APT:framework-end -->\n?/;
23
35
  const SECTION_HEADING = '## Aperant Framework';
24
36
  const APPENDIX_REL_PATH = ['templates', 'aperant-claude-md-appendix.md'];
25
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"aperant-section.mjs","sourceRoot":"","sources":["../../../src/cli/util/aperant-section.mjs"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aperant-section.mjs","sourceRoot":"","sources":["../../../src/cli/util/aperant-section.mjs"],"names":[],"mappings":"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"}
@@ -1,4 +1,31 @@
1
1
  export function copyDirRecursive(src: any, dest: any): void;
2
+ /**
3
+ * Preflight-only sibling of `injectInstructionFile`. Runs the same
4
+ * foreign-row defensive check against `filePath` but NEVER writes — used by
5
+ * the multi-target init flow to check every instruction target up-front so a
6
+ * single aborting target leaves NO file partially written (US-03 / AC3).
7
+ *
8
+ * Returns the same status vocabulary as `injectInstructionFile` minus the
9
+ * write side-effect: `'created'` (file absent → would be appended-to),
10
+ * `'updated'` (markers present, no foreign rows → would be replaced),
11
+ * `'aborted-foreign-rows'` (markers present with rows not in the generated
12
+ * set → init must abort). `force` short-circuits the foreign-row gate exactly
13
+ * as the writer does.
14
+ *
15
+ * @param {string} filePath
16
+ * @param {Object} opts
17
+ * @param {string} opts.aptSection Output of buildAptSection().
18
+ * @param {boolean} [opts.force=false]
19
+ * Bypass the foreign-row check.
20
+ * @returns {{ status: 'created' | 'updated' | 'aborted-foreign-rows', foreignRowIds?: string[] }}
21
+ */
22
+ export function checkInstructionFile(filePath: string, { aptSection, force }: {
23
+ aptSection: string;
24
+ force?: boolean | undefined;
25
+ }): {
26
+ status: "created" | "updated" | "aborted-foreign-rows";
27
+ foreignRowIds?: string[];
28
+ };
2
29
  /**
3
30
  * Write the (already-generated) APT section into `filePath`. Creates the
4
31
  * file if missing; replaces the section in-place if the markers are
@@ -1 +1 @@
1
- {"version":3,"file":"copy.d.mts","sourceRoot":"","sources":["../../../src/cli/util/copy.mjs"],"names":[],"mappings":"AAwBA,4DAWC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,gDARW,MAAM,yBAEd;IAAqB,UAAU,EAAvB,MAAM;IAES,KAAK;CAE5B,GAAU;IAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,sBAAsB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0BlH"}
1
+ {"version":3,"file":"copy.d.mts","sourceRoot":"","sources":["../../../src/cli/util/copy.mjs"],"names":[],"mappings":"AAsCA,4DAWC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,+CAPW,MAAM,yBAEd;IAAqB,UAAU,EAAvB,MAAM;IACS,KAAK;CAE5B,GAAU;IAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,sBAAsB,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBhG;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,gDARW,MAAM,yBAEd;IAAqB,UAAU,EAAvB,MAAM;IAES,KAAK;CAE5B,GAAU;IAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,sBAAsB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAqBlH"}
@@ -12,7 +12,20 @@
12
12
  */
13
13
  import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from 'node:fs';
14
14
  import { join } from 'node:path';
15
- import { extractAptSectionRowIds } from './aperant-section.mjs';
15
+ import { APT_SECTION_RE, extractAptSectionRowIds } from './aperant-section.mjs';
16
+ /**
17
+ * Return the row IDs present in `existing` that are NOT present in
18
+ * `aptSection`. An empty array means no foreign rows (safe to overwrite).
19
+ *
20
+ * @param {string} existing Current on-disk file contents.
21
+ * @param {string} aptSection Output of buildAptSection().
22
+ * @returns {string[]}
23
+ */
24
+ function computeForeignRowIds(existing, aptSection) {
25
+ const existingIds = new Set(extractAptSectionRowIds(existing));
26
+ const generatedIds = new Set(extractAptSectionRowIds(aptSection));
27
+ return [...existingIds].filter((id) => !generatedIds.has(id));
28
+ }
16
29
  export function copyDirRecursive(src, dest) {
17
30
  mkdirSync(dest, { recursive: true });
18
31
  for (const entry of readdirSync(src, { withFileTypes: true })) {
@@ -26,6 +39,39 @@ export function copyDirRecursive(src, dest) {
26
39
  }
27
40
  }
28
41
  }
42
+ /**
43
+ * Preflight-only sibling of `injectInstructionFile`. Runs the same
44
+ * foreign-row defensive check against `filePath` but NEVER writes — used by
45
+ * the multi-target init flow to check every instruction target up-front so a
46
+ * single aborting target leaves NO file partially written (US-03 / AC3).
47
+ *
48
+ * Returns the same status vocabulary as `injectInstructionFile` minus the
49
+ * write side-effect: `'created'` (file absent → would be appended-to),
50
+ * `'updated'` (markers present, no foreign rows → would be replaced),
51
+ * `'aborted-foreign-rows'` (markers present with rows not in the generated
52
+ * set → init must abort). `force` short-circuits the foreign-row gate exactly
53
+ * as the writer does.
54
+ *
55
+ * @param {string} filePath
56
+ * @param {Object} opts
57
+ * @param {string} opts.aptSection Output of buildAptSection().
58
+ * @param {boolean} [opts.force=false]
59
+ * Bypass the foreign-row check.
60
+ * @returns {{ status: 'created' | 'updated' | 'aborted-foreign-rows', foreignRowIds?: string[] }}
61
+ */
62
+ export function checkInstructionFile(filePath, { aptSection, force = false }) {
63
+ const existing = existsSync(filePath) ? readFileSync(filePath, 'utf-8') : '';
64
+ if (existing.includes('<!-- APT:framework-start -->')) {
65
+ if (!force) {
66
+ const foreignRowIds = computeForeignRowIds(existing, aptSection);
67
+ if (foreignRowIds.length > 0) {
68
+ return { status: 'aborted-foreign-rows', foreignRowIds };
69
+ }
70
+ }
71
+ return { status: 'updated' };
72
+ }
73
+ return { status: 'created' };
74
+ }
29
75
  /**
30
76
  * Write the (already-generated) APT section into `filePath`. Creates the
31
77
  * file if missing; replaces the section in-place if the markers are
@@ -50,14 +96,12 @@ export function injectInstructionFile(filePath, { aptSection, force = false }) {
50
96
  const existing = existsSync(filePath) ? readFileSync(filePath, 'utf-8') : '';
51
97
  if (existing.includes('<!-- APT:framework-start -->')) {
52
98
  if (!force) {
53
- const existingIds = new Set(extractAptSectionRowIds(existing));
54
- const generatedIds = new Set(extractAptSectionRowIds(aptSection));
55
- const foreignRowIds = [...existingIds].filter((id) => !generatedIds.has(id));
99
+ const foreignRowIds = computeForeignRowIds(existing, aptSection);
56
100
  if (foreignRowIds.length > 0) {
57
101
  return { status: 'aborted-foreign-rows', written: false, foreignRowIds };
58
102
  }
59
103
  }
60
- const updated = existing.replace(/<!-- APT:framework-start -->[\s\S]*?<!-- APT:framework-end -->/, aptSection);
104
+ const updated = existing.replace(APT_SECTION_RE, aptSection);
61
105
  writeFileSync(filePath, updated, 'utf-8');
62
106
  return { status: 'updated', written: true };
63
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"copy.mjs","sourceRoot":"","sources":["../../../src/cli/util/copy.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACb,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,MAAM,UAAU,gBAAgB,CAAC,GAAG,EAAE,IAAI;IACzC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACpC,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAChC,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,EAAE;IAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5E,IAAI,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAA;YAC9D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAA;YACjE,MAAM,aAAa,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YAC5E,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;YACzE,CAAC;QACF,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAC/B,gEAAgE,EAChE,UAAU,CACV,CAAA;QACD,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACzC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAED,uDAAuD;IACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;IAC1E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC5C,CAAC"}
1
+ {"version":3,"file":"copy.mjs","sourceRoot":"","sources":["../../../src/cli/util/copy.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACb,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAE/E;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,QAAQ,EAAE,UAAU;IACjD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAA;IACjE,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAG,EAAE,IAAI;IACzC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACpC,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAChC,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,EAAE;IAC3E,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5E,IAAI,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YAChE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,aAAa,EAAE,CAAA;YACzD,CAAC;QACF,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IAC7B,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,EAAE;IAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5E,IAAI,QAAQ,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YAChE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;YACzE,CAAC;QACF,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC5D,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACzC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAED,uDAAuD;IACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;IAC1E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC5C,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Compute today's events filename relative to projectDir.
3
+ * @param {string} projectDir
4
+ * @param {Date} [now]
5
+ * @returns {string}
6
+ */
7
+ export function dailyEventsPath(projectDir: string, now?: Date): string;
8
+ //# sourceMappingURL=events-path.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-path.d.mts","sourceRoot":"","sources":["../../../src/cli/util/events-path.mjs"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,4CAJW,MAAM,QACN,IAAI,GACF,MAAM,CAOlB"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * util/events-path.mjs — canonical path computation for the per-day event
3
+ * log at `.aperant/events/{YYYY-MM-DD}.jsonl` (ID-05).
4
+ *
5
+ * Lives in util/ so both the install layer (install/mcp-provision.mjs) and the
6
+ * verify-proof layer (verify-proof/audit.mjs) compute the same path WITHOUT
7
+ * install/ importing from verify-proof/ (the layer-boundary rule). Pure
8
+ * function — no fs, no exec.
9
+ */
10
+ import { join, resolve } from 'node:path';
11
+ /**
12
+ * Compute today's events filename relative to projectDir.
13
+ * @param {string} projectDir
14
+ * @param {Date} [now]
15
+ * @returns {string}
16
+ */
17
+ export function dailyEventsPath(projectDir, now = new Date()) {
18
+ const yyyy = now.getUTCFullYear();
19
+ const mm = String(now.getUTCMonth() + 1).padStart(2, '0');
20
+ const dd = String(now.getUTCDate()).padStart(2, '0');
21
+ return join(resolve(projectDir), '.aperant/events', `${yyyy}-${mm}-${dd}.jsonl`);
22
+ }
23
+ //# sourceMappingURL=events-path.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-path.mjs","sourceRoot":"","sources":["../../../src/cli/util/events-path.mjs"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc,EAAE,CAAA;IACjC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACzD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,iBAAiB,EAAE,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AACjF,CAAC"}