@cleocode/core 2026.10.5 → 2026.10.6-rc.ci.673
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/bootstrap.d.ts +13 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +21 -32
- package/dist/bootstrap.js.map +1 -1
- package/dist/build-provenance.json +2 -2
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +3 -1
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-device.d.ts +1 -1
- package/dist/cloud/nexus-presence-refresh.d.ts.map +1 -1
- package/dist/cloud/nexus-presence-refresh.js +20 -13
- package/dist/cloud/nexus-presence-refresh.js.map +1 -1
- package/dist/cloud/nexus-vault.d.ts.map +1 -1
- package/dist/cloud/nexus-vault.js +4 -1
- package/dist/cloud/nexus-vault.js.map +1 -1
- package/dist/docs/derive-links.d.ts +69 -0
- package/dist/docs/derive-links.d.ts.map +1 -0
- package/dist/docs/derive-links.js +85 -0
- package/dist/docs/derive-links.js.map +1 -0
- package/dist/docs/docs-generator.d.ts.map +1 -1
- package/dist/docs/docs-generator.js +2 -0
- package/dist/docs/docs-generator.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +24 -4
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/fetch-result.d.ts +77 -0
- package/dist/docs/fetch-result.d.ts.map +1 -0
- package/dist/docs/fetch-result.js +132 -0
- package/dist/docs/fetch-result.js.map +1 -0
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +9 -0
- package/dist/docs/supersede.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +64 -29
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/row-identity-refill.d.ts.map +1 -1
- package/dist/doctor/row-identity-refill.js +25 -10
- package/dist/doctor/row-identity-refill.js.map +1 -1
- package/dist/doctor/row-identity.d.ts.map +1 -1
- package/dist/doctor/row-identity.js +8 -2
- package/dist/doctor/row-identity.js.map +1 -1
- package/dist/doctor/sync-repair.d.ts +5 -0
- package/dist/doctor/sync-repair.d.ts.map +1 -1
- package/dist/doctor/sync-repair.js +11 -0
- package/dist/doctor/sync-repair.js.map +1 -1
- package/dist/doctor/sync-triggers.d.ts.map +1 -1
- package/dist/doctor/sync-triggers.js +3 -17
- package/dist/doctor/sync-triggers.js.map +1 -1
- package/dist/hygiene/validate-spawn-readiness.d.ts +6 -1
- package/dist/hygiene/validate-spawn-readiness.d.ts.map +1 -1
- package/dist/hygiene/validate-spawn-readiness.js +11 -6
- package/dist/hygiene/validate-spawn-readiness.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +10 -1
- package/dist/init.js.map +1 -1
- package/dist/injection.d.ts +37 -12
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +152 -35
- package/dist/injection.js.map +1 -1
- package/dist/memory/brain-search.d.ts.map +1 -1
- package/dist/memory/brain-search.js +7 -32
- package/dist/memory/brain-search.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +2 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +51 -9
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/nexus/assessment-projection.d.ts +96 -1
- package/dist/nexus/assessment-projection.d.ts.map +1 -1
- package/dist/nexus/assessment-projection.js +135 -0
- package/dist/nexus/assessment-projection.js.map +1 -1
- package/dist/nexus/assessment-store.d.ts +54 -0
- package/dist/nexus/assessment-store.d.ts.map +1 -1
- package/dist/nexus/assessment-store.js +161 -2
- package/dist/nexus/assessment-store.js.map +1 -1
- package/dist/nexus/knowledge.d.ts +19 -0
- package/dist/nexus/knowledge.d.ts.map +1 -1
- package/dist/nexus/knowledge.js +56 -2
- package/dist/nexus/knowledge.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +12 -1
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/release/commit-presence.d.ts +24 -0
- package/dist/release/commit-presence.d.ts.map +1 -1
- package/dist/release/commit-presence.js +31 -0
- package/dist/release/commit-presence.js.map +1 -1
- package/dist/release/plan.d.ts +8 -6
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +11 -6
- package/dist/release/plan.js.map +1 -1
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +10 -8
- package/dist/release/reconcile.js.map +1 -1
- package/dist/release/verify-provenance.d.ts.map +1 -1
- package/dist/release/verify-provenance.js +6 -8
- package/dist/release/verify-provenance.js.map +1 -1
- package/dist/resources/admission-ledger.d.ts +66 -0
- package/dist/resources/admission-ledger.d.ts.map +1 -1
- package/dist/resources/admission-ledger.js +145 -6
- package/dist/resources/admission-ledger.js.map +1 -1
- package/dist/resources/run-class.d.ts +71 -0
- package/dist/resources/run-class.d.ts.map +1 -1
- package/dist/resources/run-class.js +203 -0
- package/dist/resources/run-class.js.map +1 -1
- package/dist/resources/run-governed.d.ts +2 -0
- package/dist/resources/run-governed.d.ts.map +1 -1
- package/dist/resources/run-governed.js +1 -0
- package/dist/resources/run-governed.js.map +1 -1
- package/dist/scaffold/ensure-config.d.ts +20 -9
- package/dist/scaffold/ensure-config.d.ts.map +1 -1
- package/dist/scaffold/ensure-config.js +56 -23
- package/dist/scaffold/ensure-config.js.map +1 -1
- package/dist/scaffold/ensure-skills.d.ts +10 -0
- package/dist/scaffold/ensure-skills.d.ts.map +1 -1
- package/dist/scaffold/ensure-skills.js +47 -3
- package/dist/scaffold/ensure-skills.js.map +1 -1
- package/dist/scaffold/upgrade-file-journal.d.ts +79 -0
- package/dist/scaffold/upgrade-file-journal.d.ts.map +1 -0
- package/dist/scaffold/upgrade-file-journal.js +111 -0
- package/dist/scaffold/upgrade-file-journal.js.map +1 -0
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +10 -2
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +3 -0
- package/dist/sessions/index.js.map +1 -1
- package/dist/spawn/worktree-lock-holder.d.ts +59 -1
- package/dist/spawn/worktree-lock-holder.d.ts.map +1 -1
- package/dist/spawn/worktree-lock-holder.js +114 -0
- package/dist/spawn/worktree-lock-holder.js.map +1 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +38 -0
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/backup-recover.d.ts +4 -4
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +11 -4
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/backup-sidecar.d.ts +19 -1
- package/dist/store/backup-sidecar.d.ts.map +1 -1
- package/dist/store/backup-sidecar.js +57 -6
- package/dist/store/backup-sidecar.js.map +1 -1
- package/dist/store/db-helpers.js +1 -1
- package/dist/store/display-id-alias.js +1 -1
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +2 -0
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +28 -16
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/archive.d.ts +42 -2
- package/dist/store/exodus/archive.d.ts.map +1 -1
- package/dist/store/exodus/archive.js +81 -4
- package/dist/store/exodus/archive.js.map +1 -1
- package/dist/store/exodus/bare-family.d.ts +104 -0
- package/dist/store/exodus/bare-family.d.ts.map +1 -0
- package/dist/store/exodus/bare-family.js +470 -0
- package/dist/store/exodus/bare-family.js.map +1 -0
- package/dist/store/exodus/column-transforms.d.ts.map +1 -1
- package/dist/store/exodus/column-transforms.js +15 -8
- package/dist/store/exodus/column-transforms.js.map +1 -1
- package/dist/store/exodus/health.d.ts +2 -0
- package/dist/store/exodus/health.d.ts.map +1 -1
- package/dist/store/exodus/health.js +7 -1
- package/dist/store/exodus/health.js.map +1 -1
- package/dist/store/exodus/index.d.ts +2 -2
- package/dist/store/exodus/index.d.ts.map +1 -1
- package/dist/store/exodus/index.js +2 -2
- package/dist/store/exodus/index.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +30 -1
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +11 -0
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +26 -1
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/prior-recoveries.d.ts +3 -2
- package/dist/store/exodus/prior-recoveries.d.ts.map +1 -1
- package/dist/store/exodus/prior-recoveries.js +7 -3
- package/dist/store/exodus/prior-recoveries.js.map +1 -1
- package/dist/store/exodus/reconcile.d.ts +44 -6
- package/dist/store/exodus/reconcile.d.ts.map +1 -1
- package/dist/store/exodus/reconcile.js +246 -173
- package/dist/store/exodus/reconcile.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts +48 -0
- package/dist/store/exodus/recovery.d.ts.map +1 -1
- package/dist/store/exodus/recovery.js +104 -6
- package/dist/store/exodus/recovery.js.map +1 -1
- package/dist/store/exodus/seal.d.ts.map +1 -1
- package/dist/store/exodus/seal.js +4 -2
- package/dist/store/exodus/seal.js.map +1 -1
- package/dist/store/exodus/table-order.d.ts +6 -0
- package/dist/store/exodus/table-order.d.ts.map +1 -1
- package/dist/store/exodus/table-order.js +15 -0
- package/dist/store/exodus/table-order.js.map +1 -1
- package/dist/store/exodus/types.d.ts +4 -0
- package/dist/store/exodus/types.d.ts.map +1 -1
- package/dist/store/exodus/types.js +4 -0
- package/dist/store/exodus/types.js.map +1 -1
- package/dist/store/exodus/verify-migration.d.ts.map +1 -1
- package/dist/store/exodus/verify-migration.js +22 -17
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/dist/store/identity-share.d.ts +14 -0
- package/dist/store/identity-share.d.ts.map +1 -1
- package/dist/store/identity-share.js +33 -0
- package/dist/store/identity-share.js.map +1 -1
- package/dist/store/lock.d.ts +33 -0
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +60 -0
- package/dist/store/lock.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +7 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts +3 -2
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +7 -5
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts +1 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +9 -1
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/repair-malformed-dbs.d.ts.map +1 -1
- package/dist/store/repair-malformed-dbs.js +36 -6
- package/dist/store/repair-malformed-dbs.js.map +1 -1
- package/dist/store/restore-marker.d.ts +20 -2
- package/dist/store/restore-marker.d.ts.map +1 -1
- package/dist/store/restore-marker.js +41 -1
- package/dist/store/restore-marker.js.map +1 -1
- package/dist/store/row-identity-flag.d.ts +9 -6
- package/dist/store/row-identity-flag.d.ts.map +1 -1
- package/dist/store/row-identity-flag.js +10 -7
- package/dist/store/row-identity-flag.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts +4 -3
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +132 -31
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts +81 -14
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +238 -32
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +368 -0
- package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
- package/dist/store/schema/cleo-shared/brain.js +104 -2
- package/dist/store/schema/cleo-shared/brain.js.map +1 -1
- package/dist/store/sync/apply/applier.d.ts +5 -0
- package/dist/store/sync/apply/applier.d.ts.map +1 -1
- package/dist/store/sync/apply/applier.js +5 -1
- package/dist/store/sync/apply/applier.js.map +1 -1
- package/dist/store/sync/apply/parent-delete.d.ts.map +1 -1
- package/dist/store/sync/apply/parent-delete.js +4 -0
- package/dist/store/sync/apply/parent-delete.js.map +1 -1
- package/dist/store/sync/capture.d.ts +13 -1
- package/dist/store/sync/capture.d.ts.map +1 -1
- package/dist/store/sync/capture.js +31 -3
- package/dist/store/sync/capture.js.map +1 -1
- package/dist/store/sync/flags.d.ts +14 -5
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +20 -8
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/genesis.d.ts +130 -0
- package/dist/store/sync/genesis.d.ts.map +1 -0
- package/dist/store/sync/genesis.js +337 -0
- package/dist/store/sync/genesis.js.map +1 -0
- package/dist/store/sync/repair.d.ts +2 -2
- package/dist/store/sync/repair.d.ts.map +1 -1
- package/dist/store/sync/repair.js +55 -15
- package/dist/store/sync/repair.js.map +1 -1
- package/dist/store/sync/sealer.d.ts +14 -0
- package/dist/store/sync/sealer.d.ts.map +1 -1
- package/dist/store/sync/sealer.js +27 -6
- package/dist/store/sync/sealer.js.map +1 -1
- package/dist/store/sync/segments.d.ts +124 -0
- package/dist/store/sync/segments.d.ts.map +1 -0
- package/dist/store/sync/segments.js +267 -0
- package/dist/store/sync/segments.js.map +1 -0
- package/dist/store/sync/sequencing.d.ts +44 -1
- package/dist/store/sync/sequencing.d.ts.map +1 -1
- package/dist/store/sync/sequencing.js +59 -2
- package/dist/store/sync/sequencing.js.map +1 -1
- package/dist/store/sync/timestamp-canon.d.ts +6 -3
- package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
- package/dist/store/sync/timestamp-canon.js +55 -4
- package/dist/store/sync/timestamp-canon.js.map +1 -1
- package/dist/store/sync/txn-signing.d.ts +69 -0
- package/dist/store/sync/txn-signing.d.ts.map +1 -0
- package/dist/store/sync/txn-signing.js +81 -0
- package/dist/store/sync/txn-signing.js.map +1 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +30 -0
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +65 -2
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/system/backup.d.ts +3 -2
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +43 -17
- package/dist/system/backup.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +2 -1
- package/dist/system/health.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +26 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +95 -28
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +14 -4
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +50 -4
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/test-run-binding.d.ts +14 -0
- package/dist/tasks/test-run-binding.d.ts.map +1 -1
- package/dist/tasks/test-run-binding.js +35 -4
- package/dist/tasks/test-run-binding.js.map +1 -1
- package/dist/upgrade.d.ts +6 -0
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +58 -11
- package/dist/upgrade.js.map +1 -1
- package/migrations/drizzle-cleo-global/20261010120000_t12894-brain-row-uids/migration.sql +88 -0
- package/migrations/drizzle-cleo-project/20261010120000_t12894-brain-row-uids/migration.sql +92 -0
- package/migrations/sync-journal/20261007120000_t12343-segment-outbox/migration.sql +38 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +2 -2
|
@@ -38,6 +38,7 @@ function parseCount(flag, value) {
|
|
|
38
38
|
if (value === undefined)
|
|
39
39
|
return undefined;
|
|
40
40
|
if (!/^\d+$/.test(value.trim()))
|
|
41
|
+
// @sync-invariant none:input-shape a malformed CLI flag is refused before any read; nothing is written
|
|
41
42
|
throw new CleoError(ExitCode.INVALID_INPUT, `--${flag} must be a non-negative integer`, {
|
|
42
43
|
fix: `cleo nexus status --${flag} <n>`,
|
|
43
44
|
details: { field: flag, actual: value },
|
|
@@ -57,6 +58,7 @@ function parseCount(flag, value) {
|
|
|
57
58
|
export function parseAssessmentFilesRequest(flags) {
|
|
58
59
|
const status = flags.fileStatus?.trim();
|
|
59
60
|
if (status !== undefined && !GRAPH_INDEX_FILE_STATUSES.some((known) => known === status))
|
|
61
|
+
// @sync-invariant none:input-shape a malformed CLI flag is refused before any read; nothing is written
|
|
60
62
|
throw new CleoError(ExitCode.INVALID_INPUT, `--file-status must be one of ${GRAPH_INDEX_FILE_STATUSES.join(', ')}`, {
|
|
61
63
|
fix: 'cleo nexus status --file-status failed',
|
|
62
64
|
details: { field: 'file-status', actual: status },
|
|
@@ -140,4 +142,137 @@ export function projectAssessmentFiles(assessment, request = {}) {
|
|
|
140
142
|
filesPage: pageFiles(files, request),
|
|
141
143
|
};
|
|
142
144
|
}
|
|
145
|
+
/** References in the default page of `assessment.referencesPage` (T13330). */
|
|
146
|
+
export const DEFAULT_REFERENCE_PAGE_SIZE = 20;
|
|
147
|
+
/**
|
|
148
|
+
* Largest reference page one status call returns (T13330).
|
|
149
|
+
*
|
|
150
|
+
* A reference is ~700 B of JSON, so this bounds a page near 3.5 MB however
|
|
151
|
+
* large the repository; the whole list is walked with `nextOffset`.
|
|
152
|
+
*/
|
|
153
|
+
export const MAX_REFERENCE_PAGE_SIZE = 5_000;
|
|
154
|
+
/**
|
|
155
|
+
* Zero count for every reference kind. Typed as the contract's
|
|
156
|
+
* `Record<kind, number>`, so the compiler rejects a missing or unknown kind:
|
|
157
|
+
* the kind list below is derived from it and cannot drift from the contract.
|
|
158
|
+
*/
|
|
159
|
+
const EMPTY_REFERENCE_KIND_COUNTS = {
|
|
160
|
+
'unmodeled-source': 0,
|
|
161
|
+
ambiguous: 0,
|
|
162
|
+
external: 0,
|
|
163
|
+
dynamic: 0,
|
|
164
|
+
shadowed: 0,
|
|
165
|
+
unresolved: 0,
|
|
166
|
+
};
|
|
167
|
+
/** Whether `value` names a contract reference kind. */
|
|
168
|
+
function isReferenceKind(value) {
|
|
169
|
+
return Object.hasOwn(EMPTY_REFERENCE_KIND_COUNTS, value);
|
|
170
|
+
}
|
|
171
|
+
/** Every reference limitation kind, derived from the contract's kind counts. */
|
|
172
|
+
export const GRAPH_INDEX_REFERENCE_KINDS = Object.keys(EMPTY_REFERENCE_KIND_COUNTS).filter(isReferenceKind);
|
|
173
|
+
/**
|
|
174
|
+
* Validate `cleo nexus status --references` paging flags (T13330).
|
|
175
|
+
* @param flags - Raw flag values as the CLI received them.
|
|
176
|
+
* @returns The validated request; a 20-reference first page by default.
|
|
177
|
+
* @throws CleoError with `INVALID_INPUT` for a malformed or out-of-range count or an unknown kind.
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* parseReferencePageRequest({ limit: '500', offset: '1000', kind: 'unresolved' });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export function parseReferencePageRequest(flags) {
|
|
184
|
+
const kind = flags.kind?.trim();
|
|
185
|
+
if (kind !== undefined && !GRAPH_INDEX_REFERENCE_KINDS.some((known) => known === kind))
|
|
186
|
+
// @sync-invariant none:input-shape a malformed CLI flag is refused before any read; nothing is written
|
|
187
|
+
throw new CleoError(ExitCode.INVALID_INPUT, `--reference-kind must be one of ${GRAPH_INDEX_REFERENCE_KINDS.join(', ')}`, {
|
|
188
|
+
fix: 'cleo nexus status --references --reference-kind unresolved',
|
|
189
|
+
details: { field: 'reference-kind', actual: kind },
|
|
190
|
+
});
|
|
191
|
+
const limit = parseCount('references-limit', flags.limit) ?? DEFAULT_REFERENCE_PAGE_SIZE;
|
|
192
|
+
if (limit < 1 || limit > MAX_REFERENCE_PAGE_SIZE)
|
|
193
|
+
// @sync-invariant none:input-shape a malformed CLI flag is refused before any read; nothing is written
|
|
194
|
+
throw new CleoError(ExitCode.INVALID_INPUT, `--references-limit must be from 1 to ${MAX_REFERENCE_PAGE_SIZE}; walk the whole list ` +
|
|
195
|
+
'with --references-offset <referencesPage.nextOffset>', {
|
|
196
|
+
fix: `cleo nexus status --references --references-limit ${MAX_REFERENCE_PAGE_SIZE} --references-offset 0`,
|
|
197
|
+
details: { field: 'references-limit', actual: flags.limit },
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
limit,
|
|
201
|
+
offset: parseCount('references-offset', flags.offset) ?? 0,
|
|
202
|
+
...(kind === undefined
|
|
203
|
+
? {}
|
|
204
|
+
: { kind: GRAPH_INDEX_REFERENCE_KINDS.find((known) => known === kind) }),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Attach a reference page to a status projection (T13330).
|
|
209
|
+
*
|
|
210
|
+
* `references` is never placed in the projection: it is named in `_withheld`
|
|
211
|
+
* with the whole list's UTF-8 JSON size, beside the per-kind counts and the
|
|
212
|
+
* requested page, so a consumer never mistakes a page for the complete list.
|
|
213
|
+
* @param projection - The bounded status projection.
|
|
214
|
+
* @param result - The page and totals read from the published generation.
|
|
215
|
+
* @returns The projection with `referencesByKind` and `referencesPage`.
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* const status = withReferencePage(projectAssessmentFiles(summary), page);
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export function withReferencePage(projection, result) {
|
|
222
|
+
const { references: _references, ...rest } = projection;
|
|
223
|
+
return {
|
|
224
|
+
...rest,
|
|
225
|
+
_withheld: { ...projection._withheld, references: result.bytes },
|
|
226
|
+
referencesByKind: result.byKind,
|
|
227
|
+
referencesPage: result.page,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Fold a stream of stored references into one page plus whole-list totals (T13330).
|
|
232
|
+
*
|
|
233
|
+
* Every reference is counted by kind and then dropped; only the rows of the
|
|
234
|
+
* requested page are kept. Memory is therefore bounded by the page whatever
|
|
235
|
+
* the length of the list — 846 151 references on one repository.
|
|
236
|
+
* @param items - Stored references in stored order, with their JSON sizes.
|
|
237
|
+
* @param request - Page size, offset and optional kind filter.
|
|
238
|
+
* @param readers - Validation for a reference's kind and for a page row.
|
|
239
|
+
* @returns The page, per-kind counts, whole-list JSON size and reference count.
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* const result = await pageReferences(streamStoredReferences(blob), request, readers);
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export async function pageReferences(items, request, readers) {
|
|
246
|
+
const byKind = { ...EMPTY_REFERENCE_KIND_COUNTS };
|
|
247
|
+
const rows = [];
|
|
248
|
+
let count = 0;
|
|
249
|
+
let matching = 0;
|
|
250
|
+
let bytes = 0;
|
|
251
|
+
for await (const { item, bytes: size } of items) {
|
|
252
|
+
const kind = readers.kind(item);
|
|
253
|
+
byKind[kind] += 1;
|
|
254
|
+
count += 1;
|
|
255
|
+
bytes += size;
|
|
256
|
+
if (request.kind !== undefined && kind !== request.kind)
|
|
257
|
+
continue;
|
|
258
|
+
if (matching >= request.offset && rows.length < request.limit)
|
|
259
|
+
rows.push(readers.row(item));
|
|
260
|
+
matching += 1;
|
|
261
|
+
}
|
|
262
|
+
const end = Math.min(request.offset + request.limit, matching);
|
|
263
|
+
return {
|
|
264
|
+
count,
|
|
265
|
+
byKind,
|
|
266
|
+
bytes: bytes + 2 + Math.max(count - 1, 0),
|
|
267
|
+
page: {
|
|
268
|
+
offset: request.offset,
|
|
269
|
+
limit: request.limit,
|
|
270
|
+
...(request.kind === undefined ? {} : { kind: request.kind }),
|
|
271
|
+
total: matching,
|
|
272
|
+
returned: rows.length,
|
|
273
|
+
nextOffset: end < matching ? end : null,
|
|
274
|
+
rows,
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
143
278
|
//# sourceMappingURL=assessment-projection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assessment-projection.js","sourceRoot":"","sources":["../../src/nexus/assessment-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"assessment-projection.js","sourceRoot":"","sources":["../../src/nexus/assessment-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
* ~0.6 s to compress and ~0.55 s to inflate. A historical plain-text list is
|
|
21
21
|
* still read as stored.
|
|
22
22
|
*
|
|
23
|
+
* The list is written one reference per line, in gzip members of
|
|
24
|
+
* {@link REFERENCES_PER_MEMBER} references, and read back line by line
|
|
25
|
+
* (T13326). Building it as ONE `JSON.stringify` string failed outright on a
|
|
26
|
+
* 5 357-file repository: 846 151 references exceed V8's maximum string length
|
|
27
|
+
* (2^29 - 24 characters), so publication died with "Invalid string length"
|
|
28
|
+
* after every other phase had finished. The text is still one valid JSON
|
|
29
|
+
* array, so a reader that parses it whole keeps working for lists that fit.
|
|
30
|
+
*
|
|
23
31
|
* Code placed in `packages/core/` per Package-Boundary Check — verified against AGENTS.md.
|
|
24
32
|
*
|
|
25
33
|
* @task T12348
|
|
@@ -34,10 +42,56 @@ export declare const ASSESSMENT_REFERENCES_KEY = "graph_assessment_references";
|
|
|
34
42
|
/**
|
|
35
43
|
* Encode a reference list for storage under {@link ASSESSMENT_REFERENCES_KEY}.
|
|
36
44
|
*
|
|
45
|
+
* The decompressed text is the JSON array `[\n<ref>,\n<ref>\n]` — one
|
|
46
|
+
* reference per line — written as concatenated gzip members, so no string
|
|
47
|
+
* longer than one member's text is ever built (T13326).
|
|
48
|
+
*
|
|
37
49
|
* @param references - The generation's retained references.
|
|
38
50
|
* @returns gzip-compressed JSON, stored as a BLOB.
|
|
39
51
|
*/
|
|
40
52
|
export declare function encodeStoredReferences(references: readonly GraphIndexReferenceReport[]): Uint8Array;
|
|
53
|
+
/**
|
|
54
|
+
* Parse a stored reference list into its items without building one string
|
|
55
|
+
* of the whole list (T13326).
|
|
56
|
+
*
|
|
57
|
+
* Reads the line-per-reference form written by {@link encodeStoredReferences},
|
|
58
|
+
* and the single-line form written before it — compressed or plain text —
|
|
59
|
+
* by parsing that one line whole, as it was always read.
|
|
60
|
+
*
|
|
61
|
+
* @param value - The raw `_nexus_meta.value` of {@link ASSESSMENT_REFERENCES_KEY}.
|
|
62
|
+
* @returns The stored items, not yet validated.
|
|
63
|
+
* @throws When the value is neither text nor a compressed list, or is not a JSON array.
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const references = z.array(referenceSchema).parse(parseStoredReferences(row.value));
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function parseStoredReferences(value: unknown): unknown[];
|
|
70
|
+
/** One stored reference, not yet validated, and the UTF-8 size of its JSON. */
|
|
71
|
+
export interface StoredReferenceItem {
|
|
72
|
+
/** The parsed reference. */
|
|
73
|
+
item: unknown;
|
|
74
|
+
/** UTF-8 bytes of the reference's own JSON text. */
|
|
75
|
+
bytes: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Stream a stored reference list one reference at a time (T13330).
|
|
79
|
+
*
|
|
80
|
+
* The compressed list is inflated incrementally and split on line breaks, so
|
|
81
|
+
* neither the decompressed text nor the parsed list is ever held whole: a
|
|
82
|
+
* reader that keeps one page holds one page. The single-line form written
|
|
83
|
+
* before T13326 has no line breaks to split on; it was small enough to be
|
|
84
|
+
* written whole, so it is parsed whole, as it was always read.
|
|
85
|
+
*
|
|
86
|
+
* @param value - The raw `_nexus_meta.value` of {@link ASSESSMENT_REFERENCES_KEY}.
|
|
87
|
+
* @returns The stored references in stored order.
|
|
88
|
+
* @throws When the value is neither text nor a compressed list, or is not a JSON array.
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* for await (const { item } of streamStoredReferences(row.value)) count++;
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function streamStoredReferences(value: unknown): AsyncGenerator<StoredReferenceItem, void, undefined>;
|
|
41
95
|
/**
|
|
42
96
|
* Decode a stored reference list back to its JSON text.
|
|
43
97
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assessment-store.d.ts","sourceRoot":"","sources":["../../src/nexus/assessment-store.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"assessment-store.d.ts","sourceRoot":"","sources":["../../src/nexus/assessment-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAE3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,mDAAmD;AACnD,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,gCAAgC,CAAC;AAiBvE;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,yBAAyB,EAAE,GAC/C,UAAU,CAYZ;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CA0B/D;AAED,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAuB,sBAAsB,CAC3C,KAAK,EAAE,OAAO,GACb,cAAc,CAAC,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,CAqDtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAI7D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,oBAAoB,GAAG,oBAAoB,CAIxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,EACnC,UAAU,EAAE,oBAAoB,GAC/B,oBAAoB,CAWtB;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,EAAE,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAAG,OAAO,CAMhG"}
|
|
@@ -20,13 +20,22 @@
|
|
|
20
20
|
* ~0.6 s to compress and ~0.55 s to inflate. A historical plain-text list is
|
|
21
21
|
* still read as stored.
|
|
22
22
|
*
|
|
23
|
+
* The list is written one reference per line, in gzip members of
|
|
24
|
+
* {@link REFERENCES_PER_MEMBER} references, and read back line by line
|
|
25
|
+
* (T13326). Building it as ONE `JSON.stringify` string failed outright on a
|
|
26
|
+
* 5 357-file repository: 846 151 references exceed V8's maximum string length
|
|
27
|
+
* (2^29 - 24 characters), so publication died with "Invalid string length"
|
|
28
|
+
* after every other phase had finished. The text is still one valid JSON
|
|
29
|
+
* array, so a reader that parses it whole keeps working for lists that fit.
|
|
30
|
+
*
|
|
23
31
|
* Code placed in `packages/core/` per Package-Boundary Check — verified against AGENTS.md.
|
|
24
32
|
*
|
|
25
33
|
* @task T12348
|
|
26
34
|
* @module nexus/assessment-store
|
|
27
35
|
*/
|
|
28
36
|
import { isAbsolute } from 'node:path';
|
|
29
|
-
import {
|
|
37
|
+
import { Readable } from 'node:stream';
|
|
38
|
+
import { createGunzip, gunzipSync, gzipSync } from 'node:zlib';
|
|
30
39
|
import { sql } from 'drizzle-orm';
|
|
31
40
|
import { encodeStoredAssessment } from './stored-roots.js';
|
|
32
41
|
/** `_nexus_meta` key of the assessment summary. */
|
|
@@ -35,14 +44,164 @@ export const ASSESSMENT_KEY = 'graph_assessment';
|
|
|
35
44
|
export const ASSESSMENT_REFERENCES_KEY = 'graph_assessment_references';
|
|
36
45
|
/** gzip level of the stored reference list: level 1 is ~16x smaller at ~1 s per 450 MB. */
|
|
37
46
|
const REFERENCES_GZIP_LEVEL = 1;
|
|
47
|
+
/**
|
|
48
|
+
* References compressed per gzip member of the stored list.
|
|
49
|
+
*
|
|
50
|
+
* Bounds the largest string the encoder builds to one member's worth (a few
|
|
51
|
+
* MB) whatever the repository size, while keeping members large enough that
|
|
52
|
+
* per-member gzip framing does not cost compression.
|
|
53
|
+
*/
|
|
54
|
+
const REFERENCES_PER_MEMBER = 4096;
|
|
55
|
+
/** Newline byte; JSON text never contains a raw one inside a value. */
|
|
56
|
+
const NEWLINE = 0x0a;
|
|
38
57
|
/**
|
|
39
58
|
* Encode a reference list for storage under {@link ASSESSMENT_REFERENCES_KEY}.
|
|
40
59
|
*
|
|
60
|
+
* The decompressed text is the JSON array `[\n<ref>,\n<ref>\n]` — one
|
|
61
|
+
* reference per line — written as concatenated gzip members, so no string
|
|
62
|
+
* longer than one member's text is ever built (T13326).
|
|
63
|
+
*
|
|
41
64
|
* @param references - The generation's retained references.
|
|
42
65
|
* @returns gzip-compressed JSON, stored as a BLOB.
|
|
43
66
|
*/
|
|
44
67
|
export function encodeStoredReferences(references) {
|
|
45
|
-
|
|
68
|
+
const members = [];
|
|
69
|
+
let text = '[';
|
|
70
|
+
references.forEach((reference, index) => {
|
|
71
|
+
text += `${index === 0 ? '\n' : ',\n'}${JSON.stringify(reference)}`;
|
|
72
|
+
if ((index + 1) % REFERENCES_PER_MEMBER === 0) {
|
|
73
|
+
members.push(gzipSync(text, { level: REFERENCES_GZIP_LEVEL }));
|
|
74
|
+
text = '';
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
members.push(gzipSync(`${text}\n]`, { level: REFERENCES_GZIP_LEVEL }));
|
|
78
|
+
return Buffer.concat(members);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse a stored reference list into its items without building one string
|
|
82
|
+
* of the whole list (T13326).
|
|
83
|
+
*
|
|
84
|
+
* Reads the line-per-reference form written by {@link encodeStoredReferences},
|
|
85
|
+
* and the single-line form written before it — compressed or plain text —
|
|
86
|
+
* by parsing that one line whole, as it was always read.
|
|
87
|
+
*
|
|
88
|
+
* @param value - The raw `_nexus_meta.value` of {@link ASSESSMENT_REFERENCES_KEY}.
|
|
89
|
+
* @returns The stored items, not yet validated.
|
|
90
|
+
* @throws When the value is neither text nor a compressed list, or is not a JSON array.
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const references = z.array(referenceSchema).parse(parseStoredReferences(row.value));
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function parseStoredReferences(value) {
|
|
97
|
+
let bytes;
|
|
98
|
+
if (typeof value === 'string')
|
|
99
|
+
bytes = Buffer.from(value, 'utf8');
|
|
100
|
+
else if (value instanceof Uint8Array)
|
|
101
|
+
bytes = gunzipSync(value);
|
|
102
|
+
// @sync-invariant none:input-shape a malformed stored list is refused on read; nothing is written
|
|
103
|
+
else
|
|
104
|
+
throw new Error('Graph reference metadata is neither text nor a compressed list.');
|
|
105
|
+
const firstBreak = bytes.indexOf(NEWLINE);
|
|
106
|
+
if (firstBreak === -1 || bytes.toString('utf8', 0, firstBreak).trim() !== '[') {
|
|
107
|
+
const whole = JSON.parse(bytes.toString('utf8'));
|
|
108
|
+
// @sync-invariant none:input-shape a malformed stored list is refused on read; nothing is written
|
|
109
|
+
if (!Array.isArray(whole))
|
|
110
|
+
throw new Error('Graph reference metadata is not a list.');
|
|
111
|
+
return whole;
|
|
112
|
+
}
|
|
113
|
+
const items = [];
|
|
114
|
+
let start = firstBreak + 1;
|
|
115
|
+
while (start < bytes.length) {
|
|
116
|
+
const end = bytes.indexOf(NEWLINE, start);
|
|
117
|
+
const line = bytes
|
|
118
|
+
.toString('utf8', start, end === -1 ? bytes.length : end)
|
|
119
|
+
.trim()
|
|
120
|
+
.replace(/,$/, '');
|
|
121
|
+
if (line !== ']' && line !== '')
|
|
122
|
+
items.push(JSON.parse(line));
|
|
123
|
+
if (end === -1)
|
|
124
|
+
break;
|
|
125
|
+
start = end + 1;
|
|
126
|
+
}
|
|
127
|
+
return items;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Stream a stored reference list one reference at a time (T13330).
|
|
131
|
+
*
|
|
132
|
+
* The compressed list is inflated incrementally and split on line breaks, so
|
|
133
|
+
* neither the decompressed text nor the parsed list is ever held whole: a
|
|
134
|
+
* reader that keeps one page holds one page. The single-line form written
|
|
135
|
+
* before T13326 has no line breaks to split on; it was small enough to be
|
|
136
|
+
* written whole, so it is parsed whole, as it was always read.
|
|
137
|
+
*
|
|
138
|
+
* @param value - The raw `_nexus_meta.value` of {@link ASSESSMENT_REFERENCES_KEY}.
|
|
139
|
+
* @returns The stored references in stored order.
|
|
140
|
+
* @throws When the value is neither text nor a compressed list, or is not a JSON array.
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* for await (const { item } of streamStoredReferences(row.value)) count++;
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export async function* streamStoredReferences(value) {
|
|
147
|
+
let source;
|
|
148
|
+
if (typeof value === 'string')
|
|
149
|
+
source = Readable.from([Buffer.from(value, 'utf8')]);
|
|
150
|
+
else if (value instanceof Uint8Array)
|
|
151
|
+
source = Readable.from([value]).pipe(createGunzip());
|
|
152
|
+
// @sync-invariant none:input-shape a malformed stored list is refused on read; nothing is written
|
|
153
|
+
else
|
|
154
|
+
throw new Error('Graph reference metadata is neither text nor a compressed list.');
|
|
155
|
+
// Unterminated bytes, kept as chunks and joined once per line (T13372): a
|
|
156
|
+
// join per CHUNK, then a rescan of the whole buffer, made a long line —
|
|
157
|
+
// the legacy single-line list is one line — cost quadratic time.
|
|
158
|
+
let parts = [];
|
|
159
|
+
let legacy = false;
|
|
160
|
+
let sawOpening = false;
|
|
161
|
+
for await (const chunk of source) {
|
|
162
|
+
if (legacy) {
|
|
163
|
+
parts.push(chunk);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
let start = 0;
|
|
167
|
+
for (let end = chunk.indexOf(NEWLINE); end !== -1; end = chunk.indexOf(NEWLINE, start)) {
|
|
168
|
+
const lineBytes = parts.length === 0
|
|
169
|
+
? chunk.subarray(start, end)
|
|
170
|
+
: Buffer.concat([...parts, chunk.subarray(start, end)]);
|
|
171
|
+
parts = [];
|
|
172
|
+
const line = lineBytes.toString('utf8').trim();
|
|
173
|
+
if (!sawOpening) {
|
|
174
|
+
if (line !== '[') {
|
|
175
|
+
// Not the line-per-reference form: keep every byte for a whole parse.
|
|
176
|
+
legacy = true;
|
|
177
|
+
parts = [lineBytes, chunk.subarray(end)];
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
sawOpening = true;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
const text = line.replace(/,$/, '');
|
|
184
|
+
if (text !== ']' && text !== '')
|
|
185
|
+
yield { item: JSON.parse(text), bytes: Buffer.byteLength(text, 'utf8') };
|
|
186
|
+
}
|
|
187
|
+
start = end + 1;
|
|
188
|
+
}
|
|
189
|
+
if (!legacy && start < chunk.length)
|
|
190
|
+
parts.push(chunk.subarray(start));
|
|
191
|
+
}
|
|
192
|
+
const rest = Buffer.concat(parts).toString('utf8').trim();
|
|
193
|
+
if (sawOpening && !legacy) {
|
|
194
|
+
const text = rest.replace(/,$/, '');
|
|
195
|
+
if (text !== ']' && text !== '')
|
|
196
|
+
yield { item: JSON.parse(text), bytes: Buffer.byteLength(text, 'utf8') };
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const whole = JSON.parse(rest);
|
|
200
|
+
// @sync-invariant none:input-shape a malformed stored list is refused on read; nothing is written
|
|
201
|
+
if (!Array.isArray(whole))
|
|
202
|
+
throw new Error('Graph reference metadata is not a list.');
|
|
203
|
+
for (const item of whole)
|
|
204
|
+
yield { item, bytes: Buffer.byteLength(JSON.stringify(item), 'utf8') };
|
|
46
205
|
}
|
|
47
206
|
/**
|
|
48
207
|
* Decode a stored reference list back to its JSON text.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assessment-store.js","sourceRoot":"","sources":["../../src/nexus/assessment-store.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"assessment-store.js","sourceRoot":"","sources":["../../src/nexus/assessment-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* against AGENTS.md. These services do not invoke a language model.
|
|
6
6
|
*/
|
|
7
7
|
import type { GraphIndexAssessment, GraphIndexReferenceReport, KnowledgeCoverage, KnowledgeCoverageStatus, KnowledgeSymbolCandidate } from '@cleocode/contracts';
|
|
8
|
+
import { type ReferencePageRequest, type ReferencePageResult } from './assessment-projection.js';
|
|
8
9
|
/**
|
|
9
10
|
* Read validated generation provenance without treating malformed metadata as healthy.
|
|
10
11
|
*
|
|
@@ -41,6 +42,24 @@ export declare function readKnowledgeIndexAssessment(projectRoot?: string): Prom
|
|
|
41
42
|
* ```
|
|
42
43
|
*/
|
|
43
44
|
export declare function readKnowledgeIndexReferences(projectRoot?: string): Promise<GraphIndexReferenceReport[] | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Read one page of the published generation's retained references, with the
|
|
47
|
+
* per-kind totals of the whole list (T13330).
|
|
48
|
+
*
|
|
49
|
+
* The stored list is streamed: every reference is parsed to count its kind and
|
|
50
|
+
* then dropped, and only the requested page is kept and fully validated. A
|
|
51
|
+
* status call therefore holds one page however many references the repository
|
|
52
|
+
* has — 846 151 on one 5 357-file project, over 500 MB as a single JSON value.
|
|
53
|
+
* @param projectRoot - Explicit project root, or the ambient canonical project when omitted.
|
|
54
|
+
* @param request - Page size, offset and optional kind filter.
|
|
55
|
+
* @returns The page and totals; `null` when no graph is published.
|
|
56
|
+
* @throws When the stored list is malformed or disagrees with the recorded count.
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const result = await readKnowledgeIndexReferencePage(root, { limit: 20, offset: 0 });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function readKnowledgeIndexReferencePage(projectRoot: string | undefined, request: ReferencePageRequest): Promise<ReferencePageResult | null>;
|
|
44
63
|
/**
|
|
45
64
|
* An unresolved short name with exact identifiers the caller can choose from.
|
|
46
65
|
* @remarks Consumers preserve the candidate list in their error envelope.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/nexus/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EACV,oBAAoB,EAEpB,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/nexus/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EACV,oBAAoB,EAEpB,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AA2NpC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,4BAA4B,CAChD,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAyBtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAChD,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,yBAAyB,EAAE,GAAG,IAAI,CAAC,CAkB7C;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA8BrC;AAED;;;;;;;GAOG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,wBAAwB;IAErC,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,wBAAwB,EAAE,CAAC;IAEhD;;;;OAIG;gBACS,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB,EAAE;CAKlE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,wBAAwB,EAAE,GACzC,wBAAwB,GAAG,IAAI,CAWjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,MAAM,GACb,IAAI,CAUN;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,SAAO,GACd,OAAO,CAAC,iBAAiB,CAAC,CAS5B"}
|
package/dist/nexus/knowledge.js
CHANGED
|
@@ -16,7 +16,8 @@ import { z } from 'zod';
|
|
|
16
16
|
import { getProjectRoot, worktreeScope } from '../paths.js';
|
|
17
17
|
import { getProjectInfoSync } from '../project-info.js';
|
|
18
18
|
import { getNexusDb, getNexusNativeDb, nexusSchema } from '../store/nexus-sqlite.js';
|
|
19
|
-
import {
|
|
19
|
+
import { pageReferences, } from './assessment-projection.js';
|
|
20
|
+
import { ASSESSMENT_KEY, ASSESSMENT_REFERENCES_KEY, parseStoredReferences, streamStoredReferences, } from './assessment-store.js';
|
|
20
21
|
import { generateProjectHash } from './hash.js';
|
|
21
22
|
import { resolveSourceRoots } from './source-roots.js';
|
|
22
23
|
import { decodeStoredAssessment, describeGraphOwnershipMismatch, graphOwnershipRemedy, } from './stored-roots.js';
|
|
@@ -274,11 +275,64 @@ export async function readKnowledgeIndexReferences(projectRoot) {
|
|
|
274
275
|
throw new Error('Graph assessment reports references, but none are stored.');
|
|
275
276
|
return [];
|
|
276
277
|
}
|
|
277
|
-
const references = z.array(referenceSchema).parse(
|
|
278
|
+
const references = z.array(referenceSchema).parse(parseStoredReferences(row.value));
|
|
278
279
|
if (assessment.referenceCount !== undefined && references.length !== assessment.referenceCount)
|
|
279
280
|
throw new Error('Stored graph references disagree with the assessment reference count.');
|
|
280
281
|
return references;
|
|
281
282
|
}
|
|
283
|
+
/** The one field a reference's kind count needs; the page rows get the full schema. */
|
|
284
|
+
const referenceKindSchema = z.object({ kind: referenceSchema.shape.kind });
|
|
285
|
+
/**
|
|
286
|
+
* Read one page of the published generation's retained references, with the
|
|
287
|
+
* per-kind totals of the whole list (T13330).
|
|
288
|
+
*
|
|
289
|
+
* The stored list is streamed: every reference is parsed to count its kind and
|
|
290
|
+
* then dropped, and only the requested page is kept and fully validated. A
|
|
291
|
+
* status call therefore holds one page however many references the repository
|
|
292
|
+
* has — 846 151 on one 5 357-file project, over 500 MB as a single JSON value.
|
|
293
|
+
* @param projectRoot - Explicit project root, or the ambient canonical project when omitted.
|
|
294
|
+
* @param request - Page size, offset and optional kind filter.
|
|
295
|
+
* @returns The page and totals; `null` when no graph is published.
|
|
296
|
+
* @throws When the stored list is malformed or disagrees with the recorded count.
|
|
297
|
+
* @example
|
|
298
|
+
* ```ts
|
|
299
|
+
* const result = await readKnowledgeIndexReferencePage(root, { limit: 20, offset: 0 });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
export async function readKnowledgeIndexReferencePage(projectRoot, request) {
|
|
303
|
+
const assessment = await readKnowledgeIndexAssessment(projectRoot);
|
|
304
|
+
if (!assessment)
|
|
305
|
+
return null;
|
|
306
|
+
let items;
|
|
307
|
+
if (assessment.references) {
|
|
308
|
+
items = assessment.references.map((item) => ({
|
|
309
|
+
item,
|
|
310
|
+
bytes: Buffer.byteLength(JSON.stringify(item), 'utf8'),
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
const native = getNexusNativeDb(projectRoot);
|
|
315
|
+
// @sync-invariant none:input-shape a read of the stored reference list refuses malformed state; nothing is written
|
|
316
|
+
if (!native)
|
|
317
|
+
throw new Error('The graph database is unavailable.');
|
|
318
|
+
const row = native
|
|
319
|
+
.prepare('SELECT value FROM main._nexus_meta WHERE key = ?')
|
|
320
|
+
.get(ASSESSMENT_REFERENCES_KEY);
|
|
321
|
+
if (!row && (assessment.referenceCount ?? 0) > 0)
|
|
322
|
+
// @sync-invariant none:input-shape a read of the stored reference list refuses malformed state; nothing is written
|
|
323
|
+
throw new Error('Graph assessment reports references, but none are stored.');
|
|
324
|
+
items = row ? streamStoredReferences(row.value) : [];
|
|
325
|
+
}
|
|
326
|
+
const result = await pageReferences(items, request, {
|
|
327
|
+
kind: (item) => referenceKindSchema.parse(item).kind,
|
|
328
|
+
row: (item) => referenceSchema.parse(item),
|
|
329
|
+
});
|
|
330
|
+
if (assessment.referenceCount !== undefined && result.count !== assessment.referenceCount)
|
|
331
|
+
// @sync-invariant none:input-shape a read of the stored reference list refuses malformed state; nothing is written
|
|
332
|
+
throw new Error('Stored graph references disagree with the assessment reference count.');
|
|
333
|
+
const { count: _count, ...page } = result;
|
|
334
|
+
return page;
|
|
335
|
+
}
|
|
282
336
|
/**
|
|
283
337
|
* An unresolved short name with exact identifiers the caller can choose from.
|
|
284
338
|
* @remarks Consumers preserve the candidate list in their error envelope.
|