@aperant/framework 0.6.7 → 0.7.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 (205) hide show
  1. package/CHANGELOG.md +240 -0
  2. package/agents/apt-planner.md +12 -0
  3. package/agents/apt-pr-review-fixer.md +13 -9
  4. package/bin/apt-tools.mjs +7 -0
  5. package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -1
  6. package/dist/cli/ci-watch/stop-matrix.mjs +16 -0
  7. package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -1
  8. package/dist/cli/commands/ci-watch.d.mts +11 -0
  9. package/dist/cli/commands/ci-watch.d.mts.map +1 -1
  10. package/dist/cli/commands/ci-watch.mjs +147 -3
  11. package/dist/cli/commands/ci-watch.mjs.map +1 -1
  12. package/dist/cli/commands/features-audit.d.mts +24 -0
  13. package/dist/cli/commands/features-audit.d.mts.map +1 -1
  14. package/dist/cli/commands/features-audit.mjs +159 -5
  15. package/dist/cli/commands/features-audit.mjs.map +1 -1
  16. package/dist/cli/commands/health-check.d.mts +16 -0
  17. package/dist/cli/commands/health-check.d.mts.map +1 -1
  18. package/dist/cli/commands/health-check.mjs +119 -3
  19. package/dist/cli/commands/health-check.mjs.map +1 -1
  20. package/dist/cli/commands/init.d.mts +19 -1
  21. package/dist/cli/commands/init.d.mts.map +1 -1
  22. package/dist/cli/commands/init.mjs +143 -8
  23. package/dist/cli/commands/init.mjs.map +1 -1
  24. package/dist/cli/commands/modes.d.mts.map +1 -1
  25. package/dist/cli/commands/modes.mjs +11 -0
  26. package/dist/cli/commands/modes.mjs.map +1 -1
  27. package/dist/cli/commands/pr-review-audit-fixer.d.mts +13 -0
  28. package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
  29. package/dist/cli/commands/pr-review-audit-fixer.mjs +18 -5
  30. package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
  31. package/dist/cli/commands/route.d.mts.map +1 -1
  32. package/dist/cli/commands/route.mjs +37 -2
  33. package/dist/cli/commands/route.mjs.map +1 -1
  34. package/dist/cli/commands/task.d.mts.map +1 -1
  35. package/dist/cli/commands/task.mjs +132 -5
  36. package/dist/cli/commands/task.mjs.map +1 -1
  37. package/dist/cli/commands/validate-evidence.d.mts +24 -2
  38. package/dist/cli/commands/validate-evidence.d.mts.map +1 -1
  39. package/dist/cli/commands/validate-evidence.mjs +154 -17
  40. package/dist/cli/commands/validate-evidence.mjs.map +1 -1
  41. package/dist/cli/commands/vitest-doctor.d.mts +2 -0
  42. package/dist/cli/commands/vitest-doctor.d.mts.map +1 -0
  43. package/dist/cli/commands/vitest-doctor.mjs +168 -0
  44. package/dist/cli/commands/vitest-doctor.mjs.map +1 -0
  45. package/dist/cli/config/gitignore-drift.d.mts +23 -1
  46. package/dist/cli/config/gitignore-drift.d.mts.map +1 -1
  47. package/dist/cli/config/gitignore-drift.mjs +81 -3
  48. package/dist/cli/config/gitignore-drift.mjs.map +1 -1
  49. package/dist/cli/config/load.d.mts +56 -2
  50. package/dist/cli/config/load.d.mts.map +1 -1
  51. package/dist/cli/config/load.mjs +192 -2
  52. package/dist/cli/config/load.mjs.map +1 -1
  53. package/dist/cli/consistency/parse-review.mjs +7 -0
  54. package/dist/cli/consistency/parse-review.mjs.map +1 -1
  55. package/dist/cli/dispatch.d.mts.map +1 -1
  56. package/dist/cli/dispatch.mjs +24 -2
  57. package/dist/cli/dispatch.mjs.map +1 -1
  58. package/dist/cli/gate/gates/gitignore-in-sync.d.mts +1 -1
  59. package/dist/cli/gate/gates/gitignore-in-sync.d.mts.map +1 -1
  60. package/dist/cli/gate/gates/gitignore-in-sync.mjs +5 -2
  61. package/dist/cli/gate/gates/gitignore-in-sync.mjs.map +1 -1
  62. package/dist/cli/gate/gates/review-clean.d.mts +5 -1
  63. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  64. package/dist/cli/gate/gates/review-clean.mjs +23 -18
  65. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  66. package/dist/cli/gate/gates/verify-approved.d.mts +49 -1
  67. package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
  68. package/dist/cli/gate/gates/verify-approved.mjs +93 -14
  69. package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
  70. package/dist/cli/help.d.mts.map +1 -1
  71. package/dist/cli/help.mjs +8 -2
  72. package/dist/cli/help.mjs.map +1 -1
  73. package/dist/cli/host/detect.d.mts +122 -9
  74. package/dist/cli/host/detect.d.mts.map +1 -1
  75. package/dist/cli/host/detect.mjs +132 -0
  76. package/dist/cli/host/detect.mjs.map +1 -1
  77. package/dist/cli/install/legacy-paths.d.mts +38 -0
  78. package/dist/cli/install/legacy-paths.d.mts.map +1 -0
  79. package/dist/cli/install/legacy-paths.mjs +69 -0
  80. package/dist/cli/install/legacy-paths.mjs.map +1 -0
  81. package/dist/cli/install/runtime-detect.d.mts +13 -0
  82. package/dist/cli/install/runtime-detect.d.mts.map +1 -1
  83. package/dist/cli/install/runtime-detect.mjs +9 -0
  84. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  85. package/dist/cli/install/runtime-migrate.d.mts +84 -0
  86. package/dist/cli/install/runtime-migrate.d.mts.map +1 -0
  87. package/dist/cli/install/runtime-migrate.mjs +244 -0
  88. package/dist/cli/install/runtime-migrate.mjs.map +1 -0
  89. package/dist/cli/route/drift-detect.d.mts +20 -0
  90. package/dist/cli/route/drift-detect.d.mts.map +1 -0
  91. package/dist/cli/route/drift-detect.mjs +107 -0
  92. package/dist/cli/route/drift-detect.mjs.map +1 -0
  93. package/dist/cli/task/index-md.d.mts.map +1 -1
  94. package/dist/cli/task/index-md.mjs +14 -2
  95. package/dist/cli/task/index-md.mjs.map +1 -1
  96. package/dist/cli/util/aperant-section.d.mts +34 -0
  97. package/dist/cli/util/aperant-section.d.mts.map +1 -0
  98. package/dist/cli/util/aperant-section.mjs +127 -0
  99. package/dist/cli/util/aperant-section.mjs.map +1 -0
  100. package/dist/cli/util/copy.d.mts +28 -1
  101. package/dist/cli/util/copy.d.mts.map +1 -1
  102. package/dist/cli/util/copy.mjs +43 -55
  103. package/dist/cli/util/copy.mjs.map +1 -1
  104. package/dist/cli/util/semver.d.mts +17 -0
  105. package/dist/cli/util/semver.d.mts.map +1 -0
  106. package/dist/cli/util/semver.mjs +29 -0
  107. package/dist/cli/util/semver.mjs.map +1 -0
  108. package/dist/cli/util/skill-installs.d.mts +65 -9
  109. package/dist/cli/util/skill-installs.d.mts.map +1 -1
  110. package/dist/cli/util/skill-installs.mjs +130 -21
  111. package/dist/cli/util/skill-installs.mjs.map +1 -1
  112. package/dist/cli/util/version-preflight.d.mts +44 -0
  113. package/dist/cli/util/version-preflight.d.mts.map +1 -0
  114. package/dist/cli/util/version-preflight.mjs +66 -0
  115. package/dist/cli/util/version-preflight.mjs.map +1 -0
  116. package/dist/plugin/.claude-plugin/plugin.json +11 -2
  117. package/dist/plugin/agents/apt-improver.md +99 -0
  118. package/dist/plugin/agents/apt-planner.md +127 -10
  119. package/dist/plugin/agents/apt-pr-review-fixer.md +13 -9
  120. package/dist/plugin/skills/apt/SKILL.md +1 -0
  121. package/dist/plugin/skills/apt-close-task/SKILL.md +63 -1
  122. package/dist/plugin/skills/apt-debug/SKILL.md +39 -6
  123. package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
  124. package/dist/plugin/skills/apt-diagram/SKILL.md +378 -0
  125. package/dist/plugin/skills/apt-diagram/appendices/design-discipline.md +97 -0
  126. package/dist/plugin/skills/apt-discuss/SKILL.md +72 -5
  127. package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +104 -0
  128. package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
  129. package/dist/plugin/skills/apt-execute/SKILL.md +57 -5
  130. package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +107 -0
  131. package/dist/plugin/skills/apt-improve/DEEPENING.md +84 -0
  132. package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
  133. package/dist/plugin/skills/apt-improve/LANGUAGE.md +104 -0
  134. package/dist/plugin/skills/apt-improve/SKILL.md +141 -0
  135. package/dist/plugin/skills/apt-plan/SKILL.md +171 -4
  136. package/dist/plugin/skills/apt-plan/adapters/conductor.md +98 -0
  137. package/dist/plugin/skills/apt-pr-review/SKILL.md +57 -18
  138. package/dist/plugin/skills/apt-prototype/LOGIC.md +109 -0
  139. package/dist/plugin/skills/apt-prototype/SKILL.md +143 -0
  140. package/dist/plugin/skills/apt-prototype/UI.md +90 -0
  141. package/dist/plugin/skills/apt-quick/SKILL.md +49 -8
  142. package/dist/plugin/skills/apt-release-notes/SKILL.md +193 -0
  143. package/dist/plugin/skills/apt-release-notes/appendices/persona-voice.md +59 -0
  144. package/dist/plugin/skills/apt-review/SKILL.md +2 -0
  145. package/dist/plugin/skills/apt-run/SKILL.md +32 -4
  146. package/dist/plugin/skills/apt-setup/SKILL.md +308 -6
  147. package/dist/plugin/skills/apt-ship/SKILL.md +122 -1
  148. package/dist/plugin/skills/apt-spar/SKILL.md +315 -0
  149. package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +84 -0
  150. package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
  151. package/dist/plugin/skills/apt-triage/SKILL.md +169 -0
  152. package/dist/plugin/skills/apt-update/SKILL.md +77 -10
  153. package/dist/plugin/skills/apt-verify/SKILL.md +3 -0
  154. package/dist/plugin/skills/apt-verify-proof/SKILL.md +10 -5
  155. package/dist/plugin/skills/apt-watch-ci/SKILL.md +166 -0
  156. package/dist/plugin/skills/apt-zoom-out/SKILL.md +130 -0
  157. package/package.json +133 -133
  158. package/prompts/conductor-framework-context.md +63 -0
  159. package/prompts/conductor-system.md +11 -0
  160. package/skills/apt-close-task/SKILL.md +6 -0
  161. package/skills/apt-discuss/SKILL.md +47 -5
  162. package/skills/apt-execute/SKILL.md +9 -0
  163. package/skills/apt-plan/SKILL.md +12 -0
  164. package/skills/apt-pr-review/SKILL.md +11 -2
  165. package/skills/apt-quick/SKILL.md +19 -8
  166. package/skills/apt-researcher.md +1 -0
  167. package/skills/apt-setup/SKILL.md +33 -2
  168. package/skills/apt-ship/SKILL.md +16 -4
  169. package/skills/apt-spar/SKILL.md +36 -11
  170. package/skills/apt-update/SKILL.md +26 -1
  171. package/skills/apt-verify-proof/SKILL.md +7 -5
  172. package/skills/apt-watch-ci/SKILL.md +4 -1
  173. package/src/cli/ci-watch/stop-matrix.mjs +17 -0
  174. package/src/cli/commands/ci-watch.mjs +152 -3
  175. package/src/cli/commands/features-audit.mjs +164 -5
  176. package/src/cli/commands/health-check.mjs +116 -3
  177. package/src/cli/commands/init.mjs +154 -6
  178. package/src/cli/commands/modes.mjs +11 -0
  179. package/src/cli/commands/pr-review-audit-fixer.mjs +18 -5
  180. package/src/cli/commands/route.mjs +38 -2
  181. package/src/cli/commands/task.mjs +132 -5
  182. package/src/cli/commands/validate-evidence.mjs +158 -17
  183. package/src/cli/commands/vitest-doctor.mjs +173 -0
  184. package/src/cli/config/gitignore-drift.mjs +74 -3
  185. package/src/cli/config/load.mjs +188 -2
  186. package/src/cli/consistency/parse-review.mjs +6 -0
  187. package/src/cli/dispatch.mjs +23 -2
  188. package/src/cli/gate/gates/gitignore-in-sync.mjs +5 -2
  189. package/src/cli/gate/gates/review-clean.mjs +24 -19
  190. package/src/cli/gate/gates/verify-approved.mjs +97 -14
  191. package/src/cli/help.mjs +8 -2
  192. package/src/cli/host/detect.mjs +135 -0
  193. package/src/cli/install/legacy-paths.mjs +69 -0
  194. package/src/cli/install/runtime-detect.mjs +9 -0
  195. package/src/cli/install/runtime-migrate.mjs +252 -0
  196. package/src/cli/route/drift-detect.mjs +107 -0
  197. package/src/cli/task/index-md.mjs +15 -2
  198. package/src/cli/util/aperant-section.mjs +136 -0
  199. package/src/cli/util/copy.mjs +43 -56
  200. package/src/cli/util/semver.mjs +28 -0
  201. package/src/cli/util/skill-installs.mjs +134 -21
  202. package/src/cli/util/version-preflight.mjs +65 -0
  203. package/templates/aperant-claude-md-appendix.md +37 -0
  204. package/templates/config.json +2 -7
  205. package/workflows/verify-proof.md +8 -3
@@ -39,6 +39,11 @@ export function detectInstalledRuntimes(targetDir: string): RuntimeDescriptor[];
39
39
  * target mapped to a host CLI (e.g. `pi`,
40
40
  * which has a detectable host but no apt
41
41
  * install root of its own).
42
+ * @property {string} [displayLabel] Optional user-facing label (e.g. "Kilo Code").
43
+ * When unset, callers fall back to the
44
+ * capitalized form of `id`. Use for runtimes
45
+ * whose product branding differs from the
46
+ * internal id (C58: `kilo` → "Kilo Code").
42
47
  */
43
48
  /** @type {RuntimeDescriptor[]} */
44
49
  export const RUNTIMES: RuntimeDescriptor[];
@@ -73,5 +78,13 @@ export type RuntimeDescriptor = {
73
78
  * install root of its own).
74
79
  */
75
80
  cliId: string | null;
81
+ /**
82
+ * Optional user-facing label (e.g. "Kilo Code").
83
+ * When unset, callers fall back to the
84
+ * capitalized form of `id`. Use for runtimes
85
+ * whose product branding differs from the
86
+ * internal id (C58: `kilo` → "Kilo Code").
87
+ */
88
+ displayLabel?: string | undefined;
76
89
  };
77
90
  //# 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":"AA8IA;;;;;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;AA/KD;;;;;;;;;;;;;;;GAeG;AAEH,kCAAkC;AAClC,uBADW,iBAAiB,EAAE,CAoG5B;AAEF,0BAA0B;AAC1B,0BADW,GAAG,CAAC,MAAM,CAAC,CACuC;;;;;QAtH/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":"AAuJA;;;;;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;AAxLD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,kCAAkC;AAClC,uBADW,iBAAiB,EAAE,CAwG5B;AAEF,0BAA0B;AAC1B,0BADW,GAAG,CAAC,MAAM,CAAC,CACuC;;;;;QA/H/C,MAAM;;;;UACN,MAAM;;;;;iBACN,MAAM;;;;;;aAEN,MAAM,EAAE;;;;;;;;;WAGR,MAAM,GAAC,IAAI"}
@@ -31,6 +31,11 @@ import { MANIFEST_FILENAME } from './manifest.mjs';
31
31
  * target mapped to a host CLI (e.g. `pi`,
32
32
  * which has a detectable host but no apt
33
33
  * install root of its own).
34
+ * @property {string} [displayLabel] Optional user-facing label (e.g. "Kilo Code").
35
+ * When unset, callers fall back to the
36
+ * capitalized form of `id`. Use for runtimes
37
+ * whose product branding differs from the
38
+ * internal id (C58: `kilo` → "Kilo Code").
34
39
  */
35
40
  /** @type {RuntimeDescriptor[]} */
36
41
  export const RUNTIMES = Object.freeze([
@@ -75,6 +80,10 @@ export const RUNTIMES = Object.freeze([
75
80
  installRoot: '.kilo',
76
81
  markers: ['.kilo/config.json'],
77
82
  cliId: 'kilo',
83
+ // C58 (0.7.2): user-visible label. Internal id stays `kilo` (zero
84
+ // migration per spec ID-01). `--kilocode` is also accepted as a
85
+ // deprecated alias of `--kilo` at the CLI flag parser layer.
86
+ displayLabel: 'Kilo Code',
78
87
  },
79
88
  {
80
89
  id: 'copilot',
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-detect.mjs","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-detect.mjs","sourceRoot":"","sources":["../../../src/cli/install/runtime-detect.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Probe the codex legacy install tree at `<targetDir>/.agents/skills/`.
3
+ *
4
+ * @param {string} targetDir
5
+ * @returns {LegacyCodexDetection}
6
+ */
7
+ export function detectLegacyCodexTree(targetDir: string): LegacyCodexDetection;
8
+ /**
9
+ * Clean up the legacy `.agents/skills/` tree if it looks orphaned.
10
+ *
11
+ * Branches:
12
+ * 1. `present: false` OR `frameworkFiles.length === 0` → no-op,
13
+ * `{ ran: false, reason: 'no-legacy' }`.
14
+ * 2. `hasManifest: true` → managed install, no-op,
15
+ * `{ ran: false, reason: 'managed' }`.
16
+ * 3. Otherwise: per-file `unlinkSync` each framework-owned file;
17
+ * `rmdirSync` any now-empty `apt-*` subdirectory; sweep
18
+ * `.agents/skills/` only if it is empty; sweep `.agents/` only if
19
+ * its `skills/` got removed and `.agents/` is empty.
20
+ *
21
+ * Returns `{ ran: true, removed, retained, rmdirs }` on the cleanup
22
+ * branch:
23
+ * - `removed` — relative paths under `install_root` that were unlinked.
24
+ * - `retained` — relative paths under `install_root` that were NOT
25
+ * removed (user-added skills / files not in the legacy set).
26
+ * - `rmdirs` — absolute paths of directories that were removed
27
+ * (apt-* subdirs, the install_root itself, .agents/), in removal order.
28
+ *
29
+ * Atomicity: per-file unlink is non-atomic. A partial-failure scenario
30
+ * (process killed mid-loop) is tolerable — the next `init` run will
31
+ * re-detect the remaining framework files and finish the sweep.
32
+ *
33
+ * @param {{ targetDir: string, dryRun?: boolean }} args
34
+ * @returns {
35
+ * | { ran: false, reason: 'no-legacy' | 'managed' }
36
+ * | { ran: true, removed: string[], retained: string[], rmdirs: string[] }
37
+ * }
38
+ */
39
+ export function runLegacyCleanup({ targetDir, dryRun }: {
40
+ targetDir: string;
41
+ dryRun?: boolean;
42
+ }): any | {
43
+ ran: false;
44
+ reason: "no-legacy" | "managed";
45
+ } | {
46
+ ran: true;
47
+ removed: string[];
48
+ retained: string[];
49
+ rmdirs: string[];
50
+ };
51
+ export type LegacyCodexDetection = {
52
+ /**
53
+ * True when `.agents/skills/` exists.
54
+ */
55
+ present: boolean;
56
+ /**
57
+ * Subset of `framework_files` that
58
+ * actually exist on disk (relative
59
+ * to install_root).
60
+ */
61
+ frameworkFiles: string[];
62
+ /**
63
+ * Everything else under
64
+ * install_root (relative to
65
+ * install_root). May include both
66
+ * files and directories. Drives the
67
+ * `retained[]` warning.
68
+ */
69
+ userFiles: string[];
70
+ /**
71
+ * Whether the legacy `.apt-version`
72
+ * stamp is present.
73
+ */
74
+ hasAptVersion: boolean;
75
+ /**
76
+ * Whether an
77
+ * `apt-file-manifest.json` is
78
+ * present at install_root (signals
79
+ * a managed install — cleanup
80
+ * should no-op).
81
+ */
82
+ hasManifest: boolean;
83
+ };
84
+ //# sourceMappingURL=runtime-migrate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-migrate.d.mts","sourceRoot":"","sources":["../../../src/cli/install/runtime-migrate.mjs"],"names":[],"mappings":"AA8FA;;;;;GAKG;AACH,iDAHW,MAAM,GACJ,oBAAoB,CA0BhC;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wDANW;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAEjD,GAAC,GAAK;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GAC/C;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAgF5E;;;;;aAxNa,OAAO;;;;;;oBACP,MAAM,EAAE;;;;;;;;eAGR,MAAM,EAAE;;;;;mBAKR,OAAO;;;;;;;;iBAEP,OAAO"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * install/runtime-migrate.mjs — at-install cleanup of legacy install
3
+ * trees the framework no longer owns (FRAMEWORK-BUG-021).
4
+ *
5
+ * Codex was originally installed into `.agents/skills/` (commit 1a8dd8a8)
6
+ * and later moved to `.codex/`. Projects that upgraded across that move
7
+ * end up with a stale `.agents/skills/` tree that:
8
+ *
9
+ * - keeps `.apt-version` on disk → the legacy fallback in
10
+ * `readSkillInstallState` reports a stale codex install.
11
+ * - shows up in `health-check` as `stale-skills`.
12
+ * - leaves dozens of orphaned SKILL.md files the runtime no longer
13
+ * reads.
14
+ *
15
+ * `runLegacyCleanup` runs once per `apt-tools init` when codex is in the
16
+ * requested runtime set. It is conservative by default:
17
+ *
18
+ * - Only files listed in `LEGACY_INSTALL_PATHS.codex.framework_files`
19
+ * are removed. User-added skill directories (`my-skill/`, …) are
20
+ * preserved. If anything beyond the known framework set remains,
21
+ * `retained[]` lists those paths.
22
+ * - A present-and-current `apt-file-manifest.json` is treated as the
23
+ * authoritative "this is a managed install, leave it alone" signal:
24
+ * the function no-ops with `reason: 'managed'`.
25
+ * - The caller can suppress cleanup entirely via `--keep-legacy` at the
26
+ * init.mjs site; the function itself is dumb about flags.
27
+ */
28
+ import { existsSync, readdirSync, rmdirSync, unlinkSync } from 'node:fs';
29
+ import { dirname, join } from 'node:path';
30
+ import { LEGACY_INSTALL_PATHS } from './legacy-paths.mjs';
31
+ import { MANIFEST_FILENAME } from './manifest.mjs';
32
+ /**
33
+ * @typedef {Object} LegacyCodexDetection
34
+ * @property {boolean} present True when `.agents/skills/` exists.
35
+ * @property {string[]} frameworkFiles Subset of `framework_files` that
36
+ * actually exist on disk (relative
37
+ * to install_root).
38
+ * @property {string[]} userFiles Everything else under
39
+ * install_root (relative to
40
+ * install_root). May include both
41
+ * files and directories. Drives the
42
+ * `retained[]` warning.
43
+ * @property {boolean} hasAptVersion Whether the legacy `.apt-version`
44
+ * stamp is present.
45
+ * @property {boolean} hasManifest Whether an
46
+ * `apt-file-manifest.json` is
47
+ * present at install_root (signals
48
+ * a managed install — cleanup
49
+ * should no-op).
50
+ */
51
+ const LEGACY = LEGACY_INSTALL_PATHS.codex;
52
+ /**
53
+ * Recursively enumerate every file path under `dir`, returning paths
54
+ * relative to `dir`. Used to compute the "user files" set (anything not
55
+ * in the framework_files list).
56
+ *
57
+ * Returns [] when the dir doesn't exist. Swallows per-entry errors so a
58
+ * single unreadable symlink doesn't abort detection.
59
+ *
60
+ * @param {string} dir
61
+ * @returns {string[]}
62
+ */
63
+ function walkRelative(dir) {
64
+ /** @type {string[]} */
65
+ const out = [];
66
+ if (!existsSync(dir))
67
+ return out;
68
+ /** @param {string} current @param {string} rel */
69
+ const visit = (current, rel) => {
70
+ let entries;
71
+ try {
72
+ entries = readdirSync(current, { withFileTypes: true });
73
+ }
74
+ catch {
75
+ return;
76
+ }
77
+ for (const entry of entries) {
78
+ const childPath = join(current, entry.name);
79
+ const childRel = rel ? `${rel}/${entry.name}` : entry.name;
80
+ if (entry.isDirectory()) {
81
+ visit(childPath, childRel);
82
+ }
83
+ else if (entry.isFile()) {
84
+ out.push(childRel);
85
+ }
86
+ // Symlinks / other entry types are intentionally ignored — the
87
+ // framework only ever writes regular files.
88
+ }
89
+ };
90
+ visit(dir, '');
91
+ return out;
92
+ }
93
+ /**
94
+ * Probe the codex legacy install tree at `<targetDir>/.agents/skills/`.
95
+ *
96
+ * @param {string} targetDir
97
+ * @returns {LegacyCodexDetection}
98
+ */
99
+ export function detectLegacyCodexTree(targetDir) {
100
+ const installRoot = join(targetDir, LEGACY.install_root);
101
+ if (!existsSync(installRoot)) {
102
+ return {
103
+ present: false,
104
+ frameworkFiles: [],
105
+ userFiles: [],
106
+ hasAptVersion: false,
107
+ hasManifest: false,
108
+ };
109
+ }
110
+ const onDisk = walkRelative(installRoot);
111
+ const frameworkSet = new Set(LEGACY.framework_files);
112
+ const frameworkFiles = onDisk.filter((p) => frameworkSet.has(p));
113
+ const userFiles = onDisk.filter((p) => !frameworkSet.has(p) && p !== MANIFEST_FILENAME);
114
+ return {
115
+ present: true,
116
+ frameworkFiles,
117
+ userFiles,
118
+ hasAptVersion: onDisk.includes('.apt-version'),
119
+ hasManifest: onDisk.includes(MANIFEST_FILENAME),
120
+ };
121
+ }
122
+ /**
123
+ * Try to remove a directory if it is empty. Swallows ENOTEMPTY / ENOENT
124
+ * so the caller can blindly sweep candidate dirs in any order.
125
+ *
126
+ * @param {string} dir
127
+ * @returns {boolean} true iff the dir was actually removed.
128
+ */
129
+ function rmEmptyDir(dir) {
130
+ if (!existsSync(dir))
131
+ return false;
132
+ try {
133
+ rmdirSync(dir);
134
+ return true;
135
+ }
136
+ catch {
137
+ return false;
138
+ }
139
+ }
140
+ /**
141
+ * Clean up the legacy `.agents/skills/` tree if it looks orphaned.
142
+ *
143
+ * Branches:
144
+ * 1. `present: false` OR `frameworkFiles.length === 0` → no-op,
145
+ * `{ ran: false, reason: 'no-legacy' }`.
146
+ * 2. `hasManifest: true` → managed install, no-op,
147
+ * `{ ran: false, reason: 'managed' }`.
148
+ * 3. Otherwise: per-file `unlinkSync` each framework-owned file;
149
+ * `rmdirSync` any now-empty `apt-*` subdirectory; sweep
150
+ * `.agents/skills/` only if it is empty; sweep `.agents/` only if
151
+ * its `skills/` got removed and `.agents/` is empty.
152
+ *
153
+ * Returns `{ ran: true, removed, retained, rmdirs }` on the cleanup
154
+ * branch:
155
+ * - `removed` — relative paths under `install_root` that were unlinked.
156
+ * - `retained` — relative paths under `install_root` that were NOT
157
+ * removed (user-added skills / files not in the legacy set).
158
+ * - `rmdirs` — absolute paths of directories that were removed
159
+ * (apt-* subdirs, the install_root itself, .agents/), in removal order.
160
+ *
161
+ * Atomicity: per-file unlink is non-atomic. A partial-failure scenario
162
+ * (process killed mid-loop) is tolerable — the next `init` run will
163
+ * re-detect the remaining framework files and finish the sweep.
164
+ *
165
+ * @param {{ targetDir: string, dryRun?: boolean }} args
166
+ * @returns {
167
+ * | { ran: false, reason: 'no-legacy' | 'managed' }
168
+ * | { ran: true, removed: string[], retained: string[], rmdirs: string[] }
169
+ * }
170
+ */
171
+ export function runLegacyCleanup({ targetDir, dryRun = false }) {
172
+ const detection = detectLegacyCodexTree(targetDir);
173
+ if (!detection.present || detection.frameworkFiles.length === 0) {
174
+ return { ran: false, reason: 'no-legacy' };
175
+ }
176
+ if (detection.hasManifest) {
177
+ return { ran: false, reason: 'managed' };
178
+ }
179
+ const installRoot = join(targetDir, LEGACY.install_root);
180
+ const removed = [];
181
+ const rmdirs = [];
182
+ if (dryRun) {
183
+ // Dry-run: report what WOULD be removed without touching the filesystem.
184
+ // `retained` is the user-file set from the pre-walk (no sweep occurred).
185
+ // `rmdirs` is the set of apt-* subdirs that would become empty after removal.
186
+ const wouldRemove = detection.frameworkFiles;
187
+ const retained = detection.userFiles;
188
+ const candidateDirs = new Set();
189
+ for (const rel of wouldRemove) {
190
+ let parent = dirname(rel);
191
+ while (parent !== '.' && parent !== '') {
192
+ candidateDirs.add(parent);
193
+ parent = dirname(parent);
194
+ }
195
+ }
196
+ const wouldRmdirs = [...candidateDirs]
197
+ .sort((a, b) => b.length - a.length)
198
+ .map((rel) => join(installRoot, rel));
199
+ return { ran: true, dryRun: true, removed: wouldRemove, retained, rmdirs: wouldRmdirs };
200
+ }
201
+ for (const rel of detection.frameworkFiles) {
202
+ const abs = join(installRoot, rel);
203
+ try {
204
+ unlinkSync(abs);
205
+ removed.push(rel);
206
+ }
207
+ catch {
208
+ /* best-effort: leave a partial sweep; next run finishes it */
209
+ }
210
+ }
211
+ // Sweep any now-empty `apt-*/` subdirs the unlinks left behind.
212
+ // Walk parent dirs of every removed file in reverse-depth order so
213
+ // nested `apt-pr-review/prompts/` empties before `apt-pr-review/`.
214
+ const candidateDirs = new Set();
215
+ for (const rel of removed) {
216
+ let parent = dirname(rel);
217
+ while (parent !== '.' && parent !== '') {
218
+ candidateDirs.add(parent);
219
+ parent = dirname(parent);
220
+ }
221
+ }
222
+ const sortedDirs = [...candidateDirs].sort((a, b) => b.length - a.length);
223
+ for (const rel of sortedDirs) {
224
+ const abs = join(installRoot, rel);
225
+ if (rmEmptyDir(abs))
226
+ rmdirs.push(abs);
227
+ }
228
+ // Sweep `.agents/skills/` only if fully empty after the per-file
229
+ // pass — preserves any user-added skill dirs.
230
+ if (rmEmptyDir(installRoot)) {
231
+ rmdirs.push(installRoot);
232
+ // Sweep `.agents/` only if it became empty too (i.e. no other
233
+ // `.agents/<sibling>` content the user keeps there).
234
+ const agentsRoot = dirname(installRoot);
235
+ if (rmEmptyDir(agentsRoot))
236
+ rmdirs.push(agentsRoot);
237
+ }
238
+ // Use the pre-walk's userFiles as `retained` — the post-walk only existed
239
+ // to defensively re-scan, but pre-walk already captured user files accurately.
240
+ // (PRF-002: avoid redundant detectLegacyCodexTree call.)
241
+ const retained = detection.userFiles;
242
+ return { ran: true, removed, retained, rmdirs };
243
+ }
244
+ //# sourceMappingURL=runtime-migrate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-migrate.mjs","sourceRoot":"","sources":["../../../src/cli/install/runtime-migrate.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Detect whether the workspace source for `@aperant/framework` is ahead
3
+ * of the installed kernel.
4
+ *
5
+ * @param {string} targetDir Absolute path the route was invoked against.
6
+ * @param {string|null} installedVersion The installed kernel's version (semver string), or null when unknown.
7
+ * @returns {null | {
8
+ * source_path: string,
9
+ * source_version: string,
10
+ * installed_version: string,
11
+ * drift: true,
12
+ * }}
13
+ */
14
+ export function detectSourceWorkspaceDrift(targetDir: string, installedVersion: string | null): null | {
15
+ source_path: string;
16
+ source_version: string;
17
+ installed_version: string;
18
+ drift: true;
19
+ };
20
+ //# sourceMappingURL=drift-detect.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detect.d.mts","sourceRoot":"","sources":["../../../src/cli/route/drift-detect.mjs"],"names":[],"mappings":"AAwDA;;;;;;;;;;;;GAYG;AACH,sDATW,MAAM,oBACN,MAAM,GAAC,IAAI,GACT,IAAI,GAAG;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,IAAI,CAAC;CACb,CAuCH"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * route/drift-detect.mjs — FRAMEWORK-BUG-017 (rung 1 of 3).
3
+ *
4
+ * In-band detection of the "installed kernel drifts behind source
5
+ * workspace" failure mode. When an Aperant contributor self-hosts the
6
+ * framework out of a monorepo checkout, the kernel at
7
+ * `.aperant/deps/node_modules/@aperant/framework/` lags behind the
8
+ * source at `packages/framework/` after every same-PR framework fix.
9
+ * The SessionStart worker only knows about npm — it cannot tell that
10
+ * the workspace is ahead of the install.
11
+ *
12
+ * This module walks up from `targetDir`, looking for a sibling
13
+ * `packages/framework/package.json`. When found AND its `version`
14
+ * differs from the installed kernel's `version`, it returns a synthetic
15
+ * `update_check`-shaped object so `route.mjs` can surface the chip
16
+ * immediately — without waiting for the SessionStart hook to fire.
17
+ *
18
+ * Safe for the route hot path: synchronous, file-existence checks
19
+ * only, bounded walk (6 segments max), no network, no spawn.
20
+ *
21
+ * Security (Codex review edit 2): the workspace `package.json:version`
22
+ * is validated against the same semver-shape regex `update-chips.mjs`
23
+ * uses on the cache. A poisoned workspace `package.json` cannot
24
+ * propagate a non-semver `latest_version` into the synthesized
25
+ * `update_check` block.
26
+ */
27
+ import { existsSync, readFileSync } from 'node:fs';
28
+ import { dirname, join } from 'node:path';
29
+ import { compareVersions, SEMVER_RE } from '../util/semver.mjs';
30
+ /** Max directory frames to walk before giving up. */
31
+ const MAX_WALK_DEPTH = 6;
32
+ /**
33
+ * Walk up from `start`, returning every directory frame including
34
+ * `start` itself. Stops at the filesystem root or at a depth of
35
+ * `MAX_WALK_DEPTH` (whichever comes first). The hard cap keeps this
36
+ * cheap on the route hot path and contains accidental scans on deeply
37
+ * nested input paths.
38
+ *
39
+ * @param {string} start
40
+ * @returns {string[]}
41
+ */
42
+ function walkUp(start) {
43
+ const frames = [];
44
+ let cur = start;
45
+ for (let i = 0; i < MAX_WALK_DEPTH; i++) {
46
+ frames.push(cur);
47
+ const parent = dirname(cur);
48
+ if (parent === cur)
49
+ break;
50
+ cur = parent;
51
+ }
52
+ return frames;
53
+ }
54
+ /**
55
+ * Detect whether the workspace source for `@aperant/framework` is ahead
56
+ * of the installed kernel.
57
+ *
58
+ * @param {string} targetDir Absolute path the route was invoked against.
59
+ * @param {string|null} installedVersion The installed kernel's version (semver string), or null when unknown.
60
+ * @returns {null | {
61
+ * source_path: string,
62
+ * source_version: string,
63
+ * installed_version: string,
64
+ * drift: true,
65
+ * }}
66
+ */
67
+ export function detectSourceWorkspaceDrift(targetDir, installedVersion) {
68
+ if (!targetDir || typeof targetDir !== 'string')
69
+ return null;
70
+ if (!installedVersion || typeof installedVersion !== 'string')
71
+ return null;
72
+ if (!SEMVER_RE.test(installedVersion))
73
+ return null;
74
+ for (const dir of walkUp(targetDir)) {
75
+ const candidate = join(dir, 'packages', 'framework', 'package.json');
76
+ if (!existsSync(candidate))
77
+ continue;
78
+ let pkg;
79
+ try {
80
+ pkg = JSON.parse(readFileSync(candidate, 'utf-8'));
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ // Validate the workspace package is actually @aperant/framework —
86
+ // guard against false matches on unrelated monorepos that happen
87
+ // to have a `packages/framework/` directory.
88
+ if (pkg?.name !== '@aperant/framework')
89
+ continue;
90
+ const sourceVersion = pkg?.version;
91
+ if (typeof sourceVersion !== 'string' || !SEMVER_RE.test(sourceVersion))
92
+ return null;
93
+ // Only report drift when workspace source is strictly ahead of the installed
94
+ // kernel. Equal (already up-to-date) and behind (installed is newer) both
95
+ // return null — only source-ahead is a drift worth surfacing.
96
+ if (compareVersions(sourceVersion, installedVersion) <= 0)
97
+ return null;
98
+ return {
99
+ source_path: candidate,
100
+ source_version: sourceVersion,
101
+ installed_version: installedVersion,
102
+ drift: true,
103
+ };
104
+ }
105
+ return null;
106
+ }
107
+ //# sourceMappingURL=drift-detect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detect.mjs","sourceRoot":"","sources":["../../../src/cli/route/drift-detect.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE/D,qDAAqD;AACrD,MAAM,cAAc,GAAG,CAAC,CAAA;AAExB;;;;;;;;;GASG;AACH,SAAS,MAAM,CAAC,KAAK;IACpB,MAAM,MAAM,GAAG,EAAE,CAAA;IACjB,IAAI,GAAG,GAAG,KAAK,CAAA;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAChB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAK;QACzB,GAAG,GAAG,MAAM,CAAA;IACb,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,0BAA0B,CAAC,SAAS,EAAE,gBAAgB;IACrE,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC5D,IAAI,CAAC,gBAAgB,IAAI,OAAO,gBAAgB,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAA;IAElD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;QACpE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAQ;QAEpC,IAAI,GAAG,CAAA;QACP,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;QACnD,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,CAAA;QACZ,CAAC;QAED,kEAAkE;QAClE,iEAAiE;QACjE,6CAA6C;QAC7C,IAAI,GAAG,EAAE,IAAI,KAAK,oBAAoB;YAAE,SAAQ;QAEhD,MAAM,aAAa,GAAG,GAAG,EAAE,OAAO,CAAA;QAClC,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAA;QACpF,6EAA6E;QAC7E,0EAA0E;QAC1E,8DAA8D;QAC9D,IAAI,eAAe,CAAC,aAAa,EAAE,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAEtE,OAAO;YACN,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,aAAa;YAC7B,iBAAiB,EAAE,gBAAgB;YACnC,KAAK,EAAE,IAAI;SACX,CAAA;IACF,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-md.d.mts","sourceRoot":"","sources":["../../../src/cli/task/index-md.mjs"],"names":[],"mappings":"AASA;;;GAGG;AACH,0DA4EC"}
1
+ {"version":3,"file":"index-md.d.mts","sourceRoot":"","sources":["../../../src/cli/task/index-md.mjs"],"names":[],"mappings":"AAUA;;;GAGG;AACH,0DAwFC"}
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
+ import { loadMergedProjectConfig } from '../config/load.mjs';
6
7
  import { withFileLock } from '../util/fs-lock.mjs';
7
8
  import { formatDateDisplay, formatTimeDisplay } from './format.mjs';
8
9
  /**
@@ -13,8 +14,19 @@ export function regenerateTaskIndex(targetDir) {
13
14
  const statePath = join(targetDir, '.aperant', 'state.json');
14
15
  if (!existsSync(statePath))
15
16
  return;
16
- const configPath = join(targetDir, '.aperant', 'config.json');
17
- const config = existsSync(configPath) ? JSON.parse(readFileSync(configPath, 'utf-8')) : {};
17
+ // AUDIT-001: read through the merged loader so per-device
18
+ // preferences.date_format / preferences.time_format overrides land
19
+ // even when the shared config.json no longer carries those fields.
20
+ // Guard: malformed config.local.json must not crash every task state
21
+ // transition — fall back to shared-config-only read and warn on stderr.
22
+ let config;
23
+ try {
24
+ config = loadMergedProjectConfig(targetDir) ?? {};
25
+ }
26
+ catch (e) {
27
+ process.stderr.write(`[index-md] config.local.json parse error — using shared config only: ${e.message}\n`);
28
+ config = {};
29
+ }
18
30
  if (config.preferences?.task_index === false)
19
31
  return;
20
32
  const state = JSON.parse(readFileSync(statePath, 'utf-8'));
@@ -1 +1 @@
1
- {"version":3,"file":"index-md.mjs","sourceRoot":"","sources":["../../../src/cli/task/index-md.mjs"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index-md.mjs","sourceRoot":"","sources":["../../../src/cli/task/index-md.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Build the full "## Aperant Framework" section, wrapped in the
3
+ * `<!-- APT:framework-* -->` markers.
4
+ *
5
+ * @param {Object} opts
6
+ * @param {string} opts.canonicalRoot Absolute path to the framework root
7
+ * (the directory that contains
8
+ * `templates/aperant-claude-md-appendix.md`).
9
+ * @param {string} opts.targetDir Project root (passed to discoverSkills).
10
+ * @param {string} [opts.cli] Host CLI label (forwarded to
11
+ * getTrustedSkillSources so the install
12
+ * root for the runtime is included).
13
+ * @returns {string} The full section, including markers
14
+ * and trailing newline before the
15
+ * end-marker. No leading newline.
16
+ */
17
+ export function buildAptSection({ canonicalRoot, targetDir, cli }: {
18
+ canonicalRoot: string;
19
+ targetDir: string;
20
+ cli?: string | undefined;
21
+ }): string;
22
+ /**
23
+ * Extract the `/apt:<slug>` (or bare `/apt`) row IDs from the
24
+ * `<!-- APT:framework-* -->` section of an existing instruction file.
25
+ * Returns `[]` when the file has no APT section.
26
+ *
27
+ * Used by `injectInstructionFile` to detect foreign rows that would be
28
+ * silently clobbered by a regeneration — see `--force-overwrite-catalog`.
29
+ *
30
+ * @param {string} text Full instruction-file contents.
31
+ * @returns {string[]} Row IDs in file order, e.g. `['/apt', '/apt:quick', …]`.
32
+ */
33
+ export function extractAptSectionRowIds(text: string): string[];
34
+ //# sourceMappingURL=aperant-section.d.mts.map
@@ -0,0 +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"}