@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,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runGraphResolver = runGraphResolver;
|
|
4
|
+
const build_edges_js_1 = require("./build-edges.js");
|
|
5
|
+
const resolve_imports_js_1 = require("./resolve-imports.js");
|
|
6
|
+
function runGraphResolver(options) {
|
|
7
|
+
const db = options.graphStore.getDatabase();
|
|
8
|
+
db.exec("BEGIN IMMEDIATE TRANSACTION");
|
|
9
|
+
try {
|
|
10
|
+
(0, resolve_imports_js_1.clearResolverStubs)(db);
|
|
11
|
+
const resolvedImports = (0, resolve_imports_js_1.resolveImports)(db);
|
|
12
|
+
const built = (0, build_edges_js_1.buildEdges)(db, resolvedImports);
|
|
13
|
+
db.exec("COMMIT");
|
|
14
|
+
return {
|
|
15
|
+
...built,
|
|
16
|
+
resolvedImports: resolvedImports.length,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
db.exec("ROLLBACK");
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveImports = resolveImports;
|
|
4
|
+
exports.clearResolverStubs = clearResolverStubs;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const queries_js_1 = require("../store/queries.js");
|
|
8
|
+
const UNRESOLVED_FILE_PREFIX = "file-unresolved-";
|
|
9
|
+
const UNRESOLVED_NODE_PREFIX = "node-unresolved-";
|
|
10
|
+
const UNRESOLVED_SYMBOL_PREFIX = "symbol-unresolved-";
|
|
11
|
+
const UNRESOLVED_PATH_PREFIX = "unresolved://";
|
|
12
|
+
const UNRESOLVED_SIGNATURE = "__UNRESOLVED__";
|
|
13
|
+
function resolveImports(db) {
|
|
14
|
+
const files = db
|
|
15
|
+
.prepare(`
|
|
16
|
+
SELECT id, path
|
|
17
|
+
FROM files
|
|
18
|
+
`)
|
|
19
|
+
.all();
|
|
20
|
+
const byPath = new Map();
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
byPath.set((0, node_path_1.normalize)(file.path), file);
|
|
23
|
+
}
|
|
24
|
+
const exportedByFileId = new Map();
|
|
25
|
+
const symbols = db
|
|
26
|
+
.prepare(`
|
|
27
|
+
SELECT id, file_id AS fileId, name, exported
|
|
28
|
+
FROM symbols
|
|
29
|
+
WHERE kind != 'import'
|
|
30
|
+
`)
|
|
31
|
+
.all();
|
|
32
|
+
for (const symbol of symbols) {
|
|
33
|
+
if (symbol.exported !== 1) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const existing = exportedByFileId.get(symbol.fileId) ?? [];
|
|
37
|
+
existing.push(symbol.id);
|
|
38
|
+
exportedByFileId.set(symbol.fileId, existing);
|
|
39
|
+
}
|
|
40
|
+
for (const symbolIds of exportedByFileId.values()) {
|
|
41
|
+
symbolIds.sort((left, right) => left.localeCompare(right));
|
|
42
|
+
}
|
|
43
|
+
const imports = db
|
|
44
|
+
.prepare(`
|
|
45
|
+
SELECT
|
|
46
|
+
s.id AS symbolId,
|
|
47
|
+
s.file_id AS importerFileId,
|
|
48
|
+
f.path AS importerFilePath,
|
|
49
|
+
s.name AS specifier
|
|
50
|
+
FROM symbols s
|
|
51
|
+
JOIN files f ON f.id = s.file_id
|
|
52
|
+
WHERE s.kind = 'import'
|
|
53
|
+
ORDER BY f.path, s.name, s.id
|
|
54
|
+
`)
|
|
55
|
+
.all();
|
|
56
|
+
const resolvedImports = [];
|
|
57
|
+
for (const entry of imports) {
|
|
58
|
+
const resolvedFile = resolveImportSpecifier(entry.importerFilePath, entry.specifier, byPath);
|
|
59
|
+
if (resolvedFile) {
|
|
60
|
+
const resolvedSymbolIds = exportedByFileId.get(resolvedFile.id) ?? [];
|
|
61
|
+
const unresolved = resolvedSymbolIds.length === 0;
|
|
62
|
+
resolvedImports.push({
|
|
63
|
+
importSymbolId: entry.symbolId,
|
|
64
|
+
importSpecifier: entry.specifier,
|
|
65
|
+
importerFileId: entry.importerFileId,
|
|
66
|
+
importerFilePath: entry.importerFilePath,
|
|
67
|
+
resolvedFileId: resolvedFile.id,
|
|
68
|
+
resolvedFilePath: resolvedFile.path,
|
|
69
|
+
resolvedSymbolIds,
|
|
70
|
+
unresolved,
|
|
71
|
+
});
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const unresolvedTarget = upsertUnresolvedImportStub(db, entry);
|
|
75
|
+
resolvedImports.push({
|
|
76
|
+
importSymbolId: entry.symbolId,
|
|
77
|
+
importSpecifier: entry.specifier,
|
|
78
|
+
importerFileId: entry.importerFileId,
|
|
79
|
+
importerFilePath: entry.importerFilePath,
|
|
80
|
+
resolvedFileId: unresolvedTarget.file.id,
|
|
81
|
+
resolvedFilePath: unresolvedTarget.file.path,
|
|
82
|
+
resolvedSymbolIds: [unresolvedTarget.symbol.id],
|
|
83
|
+
unresolved: true,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return resolvedImports;
|
|
87
|
+
}
|
|
88
|
+
function clearResolverStubs(db) {
|
|
89
|
+
db.prepare("DELETE FROM edges WHERE type IN ('CALLS', 'IMPORTS', 'DEFINED_IN')").run();
|
|
90
|
+
db.prepare("DELETE FROM symbols WHERE id LIKE ?1").run(`${UNRESOLVED_SYMBOL_PREFIX}%`);
|
|
91
|
+
db.prepare("DELETE FROM nodes WHERE id LIKE ?1").run(`${UNRESOLVED_NODE_PREFIX}%`);
|
|
92
|
+
db.prepare("DELETE FROM files WHERE id LIKE ?1 OR path LIKE ?2").run(`${UNRESOLVED_FILE_PREFIX}%`, `${UNRESOLVED_PATH_PREFIX}%`);
|
|
93
|
+
}
|
|
94
|
+
function upsertUnresolvedImportStub(db, row) {
|
|
95
|
+
const digest = makeDigest(`${row.importerFilePath}:${row.specifier}`);
|
|
96
|
+
const fileId = `${UNRESOLVED_FILE_PREFIX}${digest}`;
|
|
97
|
+
const filePath = `${UNRESOLVED_PATH_PREFIX}${row.importerFilePath}::${row.specifier}`;
|
|
98
|
+
const nodeId = `${UNRESOLVED_NODE_PREFIX}${digest}`;
|
|
99
|
+
const symbolId = `${UNRESOLVED_SYMBOL_PREFIX}${digest}`;
|
|
100
|
+
db.prepare(`
|
|
101
|
+
INSERT INTO files (id, path, language)
|
|
102
|
+
VALUES (?1, ?2, ?3)
|
|
103
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
104
|
+
path = excluded.path,
|
|
105
|
+
language = excluded.language
|
|
106
|
+
`).run(fileId, filePath, "unknown");
|
|
107
|
+
const node = {
|
|
108
|
+
id: nodeId,
|
|
109
|
+
type: "IMPORT",
|
|
110
|
+
fileId,
|
|
111
|
+
name: `UNRESOLVED:${row.specifier}`,
|
|
112
|
+
};
|
|
113
|
+
(0, queries_js_1.insertNode)(db, node);
|
|
114
|
+
db.prepare(`
|
|
115
|
+
INSERT INTO symbols (id, node_id, file_id, name, kind, signature, exported)
|
|
116
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6, 0)
|
|
117
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
118
|
+
node_id = excluded.node_id,
|
|
119
|
+
file_id = excluded.file_id,
|
|
120
|
+
name = excluded.name,
|
|
121
|
+
kind = excluded.kind,
|
|
122
|
+
signature = excluded.signature,
|
|
123
|
+
exported = excluded.exported
|
|
124
|
+
`).run(symbolId, nodeId, fileId, row.specifier, "unknown", UNRESOLVED_SIGNATURE);
|
|
125
|
+
return {
|
|
126
|
+
file: {
|
|
127
|
+
id: fileId,
|
|
128
|
+
path: filePath,
|
|
129
|
+
},
|
|
130
|
+
symbol: {
|
|
131
|
+
id: symbolId,
|
|
132
|
+
nodeId,
|
|
133
|
+
fileId,
|
|
134
|
+
name: row.specifier,
|
|
135
|
+
kind: "unknown",
|
|
136
|
+
signature: UNRESOLVED_SIGNATURE,
|
|
137
|
+
exported: false,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function resolveImportSpecifier(importerPath, specifier, byPath) {
|
|
142
|
+
if (!specifier.startsWith(".")) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const importerDir = (0, node_path_1.dirname)(importerPath);
|
|
146
|
+
const candidates = new Set();
|
|
147
|
+
const base = (0, node_path_1.normalize)((0, node_path_1.resolve)(importerDir, specifier));
|
|
148
|
+
candidates.add(base);
|
|
149
|
+
const ext = (0, node_path_1.extname)(base);
|
|
150
|
+
if (!ext) {
|
|
151
|
+
for (const extension of [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]) {
|
|
152
|
+
candidates.add(`${base}${extension}`);
|
|
153
|
+
}
|
|
154
|
+
for (const extension of ["/index.ts", "/index.tsx", "/index.js", "/index.jsx", "/index.mjs", "/index.cjs"]) {
|
|
155
|
+
candidates.add(`${base}${extension}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
for (const candidate of candidates) {
|
|
159
|
+
const found = byPath.get(candidate);
|
|
160
|
+
if (found) {
|
|
161
|
+
return found;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
function makeDigest(input) {
|
|
167
|
+
return (0, node_crypto_1.createHash)("sha256").update(input).digest("hex").slice(0, 24);
|
|
168
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphStoreAdapter = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const node_sqlite_1 = require("node:sqlite");
|
|
7
|
+
const governance_js_1 = require("../governance.js");
|
|
8
|
+
const types_js_1 = require("./types.js");
|
|
9
|
+
const MIT_NOTICE = "Includes concepts derived from an MIT-licensed graph indexing approach.";
|
|
10
|
+
const FALLBACK_SCHEMA_SQL = `
|
|
11
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
12
|
+
version INTEGER PRIMARY KEY,
|
|
13
|
+
applied_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
17
|
+
id TEXT PRIMARY KEY,
|
|
18
|
+
path TEXT NOT NULL UNIQUE,
|
|
19
|
+
language TEXT NOT NULL
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
type TEXT NOT NULL,
|
|
25
|
+
file_id TEXT NOT NULL,
|
|
26
|
+
name TEXT,
|
|
27
|
+
start_line INTEGER,
|
|
28
|
+
start_column INTEGER,
|
|
29
|
+
end_line INTEGER,
|
|
30
|
+
end_column INTEGER,
|
|
31
|
+
FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS symbols (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
node_id TEXT NOT NULL UNIQUE,
|
|
37
|
+
file_id TEXT NOT NULL,
|
|
38
|
+
name TEXT NOT NULL,
|
|
39
|
+
kind TEXT NOT NULL,
|
|
40
|
+
signature TEXT,
|
|
41
|
+
exported INTEGER NOT NULL DEFAULT 0 CHECK (exported IN (0, 1)),
|
|
42
|
+
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
43
|
+
FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
type TEXT NOT NULL,
|
|
49
|
+
from_node_id TEXT NOT NULL,
|
|
50
|
+
to_node_id TEXT NOT NULL,
|
|
51
|
+
metadata TEXT,
|
|
52
|
+
FOREIGN KEY (from_node_id) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
53
|
+
FOREIGN KEY (to_node_id) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
54
|
+
UNIQUE (type, from_node_id, to_node_id)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file_id ON nodes(file_id);
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_file_id ON symbols(file_id);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_edges_from_node_id ON edges(from_node_id);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_edges_to_node_id ON edges(to_node_id);
|
|
62
|
+
`;
|
|
63
|
+
class GraphStoreAdapter {
|
|
64
|
+
dbPath;
|
|
65
|
+
noticesOutputPath;
|
|
66
|
+
db = null;
|
|
67
|
+
initialized = false;
|
|
68
|
+
constructor(options) {
|
|
69
|
+
this.dbPath = (0, node_path_1.resolve)(options.repoRoot ?? process.cwd(), options.dbPath);
|
|
70
|
+
this.noticesOutputPath = (0, node_path_1.resolve)(options.repoRoot ?? process.cwd(), options.graphOutputPath ?? ".polaris/graph");
|
|
71
|
+
}
|
|
72
|
+
open() {
|
|
73
|
+
if (this.db) {
|
|
74
|
+
return this.db;
|
|
75
|
+
}
|
|
76
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.dbPath), { recursive: true });
|
|
77
|
+
this.db = new node_sqlite_1.DatabaseSync(this.dbPath);
|
|
78
|
+
this.db.exec("PRAGMA foreign_keys = ON;");
|
|
79
|
+
this.initSchema();
|
|
80
|
+
return this.db;
|
|
81
|
+
}
|
|
82
|
+
close() {
|
|
83
|
+
if (!this.db) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.db.close();
|
|
87
|
+
this.db = null;
|
|
88
|
+
}
|
|
89
|
+
getDatabase() {
|
|
90
|
+
if (!this.db) {
|
|
91
|
+
throw new Error("Graph store is not open.");
|
|
92
|
+
}
|
|
93
|
+
return this.db;
|
|
94
|
+
}
|
|
95
|
+
initSchema() {
|
|
96
|
+
const db = this.getDatabase();
|
|
97
|
+
db.exec(loadSchemaSql());
|
|
98
|
+
const appliedVersion = getAppliedSchemaVersion(db);
|
|
99
|
+
if (appliedVersion > types_js_1.CURRENT_GRAPH_SCHEMA_VERSION) {
|
|
100
|
+
throw new Error(`Graph schema version ${appliedVersion} is newer than supported ${types_js_1.CURRENT_GRAPH_SCHEMA_VERSION}.`);
|
|
101
|
+
}
|
|
102
|
+
for (let version = appliedVersion + 1; version <= types_js_1.CURRENT_GRAPH_SCHEMA_VERSION; version += 1) {
|
|
103
|
+
db.prepare(`
|
|
104
|
+
INSERT OR IGNORE INTO schema_version (version, applied_at)
|
|
105
|
+
VALUES (?1, CURRENT_TIMESTAMP)
|
|
106
|
+
`).run(version);
|
|
107
|
+
}
|
|
108
|
+
if (!this.initialized) {
|
|
109
|
+
(0, governance_js_1.writeGraphNotices)(this.noticesOutputPath, [MIT_NOTICE]);
|
|
110
|
+
this.initialized = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.GraphStoreAdapter = GraphStoreAdapter;
|
|
115
|
+
function loadSchemaSql() {
|
|
116
|
+
const schemaPath = (0, node_path_1.resolve)(__dirname, "schema.sql");
|
|
117
|
+
try {
|
|
118
|
+
return (0, node_fs_1.readFileSync)(schemaPath, "utf-8");
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return FALLBACK_SCHEMA_SQL;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function getAppliedSchemaVersion(db) {
|
|
125
|
+
const row = db
|
|
126
|
+
.prepare(`
|
|
127
|
+
SELECT MAX(version) AS version
|
|
128
|
+
FROM schema_version
|
|
129
|
+
`)
|
|
130
|
+
.get();
|
|
131
|
+
return row?.version ?? 0;
|
|
132
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.insertNode = insertNode;
|
|
4
|
+
exports.insertEdge = insertEdge;
|
|
5
|
+
exports.lookupSymbol = lookupSymbol;
|
|
6
|
+
exports.lookupFile = lookupFile;
|
|
7
|
+
function insertNode(db, node) {
|
|
8
|
+
db.prepare(`
|
|
9
|
+
INSERT INTO nodes (
|
|
10
|
+
id,
|
|
11
|
+
type,
|
|
12
|
+
file_id,
|
|
13
|
+
name,
|
|
14
|
+
start_line,
|
|
15
|
+
start_column,
|
|
16
|
+
end_line,
|
|
17
|
+
end_column
|
|
18
|
+
) VALUES (
|
|
19
|
+
@id,
|
|
20
|
+
@type,
|
|
21
|
+
@fileId,
|
|
22
|
+
@name,
|
|
23
|
+
@startLine,
|
|
24
|
+
@startColumn,
|
|
25
|
+
@endLine,
|
|
26
|
+
@endColumn
|
|
27
|
+
)
|
|
28
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
29
|
+
type = excluded.type,
|
|
30
|
+
file_id = excluded.file_id,
|
|
31
|
+
name = excluded.name,
|
|
32
|
+
start_line = excluded.start_line,
|
|
33
|
+
start_column = excluded.start_column,
|
|
34
|
+
end_line = excluded.end_line,
|
|
35
|
+
end_column = excluded.end_column
|
|
36
|
+
`).run({
|
|
37
|
+
id: node.id,
|
|
38
|
+
type: node.type,
|
|
39
|
+
fileId: node.fileId,
|
|
40
|
+
name: node.name ?? null,
|
|
41
|
+
startLine: node.startLine ?? null,
|
|
42
|
+
startColumn: node.startColumn ?? null,
|
|
43
|
+
endLine: node.endLine ?? null,
|
|
44
|
+
endColumn: node.endColumn ?? null,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function insertEdge(db, edge) {
|
|
48
|
+
db.prepare(`
|
|
49
|
+
INSERT INTO edges (
|
|
50
|
+
id,
|
|
51
|
+
type,
|
|
52
|
+
from_node_id,
|
|
53
|
+
to_node_id,
|
|
54
|
+
metadata
|
|
55
|
+
) VALUES (
|
|
56
|
+
@id,
|
|
57
|
+
@type,
|
|
58
|
+
@fromNodeId,
|
|
59
|
+
@toNodeId,
|
|
60
|
+
@metadata
|
|
61
|
+
)
|
|
62
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
63
|
+
type = excluded.type,
|
|
64
|
+
from_node_id = excluded.from_node_id,
|
|
65
|
+
to_node_id = excluded.to_node_id,
|
|
66
|
+
metadata = excluded.metadata
|
|
67
|
+
`).run({
|
|
68
|
+
id: edge.id,
|
|
69
|
+
type: edge.type,
|
|
70
|
+
fromNodeId: edge.fromNodeId,
|
|
71
|
+
toNodeId: edge.toNodeId,
|
|
72
|
+
metadata: edge.metadata ?? null,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function lookupSymbol(db, name, filePath) {
|
|
76
|
+
const row = db
|
|
77
|
+
.prepare(`
|
|
78
|
+
SELECT
|
|
79
|
+
s.id,
|
|
80
|
+
s.node_id AS nodeId,
|
|
81
|
+
s.file_id AS fileId,
|
|
82
|
+
s.name,
|
|
83
|
+
s.kind,
|
|
84
|
+
s.signature,
|
|
85
|
+
s.exported
|
|
86
|
+
FROM symbols s
|
|
87
|
+
JOIN files f ON f.id = s.file_id
|
|
88
|
+
WHERE s.name = ?1
|
|
89
|
+
AND (?2 IS NULL OR f.path = ?2)
|
|
90
|
+
ORDER BY s.id
|
|
91
|
+
LIMIT 1
|
|
92
|
+
`)
|
|
93
|
+
.get(name, filePath ?? null);
|
|
94
|
+
if (!row) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
id: row.id,
|
|
99
|
+
nodeId: row.nodeId,
|
|
100
|
+
fileId: row.fileId,
|
|
101
|
+
name: row.name,
|
|
102
|
+
kind: row.kind,
|
|
103
|
+
signature: row.signature,
|
|
104
|
+
exported: row.exported === 1,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function lookupFile(db, filePath) {
|
|
108
|
+
const row = db
|
|
109
|
+
.prepare(`
|
|
110
|
+
SELECT id, path, language
|
|
111
|
+
FROM files
|
|
112
|
+
WHERE path = ?1
|
|
113
|
+
LIMIT 1
|
|
114
|
+
`)
|
|
115
|
+
.get(filePath);
|
|
116
|
+
if (!row) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
id: row.id,
|
|
121
|
+
path: row.path,
|
|
122
|
+
language: row.language,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SECRET_PATTERNS = exports.DEFAULT_EXCLUSIONS = void 0;
|
|
4
|
+
exports.DEFAULT_EXCLUSIONS = [
|
|
5
|
+
// Package managers
|
|
6
|
+
"node_modules/",
|
|
7
|
+
".pnpm-store/",
|
|
8
|
+
"vendor/",
|
|
9
|
+
"Pods/",
|
|
10
|
+
// Build artifacts
|
|
11
|
+
"build/",
|
|
12
|
+
"dist/",
|
|
13
|
+
".build/",
|
|
14
|
+
"DerivedData/",
|
|
15
|
+
"*.xcarchive",
|
|
16
|
+
// Language-specific caches
|
|
17
|
+
".dart_tool/",
|
|
18
|
+
".pub-cache/",
|
|
19
|
+
"__pycache__/",
|
|
20
|
+
"*.pyc",
|
|
21
|
+
".gradle/",
|
|
22
|
+
// IDE / editor
|
|
23
|
+
".idea/",
|
|
24
|
+
".vscode/",
|
|
25
|
+
"*.xcworkspace",
|
|
26
|
+
// Secrets (always enforced, cannot be negated)
|
|
27
|
+
"*.pem",
|
|
28
|
+
"*.key",
|
|
29
|
+
"*.env",
|
|
30
|
+
".env.*",
|
|
31
|
+
"credentials.json",
|
|
32
|
+
// VCS
|
|
33
|
+
".git/",
|
|
34
|
+
];
|
|
35
|
+
exports.SECRET_PATTERNS = [
|
|
36
|
+
"*.pem",
|
|
37
|
+
"*.key",
|
|
38
|
+
"*.env",
|
|
39
|
+
".env.*",
|
|
40
|
+
"credentials.json",
|
|
41
|
+
];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parsePolarisIgnore = parsePolarisIgnore;
|
|
7
|
+
exports.isIgnored = isIgnored;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const ignore_1 = __importDefault(require("ignore"));
|
|
11
|
+
const defaults_js_1 = require("./defaults.js");
|
|
12
|
+
function parsePolarisIgnore(userPatterns) {
|
|
13
|
+
const ig = (0, ignore_1.default)();
|
|
14
|
+
// User patterns first so SECRET_PATTERNS applied after cannot be negated
|
|
15
|
+
ig.add(userPatterns);
|
|
16
|
+
ig.add(defaults_js_1.DEFAULT_EXCLUSIONS);
|
|
17
|
+
ig.add(defaults_js_1.SECRET_PATTERNS);
|
|
18
|
+
return ig;
|
|
19
|
+
}
|
|
20
|
+
function isIgnored(filePath, repoRoot) {
|
|
21
|
+
const ig = (0, ignore_1.default)();
|
|
22
|
+
ig.add(defaults_js_1.DEFAULT_EXCLUSIONS);
|
|
23
|
+
const ignorePath = (0, node_path_1.resolve)(repoRoot, ".polarisignore");
|
|
24
|
+
try {
|
|
25
|
+
const raw = (0, node_fs_1.readFileSync)(ignorePath, "utf-8");
|
|
26
|
+
const userPatterns = raw.split(/\r?\n/).filter((line) => line.trim() !== "" && !line.startsWith("#"));
|
|
27
|
+
// Apply non-secret user patterns first
|
|
28
|
+
const nonSecretPatterns = userPatterns.filter((p) => !defaults_js_1.SECRET_PATTERNS.includes(p));
|
|
29
|
+
ig.add(nonSecretPatterns);
|
|
30
|
+
// Re-add secret patterns so they cannot be negated
|
|
31
|
+
ig.add(defaults_js_1.SECRET_PATTERNS);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (typeof err === "object" && err !== null && "code" in err && err.code !== "ENOENT") {
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return ig.ignores(filePath);
|
|
39
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSkillChainFile = validateSkillChainFile;
|
|
4
|
+
exports.validateSkillChainDirectory = validateSkillChainDirectory;
|
|
5
|
+
exports.validateMapReferences = validateMapReferences;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
/**
|
|
9
|
+
* Patterns that indicate broad context preload in skill chain files.
|
|
10
|
+
* These patterns violate the Navigation Before Retrieval doctrine.
|
|
11
|
+
*/
|
|
12
|
+
const BROAD_PRELOAD_PATTERNS = [
|
|
13
|
+
/read\s+all\s+doctrine/i,
|
|
14
|
+
/load\s+all\s+charts/i,
|
|
15
|
+
/preload\s+(all\s+)?(linked\s+)?(docs|documents|doctrine|charts)/i,
|
|
16
|
+
];
|
|
17
|
+
function validateSkillChainFile(filePath) {
|
|
18
|
+
const violations = [];
|
|
19
|
+
try {
|
|
20
|
+
const content = (0, node_fs_1.readFileSync)(filePath, "utf-8");
|
|
21
|
+
const lines = content.split("\n");
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
const line = lines[i];
|
|
24
|
+
const lineNumber = i + 1;
|
|
25
|
+
for (const pattern of BROAD_PRELOAD_PATTERNS) {
|
|
26
|
+
if (pattern.test(line)) {
|
|
27
|
+
violations.push({
|
|
28
|
+
file: filePath,
|
|
29
|
+
line: lineNumber,
|
|
30
|
+
message: "[navigation-before-retrieval] Skill chain instructs broad context preload — use targeted retrieval instead",
|
|
31
|
+
rule: "navigation-before-retrieval",
|
|
32
|
+
});
|
|
33
|
+
break; // Only report one violation per line
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// If we can't read the file, skip it
|
|
40
|
+
console.warn(`Warning: Could not read file ${filePath}: ${error}`);
|
|
41
|
+
}
|
|
42
|
+
return violations;
|
|
43
|
+
}
|
|
44
|
+
function validateSkillChainDirectory(dirPath) {
|
|
45
|
+
const violations = [];
|
|
46
|
+
let filesChecked = 0;
|
|
47
|
+
try {
|
|
48
|
+
const entries = (0, node_fs_1.readdirSync)(dirPath, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
const fullPath = (0, node_path_1.join)(dirPath, entry.name);
|
|
51
|
+
if (entry.isDirectory()) {
|
|
52
|
+
// Recursively check subdirectories
|
|
53
|
+
const result = validateSkillChainDirectory(fullPath);
|
|
54
|
+
violations.push(...result.violations);
|
|
55
|
+
filesChecked += result.filesChecked;
|
|
56
|
+
}
|
|
57
|
+
else if (entry.name === "chain.md") {
|
|
58
|
+
// Check skill chain files
|
|
59
|
+
filesChecked++;
|
|
60
|
+
violations.push(...validateSkillChainFile(fullPath));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.warn(`Warning: Could not read directory ${dirPath}: ${error}`);
|
|
66
|
+
}
|
|
67
|
+
return { violations, filesChecked };
|
|
68
|
+
}
|
|
69
|
+
function validateMapReferences(repoRoot) {
|
|
70
|
+
const skillsDir = (0, node_path_1.join)(repoRoot, ".polaris", "skills");
|
|
71
|
+
return validateSkillChainDirectory(skillsDir);
|
|
72
|
+
}
|