@moldea.ai/core 7.0.4 → 8.0.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 +4 -4
- package/dist/analysis-worker.js +29 -11
- package/dist/analysis-worker.js.map +1 -1
- package/dist/chunks/{core-FyfprJqa.js → core-BCMf-ig9.js} +337 -63
- package/dist/chunks/core-BCMf-ig9.js.map +1 -0
- package/dist/chunks/{errors-Dw1ahMS1.js → errors-CvWn6gr2.js} +15 -5
- package/dist/chunks/errors-CvWn6gr2.js.map +1 -0
- package/dist/chunks/{lifecycle-h3DWn5vl.js → lifecycle-DwuevNoO.js} +2 -2
- package/dist/chunks/{lifecycle-h3DWn5vl.js.map → lifecycle-DwuevNoO.js.map} +1 -1
- package/dist/chunks/{options-AMqX7rx_.js → options-l3kVfA-K.js} +7 -3
- package/dist/chunks/options-l3kVfA-K.js.map +1 -0
- package/dist/chunks/{repository-rpc-ClAIx3-c.js → repository-rpc-DgYwMaGv.js} +29 -16
- package/dist/chunks/repository-rpc-DgYwMaGv.js.map +1 -0
- package/dist/chunks/{scope-e3-w9N7D.js → scope-D9BYchNI.js} +2 -2
- package/dist/chunks/{scope-e3-w9N7D.js.map → scope-D9BYchNI.js.map} +1 -1
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +2 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/diagnostic-utilities/index.d.ts.map +1 -1
- package/dist/diagnostics/index.d.ts +2 -2
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/integration-validation/agents-inspection.d.ts +19 -0
- package/dist/integration-validation/agents-inspection.d.ts.map +1 -0
- package/dist/integration-validation/claude-inspection.d.ts +22 -0
- package/dist/integration-validation/claude-inspection.d.ts.map +1 -0
- package/dist/integration-validation/inspection.d.ts +11 -3
- package/dist/integration-validation/inspection.d.ts.map +1 -1
- package/dist/integration-validation/parser.d.ts +8 -0
- package/dist/integration-validation/parser.d.ts.map +1 -1
- package/dist/integration-validation/types.d.ts +18 -0
- package/dist/integration-validation/types.d.ts.map +1 -1
- package/dist/integration-validation/utilities.d.ts +25 -0
- package/dist/integration-validation/utilities.d.ts.map +1 -0
- package/dist/node-inspection/client.d.ts.map +1 -1
- package/dist/node-inspection/protocol.d.ts.map +1 -1
- package/dist/node-inspection/repository-rpc.d.ts +7 -4
- package/dist/node-inspection/repository-rpc.d.ts.map +1 -1
- package/dist/node-inspection/types.d.ts +16 -0
- package/dist/node-inspection/types.d.ts.map +1 -1
- package/dist/node-runner.js +2 -2
- package/dist/node.js +31 -11
- package/dist/node.js.map +1 -1
- package/dist/project-validation/index.d.ts +1 -1
- package/dist/project-validation/index.d.ts.map +1 -1
- package/dist/repository-inspection-session/index.d.ts +8 -2
- package/dist/repository-inspection-session/index.d.ts.map +1 -1
- package/dist/retained-memory/index.d.ts +5 -4
- package/dist/retained-memory/index.d.ts.map +1 -1
- package/dist/scope.js +2 -2
- package/dist/universal-project-inspection/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/core-FyfprJqa.js.map +0 -1
- package/dist/chunks/errors-Dw1ahMS1.js.map +0 -1
- package/dist/chunks/options-AMqX7rx_.js.map +0 -1
- package/dist/chunks/repository-rpc-ClAIx3-c.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
Source-neutral, deterministic, content-safe interpretation of the `moldea` repository format.
|
|
6
6
|
|
|
7
|
-
Version
|
|
7
|
+
Version 8 accepts caller-supplied text and `@moldea.ai/repository` version 3 readers. The main, format, and scope entry points remain environment-neutral. Repository access belongs to the caller-supplied reader. Project validation returns content-free summaries, diagnostics, binding coverage, agent assignments, and metadata. Canonical document bodies are available only through an explicit path-scoped byte-range operation.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
pnpm add @moldea.ai/core@
|
|
12
|
+
pnpm add @moldea.ai/core@8 @moldea.ai/repository@3
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Public entry points
|
|
@@ -78,11 +78,11 @@ Core checks each declared binding's file and, when a symbol is named, its syntax
|
|
|
78
78
|
|
|
79
79
|
`RECOGNIZED_RUNTIME_IDS` contains 35 runtime labels plus `custom`. Labels select agent guidance. Core applies the same universal checks to every label and does not interpret SDK calls. Use the installed SDK's type definitions and real application tests to establish runtime behavior. Handoffs remain runtime-native behavior.
|
|
80
80
|
|
|
81
|
-
Every diagnostic has `severity`, `group`, and stable `source: 'core'`. The groups are `discovery`, `manifest`, `references`, `agents`, `mirrors`, and `integration`. The result reports complete `errorCount`, unaccepted `warningCount`, `acceptedWarningCount`, and `diagnosticCount`; warnings do not invalidate a project. Manifest `acceptedWarnings` match a warning's code, subject, and qualifier and require a non-empty reason. Accepted findings remain visible. Unmatched impact patterns are best-effort warnings; a skipped check never makes an acceptance obsolete. Validation and inspection also check the root `/AGENTS.md` managed block against its referenced skill installation, reporting missing blocks, missing installation files, or
|
|
81
|
+
Every diagnostic has `severity`, `group`, and stable `source: 'core'`. The groups are `discovery`, `manifest`, `references`, `agents`, `mirrors`, and `integration`. The result reports complete `errorCount`, unaccepted `warningCount`, `acceptedWarningCount`, and `diagnosticCount`; warnings do not invalidate a project. Manifest `acceptedWarnings` match a warning's code, subject, and qualifier and require a non-empty reason. Accepted findings remain visible. Unmatched impact patterns are best-effort warnings; a skipped check never makes an acceptance obsolete. Validation and inspection also check the root `/AGENTS.md` managed block against its referenced skill installation, reporting missing blocks, missing installation files, drift, or a link that doesn't lead to a file in the repository, with its reason as qualifier, as acceptable integration warnings. They also check whether `/CLAUDE.md`, `/.claude/CLAUDE.md`, or, without shared files, `/CLAUDE.local.md` loads AGENTS.md through an import line or a link, reporting `MOLDEA_INTEGRATION_CLAUDE_IMPORT_MISSING` when it does not. An optional `instructions` reader supplies the four instruction files; links are followed inside the repository with Repository's `resolveRepositoryLink`, and link targets, the skill installation, and every other check read `repository`. `parseIntegrationBlock(text)` extracts the safe relative installation path or a reason it could not be found. Manifest-only operations and `scope` do not read the integration.
|
|
82
82
|
|
|
83
83
|
## Resource and trust boundaries
|
|
84
84
|
|
|
85
|
-
Core uses independent limits for distinct entries, total bytes read, per-file bytes, manifest bytes, logical retained bytes, diagnostics, and coverage records. The default logical retained-memory ceiling is 512 MiB. Before reading a supported source for export analysis, Core checks `maxFileBytes`, confirms read-buffer headroom, and reserves `65536 + sourceBytes * (8 + 512)` bytes for text and syntax nodes. An oversized source or reservation miss records `resource-limit` without a source read; a subsequent failed read, cancellation, or operation budget failure rejects the whole operation. Each distinct source is parsed at most once per operation. Source buffers and syntax reservations are released after analysis; only export names remain in the inventory cache. Core executes no repository code, follows
|
|
85
|
+
Core uses independent limits for distinct entries, total bytes read, per-file bytes, manifest bytes, logical retained bytes, diagnostics, and coverage records. The default logical retained-memory ceiling is 512 MiB. Before reading a supported source for export analysis, Core checks `maxFileBytes`, confirms read-buffer headroom, and reserves `65536 + sourceBytes * (8 + 512)` bytes for text and syntax nodes. An oversized source or reservation miss records `resource-limit` without a source read; a subsequent failed read, cancellation, or operation budget failure rejects the whole operation. Each distinct source is parsed at most once per operation. Source buffers and syntax reservations are released after analysis; only export names remain in the inventory cache. Core executes no repository code, follows instruction links only inside the snapshot, receives no host path or source credential, and returns logical paths only.
|
|
86
86
|
|
|
87
87
|
Logical `RESOURCE_LIMIT_EXCEEDED` exceptions identify the exceeded limit, its configured maximum, the observed or projected usage, and `reduce-input-or-increase-limit`. Verified isolated-worker heap exhaustion uses `review-inspection-capacity` with unknown observed usage. Fixed transport limits have no next action. Core refuses an operation before allocating retained state beyond the applicable ceiling.
|
|
88
88
|
|
package/dist/analysis-worker.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as normalizeCoreOptions } from "./chunks/options-
|
|
1
|
+
import { n as normalizeCoreOptions } from "./chunks/options-l3kVfA-K.js";
|
|
2
2
|
import { n as CoreOperationException } from "./chunks/exceptions-CYf1pCKf.js";
|
|
3
|
-
import { a as encodeInspectionMessage, d as NODE_INSPECTION_TRANSPORT_BYTES, i as decodeInspectionMessage, n as serializeInspectionFailure, o as NODE_INSPECTION_FILE_PAGE_BYTES, r as createInspectionProcessFailure, t as deserializeInspectionFailure } from "./chunks/errors-
|
|
4
|
-
import { i as parseRpcFilePage, n as parseRpcEntry, r as parseRpcEntryPage } from "./chunks/repository-rpc-
|
|
3
|
+
import { a as encodeInspectionMessage, d as NODE_INSPECTION_TRANSPORT_BYTES, i as decodeInspectionMessage, n as serializeInspectionFailure, o as NODE_INSPECTION_FILE_PAGE_BYTES, r as createInspectionProcessFailure, t as deserializeInspectionFailure } from "./chunks/errors-CvWn6gr2.js";
|
|
4
|
+
import { a as parseRpcLinkText, i as parseRpcFilePage, n as parseRpcEntry, r as parseRpcEntryPage } from "./chunks/repository-rpc-DgYwMaGv.js";
|
|
5
5
|
import { RepositorySourceException } from "@moldea.ai/repository";
|
|
6
6
|
import { parentPort, workerData } from "node:worker_threads";
|
|
7
7
|
import { getHeapStatistics } from "node:v8";
|
|
@@ -49,23 +49,36 @@ var requestReader = (request) => {
|
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
};
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
/** Proxies one caller-owned reader; only the repository source lists entries. */
|
|
53
|
+
var createProxyReader = (source, snapshot) => ({
|
|
54
|
+
snapshot,
|
|
54
55
|
getEntry: async (path) => parseRpcEntry(await requestReader({
|
|
55
56
|
method: "getEntry",
|
|
56
|
-
path
|
|
57
|
+
path,
|
|
58
|
+
source
|
|
57
59
|
})),
|
|
58
|
-
listEntriesPage: async (options) => parseRpcEntryPage(await requestReader({
|
|
60
|
+
listEntriesPage: async (options) => source === "repository" ? parseRpcEntryPage(await requestReader({
|
|
59
61
|
method: "listEntriesPage",
|
|
60
62
|
maxEntries: Math.min(128, options.maxEntries),
|
|
61
63
|
...options.cursor === void 0 ? {} : { cursor: options.cursor },
|
|
62
64
|
...options.prefix === void 0 ? {} : { prefix: options.prefix }
|
|
65
|
+
})) : Promise.reject(new RepositorySourceException({
|
|
66
|
+
code: "SOURCE_UNAVAILABLE",
|
|
67
|
+
operation: "list-entries-page",
|
|
68
|
+
path: null,
|
|
69
|
+
retryable: false
|
|
63
70
|
})),
|
|
64
71
|
readFilePage: async (path, options) => parseRpcFilePage(await requestReader({
|
|
65
72
|
method: "readFilePage",
|
|
66
73
|
path,
|
|
67
74
|
offset: options.offset,
|
|
68
|
-
maxBytes: Math.min(NODE_INSPECTION_FILE_PAGE_BYTES, options.maxBytes)
|
|
75
|
+
maxBytes: Math.min(NODE_INSPECTION_FILE_PAGE_BYTES, options.maxBytes),
|
|
76
|
+
source
|
|
77
|
+
})),
|
|
78
|
+
readLinkText: async (path) => parseRpcLinkText(await requestReader({
|
|
79
|
+
method: "readLinkText",
|
|
80
|
+
path,
|
|
81
|
+
source
|
|
69
82
|
})),
|
|
70
83
|
compare: () => Promise.reject(new RepositorySourceException({
|
|
71
84
|
code: "SOURCE_UNAVAILABLE",
|
|
@@ -73,14 +86,19 @@ var repository = {
|
|
|
73
86
|
path: null,
|
|
74
87
|
retryable: false
|
|
75
88
|
}))
|
|
76
|
-
};
|
|
89
|
+
});
|
|
90
|
+
var repository = createProxyReader("repository", start.snapshot);
|
|
91
|
+
var instructions = start.instructions === null ? null : createProxyReader("instructions", start.instructions.snapshot);
|
|
77
92
|
/** Prepares the fixed Core implementation after the parent acknowledges the heap. */
|
|
78
93
|
var prepare = async () => {
|
|
79
|
-
const { createCore } = await import("./chunks/core-
|
|
94
|
+
const { createCore } = await import("./chunks/core-BCMf-ig9.js").then((n) => n.t);
|
|
80
95
|
inspection = await createCore(normalizeCoreOptions({ limits: {
|
|
81
96
|
...start.limits,
|
|
82
97
|
maxRetainedBytes: start.limits.maxRetainedBytes - NODE_INSPECTION_TRANSPORT_BYTES
|
|
83
|
-
} })).createProjectInspection({
|
|
98
|
+
} })).createProjectInspection({
|
|
99
|
+
repository,
|
|
100
|
+
...instructions === null ? {} : { instructions }
|
|
101
|
+
});
|
|
84
102
|
const metadata = {
|
|
85
103
|
source: inspection.source,
|
|
86
104
|
formatVersion: inspection.formatVersion,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-worker.js","names":[],"sources":["../src/node-inspection/analysis-worker.ts"],"sourcesContent":["import { getHeapStatistics } from 'node:v8';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport { RepositorySourceException, type IRepositoryReader } from '@moldea.ai/repository';\n\nimport type { IProjectInspection } from '../contracts/index.js';\nimport { CoreOperationException } from '../exceptions/index.js';\nimport { normalizeCoreOptions } from '../options/index.js';\n\nimport {\n NODE_INSPECTION_FILE_PAGE_BYTES,\n NODE_INSPECTION_MAX_REQUESTS,\n NODE_INSPECTION_TRANSPORT_BYTES,\n} from './constants.js';\nimport { deserializeInspectionFailure, serializeInspectionFailure } from './errors.js';\nimport {\n createInspectionProcessFailure,\n decodeInspectionMessage,\n encodeInspectionMessage,\n} from './protocol.js';\nimport { parseRpcEntry, parseRpcEntryPage, parseRpcFilePage } from './repository-rpc.js';\nimport type { INodeInspectionMessage, INodeReaderRequest } from './types.js';\n\nconst port = parentPort;\nif (port === null) throw createInspectionProcessFailure();\nconst start = decodeInspectionMessage(workerData);\nif (start.kind !== 'start') throw createInspectionProcessFailure();\nconst attemptId = start.attemptId;\nconst maxAnalysisHeapBytes = getHeapStatistics().heap_size_limit;\nlet inspection: IProjectInspection | undefined;\nlet hasRun = false;\nlet isReadingPage = false;\nlet nextRequestId = 0;\nconst pending = new Map<\n number,\n { resolve: (result: unknown) => void; reject: (cause: unknown) => void }\n>();\nconst send = (message: INodeInspectionMessage): void => {\n port.postMessage(encodeInspectionMessage(message));\n};\n\n/** Admits at most four requests across both bridges; no unbounded transport wait queue exists. */\nconst requestReader = (request: INodeReaderRequest): Promise<unknown> => {\n if (pending.size >= NODE_INSPECTION_MAX_REQUESTS)\n return Promise.reject(\n new CoreOperationException({\n code: 'RESOURCE_LIMIT_EXCEEDED',\n operation: 'create-project-inspection',\n limit: 'maxReaderRequests',\n limitMaximum: NODE_INSPECTION_MAX_REQUESTS,\n observedUsage: pending.size + 1,\n nextAction: null,\n }),\n );\n const requestId = nextRequestId++;\n return new Promise<unknown>((resolve, reject) => {\n pending.set(requestId, { resolve, reject });\n try {\n send({ attemptId, kind: 'reader-request', requestId, request });\n } catch (cause) {\n pending.delete(requestId);\n reject(cause instanceof Error ? cause : createInspectionProcessFailure(cause));\n }\n });\n};\n\nconst repository: IRepositoryReader = {\n snapshot: start.snapshot,\n getEntry: async (path) => parseRpcEntry(await requestReader({ method: 'getEntry', path })),\n listEntriesPage: async (options) =>\n parseRpcEntryPage(\n await requestReader({\n method: 'listEntriesPage',\n maxEntries: Math.min(128, options.maxEntries),\n ...(options.cursor === undefined ? {} : { cursor: options.cursor }),\n ...(options.prefix === undefined ? {} : { prefix: options.prefix }),\n }),\n ),\n readFilePage: async (path, options) =>\n parseRpcFilePage(\n await requestReader({\n method: 'readFilePage',\n path,\n offset: options.offset,\n maxBytes: Math.min(NODE_INSPECTION_FILE_PAGE_BYTES, options.maxBytes),\n }),\n ),\n compare: () =>\n Promise.reject(\n new RepositorySourceException({\n code: 'SOURCE_UNAVAILABLE',\n operation: 'create-comparison',\n path: null,\n retryable: false,\n }),\n ),\n};\n\n/** Prepares the fixed Core implementation after the parent acknowledges the heap. */\nconst prepare = async (): Promise<void> => {\n const { createCore } = await import('../core/index.js');\n const options = normalizeCoreOptions({\n limits: {\n ...start.limits,\n maxRetainedBytes: start.limits.maxRetainedBytes - NODE_INSPECTION_TRANSPORT_BYTES,\n },\n });\n const core = createCore(options);\n inspection = await core.createProjectInspection({ repository });\n const metadata = {\n source: inspection.source,\n formatVersion: inspection.formatVersion,\n valid: inspection.valid,\n counts: inspection.counts,\n coverageCounts: inspection.coverageCounts,\n summary: inspection.summary,\n resourceUsage: inspection.resourceUsage,\n inspectionDigest: inspection.inspectionDigest,\n };\n send({\n attemptId,\n kind: 'prepared',\n inspection: {\n ...metadata,\n maxAnalysisHeapBytes,\n resourceUsage: {\n ...metadata.resourceUsage,\n retainedBytes: metadata.resourceUsage.retainedBytes + NODE_INSPECTION_TRANSPORT_BYTES,\n peakRetainedBytes:\n metadata.resourceUsage.peakRetainedBytes + NODE_INSPECTION_TRANSPORT_BYTES,\n },\n },\n });\n};\n\n/** Translates worker failures to safe package contracts while the supervisor stays responsive. */\nconst fail = (cause: unknown): void => {\n try {\n const failure = serializeInspectionFailure(cause);\n if (\n cause instanceof CoreOperationException &&\n cause.code === 'RESOURCE_LIMIT_EXCEEDED' &&\n cause.limit === 'maxRetainedBytes' &&\n cause.observedUsage !== null\n ) {\n failure.options['limitMaximum'] = start.limits.maxRetainedBytes;\n failure.options['observedUsage'] = cause.observedUsage + NODE_INSPECTION_TRANSPORT_BYTES;\n }\n send({ attemptId, kind: 'failure', failure });\n } catch {\n port.close();\n }\n};\n\nport.on('message', (frame: unknown) => {\n try {\n const message = decodeInspectionMessage(frame);\n if (message.attemptId !== attemptId) throw createInspectionProcessFailure();\n if (message.kind === 'run') {\n if (hasRun) throw createInspectionProcessFailure();\n hasRun = true;\n void prepare().catch(fail);\n } else if (message.kind === 'reader-response' || message.kind === 'reader-failure') {\n const request = pending.get(message.requestId);\n if (request === undefined) throw createInspectionProcessFailure();\n pending.delete(message.requestId);\n if (message.kind === 'reader-failure')\n request.reject(deserializeInspectionFailure(message.failure));\n else request.resolve(message.result);\n } else if (message.kind === 'read-page') {\n if (inspection === undefined || isReadingPage) throw createInspectionProcessFailure();\n isReadingPage = true;\n try {\n if (message.input.maxItems > start.limits.maxEntries)\n throw new CoreOperationException({\n code: 'INVALID_ARGUMENT',\n operation: 'create-project-inspection',\n });\n let maxItems = Math.min(256, message.input.maxItems);\n while (true) {\n try {\n const frame = encodeInspectionMessage({\n attemptId,\n kind: 'page',\n requestId: message.requestId,\n result: inspection.readPage({ ...message.input, maxItems }),\n });\n port.postMessage(frame);\n break;\n } catch (cause) {\n if (\n !(cause instanceof CoreOperationException) ||\n cause.code !== 'RESOURCE_LIMIT_EXCEEDED' ||\n cause.limit !== 'maxInspectionMessageBytes' ||\n maxItems === 1\n )\n throw cause;\n maxItems = Math.max(1, Math.floor(maxItems / 2));\n }\n }\n } finally {\n isReadingPage = false;\n }\n } else throw createInspectionProcessFailure();\n } catch (cause) {\n fail(cause);\n }\n});\nport.on('messageerror', fail);\nsend({ attemptId, kind: 'ready', maxAnalysisHeapBytes });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analysis-worker.js","names":[],"sources":["../src/node-inspection/analysis-worker.ts"],"sourcesContent":["import { getHeapStatistics } from 'node:v8';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport {\n RepositorySourceException,\n type IRepositoryReader,\n type IRepositorySnapshot,\n} from '@moldea.ai/repository';\n\nimport type { IProjectInspection } from '../contracts/index.js';\nimport { CoreOperationException } from '../exceptions/index.js';\nimport { normalizeCoreOptions } from '../options/index.js';\n\nimport {\n NODE_INSPECTION_FILE_PAGE_BYTES,\n NODE_INSPECTION_MAX_REQUESTS,\n NODE_INSPECTION_TRANSPORT_BYTES,\n} from './constants.js';\nimport { deserializeInspectionFailure, serializeInspectionFailure } from './errors.js';\nimport {\n createInspectionProcessFailure,\n decodeInspectionMessage,\n encodeInspectionMessage,\n} from './protocol.js';\nimport {\n parseRpcEntry,\n parseRpcEntryPage,\n parseRpcFilePage,\n parseRpcLinkText,\n} from './repository-rpc.js';\nimport type { INodeInspectionMessage, INodeReaderRequest, INodeReaderSource } from './types.js';\n\nconst port = parentPort;\nif (port === null) throw createInspectionProcessFailure();\nconst start = decodeInspectionMessage(workerData);\nif (start.kind !== 'start') throw createInspectionProcessFailure();\nconst attemptId = start.attemptId;\nconst maxAnalysisHeapBytes = getHeapStatistics().heap_size_limit;\nlet inspection: IProjectInspection | undefined;\nlet hasRun = false;\nlet isReadingPage = false;\nlet nextRequestId = 0;\nconst pending = new Map<\n number,\n { resolve: (result: unknown) => void; reject: (cause: unknown) => void }\n>();\nconst send = (message: INodeInspectionMessage): void => {\n port.postMessage(encodeInspectionMessage(message));\n};\n\n/** Admits at most four requests across both bridges; no unbounded transport wait queue exists. */\nconst requestReader = (request: INodeReaderRequest): Promise<unknown> => {\n if (pending.size >= NODE_INSPECTION_MAX_REQUESTS)\n return Promise.reject(\n new CoreOperationException({\n code: 'RESOURCE_LIMIT_EXCEEDED',\n operation: 'create-project-inspection',\n limit: 'maxReaderRequests',\n limitMaximum: NODE_INSPECTION_MAX_REQUESTS,\n observedUsage: pending.size + 1,\n nextAction: null,\n }),\n );\n const requestId = nextRequestId++;\n return new Promise<unknown>((resolve, reject) => {\n pending.set(requestId, { resolve, reject });\n try {\n send({ attemptId, kind: 'reader-request', requestId, request });\n } catch (cause) {\n pending.delete(requestId);\n reject(cause instanceof Error ? cause : createInspectionProcessFailure(cause));\n }\n });\n};\n\n/** Proxies one caller-owned reader; only the repository source lists entries. */\nconst createProxyReader = (\n source: INodeReaderSource,\n snapshot: IRepositorySnapshot,\n): IRepositoryReader => ({\n snapshot,\n getEntry: async (path) =>\n parseRpcEntry(await requestReader({ method: 'getEntry', path, source })),\n listEntriesPage: async (options) =>\n source === 'repository'\n ? parseRpcEntryPage(\n await requestReader({\n method: 'listEntriesPage',\n maxEntries: Math.min(128, options.maxEntries),\n ...(options.cursor === undefined ? {} : { cursor: options.cursor }),\n ...(options.prefix === undefined ? {} : { prefix: options.prefix }),\n }),\n )\n : Promise.reject(\n new RepositorySourceException({\n code: 'SOURCE_UNAVAILABLE',\n operation: 'list-entries-page',\n path: null,\n retryable: false,\n }),\n ),\n readFilePage: async (path, options) =>\n parseRpcFilePage(\n await requestReader({\n method: 'readFilePage',\n path,\n offset: options.offset,\n maxBytes: Math.min(NODE_INSPECTION_FILE_PAGE_BYTES, options.maxBytes),\n source,\n }),\n ),\n readLinkText: async (path) =>\n parseRpcLinkText(await requestReader({ method: 'readLinkText', path, source })),\n compare: () =>\n Promise.reject(\n new RepositorySourceException({\n code: 'SOURCE_UNAVAILABLE',\n operation: 'create-comparison',\n path: null,\n retryable: false,\n }),\n ),\n});\n\nconst repository = createProxyReader('repository', start.snapshot);\nconst instructions: IRepositoryReader | null =\n start.instructions === null\n ? null\n : createProxyReader('instructions', start.instructions.snapshot);\n\n/** Prepares the fixed Core implementation after the parent acknowledges the heap. */\nconst prepare = async (): Promise<void> => {\n const { createCore } = await import('../core/index.js');\n const options = normalizeCoreOptions({\n limits: {\n ...start.limits,\n maxRetainedBytes: start.limits.maxRetainedBytes - NODE_INSPECTION_TRANSPORT_BYTES,\n },\n });\n const core = createCore(options);\n inspection = await core.createProjectInspection({\n repository,\n ...(instructions === null ? {} : { instructions }),\n });\n const metadata = {\n source: inspection.source,\n formatVersion: inspection.formatVersion,\n valid: inspection.valid,\n counts: inspection.counts,\n coverageCounts: inspection.coverageCounts,\n summary: inspection.summary,\n resourceUsage: inspection.resourceUsage,\n inspectionDigest: inspection.inspectionDigest,\n };\n send({\n attemptId,\n kind: 'prepared',\n inspection: {\n ...metadata,\n maxAnalysisHeapBytes,\n resourceUsage: {\n ...metadata.resourceUsage,\n retainedBytes: metadata.resourceUsage.retainedBytes + NODE_INSPECTION_TRANSPORT_BYTES,\n peakRetainedBytes:\n metadata.resourceUsage.peakRetainedBytes + NODE_INSPECTION_TRANSPORT_BYTES,\n },\n },\n });\n};\n\n/** Translates worker failures to safe package contracts while the supervisor stays responsive. */\nconst fail = (cause: unknown): void => {\n try {\n const failure = serializeInspectionFailure(cause);\n if (\n cause instanceof CoreOperationException &&\n cause.code === 'RESOURCE_LIMIT_EXCEEDED' &&\n cause.limit === 'maxRetainedBytes' &&\n cause.observedUsage !== null\n ) {\n failure.options['limitMaximum'] = start.limits.maxRetainedBytes;\n failure.options['observedUsage'] = cause.observedUsage + NODE_INSPECTION_TRANSPORT_BYTES;\n }\n send({ attemptId, kind: 'failure', failure });\n } catch {\n port.close();\n }\n};\n\nport.on('message', (frame: unknown) => {\n try {\n const message = decodeInspectionMessage(frame);\n if (message.attemptId !== attemptId) throw createInspectionProcessFailure();\n if (message.kind === 'run') {\n if (hasRun) throw createInspectionProcessFailure();\n hasRun = true;\n void prepare().catch(fail);\n } else if (message.kind === 'reader-response' || message.kind === 'reader-failure') {\n const request = pending.get(message.requestId);\n if (request === undefined) throw createInspectionProcessFailure();\n pending.delete(message.requestId);\n if (message.kind === 'reader-failure')\n request.reject(deserializeInspectionFailure(message.failure));\n else request.resolve(message.result);\n } else if (message.kind === 'read-page') {\n if (inspection === undefined || isReadingPage) throw createInspectionProcessFailure();\n isReadingPage = true;\n try {\n if (message.input.maxItems > start.limits.maxEntries)\n throw new CoreOperationException({\n code: 'INVALID_ARGUMENT',\n operation: 'create-project-inspection',\n });\n let maxItems = Math.min(256, message.input.maxItems);\n while (true) {\n try {\n const frame = encodeInspectionMessage({\n attemptId,\n kind: 'page',\n requestId: message.requestId,\n result: inspection.readPage({ ...message.input, maxItems }),\n });\n port.postMessage(frame);\n break;\n } catch (cause) {\n if (\n !(cause instanceof CoreOperationException) ||\n cause.code !== 'RESOURCE_LIMIT_EXCEEDED' ||\n cause.limit !== 'maxInspectionMessageBytes' ||\n maxItems === 1\n )\n throw cause;\n maxItems = Math.max(1, Math.floor(maxItems / 2));\n }\n }\n } finally {\n isReadingPage = false;\n }\n } else throw createInspectionProcessFailure();\n } catch (cause) {\n fail(cause);\n }\n});\nport.on('messageerror', fail);\nsend({ attemptId, kind: 'ready', maxAnalysisHeapBytes });\n"],"mappings":"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"}
|