@remnic/core 9.3.655 → 9.3.656
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/dist/access-cli.js +22 -22
- package/dist/access-http.d.ts +4 -4
- package/dist/access-http.js +10 -10
- package/dist/access-mcp.d.ts +4 -4
- package/dist/access-mcp.js +9 -9
- package/dist/access-schema.d.ts +10 -10
- package/dist/{access-service-BEJvriUt.d.ts → access-service-D_nbpexW.d.ts} +33 -2
- package/dist/access-service.d.ts +4 -4
- package/dist/access-service.js +8 -8
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +3 -3
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +3 -3
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-PVE7KSQP.js → chunk-2BD7DG37.js} +2 -2
- package/dist/{chunk-54LOUIBE.js → chunk-2MXEVL75.js} +2 -2
- package/dist/{chunk-55ZMNKMQ.js → chunk-4UL7VPTD.js} +276 -57
- package/dist/chunk-4UL7VPTD.js.map +1 -0
- package/dist/{chunk-COVZLGMR.js → chunk-54XF2FY7.js} +17 -17
- package/dist/{chunk-UYNFWZWG.js → chunk-AGJKWOKV.js} +2 -2
- package/dist/{chunk-TDZSSJV4.js → chunk-AZBV4RRY.js} +1 -1
- package/dist/chunk-AZBV4RRY.js.map +1 -0
- package/dist/{chunk-KOI765XP.js → chunk-CTAV55JM.js} +241 -1
- package/dist/chunk-CTAV55JM.js.map +1 -0
- package/dist/{chunk-A3Y37UWI.js → chunk-DIBWFCLA.js} +3 -3
- package/dist/{chunk-QDVQ4AN2.js → chunk-DR67OK4E.js} +5 -5
- package/dist/{chunk-XBIACVCO.js → chunk-EC2AYKRX.js} +2 -2
- package/dist/{chunk-IQ53ZSXV.js → chunk-GCYFUTUC.js} +2 -2
- package/dist/{chunk-YYN3LIYA.js → chunk-GSHW5VVD.js} +5 -5
- package/dist/chunk-GYSYLGNE.js +650 -0
- package/dist/chunk-GYSYLGNE.js.map +1 -0
- package/dist/{chunk-NRBGRZW4.js → chunk-IOZ5WBWD.js} +2 -2
- package/dist/{chunk-NCSJKK23.js → chunk-JSVFEHLL.js} +7 -5
- package/dist/chunk-JSVFEHLL.js.map +1 -0
- package/dist/{chunk-7LWRCOP7.js → chunk-LZTFCAKE.js} +2 -2
- package/dist/{chunk-TEO46GMM.js → chunk-NXCK7DO7.js} +2 -2
- package/dist/{chunk-XOFXKASO.js → chunk-PEPHBH2W.js} +2 -2
- package/dist/{chunk-WDTUYOLS.js → chunk-QZRKNA5F.js} +2 -2
- package/dist/{chunk-PS3SYNHP.js → chunk-R5DB26G6.js} +2 -2
- package/dist/{chunk-5QD3QD76.js → chunk-RDW5G6DO.js} +659 -123
- package/dist/chunk-RDW5G6DO.js.map +1 -0
- package/dist/{chunk-BGKXTVNG.js → chunk-SWDHVH2P.js} +2 -2
- package/dist/{chunk-67G4T7KI.js → chunk-SXYCVRLK.js} +3 -3
- package/dist/{chunk-UCEABZZN.js → chunk-TFFZUFEP.js} +7 -5
- package/dist/chunk-TFFZUFEP.js.map +1 -0
- package/dist/{chunk-UCEDY5M7.js → chunk-TIJYQXDI.js} +2 -2
- package/dist/{chunk-2RCGZ67B.js → chunk-VAEAGTEQ.js} +3 -3
- package/dist/{chunk-XRKQOQLY.js → chunk-WIKMCJUR.js} +2 -2
- package/dist/{chunk-KZZ4YAEC.js → chunk-WWMHAMAY.js} +2 -2
- package/dist/{chunk-OKW6F5S5.js → chunk-YEZHZCUO.js} +4 -4
- package/dist/{chunk-5FOCXX5E.js → chunk-YVVQUAOO.js} +3 -3
- package/dist/{chunk-5FOCXX5E.js.map → chunk-YVVQUAOO.js.map} +1 -1
- package/dist/{chunk-3XGWCZ63.js → chunk-YXLT4EMM.js} +2 -2
- package/dist/{chunk-PTMJ2FH2.js → chunk-Z6UDTNY6.js} +2 -2
- package/dist/{cli-BGahB_d3.d.ts → cli-aYxSuPvP.d.ts} +3 -3
- package/dist/cli.d.ts +5 -5
- package/dist/cli.js +22 -22
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -3
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +3 -3
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +3 -3
- package/dist/explicit-cue-recall.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/focused-list-recall.js +2 -2
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +121 -121
- package/dist/index.js +32 -32
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lcm-fallback-read.js +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +4 -4
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +3 -3
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +7 -7
- package/dist/{orchestrator-BgzZlWxH.d.ts → orchestrator-D1wcmPNj.d.ts} +8 -2
- package/dist/orchestrator.d.ts +3 -3
- package/dist/orchestrator.js +18 -18
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/response-guidance-recall.js +2 -2
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-Z8d_uMq8.d.ts → semantic-consolidation-MWOdNtSE.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.d.ts +3 -2
- package/dist/semantic-rule-verifier.js +5 -3
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +2 -2
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/targeted-fact-recall.js +2 -2
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/{types-2OPlQWJG.d.ts → types-CgcCpUrf.d.ts} +39 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.d.ts +2 -1
- package/dist/verified-recall.js +5 -3
- package/package.json +1 -1
- package/src/access-service-observe-lcm-parity.test.ts +86 -1
- package/src/access-service-observe-scope.test.ts +283 -1
- package/src/access-service-raw-excerpt-read-gate.test.ts +53 -0
- package/src/access-service.ts +391 -93
- package/src/coding/coding-namespace.ts +0 -3
- package/src/config.ts +282 -0
- package/src/lcm-fallback-read.ts +2 -6
- package/src/namespaces/scope-profiles.test.ts +1074 -0
- package/src/namespaces/scope-profiles.ts +456 -0
- package/src/orchestrator-flush.test.ts +142 -0
- package/src/orchestrator-source-attribution.test.ts +73 -0
- package/src/orchestrator.ts +835 -163
- package/src/semantic-rule-verifier.ts +13 -6
- package/src/types.ts +52 -0
- package/src/verified-recall.ts +10 -6
- package/dist/chunk-55ZMNKMQ.js.map +0 -1
- package/dist/chunk-5QD3QD76.js.map +0 -1
- package/dist/chunk-KOI765XP.js.map +0 -1
- package/dist/chunk-MMJANTJX.js +0 -339
- package/dist/chunk-MMJANTJX.js.map +0 -1
- package/dist/chunk-NCSJKK23.js.map +0 -1
- package/dist/chunk-TDZSSJV4.js.map +0 -1
- package/dist/chunk-UCEABZZN.js.map +0 -1
- /package/dist/{chunk-PVE7KSQP.js.map → chunk-2BD7DG37.js.map} +0 -0
- /package/dist/{chunk-54LOUIBE.js.map → chunk-2MXEVL75.js.map} +0 -0
- /package/dist/{chunk-COVZLGMR.js.map → chunk-54XF2FY7.js.map} +0 -0
- /package/dist/{chunk-UYNFWZWG.js.map → chunk-AGJKWOKV.js.map} +0 -0
- /package/dist/{chunk-A3Y37UWI.js.map → chunk-DIBWFCLA.js.map} +0 -0
- /package/dist/{chunk-QDVQ4AN2.js.map → chunk-DR67OK4E.js.map} +0 -0
- /package/dist/{chunk-XBIACVCO.js.map → chunk-EC2AYKRX.js.map} +0 -0
- /package/dist/{chunk-IQ53ZSXV.js.map → chunk-GCYFUTUC.js.map} +0 -0
- /package/dist/{chunk-YYN3LIYA.js.map → chunk-GSHW5VVD.js.map} +0 -0
- /package/dist/{chunk-NRBGRZW4.js.map → chunk-IOZ5WBWD.js.map} +0 -0
- /package/dist/{chunk-7LWRCOP7.js.map → chunk-LZTFCAKE.js.map} +0 -0
- /package/dist/{chunk-TEO46GMM.js.map → chunk-NXCK7DO7.js.map} +0 -0
- /package/dist/{chunk-XOFXKASO.js.map → chunk-PEPHBH2W.js.map} +0 -0
- /package/dist/{chunk-WDTUYOLS.js.map → chunk-QZRKNA5F.js.map} +0 -0
- /package/dist/{chunk-PS3SYNHP.js.map → chunk-R5DB26G6.js.map} +0 -0
- /package/dist/{chunk-BGKXTVNG.js.map → chunk-SWDHVH2P.js.map} +0 -0
- /package/dist/{chunk-67G4T7KI.js.map → chunk-SXYCVRLK.js.map} +0 -0
- /package/dist/{chunk-UCEDY5M7.js.map → chunk-TIJYQXDI.js.map} +0 -0
- /package/dist/{chunk-2RCGZ67B.js.map → chunk-VAEAGTEQ.js.map} +0 -0
- /package/dist/{chunk-XRKQOQLY.js.map → chunk-WIKMCJUR.js.map} +0 -0
- /package/dist/{chunk-KZZ4YAEC.js.map → chunk-WWMHAMAY.js.map} +0 -0
- /package/dist/{chunk-OKW6F5S5.js.map → chunk-YEZHZCUO.js.map} +0 -0
- /package/dist/{chunk-3XGWCZ63.js.map → chunk-YXLT4EMM.js.map} +0 -0
- /package/dist/{chunk-PTMJ2FH2.js.map → chunk-Z6UDTNY6.js.map} +0 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
import {
|
|
2
|
+
launchProcessSync
|
|
3
|
+
} from "./chunk-O75CRYGF.js";
|
|
4
|
+
import {
|
|
5
|
+
canReadNamespace,
|
|
6
|
+
canWriteNamespace,
|
|
7
|
+
defaultNamespaceForPrincipal
|
|
8
|
+
} from "./chunk-UZYLX7M6.js";
|
|
9
|
+
import {
|
|
10
|
+
isSafeRouteNamespace
|
|
11
|
+
} from "./chunk-U3PN77QT.js";
|
|
12
|
+
import {
|
|
13
|
+
expandTildePath
|
|
14
|
+
} from "./chunk-EYIEWJNI.js";
|
|
15
|
+
|
|
16
|
+
// src/coding/git-context.ts
|
|
17
|
+
import path from "path";
|
|
18
|
+
var DEFAULT_GIT_TIMEOUT_MS = 2e3;
|
|
19
|
+
function defaultGitInvoker() {
|
|
20
|
+
return (cwd, args) => {
|
|
21
|
+
const result = launchProcessSync("git", args, {
|
|
22
|
+
cwd,
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
timeout: DEFAULT_GIT_TIMEOUT_MS,
|
|
25
|
+
shell: false
|
|
26
|
+
});
|
|
27
|
+
if (result.error) {
|
|
28
|
+
return { stdout: "", exitCode: 127 };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
32
|
+
exitCode: typeof result.status === "number" ? result.status : 1
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function stableHash(input) {
|
|
37
|
+
let hash = 2166136261;
|
|
38
|
+
for (let i = 0; i < input.length; i++) {
|
|
39
|
+
hash ^= input.charCodeAt(i);
|
|
40
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
41
|
+
}
|
|
42
|
+
return hash.toString(16).padStart(8, "0");
|
|
43
|
+
}
|
|
44
|
+
function normalizeOriginUrl(rawUrl) {
|
|
45
|
+
let url = rawUrl.trim();
|
|
46
|
+
if (!url) return "";
|
|
47
|
+
if (/\.git$/i.test(url)) url = url.slice(0, -4);
|
|
48
|
+
if (/^[A-Za-z]:[\\/]/.test(url)) {
|
|
49
|
+
return url.toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
const protoMatch = /^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]+@)?(\[[^\]]+\]|[^/:]*)(?::(\d+))?(\/.*)?$/i.exec(url);
|
|
52
|
+
if (protoMatch) {
|
|
53
|
+
let host = protoMatch[1] ?? "";
|
|
54
|
+
const wasBracketed = host.startsWith("[") && host.endsWith("]");
|
|
55
|
+
if (wasBracketed) host = host.slice(1, -1);
|
|
56
|
+
const port = protoMatch[2];
|
|
57
|
+
const repoPath = (protoMatch[3] ?? "").replace(/^\/+/, "");
|
|
58
|
+
const hostPort = port ? wasBracketed ? `[${host}]:${port}` : `${host}:${port}` : host;
|
|
59
|
+
const prefix = hostPort.length > 0 ? hostPort : "localhost";
|
|
60
|
+
return `${prefix}/${repoPath}`.toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
const scpMatch = /^(?:([^@\s/]+)@)?(\[[^\]]+\]|[^:@\s/]+):(.+)$/.exec(url);
|
|
63
|
+
if (scpMatch) {
|
|
64
|
+
let host = scpMatch[2] ?? "";
|
|
65
|
+
if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
|
|
66
|
+
const repoPath = scpMatch[3] ?? "";
|
|
67
|
+
if (repoPath.startsWith("//")) {
|
|
68
|
+
return url.toLowerCase();
|
|
69
|
+
}
|
|
70
|
+
return `${host}/${repoPath.replace(/^\/+/, "")}`.toLowerCase();
|
|
71
|
+
}
|
|
72
|
+
return url.toLowerCase();
|
|
73
|
+
}
|
|
74
|
+
async function resolveGitContext(cwd, options = {}) {
|
|
75
|
+
try {
|
|
76
|
+
if (typeof cwd !== "string" || cwd.length === 0) return null;
|
|
77
|
+
const expanded = expandTildePath(cwd);
|
|
78
|
+
if (!path.isAbsolute(expanded)) return null;
|
|
79
|
+
const invoker = options.invoker ?? defaultGitInvoker();
|
|
80
|
+
const topLevel = invoker(expanded, ["rev-parse", "--show-toplevel"]);
|
|
81
|
+
if (topLevel.exitCode !== 0) return null;
|
|
82
|
+
const rootPath = topLevel.stdout.trim();
|
|
83
|
+
if (!rootPath) return null;
|
|
84
|
+
const branchResult = invoker(rootPath, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
85
|
+
let branch = null;
|
|
86
|
+
if (branchResult.exitCode === 0) {
|
|
87
|
+
const raw = branchResult.stdout.trim();
|
|
88
|
+
branch = raw && raw !== "HEAD" ? raw : null;
|
|
89
|
+
} else {
|
|
90
|
+
const unbornRef = invoker(rootPath, ["symbolic-ref", "--quiet", "HEAD"]);
|
|
91
|
+
if (unbornRef.exitCode === 0) {
|
|
92
|
+
const raw = unbornRef.stdout.trim();
|
|
93
|
+
const prefix = "refs/heads/";
|
|
94
|
+
if (raw.startsWith(prefix)) {
|
|
95
|
+
const candidate = raw.slice(prefix.length);
|
|
96
|
+
if (candidate) branch = candidate;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const originResult = invoker(rootPath, ["remote", "get-url", "origin"]);
|
|
101
|
+
let projectId;
|
|
102
|
+
if (originResult.exitCode === 0) {
|
|
103
|
+
const normalized = normalizeOriginUrl(originResult.stdout);
|
|
104
|
+
projectId = normalized ? `origin:${stableHash(normalized)}` : `root:${stableHash(rootPath)}`;
|
|
105
|
+
} else {
|
|
106
|
+
projectId = `root:${stableHash(rootPath)}`;
|
|
107
|
+
}
|
|
108
|
+
const headRef = invoker(rootPath, ["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"]);
|
|
109
|
+
let defaultBranch = null;
|
|
110
|
+
if (headRef.exitCode === 0) {
|
|
111
|
+
const raw = headRef.stdout.trim();
|
|
112
|
+
const prefix = "refs/remotes/origin/";
|
|
113
|
+
if (raw.startsWith(prefix)) {
|
|
114
|
+
const candidate = raw.slice(prefix.length);
|
|
115
|
+
if (candidate) defaultBranch = candidate;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
projectId,
|
|
120
|
+
branch,
|
|
121
|
+
rootPath,
|
|
122
|
+
defaultBranch
|
|
123
|
+
};
|
|
124
|
+
} catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/coding/coding-namespace.ts
|
|
130
|
+
function sanitizeFragment(input) {
|
|
131
|
+
if (typeof input !== "string") return "";
|
|
132
|
+
const trimmed = input.trim().toLowerCase();
|
|
133
|
+
let out = "";
|
|
134
|
+
let prevIsDash = true;
|
|
135
|
+
for (let i = 0; i < trimmed.length; i += 1) {
|
|
136
|
+
const c = trimmed[i];
|
|
137
|
+
const cc = trimmed.charCodeAt(i);
|
|
138
|
+
const isSafe = cc >= 48 && cc <= 57 || cc >= 97 && cc <= 122 || cc === 46 || cc === 95;
|
|
139
|
+
if (isSafe) {
|
|
140
|
+
out += c;
|
|
141
|
+
prevIsDash = false;
|
|
142
|
+
} else if (!prevIsDash) {
|
|
143
|
+
out += "-";
|
|
144
|
+
prevIsDash = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (out.endsWith("-")) out = out.slice(0, -1);
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
var MAX_NAMESPACE_LEN = 64;
|
|
151
|
+
var HASH_SUFFIX_LEN = 9;
|
|
152
|
+
function capLength(value) {
|
|
153
|
+
if (value.length <= MAX_NAMESPACE_LEN) return value;
|
|
154
|
+
const hash = stableHash(value);
|
|
155
|
+
let end = MAX_NAMESPACE_LEN - HASH_SUFFIX_LEN;
|
|
156
|
+
while (end > 0 && value.charCodeAt(end - 1) === 45) end -= 1;
|
|
157
|
+
return `${value.slice(0, end)}-${hash}`;
|
|
158
|
+
}
|
|
159
|
+
function projectNamespaceName(projectId) {
|
|
160
|
+
const frag = sanitizeFragment(projectId);
|
|
161
|
+
return capLength(`project-${frag || "unknown"}`);
|
|
162
|
+
}
|
|
163
|
+
function projectTagProjectId(projectTag) {
|
|
164
|
+
const trimmed = projectTag.trim();
|
|
165
|
+
const frag = sanitizeFragment(trimmed);
|
|
166
|
+
const disambig = trimmed.length > 0 && frag !== trimmed;
|
|
167
|
+
const suffix = disambig ? `-${stableHash(trimmed)}` : "";
|
|
168
|
+
return `tag:${frag || "unknown"}${suffix}`;
|
|
169
|
+
}
|
|
170
|
+
function sanitizeBaseFragment(input) {
|
|
171
|
+
if (typeof input !== "string") return "";
|
|
172
|
+
const trimmed = input.trim();
|
|
173
|
+
let out = "";
|
|
174
|
+
let prevIsDash = true;
|
|
175
|
+
for (let i = 0; i < trimmed.length; i += 1) {
|
|
176
|
+
const c = trimmed[i];
|
|
177
|
+
const cc = trimmed.charCodeAt(i);
|
|
178
|
+
const isSafe = cc >= 48 && cc <= 57 || cc >= 65 && cc <= 90 || cc >= 97 && cc <= 122 || cc === 46 || cc === 95;
|
|
179
|
+
if (isSafe) {
|
|
180
|
+
out += c;
|
|
181
|
+
prevIsDash = false;
|
|
182
|
+
} else if (!prevIsDash) {
|
|
183
|
+
out += "-";
|
|
184
|
+
prevIsDash = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (out.endsWith("-")) out = out.slice(0, -1);
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
function combineNamespaces(base, overlay) {
|
|
191
|
+
const baseFrag = sanitizeBaseFragment(base);
|
|
192
|
+
const overlayFrag = sanitizeFragment(overlay);
|
|
193
|
+
if (!baseFrag) return capLength(overlayFrag || "unknown");
|
|
194
|
+
if (!overlayFrag) return capLength(baseFrag);
|
|
195
|
+
return capLength(`${baseFrag}-${overlayFrag}`);
|
|
196
|
+
}
|
|
197
|
+
function branchNamespaceName(projectId, branch) {
|
|
198
|
+
const projectFrag = sanitizeFragment(projectId);
|
|
199
|
+
const trimmedBranch = branch.trim();
|
|
200
|
+
const branchFrag = sanitizeFragment(trimmedBranch);
|
|
201
|
+
const disambig = trimmedBranch.length > 0 && branchFrag !== trimmedBranch;
|
|
202
|
+
const base = `project-${projectFrag || "unknown"}-branch-${branchFrag || "unknown"}`;
|
|
203
|
+
const suffixed = disambig ? `${base}-${stableHash(trimmedBranch)}` : base;
|
|
204
|
+
return capLength(suffixed);
|
|
205
|
+
}
|
|
206
|
+
function resolveCodingNamespaceOverlay(codingContext, config, defaultNamespace) {
|
|
207
|
+
if (!codingContext) return null;
|
|
208
|
+
if (!config.projectScope) return null;
|
|
209
|
+
const projectId = typeof codingContext.projectId === "string" ? codingContext.projectId.trim() : "";
|
|
210
|
+
if (!projectId) return null;
|
|
211
|
+
const projectNs = projectNamespaceName(projectId);
|
|
212
|
+
const includeRoot = config.globalFallback === true;
|
|
213
|
+
if (config.branchScope && typeof codingContext.branch === "string" && codingContext.branch.length > 0) {
|
|
214
|
+
const branchNs = branchNamespaceName(projectId, codingContext.branch);
|
|
215
|
+
const fallbacks = [projectNs];
|
|
216
|
+
if (includeRoot) fallbacks.push("");
|
|
217
|
+
return {
|
|
218
|
+
namespace: branchNs,
|
|
219
|
+
readFallbacks: fallbacks,
|
|
220
|
+
scope: "branch"
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
namespace: projectNs,
|
|
225
|
+
readFallbacks: includeRoot ? [""] : [],
|
|
226
|
+
scope: "project"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function describeCodingScope(codingContext, config, defaultNamespace) {
|
|
230
|
+
const projectId = codingContext?.projectId ?? null;
|
|
231
|
+
const branch = codingContext?.branch ?? null;
|
|
232
|
+
if (!codingContext) {
|
|
233
|
+
return {
|
|
234
|
+
scope: "none",
|
|
235
|
+
projectId: null,
|
|
236
|
+
branch: null,
|
|
237
|
+
effectiveNamespace: null,
|
|
238
|
+
readFallbacks: [],
|
|
239
|
+
disabledReason: "no-context"
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (!config.projectScope) {
|
|
243
|
+
return {
|
|
244
|
+
scope: "none",
|
|
245
|
+
projectId,
|
|
246
|
+
branch,
|
|
247
|
+
effectiveNamespace: null,
|
|
248
|
+
readFallbacks: [],
|
|
249
|
+
disabledReason: "disabled"
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const trimmedId = typeof projectId === "string" ? projectId.trim() : "";
|
|
253
|
+
if (!trimmedId) {
|
|
254
|
+
return {
|
|
255
|
+
scope: "none",
|
|
256
|
+
projectId,
|
|
257
|
+
branch,
|
|
258
|
+
effectiveNamespace: null,
|
|
259
|
+
readFallbacks: [],
|
|
260
|
+
disabledReason: "empty-project"
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const overlay = resolveCodingNamespaceOverlay(codingContext, config, defaultNamespace);
|
|
264
|
+
if (!overlay) {
|
|
265
|
+
return {
|
|
266
|
+
scope: "none",
|
|
267
|
+
projectId,
|
|
268
|
+
branch,
|
|
269
|
+
effectiveNamespace: null,
|
|
270
|
+
readFallbacks: [],
|
|
271
|
+
disabledReason: "disabled"
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
scope: overlay.scope,
|
|
276
|
+
projectId,
|
|
277
|
+
branch,
|
|
278
|
+
effectiveNamespace: overlay.namespace,
|
|
279
|
+
readFallbacks: overlay.readFallbacks,
|
|
280
|
+
disabledReason: null
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
var LCM_NS_SENTINEL = "";
|
|
284
|
+
function escapeDefaultLcmKey(sessionKey) {
|
|
285
|
+
return sessionKey.startsWith(LCM_NS_SENTINEL) ? `${LCM_NS_SENTINEL}${sessionKey}` : sessionKey;
|
|
286
|
+
}
|
|
287
|
+
function lcmSessionKeyForNamespace(namespace, sessionKey, defaultNamespace) {
|
|
288
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return sessionKey;
|
|
289
|
+
if (typeof namespace === "string" && namespace.length > 0 && namespace !== defaultNamespace) {
|
|
290
|
+
return `${LCM_NS_SENTINEL}${namespace}${LCM_NS_SENTINEL}${sessionKey}`;
|
|
291
|
+
}
|
|
292
|
+
return escapeDefaultLcmKey(sessionKey);
|
|
293
|
+
}
|
|
294
|
+
function lcmReadSessionIdsForNamespaces(namespaces, sessionKey, defaultNamespace) {
|
|
295
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) {
|
|
296
|
+
return [void 0];
|
|
297
|
+
}
|
|
298
|
+
const out = [];
|
|
299
|
+
const seen = /* @__PURE__ */ new Set();
|
|
300
|
+
for (const namespace of namespaces) {
|
|
301
|
+
const key = lcmSessionKeyForNamespace(namespace, sessionKey, defaultNamespace) ?? sessionKey;
|
|
302
|
+
if (!seen.has(key)) {
|
|
303
|
+
seen.add(key);
|
|
304
|
+
out.push(key);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return out;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/namespaces/scope-profiles.ts
|
|
311
|
+
import { createHash } from "crypto";
|
|
312
|
+
function activeScopeProfile(config) {
|
|
313
|
+
const profileId = config.defaultScopeProfile;
|
|
314
|
+
if (!profileId) return null;
|
|
315
|
+
const profile = (config.scopeProfiles ?? {})[profileId];
|
|
316
|
+
return profile ? { profileId, profile } : null;
|
|
317
|
+
}
|
|
318
|
+
function principalListed(list, principal) {
|
|
319
|
+
if (!principal) return false;
|
|
320
|
+
return list.includes(principal) || list.includes("*");
|
|
321
|
+
}
|
|
322
|
+
function derivedScopeProfileSelfNamespace(principal, config) {
|
|
323
|
+
if (!principal || principal === config.defaultNamespace || principal === config.sharedNamespace) return null;
|
|
324
|
+
if (isSafeRouteNamespace(principal)) return principal;
|
|
325
|
+
return "principal-" + createHash("sha256").update(principal).digest("hex").slice(0, 54);
|
|
326
|
+
}
|
|
327
|
+
function scopeProfileSelfNamespace(principal, config) {
|
|
328
|
+
const existing = defaultNamespaceForPrincipal(principal, config);
|
|
329
|
+
if (existing !== config.defaultNamespace) return existing;
|
|
330
|
+
return derivedScopeProfileSelfNamespace(principal, config) ?? existing;
|
|
331
|
+
}
|
|
332
|
+
function hasExplicitNamespacePolicy(namespace, config) {
|
|
333
|
+
return (config.namespacePolicies ?? []).some((policy) => policy.name === namespace);
|
|
334
|
+
}
|
|
335
|
+
function isScopeProfileImplicitSelfNamespace(principal, namespace, config) {
|
|
336
|
+
const derived = derivedScopeProfileSelfNamespace(principal, config);
|
|
337
|
+
return Boolean(
|
|
338
|
+
derived && namespace === derived && namespace !== config.defaultNamespace && namespace !== config.sharedNamespace && isSafeRouteNamespace(namespace) && !hasExplicitNamespacePolicy(namespace, config)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
function canReadScopeProfileNamespace(principal, namespace, config) {
|
|
342
|
+
return isScopeProfileImplicitSelfNamespace(principal, namespace, config) || canReadNamespace(principal, namespace, config);
|
|
343
|
+
}
|
|
344
|
+
function canWriteScopeProfileNamespace(principal, namespace, config) {
|
|
345
|
+
return isScopeProfileImplicitSelfNamespace(principal, namespace, config) || canWriteNamespace(principal, namespace, config);
|
|
346
|
+
}
|
|
347
|
+
function resolveTeam(config, profile, principal) {
|
|
348
|
+
const configuredTeamId = profile.teamProject?.teamId;
|
|
349
|
+
if (configuredTeamId) {
|
|
350
|
+
const configured = (config.teams ?? {})[configuredTeamId];
|
|
351
|
+
return configured ? { teamId: configuredTeamId, team: configured } : null;
|
|
352
|
+
}
|
|
353
|
+
const readableTeams = Object.entries(config.teams ?? {}).filter(
|
|
354
|
+
([, team]) => principalListed(team.principals, principal) || principalListed(team.read, principal)
|
|
355
|
+
);
|
|
356
|
+
const needsWritableTeam = profile.writeDefault === "teamProject" || profile.readOrder.includes("teamProject");
|
|
357
|
+
if (needsWritableTeam) {
|
|
358
|
+
const writableTeam = readableTeams.find(([, team]) => principalListed(team.write, principal));
|
|
359
|
+
if (writableTeam) return { teamId: writableTeam[0], team: writableTeam[1] };
|
|
360
|
+
}
|
|
361
|
+
const needsPromotableTeam = profile.promotionTargets.includes("teamProject") || profile.autoPromote.targets.includes("teamProject");
|
|
362
|
+
if (needsPromotableTeam) {
|
|
363
|
+
const promotableTeam = readableTeams.find(
|
|
364
|
+
([, team]) => principalListed(team.promote, principal) || principalListed(team.write, principal)
|
|
365
|
+
);
|
|
366
|
+
if (promotableTeam) return { teamId: promotableTeam[0], team: promotableTeam[1] };
|
|
367
|
+
}
|
|
368
|
+
const firstReadableTeam = readableTeams[0];
|
|
369
|
+
return firstReadableTeam ? { teamId: firstReadableTeam[0], team: firstReadableTeam[1] } : null;
|
|
370
|
+
}
|
|
371
|
+
function renderTeamProjectNamespace(params) {
|
|
372
|
+
const replacements = {
|
|
373
|
+
teamId: params.teamId,
|
|
374
|
+
principal: params.principal ?? "anonymous",
|
|
375
|
+
projectId: params.codingContext.projectId,
|
|
376
|
+
projectHash: stableHash(params.codingContext.projectId),
|
|
377
|
+
projectNamespace: params.codingOverlay.namespace
|
|
378
|
+
};
|
|
379
|
+
const unknownPlaceholders = [];
|
|
380
|
+
const namespace = params.template.replace(/\{([A-Za-z][A-Za-z0-9]*)\}/g, (match, key) => {
|
|
381
|
+
const replacement = replacements[key];
|
|
382
|
+
if (replacement !== void 0) return replacement;
|
|
383
|
+
if (!unknownPlaceholders.includes(key)) unknownPlaceholders.push(key);
|
|
384
|
+
return match;
|
|
385
|
+
});
|
|
386
|
+
return { namespace, unknownPlaceholders };
|
|
387
|
+
}
|
|
388
|
+
function resolveLayer(params) {
|
|
389
|
+
const { id, config, profile, principal, baseNamespace, codingContext, codingOverlay } = params;
|
|
390
|
+
if (id === "userGlobal") {
|
|
391
|
+
return {
|
|
392
|
+
id,
|
|
393
|
+
kind: "user-global",
|
|
394
|
+
namespace: baseNamespace,
|
|
395
|
+
readable: canReadScopeProfileNamespace(principal, baseNamespace, config),
|
|
396
|
+
writable: canWriteScopeProfileNamespace(principal, baseNamespace, config),
|
|
397
|
+
promotable: canWriteScopeProfileNamespace(principal, baseNamespace, config),
|
|
398
|
+
reason: "principal self/global namespace"
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
if (id === "serverShared") {
|
|
402
|
+
return {
|
|
403
|
+
id,
|
|
404
|
+
kind: "server-shared",
|
|
405
|
+
namespace: config.sharedNamespace,
|
|
406
|
+
readable: canReadNamespace(principal, config.sharedNamespace, config),
|
|
407
|
+
writable: canWriteNamespace(principal, config.sharedNamespace, config),
|
|
408
|
+
promotable: canWriteNamespace(principal, config.sharedNamespace, config),
|
|
409
|
+
reason: "configured shared namespace"
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
if (id === "userProject") {
|
|
413
|
+
if (!codingContext || !codingOverlay) {
|
|
414
|
+
return {
|
|
415
|
+
id,
|
|
416
|
+
kind: "user-project",
|
|
417
|
+
readable: false,
|
|
418
|
+
writable: false,
|
|
419
|
+
promotable: false,
|
|
420
|
+
reason: "missing project context"
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
const namespace2 = combineNamespaces(baseNamespace, codingOverlay.namespace);
|
|
424
|
+
const explicitProjectPolicy = hasExplicitNamespacePolicy(namespace2, config);
|
|
425
|
+
const baseReadable = canReadScopeProfileNamespace(principal, baseNamespace, config);
|
|
426
|
+
const baseWritable = canWriteScopeProfileNamespace(principal, baseNamespace, config);
|
|
427
|
+
const projectReadable = explicitProjectPolicy ? canReadNamespace(principal, namespace2, config) : baseReadable;
|
|
428
|
+
const projectWritable = explicitProjectPolicy ? canWriteNamespace(principal, namespace2, config) : baseWritable;
|
|
429
|
+
return {
|
|
430
|
+
id,
|
|
431
|
+
kind: "user-project",
|
|
432
|
+
namespace: namespace2,
|
|
433
|
+
readable: projectReadable,
|
|
434
|
+
writable: projectWritable,
|
|
435
|
+
promotable: projectWritable,
|
|
436
|
+
reason: explicitProjectPolicy ? "explicit user-project namespace policy" : baseReadable || baseWritable ? "principal project namespace derived from coding context" : "principal base namespace is not authorized"
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
const team = resolveTeam(config, profile, principal);
|
|
440
|
+
if (!team) {
|
|
441
|
+
return {
|
|
442
|
+
id,
|
|
443
|
+
kind: "team-project",
|
|
444
|
+
readable: false,
|
|
445
|
+
writable: false,
|
|
446
|
+
promotable: false,
|
|
447
|
+
reason: "no authorized team mapping"
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
if (!codingContext || !codingOverlay) {
|
|
451
|
+
return {
|
|
452
|
+
id,
|
|
453
|
+
kind: "team-project",
|
|
454
|
+
readable: false,
|
|
455
|
+
writable: false,
|
|
456
|
+
promotable: false,
|
|
457
|
+
reason: "missing project context"
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const template = profile.teamProject?.namespaceTemplate ?? team.team.projectNamespaceTemplate ?? "team-{teamId}-project-{projectHash}";
|
|
461
|
+
const renderedNamespace = renderTeamProjectNamespace({
|
|
462
|
+
template,
|
|
463
|
+
teamId: team.teamId,
|
|
464
|
+
principal,
|
|
465
|
+
codingContext,
|
|
466
|
+
codingOverlay
|
|
467
|
+
});
|
|
468
|
+
const namespace = renderedNamespace.namespace.trim();
|
|
469
|
+
if (renderedNamespace.unknownPlaceholders.length > 0) {
|
|
470
|
+
return {
|
|
471
|
+
id,
|
|
472
|
+
kind: "team-project",
|
|
473
|
+
namespace,
|
|
474
|
+
readable: false,
|
|
475
|
+
writable: false,
|
|
476
|
+
promotable: false,
|
|
477
|
+
reason: `unknown team-project namespace template placeholder(s): ${renderedNamespace.unknownPlaceholders.join(", ")}`
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
if (!namespace || !isSafeRouteNamespace(namespace)) {
|
|
481
|
+
return {
|
|
482
|
+
id,
|
|
483
|
+
kind: "team-project",
|
|
484
|
+
namespace,
|
|
485
|
+
readable: false,
|
|
486
|
+
writable: false,
|
|
487
|
+
promotable: false,
|
|
488
|
+
reason: "team-project namespace template resolved to an unsafe namespace"
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
const teamReadable = principalListed(team.team.read, principal) || principalListed(team.team.principals, principal);
|
|
492
|
+
const teamWritable = principalListed(team.team.write, principal);
|
|
493
|
+
const teamPromotable = principalListed(team.team.promote, principal) || principalListed(team.team.write, principal);
|
|
494
|
+
const userProjectSuffix = `-${codingOverlay.namespace}`;
|
|
495
|
+
const userProjectBase = namespace.endsWith(userProjectSuffix) ? namespace.slice(0, -userProjectSuffix.length) : "";
|
|
496
|
+
const dynamicUserProjectCollision = userProjectBase.length > 0 && (userProjectBase === config.defaultNamespace || userProjectBase === config.sharedNamespace || (config.namespacePolicies ?? []).some((policy) => policy.name === userProjectBase));
|
|
497
|
+
const protectedNamespace = namespace === config.defaultNamespace || namespace === config.sharedNamespace || dynamicUserProjectCollision || (config.namespacePolicies ?? []).some((policy) => policy.name === namespace);
|
|
498
|
+
const policyReadable = !protectedNamespace || canReadNamespace(principal, namespace, config);
|
|
499
|
+
const policyWritable = !protectedNamespace || canWriteNamespace(principal, namespace, config);
|
|
500
|
+
const policyBlocked = protectedNamespace && (!policyReadable || !policyWritable);
|
|
501
|
+
return {
|
|
502
|
+
id,
|
|
503
|
+
kind: "team-project",
|
|
504
|
+
namespace,
|
|
505
|
+
readable: teamReadable && policyReadable,
|
|
506
|
+
writable: teamWritable && policyWritable,
|
|
507
|
+
promotable: teamPromotable && policyWritable,
|
|
508
|
+
reason: policyBlocked ? "team-project namespace collides with a protected namespace policy" : "trusted team-project namespace derived from team and project config"
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
function resolveScopeProfilePlan(options) {
|
|
512
|
+
const active = activeScopeProfile(options.config);
|
|
513
|
+
if (!active || !options.config.namespacesEnabled) return null;
|
|
514
|
+
const baseNamespace = scopeProfileSelfNamespace(options.principal, options.config);
|
|
515
|
+
const layerIds = Array.from(
|
|
516
|
+
/* @__PURE__ */ new Set([
|
|
517
|
+
...active.profile.readOrder,
|
|
518
|
+
active.profile.writeDefault,
|
|
519
|
+
"userGlobal",
|
|
520
|
+
...active.profile.promotionTargets.filter(
|
|
521
|
+
(target) => ["userProject", "teamProject", "userGlobal", "serverShared"].includes(target)
|
|
522
|
+
)
|
|
523
|
+
])
|
|
524
|
+
);
|
|
525
|
+
const layerMap = /* @__PURE__ */ new Map();
|
|
526
|
+
for (const id of layerIds) {
|
|
527
|
+
layerMap.set(
|
|
528
|
+
id,
|
|
529
|
+
resolveLayer({
|
|
530
|
+
id,
|
|
531
|
+
config: options.config,
|
|
532
|
+
profile: active.profile,
|
|
533
|
+
principal: options.principal,
|
|
534
|
+
baseNamespace,
|
|
535
|
+
codingContext: options.codingContext,
|
|
536
|
+
codingOverlay: options.codingOverlay
|
|
537
|
+
})
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
const readNamespaces = [];
|
|
541
|
+
for (const id of active.profile.readOrder) {
|
|
542
|
+
const layer = layerMap.get(id);
|
|
543
|
+
if (layer?.readable && layer.namespace && !readNamespaces.includes(layer.namespace)) {
|
|
544
|
+
readNamespaces.push(layer.namespace);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
const preferredWriteLayer = layerMap.get(active.profile.writeDefault);
|
|
548
|
+
const readableWriteLayers = active.profile.readOrder.map((id) => layerMap.get(id)).filter(
|
|
549
|
+
(layer) => Boolean(layer?.writable && layer.namespace && readNamespaces.includes(layer.namespace))
|
|
550
|
+
);
|
|
551
|
+
const fallbackWriteLayer = preferredWriteLayer?.writable && preferredWriteLayer.namespace && readNamespaces.includes(preferredWriteLayer.namespace) ? preferredWriteLayer : readableWriteLayers[0];
|
|
552
|
+
const warnings = [];
|
|
553
|
+
if (!fallbackWriteLayer?.namespace) {
|
|
554
|
+
warnings.push(`scope profile ${active.profileId} has no writable layer inside the profile read stack; writes disabled`);
|
|
555
|
+
} else if (fallbackWriteLayer.id !== active.profile.writeDefault) {
|
|
556
|
+
warnings.push(
|
|
557
|
+
`scope profile ${active.profileId} writeDefault ${active.profile.writeDefault} unavailable: ${preferredWriteLayer?.reason ?? "not resolved"}`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
const promotionTargets = active.profile.promotionTargets.map((target) => {
|
|
561
|
+
const layer = layerMap.get(target);
|
|
562
|
+
if (!layer) {
|
|
563
|
+
return {
|
|
564
|
+
target,
|
|
565
|
+
authorized: false,
|
|
566
|
+
reason: "promotion target did not resolve to a profile layer"
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
target,
|
|
571
|
+
namespace: layer.namespace,
|
|
572
|
+
authorized: layer.promotable && Boolean(layer.namespace),
|
|
573
|
+
reason: layer.reason
|
|
574
|
+
};
|
|
575
|
+
});
|
|
576
|
+
return {
|
|
577
|
+
profileId: active.profileId,
|
|
578
|
+
profile: active.profile,
|
|
579
|
+
baseNamespace,
|
|
580
|
+
writeLayer: fallbackWriteLayer?.id ?? active.profile.writeDefault,
|
|
581
|
+
writeNamespace: fallbackWriteLayer?.namespace ?? "",
|
|
582
|
+
readNamespaces,
|
|
583
|
+
layers: [...layerMap.values()],
|
|
584
|
+
promotionTargets,
|
|
585
|
+
warnings
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function expandScopeProfileReadNamespaces(options) {
|
|
589
|
+
if (options.profilePlan.readNamespaces.length === 0) {
|
|
590
|
+
return [];
|
|
591
|
+
}
|
|
592
|
+
const out = [...options.profilePlan.readNamespaces];
|
|
593
|
+
const add = (namespace) => {
|
|
594
|
+
if (namespace && !out.includes(namespace)) out.push(namespace);
|
|
595
|
+
};
|
|
596
|
+
const userProjectReadable = options.profilePlan.profile.readOrder.includes("userProject") && options.profilePlan.layers.some(
|
|
597
|
+
(layer) => layer.id === "userProject" && layer.readable && layer.namespace
|
|
598
|
+
);
|
|
599
|
+
const userGlobalReadable = options.profilePlan.profile.readOrder.includes("userGlobal") && options.profilePlan.layers.some(
|
|
600
|
+
(layer) => layer.id === "userGlobal" && layer.readable && layer.namespace
|
|
601
|
+
);
|
|
602
|
+
if (userProjectReadable) {
|
|
603
|
+
for (const fallback of options.codingOverlay?.readFallbacks ?? []) {
|
|
604
|
+
if (fallback === "" && !userGlobalReadable) continue;
|
|
605
|
+
const fallbackNamespace = combineNamespaces(options.principalSelfNamespace, fallback);
|
|
606
|
+
if (!hasExplicitNamespacePolicy(fallbackNamespace, options.config) || canReadScopeProfileNamespace(options.principal, fallbackNamespace, options.config)) {
|
|
607
|
+
add(fallbackNamespace);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return out;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/procedural/reinforcement-core.ts
|
|
615
|
+
function clusterByKey(items, keyFn) {
|
|
616
|
+
const clusters = /* @__PURE__ */ new Map();
|
|
617
|
+
for (const item of items) {
|
|
618
|
+
const key = keyFn(item);
|
|
619
|
+
if (typeof key !== "string") {
|
|
620
|
+
throw new TypeError(
|
|
621
|
+
`clusterByKey: keyFn must return a string, got ${key === null ? "null" : typeof key}`
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
const existing = clusters.get(key);
|
|
625
|
+
if (existing) {
|
|
626
|
+
existing.push(item);
|
|
627
|
+
} else {
|
|
628
|
+
clusters.set(key, [item]);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return clusters;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export {
|
|
635
|
+
clusterByKey,
|
|
636
|
+
stableHash,
|
|
637
|
+
normalizeOriginUrl,
|
|
638
|
+
resolveGitContext,
|
|
639
|
+
projectNamespaceName,
|
|
640
|
+
projectTagProjectId,
|
|
641
|
+
combineNamespaces,
|
|
642
|
+
branchNamespaceName,
|
|
643
|
+
resolveCodingNamespaceOverlay,
|
|
644
|
+
describeCodingScope,
|
|
645
|
+
lcmSessionKeyForNamespace,
|
|
646
|
+
lcmReadSessionIdsForNamespaces,
|
|
647
|
+
resolveScopeProfilePlan,
|
|
648
|
+
expandScopeProfileReadNamespaces
|
|
649
|
+
};
|
|
650
|
+
//# sourceMappingURL=chunk-GYSYLGNE.js.map
|