@lsctech/polaris 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/README.md +87 -0
  2. package/dist/__mocks__/tool-server-linear.js +34 -0
  3. package/dist/cli/adopt-approve.js +60 -0
  4. package/dist/cli/adopt-cognition.js +199 -0
  5. package/dist/cli/adopt-instructions.js +143 -0
  6. package/dist/cli/adopt-rules.js +169 -0
  7. package/dist/cli/adopt-scan.js +25 -0
  8. package/dist/cli/adopt-smartdocs.js +192 -0
  9. package/dist/cli/adoption-inventory.js +350 -0
  10. package/dist/cli/adoption-plan.js +222 -0
  11. package/dist/cli/args.js +28 -0
  12. package/dist/cli/args.test.js +30 -0
  13. package/dist/cli/branding.js +41 -0
  14. package/dist/cli/graph.js +358 -0
  15. package/dist/cli/index.js +127 -0
  16. package/dist/cli/index.test.js +162 -0
  17. package/dist/cli/init-detect.js +61 -0
  18. package/dist/cli/init.js +492 -0
  19. package/dist/cli/init.test.js +259 -0
  20. package/dist/cli/librarian.js +32 -0
  21. package/dist/cli/medic.js +96 -0
  22. package/dist/cli/startup.test.js +23 -0
  23. package/dist/cli/tracker.js +130 -0
  24. package/dist/cli/tracker.test.js +126 -0
  25. package/dist/cli/version.js +10 -0
  26. package/dist/cli/version.test.js +11 -0
  27. package/dist/cli/worker.js +287 -0
  28. package/dist/cluster-state/fixtures/test-clusters.json +19 -0
  29. package/dist/cluster-state/store.js +302 -0
  30. package/dist/cluster-state/store.test.js +145 -0
  31. package/dist/cluster-state/types.js +2 -0
  32. package/dist/cognition/archive.js +158 -0
  33. package/dist/cognition/closeout-librarian-types.js +161 -0
  34. package/dist/cognition/cognition.test.js +623 -0
  35. package/dist/cognition/index.js +41 -0
  36. package/dist/cognition/librarian-dispatch.js +391 -0
  37. package/dist/cognition/librarian-dispatch.test.js +247 -0
  38. package/dist/cognition/librarian-packet.js +313 -0
  39. package/dist/cognition/librarian-types.js +57 -0
  40. package/dist/cognition/route-cognition-delta.js +350 -0
  41. package/dist/cognition/summary-delta.js +279 -0
  42. package/dist/cognition/validate.js +162 -0
  43. package/dist/config/defaults.js +98 -0
  44. package/dist/config/doctor.js +273 -0
  45. package/dist/config/index.js +14 -0
  46. package/dist/config/loader.js +58 -0
  47. package/dist/config/provider-detect.js +60 -0
  48. package/dist/config/provider-detect.test.js +119 -0
  49. package/dist/config/schema.js +2 -0
  50. package/dist/config/show.js +44 -0
  51. package/dist/config/show.test.js +42 -0
  52. package/dist/config/validator.js +675 -0
  53. package/dist/config/validator.test.js +77 -0
  54. package/dist/docs/canon-check.js +334 -0
  55. package/dist/docs/canon-check.test.js +207 -0
  56. package/dist/docs/doctrine.js +133 -0
  57. package/dist/docs/doctrine.test.js +139 -0
  58. package/dist/docs/index.js +168 -0
  59. package/dist/docs/index.test.js +83 -0
  60. package/dist/docs/ingest.js +295 -0
  61. package/dist/docs/ingest.test.js +71 -0
  62. package/dist/docs/migrate.js +165 -0
  63. package/dist/docs/migrate.test.js +136 -0
  64. package/dist/docs/seed-instructions.js +147 -0
  65. package/dist/docs/seed-instructions.test.js +137 -0
  66. package/dist/docs/validate-instructions.js +267 -0
  67. package/dist/docs/validate-instructions.test.js +238 -0
  68. package/dist/finalize/artifact-policy.js +214 -0
  69. package/dist/finalize/artifact-policy.test.js +84 -0
  70. package/dist/finalize/delivery-integrity.js +141 -0
  71. package/dist/finalize/finalize.test.js +210 -0
  72. package/dist/finalize/github.js +41 -0
  73. package/dist/finalize/index.js +474 -0
  74. package/dist/finalize/linear.js +213 -0
  75. package/dist/finalize/run-report.js +47 -0
  76. package/dist/finalize/steps/01-map-update.js +11 -0
  77. package/dist/finalize/steps/02-map-validate.js +11 -0
  78. package/dist/finalize/steps/03-schema-validate.js +11 -0
  79. package/dist/finalize/steps/04-run-checks.js +118 -0
  80. package/dist/finalize/steps/05-generate-report.js +14 -0
  81. package/dist/finalize/steps/06-commit.js +39 -0
  82. package/dist/finalize/steps/07-push.js +10 -0
  83. package/dist/finalize/steps/08-create-pr.js +9 -0
  84. package/dist/finalize/steps/09-update-state.js +9 -0
  85. package/dist/finalize/steps/10-append-jsonl.js +23 -0
  86. package/dist/finalize/steps/11-update-linear.js +22 -0
  87. package/dist/finalize/steps/12-archive.js +21 -0
  88. package/dist/graph/adapter/c/adapter.js +45 -0
  89. package/dist/graph/adapter/c/extract.js +135 -0
  90. package/dist/graph/adapter/c/index.js +10 -0
  91. package/dist/graph/adapter/c/runtime.js +67 -0
  92. package/dist/graph/adapter/cpp/adapter.js +45 -0
  93. package/dist/graph/adapter/cpp/extract.js +159 -0
  94. package/dist/graph/adapter/cpp/index.js +10 -0
  95. package/dist/graph/adapter/cpp/runtime.js +61 -0
  96. package/dist/graph/adapter/csharp/adapter.js +45 -0
  97. package/dist/graph/adapter/csharp/extract.js +127 -0
  98. package/dist/graph/adapter/csharp/index.js +10 -0
  99. package/dist/graph/adapter/csharp/runtime.js +61 -0
  100. package/dist/graph/adapter/dart/adapter.js +56 -0
  101. package/dist/graph/adapter/dart/extract.js +130 -0
  102. package/dist/graph/adapter/dart/index.js +10 -0
  103. package/dist/graph/adapter/dart/runtime.js +61 -0
  104. package/dist/graph/adapter/go/adapter.js +45 -0
  105. package/dist/graph/adapter/go/extract.js +112 -0
  106. package/dist/graph/adapter/go/index.js +10 -0
  107. package/dist/graph/adapter/go/runtime.js +58 -0
  108. package/dist/graph/adapter/kotlin-java/extract-common.js +83 -0
  109. package/dist/graph/adapter/kotlin-java/index.js +15 -0
  110. package/dist/graph/adapter/kotlin-java/java-adapter.js +45 -0
  111. package/dist/graph/adapter/kotlin-java/java-extract.js +42 -0
  112. package/dist/graph/adapter/kotlin-java/kotlin-adapter.js +48 -0
  113. package/dist/graph/adapter/kotlin-java/kotlin-extract.js +58 -0
  114. package/dist/graph/adapter/kotlin-java/runtime.js +75 -0
  115. package/dist/graph/adapter/python/adapter.js +45 -0
  116. package/dist/graph/adapter/python/extract.js +121 -0
  117. package/dist/graph/adapter/python/index.js +10 -0
  118. package/dist/graph/adapter/python/runtime.js +70 -0
  119. package/dist/graph/adapter/registry.js +82 -0
  120. package/dist/graph/adapter/rust/adapter.js +45 -0
  121. package/dist/graph/adapter/rust/extract.js +110 -0
  122. package/dist/graph/adapter/rust/index.js +10 -0
  123. package/dist/graph/adapter/rust/runtime.js +74 -0
  124. package/dist/graph/adapter/shell/adapter.js +34 -0
  125. package/dist/graph/adapter/shell/extract.js +98 -0
  126. package/dist/graph/adapter/shell/index.js +8 -0
  127. package/dist/graph/adapter/svelte/adapter.js +91 -0
  128. package/dist/graph/adapter/svelte/extract.js +41 -0
  129. package/dist/graph/adapter/svelte/index.js +8 -0
  130. package/dist/graph/adapter/swift/adapter.js +45 -0
  131. package/dist/graph/adapter/swift/extract.js +120 -0
  132. package/dist/graph/adapter/swift/index.js +10 -0
  133. package/dist/graph/adapter/swift/runtime.js +70 -0
  134. package/dist/graph/adapter/types.js +2 -0
  135. package/dist/graph/adapter/typescript-javascript/adapter.js +72 -0
  136. package/dist/graph/adapter/typescript-javascript/extract.js +115 -0
  137. package/dist/graph/adapter/typescript-javascript/index.js +10 -0
  138. package/dist/graph/adapter/typescript-javascript/runtime.js +97 -0
  139. package/dist/graph/capability/index.js +105 -0
  140. package/dist/graph/governance.js +104 -0
  141. package/dist/graph/parser/extract.js +5 -0
  142. package/dist/graph/parser/loader.js +2 -0
  143. package/dist/graph/parser/pipeline.js +194 -0
  144. package/dist/graph/query/index.js +277 -0
  145. package/dist/graph/query/types.js +5 -0
  146. package/dist/graph/resolver/build-edges.js +211 -0
  147. package/dist/graph/resolver/index.js +23 -0
  148. package/dist/graph/resolver/resolve-imports.js +168 -0
  149. package/dist/graph/store/adapter.js +132 -0
  150. package/dist/graph/store/queries.js +124 -0
  151. package/dist/graph/store/types.js +4 -0
  152. package/dist/ignore/defaults.js +41 -0
  153. package/dist/ignore/parser.js +39 -0
  154. package/dist/lint/map-reference-validator.js +72 -0
  155. package/dist/loop/abort.js +188 -0
  156. package/dist/loop/abort.test.js +151 -0
  157. package/dist/loop/adapters/__tests__/terminal-cli.test.js +92 -0
  158. package/dist/loop/adapters/agent-subtask.js +137 -0
  159. package/dist/loop/adapters/agent-subtask.test.js +151 -0
  160. package/dist/loop/adapters/cli-subtask-bridge.js +108 -0
  161. package/dist/loop/adapters/index.js +9 -0
  162. package/dist/loop/adapters/registry.js +17 -0
  163. package/dist/loop/adapters/terminal-cli.js +403 -0
  164. package/dist/loop/adapters/types.js +2 -0
  165. package/dist/loop/adapters/worker-instructions.js +85 -0
  166. package/dist/loop/body-parser.js +226 -0
  167. package/dist/loop/bootstrap-packet.js +97 -0
  168. package/dist/loop/bootstrap-packet.test.js +171 -0
  169. package/dist/loop/branch-governance.js +54 -0
  170. package/dist/loop/budget.js +63 -0
  171. package/dist/loop/budget.test.js +163 -0
  172. package/dist/loop/checkpoint.js +325 -0
  173. package/dist/loop/compact-return.js +59 -0
  174. package/dist/loop/continue.js +645 -0
  175. package/dist/loop/continue.test.js +337 -0
  176. package/dist/loop/dispatch-boundary.js +335 -0
  177. package/dist/loop/dispatch-state.js +223 -0
  178. package/dist/loop/dispatch-state.test.js +186 -0
  179. package/dist/loop/dispatch.js +1236 -0
  180. package/dist/loop/dispatch.test.js +499 -0
  181. package/dist/loop/ephemeral-smoke.test.js +160 -0
  182. package/dist/loop/evidence-backfill.js +216 -0
  183. package/dist/loop/execution-adapter.js +141 -0
  184. package/dist/loop/execution-adapter.test.js +66 -0
  185. package/dist/loop/finalize-evidence.js +169 -0
  186. package/dist/loop/git-custody.js +250 -0
  187. package/dist/loop/impl-packet-input.js +38 -0
  188. package/dist/loop/index.js +270 -0
  189. package/dist/loop/ledger.js +49 -0
  190. package/dist/loop/ledger.test.js +127 -0
  191. package/dist/loop/lifecycle-dispatch.js +348 -0
  192. package/dist/loop/lifecycle-dispatch.test.js +318 -0
  193. package/dist/loop/lifecycle.js +93 -0
  194. package/dist/loop/lifecycle.test.js +150 -0
  195. package/dist/loop/orphan-recovery.js +276 -0
  196. package/dist/loop/orphan-recovery.test.js +236 -0
  197. package/dist/loop/parent.js +1566 -0
  198. package/dist/loop/parent.test.js +738 -0
  199. package/dist/loop/provider-sealed-packet.test.js +164 -0
  200. package/dist/loop/resume.js +295 -0
  201. package/dist/loop/resume.test.js +172 -0
  202. package/dist/loop/run-bootstrap.js +234 -0
  203. package/dist/loop/run-preflight.js +203 -0
  204. package/dist/loop/status.js +665 -0
  205. package/dist/loop/status.test.js +235 -0
  206. package/dist/loop/wait.js +86 -0
  207. package/dist/loop/worker-packet.js +406 -0
  208. package/dist/loop/worker-packet.test.js +243 -0
  209. package/dist/loop/worker-prompt.js +260 -0
  210. package/dist/loop/worker-prompt.test.js +247 -0
  211. package/dist/loop/worker.js +498 -0
  212. package/dist/loop/worker.test.js +372 -0
  213. package/dist/map/atlas.js +77 -0
  214. package/dist/map/backfill.js +171 -0
  215. package/dist/map/backfill.test.js +120 -0
  216. package/dist/map/index.js +255 -0
  217. package/dist/map/inference.js +73 -0
  218. package/dist/map/inference.test.js +35 -0
  219. package/dist/map/query.js +157 -0
  220. package/dist/map/query.test.js +174 -0
  221. package/dist/map/update.js +355 -0
  222. package/dist/map/update.test.js +67 -0
  223. package/dist/map/validate.js +153 -0
  224. package/dist/map/validate.test.js +90 -0
  225. package/dist/map/welfare.js +86 -0
  226. package/dist/mcp/lib/invoke.js +35 -0
  227. package/dist/mcp/lib/redact.js +24 -0
  228. package/dist/mcp/lib/redact.test.js +112 -0
  229. package/dist/mcp/lib/root.js +41 -0
  230. package/dist/mcp/lib/root.test.js +114 -0
  231. package/dist/mcp/server.js +15 -0
  232. package/dist/mcp/tools/claim-child.js +119 -0
  233. package/dist/mcp/tools/claim-child.test.js +69 -0
  234. package/dist/mcp/tools/current-state.js +73 -0
  235. package/dist/mcp/tools/current-state.test.js +114 -0
  236. package/dist/mcp/tools/dispatch-result.js +186 -0
  237. package/dist/mcp/tools/dispatch-result.test.js +109 -0
  238. package/dist/mcp/tools/index.js +222 -0
  239. package/dist/mcp/tools/index.test.js +172 -0
  240. package/dist/mcp/tools/linear.js +74 -0
  241. package/dist/mcp/tools/loop-continue.js +159 -0
  242. package/dist/mcp/tools/loop-continue.test.js +186 -0
  243. package/dist/mcp/tools/loop-dry-run.js +15 -0
  244. package/dist/mcp/tools/status.js +65 -0
  245. package/dist/medic/chart-id.js +75 -0
  246. package/dist/medic/chart-schema.js +139 -0
  247. package/dist/runs/index.js +119 -0
  248. package/dist/runs/index.test.js +184 -0
  249. package/dist/runs/ledger-tail.js +15 -0
  250. package/dist/runs/list.js +29 -0
  251. package/dist/runs/reconcile.js +74 -0
  252. package/dist/runs/show.js +10 -0
  253. package/dist/runtime/audit/logger.js +15 -0
  254. package/dist/runtime/audit/reader.js +42 -0
  255. package/dist/runtime/checkpoint.js +89 -0
  256. package/dist/runtime/continuation/confirmed.js +225 -0
  257. package/dist/runtime/continuation/confirmed.test.js +421 -0
  258. package/dist/runtime/continuation/dry-run.js +74 -0
  259. package/dist/runtime/execution-window.js +106 -0
  260. package/dist/runtime/scheduling/child-selector.js +16 -0
  261. package/dist/runtime/state.js +43 -0
  262. package/dist/runtime/status.js +46 -0
  263. package/dist/runtime/verification/envelope.js +80 -0
  264. package/dist/runtime/verification/fingerprint.js +26 -0
  265. package/dist/skill-packet/cli.test.js +105 -0
  266. package/dist/skill-packet/generator.js +225 -0
  267. package/dist/skill-packet/generator.test.js +159 -0
  268. package/dist/skill-packet/index.js +49 -0
  269. package/dist/skill-packet/types.js +2 -0
  270. package/dist/smartdocs-engine/audit.js +194 -0
  271. package/dist/smartdocs-engine/audit.test.js +122 -0
  272. package/dist/smartdocs-engine/canon-check.js +340 -0
  273. package/dist/smartdocs-engine/canon-check.test.js +234 -0
  274. package/dist/smartdocs-engine/doctrine.js +633 -0
  275. package/dist/smartdocs-engine/doctrine.test.js +374 -0
  276. package/dist/smartdocs-engine/index.js +456 -0
  277. package/dist/smartdocs-engine/index.test.js +82 -0
  278. package/dist/smartdocs-engine/ingest.js +495 -0
  279. package/dist/smartdocs-engine/ingest.test.js +163 -0
  280. package/dist/smartdocs-engine/migrate.js +217 -0
  281. package/dist/smartdocs-engine/migrate.test.js +200 -0
  282. package/dist/smartdocs-engine/seed-instructions.js +335 -0
  283. package/dist/smartdocs-engine/seed-instructions.test.js +275 -0
  284. package/dist/smartdocs-engine/smartdoc-ignore.js +258 -0
  285. package/dist/smartdocs-engine/smartdoc-ignore.test.js +146 -0
  286. package/dist/smartdocs-engine/validate-instructions.js +366 -0
  287. package/dist/smartdocs-engine/validate-instructions.test.js +283 -0
  288. package/dist/tracker/adapters/github/index.js +305 -0
  289. package/dist/tracker/adapters/jira/index.js +293 -0
  290. package/dist/tracker/adapters/linear/http-errors.test.js +51 -0
  291. package/dist/tracker/adapters/linear/index.js +621 -0
  292. package/dist/tracker/adapters/linear/index.test.js +238 -0
  293. package/dist/tracker/adapters/linear.js +50 -0
  294. package/dist/tracker/adapters/local/index.js +10 -0
  295. package/dist/tracker/adapters/local-file/index.js +159 -0
  296. package/dist/tracker/adapters/mcp-bridge.js +158 -0
  297. package/dist/tracker/adapters/mcp-bridge.test.js +12 -0
  298. package/dist/tracker/adapters/spec/index.js +146 -0
  299. package/dist/tracker/capabilities.js +2 -0
  300. package/dist/tracker/index.js +49 -0
  301. package/dist/tracker/lifecycle-policy.js +139 -0
  302. package/dist/tracker/lifecycle-transition.js +164 -0
  303. package/dist/tracker/local-graph.js +98 -0
  304. package/dist/tracker/migration.js +56 -0
  305. package/dist/tracker/schema.js +86 -0
  306. package/dist/tracker/sync/index.js +404 -0
  307. package/dist/tracker/sync/queue-store.js +95 -0
  308. package/dist/tracker/sync/queue-store.test.js +104 -0
  309. package/dist/tracker/types.js +11 -0
  310. package/dist/types/linear.js +3 -0
  311. package/dist/types/result-packet.js +12 -0
  312. package/dist/types/runtime-state.js +2 -0
  313. package/dist/types/work-contract.js +2 -0
  314. package/dist/utils/monotonic-timestamp.js +13 -0
  315. package/dist/utils/monotonic-timestamp.test.js +19 -0
  316. package/package.json +64 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectRepoState = detectRepoState;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const SOURCE_ROOT_HINTS = ["src", "lib", "app", "packages", "services", "server", "client"];
7
+ const DOC_ROOT_HINTS = [
8
+ "docs",
9
+ "doc",
10
+ "wiki",
11
+ "adr",
12
+ "rfcs",
13
+ "architecture",
14
+ "design",
15
+ "spec",
16
+ "specs",
17
+ "guides",
18
+ ];
19
+ const AGENT_INSTRUCTION_FILES = ["AGENTS.md", "CLAUDE.md", "POLARIS.md", "SUMMARY.md"];
20
+ function safeReadDir(repoRoot) {
21
+ try {
22
+ return (0, node_fs_1.readdirSync)(repoRoot);
23
+ }
24
+ catch {
25
+ return [];
26
+ }
27
+ }
28
+ function hasAny(entries, values) {
29
+ return entries.some((entry) => values.includes(entry));
30
+ }
31
+ function hasPolarisConfig(repoRoot) {
32
+ return (0, node_fs_1.existsSync)((0, node_path_1.join)(repoRoot, "polaris.config.json"));
33
+ }
34
+ function hasFileRoutes(repoRoot) {
35
+ return (0, node_fs_1.existsSync)((0, node_path_1.join)(repoRoot, ".polaris", "map", "file-routes.json"));
36
+ }
37
+ function detectRepoState(repoRoot) {
38
+ const topLevelEntries = safeReadDir(repoRoot);
39
+ const meaningfulEntries = topLevelEntries.filter((entry) => entry !== ".git");
40
+ if (meaningfulEntries.length === 0) {
41
+ return "empty";
42
+ }
43
+ const configExists = hasPolarisConfig(repoRoot);
44
+ const fileRoutesExists = hasFileRoutes(repoRoot);
45
+ if (configExists && fileRoutesExists) {
46
+ return "polaris-enabled";
47
+ }
48
+ if (configExists) {
49
+ return "partial";
50
+ }
51
+ const hasSourceRoots = hasAny(topLevelEntries, SOURCE_ROOT_HINTS);
52
+ const hasDocsRoots = hasAny(topLevelEntries, DOC_ROOT_HINTS);
53
+ const hasAgentInstructionFiles = hasAny(topLevelEntries, AGENT_INSTRUCTION_FILES);
54
+ if (hasSourceRoots || hasDocsRoots || hasAgentInstructionFiles) {
55
+ return "existing";
56
+ }
57
+ if ((0, node_fs_1.existsSync)((0, node_path_1.join)(repoRoot, "package.json")) || hasSourceRoots) {
58
+ return "new";
59
+ }
60
+ return "existing";
61
+ }
@@ -0,0 +1,492 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectRepoState = void 0;
4
+ exports.runAdoptionAtlas = runAdoptionAtlas;
5
+ exports.finalizeAdoption = finalizeAdoption;
6
+ exports.runInit = runInit;
7
+ exports.createInitCommand = createInitCommand;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_child_process_1 = require("node:child_process");
10
+ const node_path_1 = require("node:path");
11
+ const commander_1 = require("commander");
12
+ const init_detect_js_1 = require("./init-detect.js");
13
+ const provider_detect_js_1 = require("../config/provider-detect.js");
14
+ const adoption_plan_js_1 = require("./adoption-plan.js");
15
+ const adopt_approve_js_1 = require("./adopt-approve.js");
16
+ const adopt_scan_js_1 = require("./adopt-scan.js");
17
+ const adopt_cognition_js_1 = require("./adopt-cognition.js");
18
+ const adopt_smartdocs_js_1 = require("./adopt-smartdocs.js");
19
+ const index_js_1 = require("../map/index.js");
20
+ const adopt_instructions_js_1 = require("./adopt-instructions.js");
21
+ const artifact_policy_js_1 = require("../finalize/artifact-policy.js");
22
+ var init_detect_js_2 = require("./init-detect.js");
23
+ Object.defineProperty(exports, "detectRepoState", { enumerable: true, get: function () { return init_detect_js_2.detectRepoState; } });
24
+ const PLAN_COMPLETE_STATUSES = new Set(["completed", "skipped"]);
25
+ const ADOPTION_LOCKED_EXECUTION = {
26
+ rotation: [],
27
+ allowCrossAgentFallback: false,
28
+ adapter: "terminal-cli",
29
+ };
30
+ const ADOPTION_LOCKED_ORCHESTRATION = {
31
+ mode: "supervised",
32
+ };
33
+ function applySmartDocsMigration(repoRoot, inventory) {
34
+ let moved = 0;
35
+ let skipped = 0;
36
+ for (const candidate of inventory.smartdocs_candidates) {
37
+ const sourcePath = (0, node_path_1.join)(repoRoot, candidate.path);
38
+ const destinationPath = (0, node_path_1.join)(repoRoot, candidate.suggested_destination);
39
+ if (!(0, node_fs_1.existsSync)(sourcePath) || (0, node_fs_1.existsSync)(destinationPath)) {
40
+ skipped += 1;
41
+ continue;
42
+ }
43
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(destinationPath), { recursive: true });
44
+ (0, node_fs_1.renameSync)(sourcePath, destinationPath);
45
+ moved += 1;
46
+ }
47
+ return { moved, skipped };
48
+ }
49
+ function asRecord(value) {
50
+ return typeof value === "object" && value !== null && !Array.isArray(value)
51
+ ? value
52
+ : {};
53
+ }
54
+ function isAdoptionConfigLocked(existing) {
55
+ const execution = asRecord(existing.execution);
56
+ const orchestration = asRecord(existing.orchestration);
57
+ return (Array.isArray(execution.rotation) &&
58
+ execution.rotation.length === 0 &&
59
+ execution.allowCrossAgentFallback === false &&
60
+ execution.adapter === ADOPTION_LOCKED_EXECUTION.adapter &&
61
+ orchestration.mode === ADOPTION_LOCKED_ORCHESTRATION.mode);
62
+ }
63
+ function buildInitConfig(existing, detected, detectedRepoAnalysis, adopt) {
64
+ const existingProviders = asRecord(existing.providers);
65
+ const updatedProviders = { ...existingProviders };
66
+ if (detected.length > 0) {
67
+ updatedProviders.compactionProviders = detected;
68
+ }
69
+ else {
70
+ delete updatedProviders.compactionProviders;
71
+ }
72
+ const existingRepoAnalysis = asRecord(existingProviders.repoAnalysis);
73
+ const updatedRepoAnalysis = detectedRepoAnalysis.length > 0
74
+ ? { ...existingRepoAnalysis, preferred: detectedRepoAnalysis[0] }
75
+ : Object.fromEntries(Object.entries(existingRepoAnalysis).filter(([key]) => key !== "preferred"));
76
+ const updated = {
77
+ ...existing,
78
+ version: typeof existing.version === "string" ? existing.version : "1.0",
79
+ };
80
+ if (adopt) {
81
+ const existingExecution = asRecord(existing.execution);
82
+ updated.execution = {
83
+ ...existingExecution,
84
+ ...ADOPTION_LOCKED_EXECUTION,
85
+ };
86
+ const existingOrchestration = asRecord(existing.orchestration);
87
+ updated.orchestration = {
88
+ ...existingOrchestration,
89
+ ...ADOPTION_LOCKED_ORCHESTRATION,
90
+ };
91
+ }
92
+ if (Object.keys(updatedProviders).length > 0) {
93
+ updated.providers = updatedProviders;
94
+ }
95
+ else if ("providers" in updated && Object.keys(updatedProviders).length === 0 && detected.length === 0) {
96
+ delete updated.providers;
97
+ }
98
+ if (Object.keys(updatedRepoAnalysis).length > 0) {
99
+ updatedProviders.repoAnalysis = updatedRepoAnalysis;
100
+ updated.providers = updatedProviders;
101
+ }
102
+ else if (updated.providers) {
103
+ const providers = asRecord(updated.providers);
104
+ delete providers.repoAnalysis;
105
+ if (Object.keys(providers).length > 0) {
106
+ updated.providers = providers;
107
+ }
108
+ else {
109
+ delete updated.providers;
110
+ }
111
+ }
112
+ return updated;
113
+ }
114
+ function writeAdoptionConfigLock(repoRoot, configPath, existing, detected, detectedRepoAnalysis) {
115
+ if (isAdoptionConfigLocked(existing)) {
116
+ process.stdout.write("Provider config already locked — skipping.\n");
117
+ return false;
118
+ }
119
+ const updated = buildInitConfig(existing, detected, detectedRepoAnalysis, true);
120
+ (0, node_fs_1.writeFileSync)(configPath, `${JSON.stringify(updated, null, 2)}\n`, "utf-8");
121
+ process.stdout.write(`polaris.config.json written to ${configPath}\n`);
122
+ return true;
123
+ }
124
+ function areAllPlanStepsComplete(plan) {
125
+ return plan.steps.length > 0 && plan.steps.every((step) => PLAN_COMPLETE_STATUSES.has(step.status));
126
+ }
127
+ function loadAdoptionPlanArtifacts(repoRoot) {
128
+ const jsonPath = (0, node_path_1.join)(repoRoot, ".polaris", "adoption-plan.json");
129
+ const markdownPath = (0, node_path_1.join)(repoRoot, ".polaris", "adoption-plan.md");
130
+ if (!(0, node_fs_1.existsSync)(jsonPath)) {
131
+ return null;
132
+ }
133
+ try {
134
+ const json = (0, node_fs_1.readFileSync)(jsonPath, "utf-8");
135
+ const plan = JSON.parse(json);
136
+ const markdown = (0, node_fs_1.existsSync)(markdownPath)
137
+ ? (0, node_fs_1.readFileSync)(markdownPath, "utf-8")
138
+ : (0, adoption_plan_js_1.renderAdoptionPlanMarkdown)(plan);
139
+ return {
140
+ plan,
141
+ json,
142
+ markdown,
143
+ jsonPath,
144
+ markdownPath,
145
+ wroteFiles: false,
146
+ };
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ function ensureRuntimeArtifactExclusions(repoRoot) {
153
+ const gitignorePath = (0, node_path_1.join)(repoRoot, ".gitignore");
154
+ const existing = (0, node_fs_1.existsSync)(gitignorePath) ? (0, node_fs_1.readFileSync)(gitignorePath, "utf-8") : "";
155
+ const lines = existing.split(/\r?\n/);
156
+ const ignoreBlock = (0, artifact_policy_js_1.formatGitignoreBlock)();
157
+ const required = ignoreBlock.split("\n");
158
+ const missing = !required.every((line) => lines.includes(line));
159
+ if (!missing) {
160
+ return;
161
+ }
162
+ const trimmed = existing.trimEnd();
163
+ const separator = trimmed.length > 0 ? "\n\n" : "";
164
+ const next = `${trimmed}${separator}${ignoreBlock}\n`;
165
+ (0, node_fs_1.writeFileSync)(gitignorePath, next, "utf-8");
166
+ }
167
+ function readBaselineCoverage(repoRoot) {
168
+ const mapIndexPath = (0, node_path_1.join)(repoRoot, ".polaris", "map", "index.json");
169
+ if (!(0, node_fs_1.existsSync)(mapIndexPath)) {
170
+ return "n/a";
171
+ }
172
+ try {
173
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(mapIndexPath, "utf-8"));
174
+ const baseline = parsed.adoption_baseline_coverage_pct;
175
+ if (typeof baseline === "number") {
176
+ return `${baseline}%`;
177
+ }
178
+ const coverage = parsed.coverage_pct;
179
+ if (typeof coverage === "number") {
180
+ return `${coverage}%`;
181
+ }
182
+ }
183
+ catch {
184
+ return "n/a";
185
+ }
186
+ return "n/a";
187
+ }
188
+ function runAdoptionAtlas(plan, repoRoot = (0, node_path_1.resolve)(process.cwd())) {
189
+ if (!plan.steps.some((step) => step.category === "atlas-generate")) {
190
+ return Promise.resolve();
191
+ }
192
+ try {
193
+ (0, index_js_1.runMapIndex)(repoRoot, false, false, { seedCognition: false, skipThreshold: true });
194
+ const mapDir = (0, node_path_1.join)(repoRoot, ".polaris", "map");
195
+ const indexPath = (0, node_path_1.join)(mapDir, "index.json");
196
+ if (!(0, node_fs_1.existsSync)(indexPath)) {
197
+ throw new Error("Adoption atlas generation did not produce .polaris/map/index.json");
198
+ }
199
+ const atlasIndex = asRecord(JSON.parse((0, node_fs_1.readFileSync)(indexPath, "utf-8")));
200
+ const entries = asRecord(atlasIndex.entries);
201
+ const hasSmartDocsRawEntry = Object.keys(entries).some((filePath) => filePath.startsWith("smartdocs/raw/"));
202
+ if (!hasSmartDocsRawEntry) {
203
+ throw new Error("Adoption atlas validation failed: no smartdocs/raw/ entries found in atlas");
204
+ }
205
+ const needsReviewPath = (0, node_path_1.join)(mapDir, "needs-review.json");
206
+ const needsReviewEntries = (0, node_fs_1.existsSync)(needsReviewPath)
207
+ ? asRecord(JSON.parse((0, node_fs_1.readFileSync)(needsReviewPath, "utf-8")))
208
+ : {};
209
+ const totalFiles = typeof atlasIndex.file_count === "number"
210
+ ? atlasIndex.file_count
211
+ : Object.keys(entries).length;
212
+ const needsReviewCount = Object.keys(needsReviewEntries).length;
213
+ const needsReviewPct = totalFiles > 0 ? (needsReviewCount / totalFiles) * 100 : 0;
214
+ if (needsReviewPct > 20) {
215
+ process.stdout.write(`[WARN] Adoption atlas needs-review debt is ${needsReviewPct.toFixed(1)}% (${needsReviewCount}/${totalFiles}); continuing.\n`);
216
+ }
217
+ const baselineCoverage = typeof atlasIndex.coverage_pct === "number" ? atlasIndex.coverage_pct : 0;
218
+ (0, node_fs_1.writeFileSync)(indexPath, `${JSON.stringify({
219
+ ...atlasIndex,
220
+ adoption_baseline_coverage_pct: baselineCoverage,
221
+ }, null, 2)}\n`, "utf-8");
222
+ return Promise.resolve();
223
+ }
224
+ catch (error) {
225
+ return Promise.reject(error);
226
+ }
227
+ }
228
+ function updatePlanForFinalization(repoRoot, plan, now) {
229
+ const completedAt = now.toISOString();
230
+ const updatedPlan = {
231
+ ...plan,
232
+ approved: true,
233
+ approved_at: plan.approved_at ?? completedAt,
234
+ steps: plan.steps.map((step) => PLAN_COMPLETE_STATUSES.has(step.status)
235
+ ? step
236
+ : {
237
+ ...step,
238
+ status: "completed",
239
+ completed_at: completedAt,
240
+ error: undefined,
241
+ }),
242
+ };
243
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(repoRoot, ".polaris", "adoption-plan.json"), `${JSON.stringify(updatedPlan, null, 2)}\n`, "utf-8");
244
+ return updatedPlan;
245
+ }
246
+ function stageAdoptionOutputs(repoRoot, plan) {
247
+ const stagePaths = new Set([
248
+ ".polaris/adoption-plan.json",
249
+ ".polaris/adoption-inventory.json",
250
+ ".polaris/adoption-provenance.json",
251
+ "polaris.config.json",
252
+ ".polaris/map",
253
+ "POLARIS.md",
254
+ "SUMMARY.md",
255
+ ".gitignore",
256
+ ]);
257
+ for (const step of plan.steps) {
258
+ if (step.source_path) {
259
+ stagePaths.add(step.source_path);
260
+ }
261
+ if (step.dest_path) {
262
+ stagePaths.add(step.dest_path);
263
+ }
264
+ }
265
+ const existingPaths = [...stagePaths].filter((p) => (0, node_fs_1.existsSync)((0, node_path_1.resolve)(repoRoot, p)));
266
+ if (existingPaths.length > 0) {
267
+ (0, node_child_process_1.execFileSync)("git", ["add", "-A", "--", ...existingPaths], { cwd: repoRoot, stdio: "pipe" });
268
+ }
269
+ }
270
+ function unstageRuntimeArtifacts(repoRoot) {
271
+ const stagedPaths = (0, node_child_process_1.execFileSync)("git", ["diff", "--cached", "--name-only"], {
272
+ cwd: repoRoot,
273
+ encoding: "utf-8",
274
+ })
275
+ .split("\n")
276
+ .map((line) => line.trim())
277
+ .filter(Boolean);
278
+ const blocked = stagedPaths.filter((path) => (0, artifact_policy_js_1.isPathBlockedFromStaging)(path));
279
+ if (blocked.length === 0) {
280
+ return;
281
+ }
282
+ (0, node_child_process_1.execFileSync)("git", ["restore", "--staged", "--", ...blocked], { cwd: repoRoot, stdio: "pipe" });
283
+ }
284
+ function createAdoptionCommitMessage(plan) {
285
+ const moved = plan.impact_summary.smartdocs_candidates_moved;
286
+ const cognition = plan.impact_summary.cognition_files_to_generate;
287
+ return `chore: adopt Polaris init — ${moved} files moved, ${cognition} cognition files generated`;
288
+ }
289
+ function printAdoptionSummary(repoRoot, plan) {
290
+ const baselineCoverage = readBaselineCoverage(repoRoot);
291
+ process.stdout.write(`Adoption summary: moved=${plan.impact_summary.smartdocs_candidates_moved}, cognition=${plan.impact_summary.cognition_files_to_generate}, instruction_files=${plan.impact_summary.instruction_files_affected}, baseline_coverage=${baselineCoverage}\n`);
292
+ }
293
+ function finalizeAdoption(plan, options = {}) {
294
+ if (areAllPlanStepsComplete(plan)) {
295
+ process.stdout.write("Adoption already complete.\n");
296
+ return Promise.resolve();
297
+ }
298
+ const repoRoot = options.repoRoot ?? (0, node_path_1.resolve)(process.cwd());
299
+ ensureRuntimeArtifactExclusions(repoRoot);
300
+ return runAdoptionAtlas(plan, repoRoot).then(() => {
301
+ const updatedPlan = updatePlanForFinalization(repoRoot, plan, options.now ?? new Date());
302
+ stageAdoptionOutputs(repoRoot, updatedPlan);
303
+ unstageRuntimeArtifacts(repoRoot);
304
+ printAdoptionSummary(repoRoot, updatedPlan);
305
+ if (options.commit) {
306
+ const message = options.commitMessage ?? createAdoptionCommitMessage(updatedPlan);
307
+ (0, node_child_process_1.execFileSync)("git", ["commit", "-m", message], { cwd: repoRoot, stdio: "pipe" });
308
+ process.stdout.write(`Adoption commit created: ${message}\n`);
309
+ }
310
+ else {
311
+ process.stdout.write("Adoption changes staged. Review with `git diff --cached` and commit when ready.\n");
312
+ }
313
+ });
314
+ }
315
+ /**
316
+ * Generates (or updates) `polaris.config.json` in the repo root.
317
+ *
318
+ * Compaction provider detection:
319
+ * - Caveman: detected when `.polaris/skills/caveman/SKILL.md` is present (falls back to `.codex/skills/caveman/SKILL.md`).
320
+ * - GitNexus: detected when `gitnexus` is on PATH.
321
+ *
322
+ * The `providers.compactionProviders` field is written only when at least
323
+ * one provider is detected; it is omitted entirely otherwise.
324
+ *
325
+ * Repo-analysis provider detection writes `providers.repoAnalysis.preferred`
326
+ * only when an external provider is detected.
327
+ */
328
+ async function runInit(options = {}) {
329
+ const repoRoot = options.repoRoot ?? (0, node_path_1.resolve)(process.cwd());
330
+ const configPath = (0, node_path_1.join)(repoRoot, "polaris.config.json");
331
+ const detectCompaction = options.detectProviders ?? provider_detect_js_1.detectCompactionProviders;
332
+ const detectRepoAnalysis = options.detectRepoAnalysisProviders ?? provider_detect_js_1.detectRepoAnalysisProviders;
333
+ const repoState = (options.detectRepoState ?? init_detect_js_1.detectRepoState)(repoRoot);
334
+ if (options.status) {
335
+ process.stdout.write(`Repository state: ${repoState}\n`);
336
+ return;
337
+ }
338
+ if (!options.adopt && repoState === "existing") {
339
+ process.stdout.write("This repo has existing content. Run `polaris init --adopt` to begin adoption.\nThis repo has existing content. Run polaris init --adopt to begin adoption.\n");
340
+ return;
341
+ }
342
+ // Load existing config (if any) so we preserve user-authored fields.
343
+ let existing = {};
344
+ if ((0, node_fs_1.existsSync)(configPath)) {
345
+ try {
346
+ existing = JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf-8"));
347
+ }
348
+ catch {
349
+ // Malformed JSON — start fresh rather than aborting.
350
+ existing = {};
351
+ }
352
+ }
353
+ const detected = detectCompaction(repoRoot);
354
+ const detectedRepoAnalysis = detectRepoAnalysis(repoRoot);
355
+ const updated = buildInitConfig(existing, detected, detectedRepoAnalysis, Boolean(options.adopt));
356
+ if (options.dryRun && !options.adopt) {
357
+ process.stdout.write(`${JSON.stringify(updated, null, 2)}\n`);
358
+ return;
359
+ }
360
+ if (options.adopt) {
361
+ if (!options.dryRun) {
362
+ writeAdoptionConfigLock(repoRoot, configPath, existing, detected, detectedRepoAnalysis);
363
+ }
364
+ }
365
+ else {
366
+ (0, node_fs_1.writeFileSync)(configPath, `${JSON.stringify(updated, null, 2)}\n`, "utf-8");
367
+ const providerSummary = detected.length > 0
368
+ ? `Detected providers: ${detected.join(", ")}`
369
+ : "No compaction providers detected";
370
+ process.stdout.write(`polaris.config.json written to ${configPath}\n${providerSummary}\n`);
371
+ }
372
+ if (!options.adopt) {
373
+ return;
374
+ }
375
+ const adoptionPlanPath = (0, node_path_1.join)(repoRoot, ".polaris", "adoption-plan.json");
376
+ if ((0, node_fs_1.existsSync)(adoptionPlanPath)) {
377
+ try {
378
+ const existingPlan = JSON.parse((0, node_fs_1.readFileSync)(adoptionPlanPath, "utf-8"));
379
+ if (areAllPlanStepsComplete(existingPlan)) {
380
+ process.stdout.write("Adoption already complete.\n");
381
+ return;
382
+ }
383
+ }
384
+ catch {
385
+ // Fall through and regenerate adoption artifacts.
386
+ }
387
+ }
388
+ const now = options.now ?? new Date();
389
+ const scanAdoptionInventory = options.scanAdoptionInventory ??
390
+ ((root) => (0, adopt_scan_js_1.scanRepo)(root, { now, rescan: options.rescan }));
391
+ const inventoryResult = scanAdoptionInventory(repoRoot);
392
+ let inventory;
393
+ if (inventoryResult && typeof inventoryResult.then === "function") {
394
+ inventory = await inventoryResult;
395
+ }
396
+ else {
397
+ inventory = inventoryResult;
398
+ }
399
+ const loadedArtifacts = options.resume ? loadAdoptionPlanArtifacts(repoRoot) : null;
400
+ const adoptionArtifacts = loadedArtifacts ?? (options.generateAdoptionArtifacts ?? adoption_plan_js_1.generateAdoptionPlanArtifacts)(repoRoot, inventory, { dryRun: options.dryRun, now });
401
+ if (options.dryRun) {
402
+ process.stdout.write(`${adoptionArtifacts.markdown}\n`);
403
+ process.stdout.write("Adoption dry run: Phase C writes skipped.\n");
404
+ return;
405
+ }
406
+ let approved = false;
407
+ if (options.yes) {
408
+ process.stdout.write(`${adoptionArtifacts.markdown}\n`);
409
+ (0, adopt_approve_js_1.persistApprovedAdoptionPlan)(adoptionArtifacts.plan, repoRoot, now);
410
+ (0, adopt_approve_js_1.logAdoptionApprovalTelemetry)(repoRoot, {
411
+ event: "adoption-approval-bypassed",
412
+ run_mode: "yes",
413
+ plan_id: adoptionArtifacts.plan.plan_id,
414
+ timestamp: now.toISOString(),
415
+ });
416
+ process.stdout.write("Adoption approval bypassed via --yes.\n");
417
+ approved = true;
418
+ }
419
+ else if (options.resume && adoptionArtifacts.plan.approved) {
420
+ process.stdout.write(`${adoptionArtifacts.markdown}\n`);
421
+ if (!adoptionArtifacts.plan.approved_at) {
422
+ (0, adopt_approve_js_1.persistApprovedAdoptionPlan)(adoptionArtifacts.plan, repoRoot, now);
423
+ }
424
+ approved = true;
425
+ }
426
+ else if (options.readAdoptionApproval) {
427
+ process.stdout.write(`${adoptionArtifacts.markdown}\n`);
428
+ approved = options.readAdoptionApproval();
429
+ if (approved) {
430
+ (0, adopt_approve_js_1.persistApprovedAdoptionPlan)(adoptionArtifacts.plan, repoRoot, now);
431
+ }
432
+ else {
433
+ process.stdout.write("Adoption aborted: explicit approval required.\n");
434
+ return;
435
+ }
436
+ }
437
+ else {
438
+ approved = await (0, adopt_approve_js_1.promptApproval)(adoptionArtifacts.plan, { repoRoot, now });
439
+ if (!approved) {
440
+ return;
441
+ }
442
+ }
443
+ const smartDocsMigrationSteps = adoptionArtifacts.plan.steps.filter((step) => step.category === "smartdocs-migrate");
444
+ if (smartDocsMigrationSteps.length > 0) {
445
+ (0, adopt_smartdocs_js_1.migrateSmartDocs)(adoptionArtifacts.plan, repoRoot);
446
+ const moved = adoptionArtifacts.plan.steps.filter((step) => step.category === "smartdocs-migrate" && step.status === "completed").length;
447
+ const skipped = adoptionArtifacts.plan.steps.filter((step) => step.category === "smartdocs-migrate" && step.status === "skipped").length;
448
+ process.stdout.write(`SmartDocs migration step completed: moved ${moved}, skipped ${skipped}.\n`);
449
+ }
450
+ else {
451
+ const migrationResult = (options.applySmartDocsMigration ?? applySmartDocsMigration)(repoRoot, inventory);
452
+ process.stdout.write(`SmartDocs migration step completed: moved ${migrationResult.moved}, skipped ${migrationResult.skipped}.\n`);
453
+ }
454
+ void (options.generateFolderCognition ?? adopt_cognition_js_1.generateFolderCognition)(adoptionArtifacts.plan, inventory);
455
+ process.stdout.write("Folder cognition generation step completed.\n");
456
+ (0, adopt_instructions_js_1.handleInstructionFiles)(adoptionArtifacts.plan, inventory);
457
+ process.stdout.write("Instruction file handling step completed.\n");
458
+ if (adoptionArtifacts.plan.steps.some((step) => step.category === "stage")) {
459
+ finalizeAdoption(adoptionArtifacts.plan, {
460
+ repoRoot,
461
+ commit: options.commit,
462
+ now,
463
+ });
464
+ return;
465
+ }
466
+ process.stdout.write("Adoption approved. Proceeding with mutation phases.\n");
467
+ }
468
+ /**
469
+ * Registers the `init` subcommand on a Commander program.
470
+ */
471
+ function createInitCommand(options = {}) {
472
+ const cmd = new commander_1.Command("init")
473
+ .description("initialise polaris.config.json and detect compaction providers")
474
+ .option("--dry-run", "print generated config to stdout without writing")
475
+ .option("--status", "detect and print current repository state without writing files")
476
+ .option("--adopt", "run existing repository adoption flow")
477
+ .option("--resume", "resume an approved adoption plan without prompting")
478
+ .option("--yes", "auto-approve adoption plan when used with --adopt")
479
+ .option("--commit", "create an adoption commit when used with --adopt")
480
+ .action(async (cmdOptions) => {
481
+ await runInit({
482
+ ...options,
483
+ dryRun: cmdOptions.dryRun,
484
+ status: cmdOptions.status,
485
+ adopt: cmdOptions.adopt,
486
+ resume: cmdOptions.resume,
487
+ yes: cmdOptions.yes,
488
+ commit: cmdOptions.commit,
489
+ });
490
+ });
491
+ return cmd;
492
+ }