@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.
- package/README.md +87 -0
- package/dist/__mocks__/tool-server-linear.js +34 -0
- package/dist/cli/adopt-approve.js +60 -0
- package/dist/cli/adopt-cognition.js +199 -0
- package/dist/cli/adopt-instructions.js +143 -0
- package/dist/cli/adopt-rules.js +169 -0
- package/dist/cli/adopt-scan.js +25 -0
- package/dist/cli/adopt-smartdocs.js +192 -0
- package/dist/cli/adoption-inventory.js +350 -0
- package/dist/cli/adoption-plan.js +222 -0
- package/dist/cli/args.js +28 -0
- package/dist/cli/args.test.js +30 -0
- package/dist/cli/branding.js +41 -0
- package/dist/cli/graph.js +358 -0
- package/dist/cli/index.js +127 -0
- package/dist/cli/index.test.js +162 -0
- package/dist/cli/init-detect.js +61 -0
- package/dist/cli/init.js +492 -0
- package/dist/cli/init.test.js +259 -0
- package/dist/cli/librarian.js +32 -0
- package/dist/cli/medic.js +96 -0
- package/dist/cli/startup.test.js +23 -0
- package/dist/cli/tracker.js +130 -0
- package/dist/cli/tracker.test.js +126 -0
- package/dist/cli/version.js +10 -0
- package/dist/cli/version.test.js +11 -0
- package/dist/cli/worker.js +287 -0
- package/dist/cluster-state/fixtures/test-clusters.json +19 -0
- package/dist/cluster-state/store.js +302 -0
- package/dist/cluster-state/store.test.js +145 -0
- package/dist/cluster-state/types.js +2 -0
- package/dist/cognition/archive.js +158 -0
- package/dist/cognition/closeout-librarian-types.js +161 -0
- package/dist/cognition/cognition.test.js +623 -0
- package/dist/cognition/index.js +41 -0
- package/dist/cognition/librarian-dispatch.js +391 -0
- package/dist/cognition/librarian-dispatch.test.js +247 -0
- package/dist/cognition/librarian-packet.js +313 -0
- package/dist/cognition/librarian-types.js +57 -0
- package/dist/cognition/route-cognition-delta.js +350 -0
- package/dist/cognition/summary-delta.js +279 -0
- package/dist/cognition/validate.js +162 -0
- package/dist/config/defaults.js +98 -0
- package/dist/config/doctor.js +273 -0
- package/dist/config/index.js +14 -0
- package/dist/config/loader.js +58 -0
- package/dist/config/provider-detect.js +60 -0
- package/dist/config/provider-detect.test.js +119 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/show.js +44 -0
- package/dist/config/show.test.js +42 -0
- package/dist/config/validator.js +675 -0
- package/dist/config/validator.test.js +77 -0
- package/dist/docs/canon-check.js +334 -0
- package/dist/docs/canon-check.test.js +207 -0
- package/dist/docs/doctrine.js +133 -0
- package/dist/docs/doctrine.test.js +139 -0
- package/dist/docs/index.js +168 -0
- package/dist/docs/index.test.js +83 -0
- package/dist/docs/ingest.js +295 -0
- package/dist/docs/ingest.test.js +71 -0
- package/dist/docs/migrate.js +165 -0
- package/dist/docs/migrate.test.js +136 -0
- package/dist/docs/seed-instructions.js +147 -0
- package/dist/docs/seed-instructions.test.js +137 -0
- package/dist/docs/validate-instructions.js +267 -0
- package/dist/docs/validate-instructions.test.js +238 -0
- package/dist/finalize/artifact-policy.js +214 -0
- package/dist/finalize/artifact-policy.test.js +84 -0
- package/dist/finalize/delivery-integrity.js +141 -0
- package/dist/finalize/finalize.test.js +210 -0
- package/dist/finalize/github.js +41 -0
- package/dist/finalize/index.js +474 -0
- package/dist/finalize/linear.js +213 -0
- package/dist/finalize/run-report.js +47 -0
- package/dist/finalize/steps/01-map-update.js +11 -0
- package/dist/finalize/steps/02-map-validate.js +11 -0
- package/dist/finalize/steps/03-schema-validate.js +11 -0
- package/dist/finalize/steps/04-run-checks.js +118 -0
- package/dist/finalize/steps/05-generate-report.js +14 -0
- package/dist/finalize/steps/06-commit.js +39 -0
- package/dist/finalize/steps/07-push.js +10 -0
- package/dist/finalize/steps/08-create-pr.js +9 -0
- package/dist/finalize/steps/09-update-state.js +9 -0
- package/dist/finalize/steps/10-append-jsonl.js +23 -0
- package/dist/finalize/steps/11-update-linear.js +22 -0
- package/dist/finalize/steps/12-archive.js +21 -0
- package/dist/graph/adapter/c/adapter.js +45 -0
- package/dist/graph/adapter/c/extract.js +135 -0
- package/dist/graph/adapter/c/index.js +10 -0
- package/dist/graph/adapter/c/runtime.js +67 -0
- package/dist/graph/adapter/cpp/adapter.js +45 -0
- package/dist/graph/adapter/cpp/extract.js +159 -0
- package/dist/graph/adapter/cpp/index.js +10 -0
- package/dist/graph/adapter/cpp/runtime.js +61 -0
- package/dist/graph/adapter/csharp/adapter.js +45 -0
- package/dist/graph/adapter/csharp/extract.js +127 -0
- package/dist/graph/adapter/csharp/index.js +10 -0
- package/dist/graph/adapter/csharp/runtime.js +61 -0
- package/dist/graph/adapter/dart/adapter.js +56 -0
- package/dist/graph/adapter/dart/extract.js +130 -0
- package/dist/graph/adapter/dart/index.js +10 -0
- package/dist/graph/adapter/dart/runtime.js +61 -0
- package/dist/graph/adapter/go/adapter.js +45 -0
- package/dist/graph/adapter/go/extract.js +112 -0
- package/dist/graph/adapter/go/index.js +10 -0
- package/dist/graph/adapter/go/runtime.js +58 -0
- package/dist/graph/adapter/kotlin-java/extract-common.js +83 -0
- package/dist/graph/adapter/kotlin-java/index.js +15 -0
- package/dist/graph/adapter/kotlin-java/java-adapter.js +45 -0
- package/dist/graph/adapter/kotlin-java/java-extract.js +42 -0
- package/dist/graph/adapter/kotlin-java/kotlin-adapter.js +48 -0
- package/dist/graph/adapter/kotlin-java/kotlin-extract.js +58 -0
- package/dist/graph/adapter/kotlin-java/runtime.js +75 -0
- package/dist/graph/adapter/python/adapter.js +45 -0
- package/dist/graph/adapter/python/extract.js +121 -0
- package/dist/graph/adapter/python/index.js +10 -0
- package/dist/graph/adapter/python/runtime.js +70 -0
- package/dist/graph/adapter/registry.js +82 -0
- package/dist/graph/adapter/rust/adapter.js +45 -0
- package/dist/graph/adapter/rust/extract.js +110 -0
- package/dist/graph/adapter/rust/index.js +10 -0
- package/dist/graph/adapter/rust/runtime.js +74 -0
- package/dist/graph/adapter/shell/adapter.js +34 -0
- package/dist/graph/adapter/shell/extract.js +98 -0
- package/dist/graph/adapter/shell/index.js +8 -0
- package/dist/graph/adapter/svelte/adapter.js +91 -0
- package/dist/graph/adapter/svelte/extract.js +41 -0
- package/dist/graph/adapter/svelte/index.js +8 -0
- package/dist/graph/adapter/swift/adapter.js +45 -0
- package/dist/graph/adapter/swift/extract.js +120 -0
- package/dist/graph/adapter/swift/index.js +10 -0
- package/dist/graph/adapter/swift/runtime.js +70 -0
- package/dist/graph/adapter/types.js +2 -0
- package/dist/graph/adapter/typescript-javascript/adapter.js +72 -0
- package/dist/graph/adapter/typescript-javascript/extract.js +115 -0
- package/dist/graph/adapter/typescript-javascript/index.js +10 -0
- package/dist/graph/adapter/typescript-javascript/runtime.js +97 -0
- package/dist/graph/capability/index.js +105 -0
- package/dist/graph/governance.js +104 -0
- package/dist/graph/parser/extract.js +5 -0
- package/dist/graph/parser/loader.js +2 -0
- package/dist/graph/parser/pipeline.js +194 -0
- package/dist/graph/query/index.js +277 -0
- package/dist/graph/query/types.js +5 -0
- package/dist/graph/resolver/build-edges.js +211 -0
- package/dist/graph/resolver/index.js +23 -0
- package/dist/graph/resolver/resolve-imports.js +168 -0
- package/dist/graph/store/adapter.js +132 -0
- package/dist/graph/store/queries.js +124 -0
- package/dist/graph/store/types.js +4 -0
- package/dist/ignore/defaults.js +41 -0
- package/dist/ignore/parser.js +39 -0
- package/dist/lint/map-reference-validator.js +72 -0
- package/dist/loop/abort.js +188 -0
- package/dist/loop/abort.test.js +151 -0
- package/dist/loop/adapters/__tests__/terminal-cli.test.js +92 -0
- package/dist/loop/adapters/agent-subtask.js +137 -0
- package/dist/loop/adapters/agent-subtask.test.js +151 -0
- package/dist/loop/adapters/cli-subtask-bridge.js +108 -0
- package/dist/loop/adapters/index.js +9 -0
- package/dist/loop/adapters/registry.js +17 -0
- package/dist/loop/adapters/terminal-cli.js +403 -0
- package/dist/loop/adapters/types.js +2 -0
- package/dist/loop/adapters/worker-instructions.js +85 -0
- package/dist/loop/body-parser.js +226 -0
- package/dist/loop/bootstrap-packet.js +97 -0
- package/dist/loop/bootstrap-packet.test.js +171 -0
- package/dist/loop/branch-governance.js +54 -0
- package/dist/loop/budget.js +63 -0
- package/dist/loop/budget.test.js +163 -0
- package/dist/loop/checkpoint.js +325 -0
- package/dist/loop/compact-return.js +59 -0
- package/dist/loop/continue.js +645 -0
- package/dist/loop/continue.test.js +337 -0
- package/dist/loop/dispatch-boundary.js +335 -0
- package/dist/loop/dispatch-state.js +223 -0
- package/dist/loop/dispatch-state.test.js +186 -0
- package/dist/loop/dispatch.js +1236 -0
- package/dist/loop/dispatch.test.js +499 -0
- package/dist/loop/ephemeral-smoke.test.js +160 -0
- package/dist/loop/evidence-backfill.js +216 -0
- package/dist/loop/execution-adapter.js +141 -0
- package/dist/loop/execution-adapter.test.js +66 -0
- package/dist/loop/finalize-evidence.js +169 -0
- package/dist/loop/git-custody.js +250 -0
- package/dist/loop/impl-packet-input.js +38 -0
- package/dist/loop/index.js +270 -0
- package/dist/loop/ledger.js +49 -0
- package/dist/loop/ledger.test.js +127 -0
- package/dist/loop/lifecycle-dispatch.js +348 -0
- package/dist/loop/lifecycle-dispatch.test.js +318 -0
- package/dist/loop/lifecycle.js +93 -0
- package/dist/loop/lifecycle.test.js +150 -0
- package/dist/loop/orphan-recovery.js +276 -0
- package/dist/loop/orphan-recovery.test.js +236 -0
- package/dist/loop/parent.js +1566 -0
- package/dist/loop/parent.test.js +738 -0
- package/dist/loop/provider-sealed-packet.test.js +164 -0
- package/dist/loop/resume.js +295 -0
- package/dist/loop/resume.test.js +172 -0
- package/dist/loop/run-bootstrap.js +234 -0
- package/dist/loop/run-preflight.js +203 -0
- package/dist/loop/status.js +665 -0
- package/dist/loop/status.test.js +235 -0
- package/dist/loop/wait.js +86 -0
- package/dist/loop/worker-packet.js +406 -0
- package/dist/loop/worker-packet.test.js +243 -0
- package/dist/loop/worker-prompt.js +260 -0
- package/dist/loop/worker-prompt.test.js +247 -0
- package/dist/loop/worker.js +498 -0
- package/dist/loop/worker.test.js +372 -0
- package/dist/map/atlas.js +77 -0
- package/dist/map/backfill.js +171 -0
- package/dist/map/backfill.test.js +120 -0
- package/dist/map/index.js +255 -0
- package/dist/map/inference.js +73 -0
- package/dist/map/inference.test.js +35 -0
- package/dist/map/query.js +157 -0
- package/dist/map/query.test.js +174 -0
- package/dist/map/update.js +355 -0
- package/dist/map/update.test.js +67 -0
- package/dist/map/validate.js +153 -0
- package/dist/map/validate.test.js +90 -0
- package/dist/map/welfare.js +86 -0
- package/dist/mcp/lib/invoke.js +35 -0
- package/dist/mcp/lib/redact.js +24 -0
- package/dist/mcp/lib/redact.test.js +112 -0
- package/dist/mcp/lib/root.js +41 -0
- package/dist/mcp/lib/root.test.js +114 -0
- package/dist/mcp/server.js +15 -0
- package/dist/mcp/tools/claim-child.js +119 -0
- package/dist/mcp/tools/claim-child.test.js +69 -0
- package/dist/mcp/tools/current-state.js +73 -0
- package/dist/mcp/tools/current-state.test.js +114 -0
- package/dist/mcp/tools/dispatch-result.js +186 -0
- package/dist/mcp/tools/dispatch-result.test.js +109 -0
- package/dist/mcp/tools/index.js +222 -0
- package/dist/mcp/tools/index.test.js +172 -0
- package/dist/mcp/tools/linear.js +74 -0
- package/dist/mcp/tools/loop-continue.js +159 -0
- package/dist/mcp/tools/loop-continue.test.js +186 -0
- package/dist/mcp/tools/loop-dry-run.js +15 -0
- package/dist/mcp/tools/status.js +65 -0
- package/dist/medic/chart-id.js +75 -0
- package/dist/medic/chart-schema.js +139 -0
- package/dist/runs/index.js +119 -0
- package/dist/runs/index.test.js +184 -0
- package/dist/runs/ledger-tail.js +15 -0
- package/dist/runs/list.js +29 -0
- package/dist/runs/reconcile.js +74 -0
- package/dist/runs/show.js +10 -0
- package/dist/runtime/audit/logger.js +15 -0
- package/dist/runtime/audit/reader.js +42 -0
- package/dist/runtime/checkpoint.js +89 -0
- package/dist/runtime/continuation/confirmed.js +225 -0
- package/dist/runtime/continuation/confirmed.test.js +421 -0
- package/dist/runtime/continuation/dry-run.js +74 -0
- package/dist/runtime/execution-window.js +106 -0
- package/dist/runtime/scheduling/child-selector.js +16 -0
- package/dist/runtime/state.js +43 -0
- package/dist/runtime/status.js +46 -0
- package/dist/runtime/verification/envelope.js +80 -0
- package/dist/runtime/verification/fingerprint.js +26 -0
- package/dist/skill-packet/cli.test.js +105 -0
- package/dist/skill-packet/generator.js +225 -0
- package/dist/skill-packet/generator.test.js +159 -0
- package/dist/skill-packet/index.js +49 -0
- package/dist/skill-packet/types.js +2 -0
- package/dist/smartdocs-engine/audit.js +194 -0
- package/dist/smartdocs-engine/audit.test.js +122 -0
- package/dist/smartdocs-engine/canon-check.js +340 -0
- package/dist/smartdocs-engine/canon-check.test.js +234 -0
- package/dist/smartdocs-engine/doctrine.js +633 -0
- package/dist/smartdocs-engine/doctrine.test.js +374 -0
- package/dist/smartdocs-engine/index.js +456 -0
- package/dist/smartdocs-engine/index.test.js +82 -0
- package/dist/smartdocs-engine/ingest.js +495 -0
- package/dist/smartdocs-engine/ingest.test.js +163 -0
- package/dist/smartdocs-engine/migrate.js +217 -0
- package/dist/smartdocs-engine/migrate.test.js +200 -0
- package/dist/smartdocs-engine/seed-instructions.js +335 -0
- package/dist/smartdocs-engine/seed-instructions.test.js +275 -0
- package/dist/smartdocs-engine/smartdoc-ignore.js +258 -0
- package/dist/smartdocs-engine/smartdoc-ignore.test.js +146 -0
- package/dist/smartdocs-engine/validate-instructions.js +366 -0
- package/dist/smartdocs-engine/validate-instructions.test.js +283 -0
- package/dist/tracker/adapters/github/index.js +305 -0
- package/dist/tracker/adapters/jira/index.js +293 -0
- package/dist/tracker/adapters/linear/http-errors.test.js +51 -0
- package/dist/tracker/adapters/linear/index.js +621 -0
- package/dist/tracker/adapters/linear/index.test.js +238 -0
- package/dist/tracker/adapters/linear.js +50 -0
- package/dist/tracker/adapters/local/index.js +10 -0
- package/dist/tracker/adapters/local-file/index.js +159 -0
- package/dist/tracker/adapters/mcp-bridge.js +158 -0
- package/dist/tracker/adapters/mcp-bridge.test.js +12 -0
- package/dist/tracker/adapters/spec/index.js +146 -0
- package/dist/tracker/capabilities.js +2 -0
- package/dist/tracker/index.js +49 -0
- package/dist/tracker/lifecycle-policy.js +139 -0
- package/dist/tracker/lifecycle-transition.js +164 -0
- package/dist/tracker/local-graph.js +98 -0
- package/dist/tracker/migration.js +56 -0
- package/dist/tracker/schema.js +86 -0
- package/dist/tracker/sync/index.js +404 -0
- package/dist/tracker/sync/queue-store.js +95 -0
- package/dist/tracker/sync/queue-store.test.js +104 -0
- package/dist/tracker/types.js +11 -0
- package/dist/types/linear.js +3 -0
- package/dist/types/result-packet.js +12 -0
- package/dist/types/runtime-state.js +2 -0
- package/dist/types/work-contract.js +2 -0
- package/dist/utils/monotonic-timestamp.js +13 -0
- package/dist/utils/monotonic-timestamp.test.js +19 -0
- package/package.json +64 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cognition surface validation.
|
|
4
|
+
*
|
|
5
|
+
* Validates SUMMARY.md and POLARIS.md files for:
|
|
6
|
+
* - Oversized SUMMARY.md (exceeds byte cap)
|
|
7
|
+
* - Doctrine bleed in SUMMARY.md (operational imperatives belong in POLARIS.md)
|
|
8
|
+
* - POLARIS.md churn detection (trivial/non-operational changes)
|
|
9
|
+
* - Locality assumptions (route-local only, no repo-wide surface)
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.looksLikePolarisChurn = looksLikePolarisChurn;
|
|
13
|
+
exports.validateCognitionSurfaces = validateCognitionSurfaces;
|
|
14
|
+
exports.validateSummaryFile = validateSummaryFile;
|
|
15
|
+
exports.getSummaryFileSize = getSummaryFileSize;
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
18
|
+
const route_cognition_delta_js_1 = require("./route-cognition-delta.js");
|
|
19
|
+
const summary_delta_js_1 = require("./summary-delta.js");
|
|
20
|
+
// ── POLARIS.md churn detection ────────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* Signals that indicate a POLARIS.md change is likely non-operational churn
|
|
23
|
+
* (formatting, comments, tiny refactors).
|
|
24
|
+
* Returns true when the diff looks like churn.
|
|
25
|
+
*/
|
|
26
|
+
function looksLikePolarisChurn(before, after) {
|
|
27
|
+
// Normalize whitespace and comments for comparison
|
|
28
|
+
const normalize = (s) => s
|
|
29
|
+
.split("\n")
|
|
30
|
+
.map((l) => l.trimEnd())
|
|
31
|
+
.filter((l) => !l.startsWith("<!--") && l !== "")
|
|
32
|
+
.join("\n");
|
|
33
|
+
const a = normalize(before);
|
|
34
|
+
const b = normalize(after);
|
|
35
|
+
// If normalized content is identical, it's churn
|
|
36
|
+
if (a === b)
|
|
37
|
+
return true;
|
|
38
|
+
// If only whitespace/blank-line diff
|
|
39
|
+
if (before.replace(/\s+/g, " ").trim() === after.replace(/\s+/g, " ").trim())
|
|
40
|
+
return true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
// ── Walker ────────────────────────────────────────────────────────────────────
|
|
44
|
+
function* walkForCognitionFiles(dir, repoRoot) {
|
|
45
|
+
let entries;
|
|
46
|
+
try {
|
|
47
|
+
entries = (0, node_fs_1.readdirSync)(dir, { withFileTypes: true });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const full = (0, node_path_1.join)(dir, entry.name);
|
|
54
|
+
const rel = (0, node_path_1.relative)(repoRoot, full).replace(/\\/g, "/");
|
|
55
|
+
if (entry.isDirectory()) {
|
|
56
|
+
if ((0, route_cognition_delta_js_1.isCognitionSkippedFolder)(rel + "/") || (0, route_cognition_delta_js_1.isCognitionSkippedFolder)(rel))
|
|
57
|
+
continue;
|
|
58
|
+
yield* walkForCognitionFiles(full, repoRoot);
|
|
59
|
+
}
|
|
60
|
+
else if (entry.name === "SUMMARY.md" || entry.name === "POLARIS.md") {
|
|
61
|
+
yield { rel, name: entry.name };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ── Main validation entry point ───────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Validate all route-local cognition surfaces under repoRoot.
|
|
68
|
+
*
|
|
69
|
+
* Checks:
|
|
70
|
+
* 1. SUMMARY.md size guard (≤ SUMMARY_MAX_BYTES)
|
|
71
|
+
* 2. SUMMARY.md doctrine bleed
|
|
72
|
+
* 3. Locality: POLARIS.md at root is not flagged (root is special)
|
|
73
|
+
*/
|
|
74
|
+
function validateCognitionSurfaces(repoRoot) {
|
|
75
|
+
const violations = [];
|
|
76
|
+
const warnings = [];
|
|
77
|
+
for (const { rel, name } of walkForCognitionFiles((0, node_path_1.resolve)(repoRoot), repoRoot)) {
|
|
78
|
+
// Skip root-level files — root cognition is special (AGENTS.md / CLAUDE.md)
|
|
79
|
+
if (!rel.includes("/"))
|
|
80
|
+
continue;
|
|
81
|
+
let content;
|
|
82
|
+
try {
|
|
83
|
+
content = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(repoRoot, rel), "utf-8");
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (name === "SUMMARY.md") {
|
|
89
|
+
if ((0, summary_delta_js_1.isSummaryOversized)(content)) {
|
|
90
|
+
const bytes = Buffer.byteLength(content, "utf-8");
|
|
91
|
+
violations.push({
|
|
92
|
+
type: "summary-oversized",
|
|
93
|
+
file: rel,
|
|
94
|
+
detail: `SUMMARY.md is ${bytes} bytes, exceeds limit of ${summary_delta_js_1.SUMMARY_MAX_BYTES} bytes`,
|
|
95
|
+
severity: "error",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if ((0, summary_delta_js_1.hasDoctrineBled)(content)) {
|
|
99
|
+
// Doctrine bleed is WARN-only — never a hard blocker.
|
|
100
|
+
// Summaries may contain "do not" in quoted context.
|
|
101
|
+
warnings.push({
|
|
102
|
+
type: "summary-doctrine-bleed",
|
|
103
|
+
file: rel,
|
|
104
|
+
detail: "SUMMARY.md may contain operational doctrine (section headings or imperatives); consider moving to POLARIS.md",
|
|
105
|
+
severity: "warn",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
valid: violations.length === 0,
|
|
112
|
+
violations,
|
|
113
|
+
warnings,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// ── Targeted file validation ──────────────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* Validate a single SUMMARY.md file by path (absolute or relative to repoRoot).
|
|
119
|
+
*/
|
|
120
|
+
function validateSummaryFile(summaryPath, repoRoot) {
|
|
121
|
+
const abs = summaryPath.startsWith("/") ? summaryPath : (0, node_path_1.resolve)(repoRoot, summaryPath);
|
|
122
|
+
const rel = (0, node_path_1.relative)(repoRoot, abs).replace(/\\/g, "/");
|
|
123
|
+
const results = [];
|
|
124
|
+
let content;
|
|
125
|
+
try {
|
|
126
|
+
content = (0, node_fs_1.readFileSync)(abs, "utf-8");
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
if ((0, summary_delta_js_1.isSummaryOversized)(content)) {
|
|
132
|
+
const bytes = Buffer.byteLength(content, "utf-8");
|
|
133
|
+
results.push({
|
|
134
|
+
type: "summary-oversized",
|
|
135
|
+
file: rel,
|
|
136
|
+
detail: `SUMMARY.md is ${bytes} bytes, exceeds limit of ${summary_delta_js_1.SUMMARY_MAX_BYTES} bytes`,
|
|
137
|
+
severity: "error",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if ((0, summary_delta_js_1.hasDoctrineBled)(content)) {
|
|
141
|
+
// Warn-only — see hasDoctrineBled() docstring.
|
|
142
|
+
results.push({
|
|
143
|
+
type: "summary-doctrine-bleed",
|
|
144
|
+
file: rel,
|
|
145
|
+
detail: "SUMMARY.md may contain operational doctrine; consider moving to POLARIS.md",
|
|
146
|
+
severity: "warn",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return results;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check file size on disk for a SUMMARY.md without reading full content.
|
|
153
|
+
*/
|
|
154
|
+
function getSummaryFileSize(summaryPath, repoRoot) {
|
|
155
|
+
const abs = (0, node_fs_1.existsSync)(summaryPath) ? summaryPath : (0, node_path_1.resolve)(repoRoot, summaryPath);
|
|
156
|
+
try {
|
|
157
|
+
return (0, node_fs_1.statSync)(abs).size;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CONFIG = void 0;
|
|
4
|
+
exports.DEFAULT_CONFIG = {
|
|
5
|
+
version: "1.0",
|
|
6
|
+
repo: {
|
|
7
|
+
name: "",
|
|
8
|
+
sourceRoots: ["src"],
|
|
9
|
+
docsRoots: [],
|
|
10
|
+
taskchainRoots: [],
|
|
11
|
+
generatedRoots: [],
|
|
12
|
+
sidecarOutputPath: ".polaris/map",
|
|
13
|
+
},
|
|
14
|
+
map: {
|
|
15
|
+
confidenceThreshold: 0.75,
|
|
16
|
+
autoWriteAbove: 0.85,
|
|
17
|
+
reviewRequiredBelow: 0.75,
|
|
18
|
+
inferenceRules: [],
|
|
19
|
+
onLowConfidence: "warn",
|
|
20
|
+
},
|
|
21
|
+
loop: {
|
|
22
|
+
bootstrapOutputPath: ".polaris/bootstrap",
|
|
23
|
+
analyzeImplBoundaryEnforced: true,
|
|
24
|
+
sessionTerminationMode: "emit-marker",
|
|
25
|
+
allowBranchDivergence: false,
|
|
26
|
+
},
|
|
27
|
+
graph: {
|
|
28
|
+
outputPath: ".polaris/graph",
|
|
29
|
+
invalidationTriggers: ["repo-change", "config-change"],
|
|
30
|
+
},
|
|
31
|
+
orchestration: {
|
|
32
|
+
mode: "supervised",
|
|
33
|
+
auto_finalize: false,
|
|
34
|
+
notification_format: "terse",
|
|
35
|
+
},
|
|
36
|
+
execution: {
|
|
37
|
+
adapter: "terminal-cli",
|
|
38
|
+
providers: {},
|
|
39
|
+
rotation: [],
|
|
40
|
+
allowCrossAgentFallback: false,
|
|
41
|
+
roles: {},
|
|
42
|
+
},
|
|
43
|
+
finalize: {
|
|
44
|
+
targetBranch: "main",
|
|
45
|
+
prDraft: true,
|
|
46
|
+
runChecks: [],
|
|
47
|
+
requireMapValidation: true,
|
|
48
|
+
requireSchemaValidation: true,
|
|
49
|
+
archiveRunSnapshot: true,
|
|
50
|
+
},
|
|
51
|
+
tracker: {
|
|
52
|
+
lifecyclePolicy: {
|
|
53
|
+
childOnDispatch: "in_progress",
|
|
54
|
+
childOnValidationPassed: "in_review",
|
|
55
|
+
childOnMerged: "done",
|
|
56
|
+
parentOnAllChildrenComplete: "in_review",
|
|
57
|
+
parentOnDeliveryMerged: "done",
|
|
58
|
+
childOnTriageRequired: "blocked",
|
|
59
|
+
providerFailureBeforeWork: "no_status_change",
|
|
60
|
+
},
|
|
61
|
+
linear: {
|
|
62
|
+
enabled: false,
|
|
63
|
+
teamId: "",
|
|
64
|
+
projectId: "",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
integrations: {
|
|
68
|
+
github: {
|
|
69
|
+
owner: "",
|
|
70
|
+
repo: "",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
canon: {
|
|
74
|
+
checkOnContinue: true,
|
|
75
|
+
checkOnFinalize: true,
|
|
76
|
+
},
|
|
77
|
+
providers: {
|
|
78
|
+
repoAnalysis: {
|
|
79
|
+
preferred: undefined,
|
|
80
|
+
fallback: ["polaris-map", "ripgrep"],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
budget: {
|
|
84
|
+
mode: "fixed-cap",
|
|
85
|
+
max_children: 6,
|
|
86
|
+
stop_on_fail: false,
|
|
87
|
+
allow_analyze_children: false,
|
|
88
|
+
},
|
|
89
|
+
compact: {
|
|
90
|
+
orchestratorMode: "standard",
|
|
91
|
+
workerMode: "standard",
|
|
92
|
+
},
|
|
93
|
+
skill_packet: {
|
|
94
|
+
analysis_confidence_threshold: 85,
|
|
95
|
+
auto_deep_analysis: false,
|
|
96
|
+
allow_cross_provider_delegation: false,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runDoctor = runDoctor;
|
|
4
|
+
exports.printDoctorReport = printDoctorReport;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const loader_js_1 = require("./loader.js");
|
|
8
|
+
function checkConfigFile(repoRoot) {
|
|
9
|
+
const configPath = (0, node_path_1.resolve)(repoRoot, "polaris.config.json");
|
|
10
|
+
if (!(0, node_fs_1.existsSync)(configPath)) {
|
|
11
|
+
return {
|
|
12
|
+
id: "config-file-exists",
|
|
13
|
+
category: "config",
|
|
14
|
+
status: "warn",
|
|
15
|
+
message: "polaris.config.json not found",
|
|
16
|
+
detail: "Using default configuration. Create polaris.config.json to customize.",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const raw = (0, node_fs_1.readFileSync)(configPath, "utf-8");
|
|
21
|
+
JSON.parse(raw);
|
|
22
|
+
return {
|
|
23
|
+
id: "config-file-exists",
|
|
24
|
+
category: "config",
|
|
25
|
+
status: "pass",
|
|
26
|
+
message: "polaris.config.json exists and is valid JSON",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
return {
|
|
31
|
+
id: "config-file-exists",
|
|
32
|
+
category: "config",
|
|
33
|
+
status: "fail",
|
|
34
|
+
message: "polaris.config.json is invalid JSON",
|
|
35
|
+
detail: err.message,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function checkConfigValidation(repoRoot) {
|
|
40
|
+
try {
|
|
41
|
+
(0, loader_js_1.loadConfig)(repoRoot);
|
|
42
|
+
return {
|
|
43
|
+
id: "config-validation",
|
|
44
|
+
category: "config",
|
|
45
|
+
status: "pass",
|
|
46
|
+
message: "Configuration passes validation",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
if (err instanceof loader_js_1.PolarisConfigError) {
|
|
51
|
+
return {
|
|
52
|
+
id: "config-validation",
|
|
53
|
+
category: "config",
|
|
54
|
+
status: "fail",
|
|
55
|
+
message: "Configuration validation failed",
|
|
56
|
+
detail: err.errors.join("\n"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
id: "config-validation",
|
|
61
|
+
category: "config",
|
|
62
|
+
status: "fail",
|
|
63
|
+
message: "Configuration validation error",
|
|
64
|
+
detail: err.message,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function checkProviderConfig(config) {
|
|
69
|
+
const hasProviders = config.execution?.providers && Object.keys(config.execution.providers).length > 0;
|
|
70
|
+
if (!hasProviders) {
|
|
71
|
+
return {
|
|
72
|
+
id: "provider-config",
|
|
73
|
+
category: "provider",
|
|
74
|
+
status: "warn",
|
|
75
|
+
message: "No external providers configured",
|
|
76
|
+
detail: "External agent providers are optional. Configure execution.providers to use external agents.",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const providers = config.execution.providers;
|
|
80
|
+
const invalidProviders = Object.entries(providers).filter(([_, provider]) => {
|
|
81
|
+
return !provider.command || typeof provider.command !== "string" || provider.command.trim() === "";
|
|
82
|
+
});
|
|
83
|
+
if (invalidProviders.length > 0) {
|
|
84
|
+
return {
|
|
85
|
+
id: "provider-config",
|
|
86
|
+
category: "provider",
|
|
87
|
+
status: "fail",
|
|
88
|
+
message: "Some providers are misconfigured",
|
|
89
|
+
detail: `Providers missing valid command: ${invalidProviders.map(([name]) => name).join(", ")}`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
id: "provider-config",
|
|
94
|
+
category: "provider",
|
|
95
|
+
status: "pass",
|
|
96
|
+
message: "External providers are configured",
|
|
97
|
+
detail: `Found ${Object.keys(providers).length} provider(s)`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function checkTrackerConfig(config) {
|
|
101
|
+
const tracker = config.tracker;
|
|
102
|
+
if (!tracker) {
|
|
103
|
+
return {
|
|
104
|
+
id: "tracker-config",
|
|
105
|
+
category: "tracker",
|
|
106
|
+
status: "pass",
|
|
107
|
+
message: "No tracker configured (local mode)",
|
|
108
|
+
detail: "Tracker is optional. Polaris will operate in local-file mode.",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const hasAdapter = tracker.adapter;
|
|
112
|
+
if (!hasAdapter) {
|
|
113
|
+
return {
|
|
114
|
+
id: "tracker-config",
|
|
115
|
+
category: "tracker",
|
|
116
|
+
status: "pass",
|
|
117
|
+
message: "No tracker adapter configured (local mode)",
|
|
118
|
+
detail: "Tracker adapter is optional. Polaris will operate in local-file mode.",
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (tracker.adapter === "linear") {
|
|
122
|
+
const linearConfig = tracker.linear;
|
|
123
|
+
if (!linearConfig?.enabled) {
|
|
124
|
+
return {
|
|
125
|
+
id: "tracker-config",
|
|
126
|
+
category: "tracker",
|
|
127
|
+
status: "warn",
|
|
128
|
+
message: "Linear tracker adapter selected but not enabled",
|
|
129
|
+
detail: "Set tracker.linear.enabled to true to use Linear integration.",
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (!linearConfig.teamId || !linearConfig.projectId) {
|
|
133
|
+
return {
|
|
134
|
+
id: "tracker-config",
|
|
135
|
+
category: "tracker",
|
|
136
|
+
status: "warn",
|
|
137
|
+
message: "Linear tracker enabled but missing teamId or projectId",
|
|
138
|
+
detail: "Configure tracker.linear.teamId and tracker.linear.projectId for full Linear integration.",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
id: "tracker-config",
|
|
143
|
+
category: "tracker",
|
|
144
|
+
status: "pass",
|
|
145
|
+
message: "Linear tracker is configured",
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if (tracker.adapter === "mcp-bridge") {
|
|
149
|
+
const mcpConfig = tracker.mcpBridge;
|
|
150
|
+
if (!mcpConfig?.enabled) {
|
|
151
|
+
return {
|
|
152
|
+
id: "tracker-config",
|
|
153
|
+
category: "tracker",
|
|
154
|
+
status: "warn",
|
|
155
|
+
message: "MCP bridge tracker adapter selected but not enabled",
|
|
156
|
+
detail: "Set tracker.mcpBridge.enabled to true to use MCP bridge integration.",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
id: "tracker-config",
|
|
161
|
+
category: "tracker",
|
|
162
|
+
status: "pass",
|
|
163
|
+
message: "MCP bridge tracker is configured",
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (tracker.adapter === "local") {
|
|
167
|
+
return {
|
|
168
|
+
id: "tracker-config",
|
|
169
|
+
category: "tracker",
|
|
170
|
+
status: "pass",
|
|
171
|
+
message: "Local file tracker adapter is configured",
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
id: "tracker-config",
|
|
176
|
+
category: "tracker",
|
|
177
|
+
status: "warn",
|
|
178
|
+
message: "Unknown tracker adapter configured",
|
|
179
|
+
detail: `Adapter: ${tracker.adapter}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function checkArtifactHygiene(repoRoot) {
|
|
183
|
+
const polarisDir = (0, node_path_1.resolve)(repoRoot, ".polaris");
|
|
184
|
+
const taskchainDir = (0, node_path_1.resolve)(repoRoot, ".taskchain_artifacts");
|
|
185
|
+
const hasPolarisDir = (0, node_fs_1.existsSync)(polarisDir);
|
|
186
|
+
const hasTaskchainDir = (0, node_fs_1.existsSync)(taskchainDir);
|
|
187
|
+
if (!hasPolarisDir && !hasTaskchainDir) {
|
|
188
|
+
return {
|
|
189
|
+
id: "artifact-hygiene",
|
|
190
|
+
category: "artifact",
|
|
191
|
+
status: "pass",
|
|
192
|
+
message: "No Polaris artifact directories found",
|
|
193
|
+
detail: "This is expected for a fresh repository. Run 'polaris init' to set up.",
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const issues = [];
|
|
197
|
+
if (hasPolarisDir) {
|
|
198
|
+
const runsDir = (0, node_path_1.resolve)(polarisDir, "runs");
|
|
199
|
+
if ((0, node_fs_1.existsSync)(runsDir)) {
|
|
200
|
+
issues.push(".polaris/runs directory exists (contains run artifacts)");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (hasTaskchainDir) {
|
|
204
|
+
const runsDir = (0, node_path_1.resolve)(taskchainDir, "polaris-run", "runs");
|
|
205
|
+
if ((0, node_fs_1.existsSync)(runsDir)) {
|
|
206
|
+
issues.push(".taskchain_artifacts/polaris-run/runs directory exists (contains run artifacts)");
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (issues.length === 0) {
|
|
210
|
+
return {
|
|
211
|
+
id: "artifact-hygiene",
|
|
212
|
+
category: "artifact",
|
|
213
|
+
status: "pass",
|
|
214
|
+
message: "Artifact directories are clean",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
id: "artifact-hygiene",
|
|
219
|
+
category: "artifact",
|
|
220
|
+
status: "warn",
|
|
221
|
+
message: "Runtime artifacts present in repository",
|
|
222
|
+
detail: issues.join("\n"),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function runDoctor(repoRoot) {
|
|
226
|
+
const checks = [];
|
|
227
|
+
// Config checks
|
|
228
|
+
checks.push(checkConfigFile(repoRoot));
|
|
229
|
+
checks.push(checkConfigValidation(repoRoot));
|
|
230
|
+
// Provider checks (only if config loaded successfully)
|
|
231
|
+
try {
|
|
232
|
+
const config = (0, loader_js_1.loadConfig)(repoRoot);
|
|
233
|
+
checks.push(checkProviderConfig(config));
|
|
234
|
+
checks.push(checkTrackerConfig(config));
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// Skip provider/tracker checks if config failed to load
|
|
238
|
+
}
|
|
239
|
+
// Artifact checks
|
|
240
|
+
checks.push(checkArtifactHygiene(repoRoot));
|
|
241
|
+
const summary = {
|
|
242
|
+
pass: checks.filter((c) => c.status === "pass").length,
|
|
243
|
+
warn: checks.filter((c) => c.status === "warn").length,
|
|
244
|
+
fail: checks.filter((c) => c.status === "fail").length,
|
|
245
|
+
};
|
|
246
|
+
return { checks, summary };
|
|
247
|
+
}
|
|
248
|
+
function printDoctorReport(report) {
|
|
249
|
+
const { checks, summary } = report;
|
|
250
|
+
// Print summary
|
|
251
|
+
console.log("\n=== Polaris Configuration Doctor ===\n");
|
|
252
|
+
console.log(`Summary: ${summary.pass} passed, ${summary.warn} warnings, ${summary.fail} failed\n`);
|
|
253
|
+
// Group checks by category
|
|
254
|
+
const categories = ["config", "provider", "tracker", "artifact"];
|
|
255
|
+
for (const category of categories) {
|
|
256
|
+
const categoryChecks = checks.filter((c) => c.category === category);
|
|
257
|
+
if (categoryChecks.length === 0)
|
|
258
|
+
continue;
|
|
259
|
+
console.log(`[${category.toUpperCase()}]`);
|
|
260
|
+
for (const check of categoryChecks) {
|
|
261
|
+
const statusSymbol = check.status === "pass" ? "✓" : check.status === "warn" ? "⚠" : "✗";
|
|
262
|
+
console.log(` ${statusSymbol} ${check.message}`);
|
|
263
|
+
if (check.detail) {
|
|
264
|
+
console.log(` ${check.detail}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
console.log();
|
|
268
|
+
}
|
|
269
|
+
// Exit with error code if any checks failed
|
|
270
|
+
if (summary.fail > 0) {
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.printDoctorReport = exports.runDoctor = exports.runConfigDoctor = exports.runConfigShow = exports.getResolvedConfigJson = exports.createConfigCommand = exports.PolarisConfigError = exports.loadConfig = void 0;
|
|
4
|
+
var loader_js_1 = require("./loader.js");
|
|
5
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return loader_js_1.loadConfig; } });
|
|
6
|
+
Object.defineProperty(exports, "PolarisConfigError", { enumerable: true, get: function () { return loader_js_1.PolarisConfigError; } });
|
|
7
|
+
var show_js_1 = require("./show.js");
|
|
8
|
+
Object.defineProperty(exports, "createConfigCommand", { enumerable: true, get: function () { return show_js_1.createConfigCommand; } });
|
|
9
|
+
Object.defineProperty(exports, "getResolvedConfigJson", { enumerable: true, get: function () { return show_js_1.getResolvedConfigJson; } });
|
|
10
|
+
Object.defineProperty(exports, "runConfigShow", { enumerable: true, get: function () { return show_js_1.runConfigShow; } });
|
|
11
|
+
Object.defineProperty(exports, "runConfigDoctor", { enumerable: true, get: function () { return show_js_1.runConfigDoctor; } });
|
|
12
|
+
var doctor_js_1 = require("./doctor.js");
|
|
13
|
+
Object.defineProperty(exports, "runDoctor", { enumerable: true, get: function () { return doctor_js_1.runDoctor; } });
|
|
14
|
+
Object.defineProperty(exports, "printDoctorReport", { enumerable: true, get: function () { return doctor_js_1.printDoctorReport; } });
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PolarisConfigError = void 0;
|
|
4
|
+
exports.loadConfig = loadConfig;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const defaults_js_1 = require("./defaults.js");
|
|
8
|
+
const validator_js_1 = require("./validator.js");
|
|
9
|
+
class PolarisConfigError extends Error {
|
|
10
|
+
errors;
|
|
11
|
+
constructor(message, errors) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "PolarisConfigError";
|
|
14
|
+
this.errors = errors;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.PolarisConfigError = PolarisConfigError;
|
|
18
|
+
function deepMerge(target, source) {
|
|
19
|
+
const result = { ...target };
|
|
20
|
+
for (const key of Object.keys(source)) {
|
|
21
|
+
const srcVal = source[key];
|
|
22
|
+
const tgtVal = result[key];
|
|
23
|
+
if (typeof srcVal === "object" &&
|
|
24
|
+
srcVal !== null &&
|
|
25
|
+
!Array.isArray(srcVal) &&
|
|
26
|
+
typeof tgtVal === "object" &&
|
|
27
|
+
tgtVal !== null &&
|
|
28
|
+
!Array.isArray(tgtVal)) {
|
|
29
|
+
result[key] = deepMerge(tgtVal, srcVal);
|
|
30
|
+
}
|
|
31
|
+
else if (srcVal !== undefined) {
|
|
32
|
+
result[key] = srcVal;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function loadConfig(repoRoot) {
|
|
38
|
+
const configPath = (0, node_path_1.resolve)(repoRoot, "polaris.config.json");
|
|
39
|
+
let userConfig = {};
|
|
40
|
+
try {
|
|
41
|
+
const raw = (0, node_fs_1.readFileSync)(configPath, "utf-8");
|
|
42
|
+
userConfig = JSON.parse(raw);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const isEnoent = typeof err === "object" &&
|
|
46
|
+
err !== null &&
|
|
47
|
+
"code" in err &&
|
|
48
|
+
err.code === "ENOENT";
|
|
49
|
+
if (!isEnoent) {
|
|
50
|
+
throw new PolarisConfigError(`Failed to read polaris.config.json: ${err.message ?? String(err)}`, []);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const validation = (0, validator_js_1.validateConfig)(userConfig);
|
|
54
|
+
if (!validation.valid) {
|
|
55
|
+
throw new PolarisConfigError(`Invalid polaris.config.json:\n${validation.errors.join("\n")}`, validation.errors);
|
|
56
|
+
}
|
|
57
|
+
return deepMerge(defaults_js_1.DEFAULT_CONFIG, userConfig);
|
|
58
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectCaveman = detectCaveman;
|
|
4
|
+
exports.detectGitNexus = detectGitNexus;
|
|
5
|
+
exports.detectCompactionProviders = detectCompactionProviders;
|
|
6
|
+
exports.detectRepoAnalysisProviders = detectRepoAnalysisProviders;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
/**
|
|
11
|
+
* Detects whether the Caveman compaction provider is available.
|
|
12
|
+
*
|
|
13
|
+
* Caveman is considered present when `.polaris/skills/caveman/SKILL.md`
|
|
14
|
+
* exists in the repository root (canonical location). Falls back to
|
|
15
|
+
* `.codex/skills/caveman/SKILL.md` for backwards compatibility.
|
|
16
|
+
*/
|
|
17
|
+
function detectCaveman(repoRoot) {
|
|
18
|
+
return ((0, node_fs_1.existsSync)((0, node_path_1.join)(repoRoot, ".polaris", "skills", "caveman", "SKILL.md")) ||
|
|
19
|
+
(0, node_fs_1.existsSync)((0, node_path_1.join)(repoRoot, ".codex", "skills", "caveman", "SKILL.md")));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detects whether the GitNexus compaction provider is available.
|
|
23
|
+
*
|
|
24
|
+
* GitNexus is considered present when the `gitnexus` executable is
|
|
25
|
+
* found on PATH (cross-platform: uses `where` on Windows, `which` on Unix).
|
|
26
|
+
*/
|
|
27
|
+
function detectGitNexus() {
|
|
28
|
+
try {
|
|
29
|
+
const command = process.platform === "win32" ? "where" : "which";
|
|
30
|
+
(0, node_child_process_1.execFileSync)(command, ["gitnexus"], { stdio: "ignore" });
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Runs all provider detections and returns the list of detected providers
|
|
39
|
+
* as an array of strings. Returns an empty array when none are detected.
|
|
40
|
+
*
|
|
41
|
+
* Recognised provider names: "caveman", "gitnexus".
|
|
42
|
+
*/
|
|
43
|
+
function detectCompactionProviders(repoRoot) {
|
|
44
|
+
const detected = [];
|
|
45
|
+
if (detectCaveman(repoRoot)) {
|
|
46
|
+
detected.push("caveman");
|
|
47
|
+
}
|
|
48
|
+
if (detectGitNexus()) {
|
|
49
|
+
detected.push("gitnexus");
|
|
50
|
+
}
|
|
51
|
+
return detected;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Runs repo-analysis provider detection and returns detected provider IDs.
|
|
55
|
+
*
|
|
56
|
+
* Recognised repo-analysis provider names: "gitnexus".
|
|
57
|
+
*/
|
|
58
|
+
function detectRepoAnalysisProviders() {
|
|
59
|
+
return detectGitNexus() ? ["gitnexus"] : [];
|
|
60
|
+
}
|