clinkx 0.3.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +119 -0
- package/LICENSE +10 -0
- package/README.md +154 -26
- package/clinkx-workflows/dist/allowed-roots.d.ts +1 -0
- package/clinkx-workflows/dist/allowed-roots.js +5 -0
- package/clinkx-workflows/dist/allowed-roots.js.map +1 -0
- package/clinkx-workflows/dist/artifacts.d.ts +20 -1
- package/clinkx-workflows/dist/artifacts.js +38 -9
- package/clinkx-workflows/dist/artifacts.js.map +1 -1
- package/clinkx-workflows/dist/backend.d.ts +4 -0
- package/clinkx-workflows/dist/chairman-knobs.d.ts +24 -0
- package/clinkx-workflows/dist/chairman-knobs.js +27 -0
- package/clinkx-workflows/dist/chairman-knobs.js.map +1 -0
- package/clinkx-workflows/dist/citation-check.d.ts +40 -0
- package/clinkx-workflows/dist/citation-check.js +348 -0
- package/clinkx-workflows/dist/citation-check.js.map +1 -0
- package/clinkx-workflows/dist/clink-client.d.ts +12 -1
- package/clinkx-workflows/dist/clink-client.js +56 -5
- package/clinkx-workflows/dist/clink-client.js.map +1 -1
- package/clinkx-workflows/dist/config.d.ts +173 -16
- package/clinkx-workflows/dist/config.js +417 -26
- package/clinkx-workflows/dist/config.js.map +1 -1
- package/clinkx-workflows/dist/contained-file.d.ts +172 -0
- package/clinkx-workflows/dist/contained-file.js +483 -0
- package/clinkx-workflows/dist/contained-file.js.map +1 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.d.ts +416 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.js +328 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.js.map +1 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.d.ts +24 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.js +39 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.js.map +1 -0
- package/clinkx-workflows/dist/context-cache-key.d.ts +53 -0
- package/clinkx-workflows/dist/context-cache-key.js +91 -0
- package/clinkx-workflows/dist/context-cache-key.js.map +1 -0
- package/clinkx-workflows/dist/context-mode-resolver.d.ts +27 -0
- package/clinkx-workflows/dist/context-mode-resolver.js +126 -0
- package/clinkx-workflows/dist/context-mode-resolver.js.map +1 -0
- package/clinkx-workflows/dist/context-preflight.d.ts +189 -0
- package/clinkx-workflows/dist/context-preflight.js +91 -0
- package/clinkx-workflows/dist/context-preflight.js.map +1 -0
- package/clinkx-workflows/dist/council-execution-policy.d.ts +68 -0
- package/clinkx-workflows/dist/council-execution-policy.js +110 -0
- package/clinkx-workflows/dist/council-execution-policy.js.map +1 -0
- package/clinkx-workflows/dist/council-expander.d.ts +10 -9
- package/clinkx-workflows/dist/council-expander.js +20 -10
- package/clinkx-workflows/dist/council-expander.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +5718 -0
- package/clinkx-workflows/dist/dashboard/activity-contract.js +157 -0
- package/clinkx-workflows/dist/dashboard/activity-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.d.ts +25 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.js +34 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.d.ts +90 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js +493 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/api-routes.d.ts +40 -0
- package/clinkx-workflows/dist/dashboard/api-routes.js +1155 -0
- package/clinkx-workflows/dist/dashboard/api-routes.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.d.ts +37 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.js +145 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.d.ts +31 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.js +65 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.d.ts +26 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.js +596 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.d.ts +60 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.js +776 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.d.ts +9 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js +44 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.d.ts +17 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.js +77 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.d.ts +25 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js +71 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/context-builder-invocation-contract.d.ts +3865 -0
- package/clinkx-workflows/dist/dashboard/context-builder-invocation-contract.js +69 -0
- package/clinkx-workflows/dist/dashboard/context-builder-invocation-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.d.ts +37 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.js +49 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.d.ts +256 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js +1301 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/contracts.d.ts +28483 -0
- package/clinkx-workflows/dist/dashboard/contracts.js +1284 -0
- package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/generation.d.ts +14 -0
- package/clinkx-workflows/dist/dashboard/generation.js +41 -0
- package/clinkx-workflows/dist/dashboard/generation.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/index.d.ts +32 -0
- package/clinkx-workflows/dist/dashboard/index.js +20 -0
- package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/invocation-contract.d.ts +786 -0
- package/clinkx-workflows/dist/dashboard/invocation-contract.js +201 -0
- package/clinkx-workflows/dist/dashboard/invocation-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +114 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js +799 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/contract.d.ts +90 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/contract.js +31 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/projection.d.ts +12 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/projection.js +286 -0
- package/clinkx-workflows/dist/dashboard/native-transcript/projection.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +446 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.js +221 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.d.ts +50 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.js +529 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +89 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js +71 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.d.ts +29 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +111 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-contract.d.ts +194 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-contract.js +89 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-store.d.ts +26 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-store.js +102 -0
- package/clinkx-workflows/dist/dashboard/prompt-builder-library-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/read-model.d.ts +86 -0
- package/clinkx-workflows/dist/dashboard/read-model.js +440 -0
- package/clinkx-workflows/dist/dashboard/read-model.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/request-admission.d.ts +31 -0
- package/clinkx-workflows/dist/dashboard/request-admission.js +130 -0
- package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/scanner.d.ts +78 -0
- package/clinkx-workflows/dist/dashboard/scanner.js +1154 -0
- package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/server-factory.d.ts +63 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js +483 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2778 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.js +506 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.d.ts +21 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.js +101 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.d.ts +43 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.js +529 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.d.ts +61 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.js +378 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +14 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js +1101 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.d.ts +23 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.js +212 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/static-responses.d.ts +10 -0
- package/clinkx-workflows/dist/dashboard/static-responses.js +94 -0
- package/clinkx-workflows/dist/dashboard/static-responses.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.d.ts +28 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.js +241 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.js.map +1 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/index-JPHQVtn9.js +106 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/style-DOMHk-j6.css +1 -0
- package/clinkx-workflows/dist/dashboard-ui/contracts/council-plan-review-input-v1.json +158 -0
- package/clinkx-workflows/dist/dashboard-ui/index.html +15 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Mono-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Sans-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/JetBrains-Mono-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/NOTICE.md +32 -0
- package/clinkx-workflows/dist/dashboard-ui/theme-init.js +8 -0
- package/clinkx-workflows/dist/definition-normalizer.d.ts +19 -0
- package/clinkx-workflows/dist/definition-normalizer.js.map +1 -1
- package/clinkx-workflows/dist/delegate-finalizer-policy.d.ts +26 -0
- package/clinkx-workflows/dist/delegate-finalizer-policy.js +72 -0
- package/clinkx-workflows/dist/delegate-finalizer-policy.js.map +1 -0
- package/clinkx-workflows/dist/delegate-signature.d.ts +14 -0
- package/clinkx-workflows/dist/delegate-signature.js +14 -0
- package/clinkx-workflows/dist/delegate-signature.js.map +1 -0
- package/clinkx-workflows/dist/delegate-validate.d.ts +108 -0
- package/clinkx-workflows/dist/delegate-validate.js +148 -0
- package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
- package/clinkx-workflows/dist/engine.d.ts +251 -0
- package/clinkx-workflows/dist/engine.js +1342 -92
- package/clinkx-workflows/dist/engine.js.map +1 -1
- package/clinkx-workflows/dist/errors.d.ts +24 -2
- package/clinkx-workflows/dist/errors.js +30 -2
- package/clinkx-workflows/dist/errors.js.map +1 -1
- package/clinkx-workflows/dist/fidelity.d.ts +47 -1
- package/clinkx-workflows/dist/fidelity.js +54 -1
- package/clinkx-workflows/dist/fidelity.js.map +1 -1
- package/clinkx-workflows/dist/fingerprint.d.ts +25 -7
- package/clinkx-workflows/dist/fingerprint.js +33 -10
- package/clinkx-workflows/dist/fingerprint.js.map +1 -1
- package/clinkx-workflows/dist/index.d.ts +19 -0
- package/clinkx-workflows/dist/index.js +68 -1
- package/clinkx-workflows/dist/index.js.map +1 -1
- package/clinkx-workflows/dist/loader.d.ts +9 -3
- package/clinkx-workflows/dist/loader.js +92 -21
- package/clinkx-workflows/dist/loader.js.map +1 -1
- package/clinkx-workflows/dist/logger.d.ts +1 -1
- package/clinkx-workflows/dist/logger.js +17 -3
- package/clinkx-workflows/dist/logger.js.map +1 -1
- package/clinkx-workflows/dist/monotonic-clock.d.ts +19 -0
- package/clinkx-workflows/dist/monotonic-clock.js +22 -0
- package/clinkx-workflows/dist/monotonic-clock.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/admission.d.ts +160 -0
- package/clinkx-workflows/dist/plan-review/admission.js +290 -0
- package/clinkx-workflows/dist/plan-review/admission.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/context-policy.d.ts +55 -0
- package/clinkx-workflows/dist/plan-review/context-policy.js +146 -0
- package/clinkx-workflows/dist/plan-review/context-policy.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/contract.d.ts +763 -0
- package/clinkx-workflows/dist/plan-review/contract.js +289 -0
- package/clinkx-workflows/dist/plan-review/contract.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/digest.d.ts +68 -0
- package/clinkx-workflows/dist/plan-review/digest.js +241 -0
- package/clinkx-workflows/dist/plan-review/digest.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/discovery.d.ts +45 -0
- package/clinkx-workflows/dist/plan-review/discovery.js +36 -0
- package/clinkx-workflows/dist/plan-review/discovery.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.d.ts +298 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.js +194 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/expander.d.ts +48 -0
- package/clinkx-workflows/dist/plan-review/expander.js +243 -0
- package/clinkx-workflows/dist/plan-review/expander.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/projector.d.ts +126 -0
- package/clinkx-workflows/dist/plan-review/projector.js +437 -0
- package/clinkx-workflows/dist/plan-review/projector.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/publication.d.ts +95 -0
- package/clinkx-workflows/dist/plan-review/publication.js +182 -0
- package/clinkx-workflows/dist/plan-review/publication.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.d.ts +34 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.js +139 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/resume.d.ts +38 -0
- package/clinkx-workflows/dist/plan-review/resume.js +122 -0
- package/clinkx-workflows/dist/plan-review/resume.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/rubric.d.ts +7 -0
- package/clinkx-workflows/dist/plan-review/rubric.js +24 -0
- package/clinkx-workflows/dist/plan-review/rubric.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/run-state.d.ts +398 -0
- package/clinkx-workflows/dist/plan-review/run-state.js +183 -0
- package/clinkx-workflows/dist/plan-review/run-state.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.d.ts +74 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.js +186 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/snapshot.d.ts +81 -0
- package/clinkx-workflows/dist/plan-review/snapshot.js +170 -0
- package/clinkx-workflows/dist/plan-review/snapshot.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/stage-error.d.ts +19 -0
- package/clinkx-workflows/dist/plan-review/stage-error.js +20 -0
- package/clinkx-workflows/dist/plan-review/stage-error.js.map +1 -0
- package/clinkx-workflows/dist/post-processors/index.d.ts +20 -0
- package/clinkx-workflows/dist/post-processors/index.js +21 -0
- package/clinkx-workflows/dist/post-processors/index.js.map +1 -0
- package/clinkx-workflows/dist/prompt-budget.d.ts +7 -0
- package/clinkx-workflows/dist/prompt-budget.js +7 -1
- package/clinkx-workflows/dist/prompt-budget.js.map +1 -1
- package/clinkx-workflows/dist/reducers/index.js +2 -0
- package/clinkx-workflows/dist/reducers/index.js.map +1 -1
- package/clinkx-workflows/dist/roster-contract.d.ts +889 -0
- package/clinkx-workflows/dist/roster-contract.js +180 -0
- package/clinkx-workflows/dist/roster-contract.js.map +1 -0
- package/clinkx-workflows/dist/rosters.d.ts +14 -0
- package/clinkx-workflows/dist/rosters.js +169 -0
- package/clinkx-workflows/dist/rosters.js.map +1 -0
- package/clinkx-workflows/dist/run-health.d.ts +7 -0
- package/clinkx-workflows/dist/run-health.js +25 -0
- package/clinkx-workflows/dist/run-health.js.map +1 -0
- package/clinkx-workflows/dist/run-lock-heartbeat.d.ts +2 -0
- package/clinkx-workflows/dist/run-lock-heartbeat.js +3 -0
- package/clinkx-workflows/dist/run-lock-heartbeat.js.map +1 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.d.ts +34 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js +74 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js.map +1 -0
- package/clinkx-workflows/dist/run-summary/cards/index.js +5 -0
- package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -1
- package/clinkx-workflows/dist/run-summary.d.ts +13 -0
- package/clinkx-workflows/dist/run-summary.js +29 -1
- package/clinkx-workflows/dist/run-summary.js.map +1 -1
- package/clinkx-workflows/dist/schema.d.ts +140 -21
- package/clinkx-workflows/dist/schema.js +34 -1
- package/clinkx-workflows/dist/schema.js.map +1 -1
- package/clinkx-workflows/dist/seed-terms.d.ts +30 -0
- package/clinkx-workflows/dist/seed-terms.js +176 -0
- package/clinkx-workflows/dist/seed-terms.js.map +1 -0
- package/clinkx-workflows/dist/server.d.ts +5 -2
- package/clinkx-workflows/dist/server.js +84 -52
- package/clinkx-workflows/dist/server.js.map +1 -1
- package/clinkx-workflows/dist/shutdown.d.ts +29 -18
- package/clinkx-workflows/dist/shutdown.js +90 -64
- package/clinkx-workflows/dist/shutdown.js.map +1 -1
- package/clinkx-workflows/dist/state-schema.d.ts +61 -0
- package/clinkx-workflows/dist/state.d.ts +175 -3
- package/clinkx-workflows/dist/state.js +1398 -44
- package/clinkx-workflows/dist/state.js.map +1 -1
- package/clinkx-workflows/dist/stdio-watchdog.d.ts +52 -0
- package/clinkx-workflows/dist/stdio-watchdog.js +212 -0
- package/clinkx-workflows/dist/stdio-watchdog.js.map +1 -0
- package/clinkx-workflows/dist/transport.d.ts +15 -0
- package/clinkx-workflows/dist/transport.js +19 -10
- package/clinkx-workflows/dist/transport.js.map +1 -1
- package/clinkx-workflows/dist/types.d.ts +20 -2
- package/clinkx-workflows/dist/validators/council.d.ts +334 -101
- package/clinkx-workflows/dist/validators/council.js +52 -13
- package/clinkx-workflows/dist/validators/council.js.map +1 -1
- package/clinkx-workflows/dist/validators/index.d.ts +1 -0
- package/clinkx-workflows/dist/validators/index.js +3 -0
- package/clinkx-workflows/dist/validators/index.js.map +1 -1
- package/clinkx-workflows/dist/validators/plan-review.d.ts +398 -0
- package/clinkx-workflows/dist/validators/plan-review.js +316 -0
- package/clinkx-workflows/dist/validators/plan-review.js.map +1 -0
- package/clinkx-workflows/dist/workflow-receipt.js +188 -4
- package/clinkx-workflows/dist/workflow-receipt.js.map +1 -1
- package/clinkx-workflows/dist/workflow-tools.d.ts +118 -3
- package/clinkx-workflows/dist/workflow-tools.js +2110 -175
- package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
- package/clinkx-workflows/dist/workspace-signature.d.ts +16 -0
- package/clinkx-workflows/dist/workspace-signature.js +388 -0
- package/clinkx-workflows/dist/workspace-signature.js.map +1 -0
- package/clinkx-workflows/templates/council/answer-chairman.txt +3 -0
- package/clinkx-workflows/templates/council/answer-cross-reviewer.txt +3 -0
- package/clinkx-workflows/templates/council/answer-specialist.txt +5 -1
- package/clinkx-workflows/templates/council/chairman.txt +3 -0
- package/clinkx-workflows/templates/council/code-review-chairman.txt +16 -0
- package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +7 -1
- package/clinkx-workflows/templates/council/code-review-reviewer.txt +22 -3
- package/clinkx-workflows/templates/council/debug-chairman.txt +3 -0
- package/clinkx-workflows/templates/council/debug-cross-reviewer.txt +3 -0
- package/clinkx-workflows/templates/council/debug-debugger.txt +5 -1
- package/clinkx-workflows/templates/council/discover-analyst.txt +5 -1
- package/clinkx-workflows/templates/council/discover-chairman.txt +3 -0
- package/clinkx-workflows/templates/council/discover-cross-reviewer.txt +3 -0
- package/clinkx-workflows/templates/council/member.txt +5 -1
- package/clinkx-workflows/templates/council/plan-review-chairman.txt +71 -0
- package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +54 -0
- package/clinkx-workflows/templates/council/plan-review-reviewer.txt +63 -0
- package/clinkx-workflows/templates/council/reviewer.txt +3 -0
- package/clinkx-workflows/templates/plan-review/chairman.txt +48 -0
- package/clinkx-workflows/templates/plan-review/cross-review.txt +52 -0
- package/clinkx-workflows/templates/plan-review/ranking.txt +16 -0
- package/clinkx-workflows/templates/plan-review/reviewer.txt +57 -0
- package/clinkx-workflows/workflows/council-answer.yaml +100 -8
- package/clinkx-workflows/workflows/council-code-review.yaml +106 -8
- package/clinkx-workflows/workflows/council-debug.yaml +100 -8
- package/clinkx-workflows/workflows/council-default.yaml +104 -8
- package/clinkx-workflows/workflows/council-discover.yaml +100 -8
- package/clinkx-workflows/workflows/council-plan-review.yaml +253 -0
- package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
- package/conf/adapters/agy.json +56 -0
- package/conf/adapters/claude.json +12 -0
- package/conf/adapters/codex-app-server.json +44 -0
- package/conf/adapters/codex.json +14 -2
- package/conf/adapters/glm.json +24 -3
- package/conf/adapters/grok.json +67 -0
- package/conf/adapters/hapi/agy.json +59 -0
- package/conf/adapters/hapi/claude.json +12 -0
- package/conf/adapters/hapi/codex.json +14 -2
- package/conf/adapters/hapi/glm.json +25 -4
- package/conf/rosters/default-council.json +21 -0
- package/dist/activity-journal.d.ts +56 -0
- package/dist/activity-journal.js +706 -0
- package/dist/activity-journal.js.map +1 -0
- package/dist/allowed-roots.d.ts +41 -0
- package/dist/allowed-roots.js +125 -3
- package/dist/allowed-roots.js.map +1 -1
- package/dist/codex/activity-session-log.d.ts +14 -0
- package/dist/codex/activity-session-log.js +206 -0
- package/dist/codex/activity-session-log.js.map +1 -0
- package/dist/codex/agent-tools.d.ts +23 -0
- package/dist/codex/agent-tools.js +1306 -0
- package/dist/codex/agent-tools.js.map +1 -0
- package/dist/codex/app-server-client.d.ts +79 -0
- package/dist/codex/app-server-client.js +593 -0
- package/dist/codex/app-server-client.js.map +1 -0
- package/dist/codex/app-server-registry.d.ts +407 -0
- package/dist/codex/app-server-registry.js +1493 -0
- package/dist/codex/app-server-registry.js.map +1 -0
- package/dist/codex/client-types.d.ts +115 -0
- package/dist/codex/client-types.js +2 -0
- package/dist/codex/client-types.js.map +1 -0
- package/dist/codex/protocol.d.ts +5375 -0
- package/dist/codex/protocol.js +614 -0
- package/dist/codex/protocol.js.map +1 -0
- package/dist/codex/session.d.ts +263 -0
- package/dist/codex/session.js +466 -0
- package/dist/codex/session.js.map +1 -0
- package/dist/config.d.ts +386 -23
- package/dist/config.js +184 -15
- package/dist/config.js.map +1 -1
- package/dist/context-builder/anchors.d.ts +1 -0
- package/dist/context-builder/anchors.js +3 -0
- package/dist/context-builder/anchors.js.map +1 -1
- package/dist/context-builder/bundle.d.ts +48 -2
- package/dist/context-builder/bundle.js +388 -2417
- package/dist/context-builder/bundle.js.map +1 -1
- package/dist/context-builder/codemap.d.ts +5 -0
- package/dist/context-builder/codemap.js +387 -13
- package/dist/context-builder/codemap.js.map +1 -1
- package/dist/context-builder/config.d.ts +1 -0
- package/dist/context-builder/config.js +12 -0
- package/dist/context-builder/config.js.map +1 -1
- package/dist/context-builder/context-run-catalog.d.ts +17 -0
- package/dist/context-builder/context-run-catalog.js +99 -0
- package/dist/context-builder/context-run-catalog.js.map +1 -0
- package/dist/context-builder/delegate-finalizer-effective.d.ts +33 -0
- package/dist/context-builder/delegate-finalizer-effective.js +82 -0
- package/dist/context-builder/delegate-finalizer-effective.js.map +1 -0
- package/dist/context-builder/delegate-packet.d.ts +55 -0
- package/dist/context-builder/delegate-packet.js +430 -74
- package/dist/context-builder/delegate-packet.js.map +1 -1
- package/dist/context-builder/delegate-reconstruction.d.ts +29 -0
- package/dist/context-builder/delegate-reconstruction.js +110 -41
- package/dist/context-builder/delegate-reconstruction.js.map +1 -1
- package/dist/context-builder/delegate-validation.d.ts +41 -1
- package/dist/context-builder/delegate-validation.js +237 -48
- package/dist/context-builder/delegate-validation.js.map +1 -1
- package/dist/context-builder/delegate.d.ts +11 -0
- package/dist/context-builder/delegate.js +210 -58
- package/dist/context-builder/delegate.js.map +1 -1
- package/dist/context-builder/diagnostics.d.ts +11 -2
- package/dist/context-builder/diagnostics.js +39 -6
- package/dist/context-builder/diagnostics.js.map +1 -1
- package/dist/context-builder/discovery-progress.d.ts +25 -0
- package/dist/context-builder/discovery-progress.js +64 -0
- package/dist/context-builder/discovery-progress.js.map +1 -0
- package/dist/context-builder/discovery-watchdog.d.ts +15 -0
- package/dist/context-builder/discovery-watchdog.js +39 -0
- package/dist/context-builder/discovery-watchdog.js.map +1 -0
- package/dist/context-builder/discovery.d.ts +36 -1
- package/dist/context-builder/discovery.js +584 -172
- package/dist/context-builder/discovery.js.map +1 -1
- package/dist/context-builder/external-gaps.d.ts +73 -0
- package/dist/context-builder/external-gaps.js +248 -0
- package/dist/context-builder/external-gaps.js.map +1 -0
- package/dist/context-builder/globs.d.ts +1 -0
- package/dist/context-builder/globs.js +25 -10
- package/dist/context-builder/globs.js.map +1 -1
- package/dist/context-builder/handler.d.ts +67 -2
- package/dist/context-builder/handler.js +1810 -2440
- package/dist/context-builder/handler.js.map +1 -1
- package/dist/context-builder/invocation-sidecar.d.ts +41 -0
- package/dist/context-builder/invocation-sidecar.js +189 -0
- package/dist/context-builder/invocation-sidecar.js.map +1 -0
- package/dist/context-builder/lifecycle-contract.d.ts +424 -0
- package/dist/context-builder/lifecycle-contract.js +523 -0
- package/dist/context-builder/lifecycle-contract.js.map +1 -0
- package/dist/context-builder/lifecycle-journal.d.ts +62 -0
- package/dist/context-builder/lifecycle-journal.js +88 -0
- package/dist/context-builder/lifecycle-journal.js.map +1 -0
- package/dist/context-builder/lifecycle-observer.d.ts +102 -0
- package/dist/context-builder/lifecycle-observer.js +258 -0
- package/dist/context-builder/lifecycle-observer.js.map +1 -0
- package/dist/context-builder/lifecycle-reconcile.d.ts +32 -0
- package/dist/context-builder/lifecycle-reconcile.js +191 -0
- package/dist/context-builder/lifecycle-reconcile.js.map +1 -0
- package/dist/context-builder/lifecycle-recovery.d.ts +2 -0
- package/dist/context-builder/lifecycle-recovery.js +14 -0
- package/dist/context-builder/lifecycle-recovery.js.map +1 -0
- package/dist/context-builder/mutation-lock.d.ts +32 -0
- package/dist/context-builder/mutation-lock.js +321 -0
- package/dist/context-builder/mutation-lock.js.map +1 -0
- package/dist/context-builder/path-signals.js +9 -5
- package/dist/context-builder/path-signals.js.map +1 -1
- package/dist/context-builder/progress.d.ts +3 -1
- package/dist/context-builder/progress.js +23 -0
- package/dist/context-builder/progress.js.map +1 -1
- package/dist/context-builder/receipt.d.ts +6 -4
- package/dist/context-builder/receipt.js +12 -1
- package/dist/context-builder/receipt.js.map +1 -1
- package/dist/context-builder/refine-handler.d.ts +14 -0
- package/dist/context-builder/refine-handler.js +790 -0
- package/dist/context-builder/refine-handler.js.map +1 -0
- package/dist/context-builder/review-coverage.d.ts +116 -0
- package/dist/context-builder/review-coverage.js +544 -0
- package/dist/context-builder/review-coverage.js.map +1 -0
- package/dist/context-builder/schema.d.ts +315 -2
- package/dist/context-builder/schema.js +133 -7
- package/dist/context-builder/schema.js.map +1 -1
- package/dist/context-builder/secrets.d.ts +59 -0
- package/dist/context-builder/secrets.js +2255 -44
- package/dist/context-builder/secrets.js.map +1 -1
- package/dist/context-builder/selection.d.ts +7 -3
- package/dist/context-builder/selection.js +200 -738
- package/dist/context-builder/selection.js.map +1 -1
- package/dist/context-builder/session-log-identity.d.ts +1 -0
- package/dist/context-builder/session-log-identity.js +66 -0
- package/dist/context-builder/session-log-identity.js.map +1 -0
- package/dist/context-builder/slice-range-math.d.ts +16 -0
- package/dist/context-builder/slice-range-math.js +137 -0
- package/dist/context-builder/slice-range-math.js.map +1 -0
- package/dist/context-builder/status.d.ts +23 -2
- package/dist/context-builder/status.js +60 -4
- package/dist/context-builder/status.js.map +1 -1
- package/dist/context-builder/storage.d.ts +59 -2
- package/dist/context-builder/storage.js +500 -168
- package/dist/context-builder/storage.js.map +1 -1
- package/dist/context-builder/token-estimate.d.ts +13 -2
- package/dist/context-builder/token-estimate.js +77 -4
- package/dist/context-builder/token-estimate.js.map +1 -1
- package/dist/context-builder/versions.d.ts +44 -0
- package/dist/context-builder/versions.js +45 -0
- package/dist/context-builder/versions.js.map +1 -0
- package/dist/context-builder/workflow-runner.d.ts +75 -0
- package/dist/context-builder/workflow-runner.js +1241 -0
- package/dist/context-builder/workflow-runner.js.map +1 -0
- package/dist/context-builder/write-watchdog.d.ts +14 -0
- package/dist/context-builder/write-watchdog.js +38 -0
- package/dist/context-builder/write-watchdog.js.map +1 -0
- package/dist/dashboard-adapter-catalog.d.ts +9 -0
- package/dist/dashboard-adapter-catalog.js +53 -0
- package/dist/dashboard-adapter-catalog.js.map +1 -0
- package/dist/dashboard-cli.d.ts +81 -0
- package/dist/dashboard-cli.js +623 -0
- package/dist/dashboard-cli.js.map +1 -0
- package/dist/dashboard-companion/client.d.ts +37 -0
- package/dist/dashboard-companion/client.js +229 -0
- package/dist/dashboard-companion/client.js.map +1 -0
- package/dist/dashboard-companion/config.d.ts +8 -0
- package/dist/dashboard-companion/config.js +52 -0
- package/dist/dashboard-companion/config.js.map +1 -0
- package/dist/dashboard-companion/http-proxy.d.ts +10 -0
- package/dist/dashboard-companion/http-proxy.js +234 -0
- package/dist/dashboard-companion/http-proxy.js.map +1 -0
- package/dist/dashboard-companion/protocol.d.ts +80 -0
- package/dist/dashboard-companion/protocol.js +458 -0
- package/dist/dashboard-companion/protocol.js.map +1 -0
- package/dist/dashboard-companion/standalone-assets.d.ts +12 -0
- package/dist/dashboard-companion/standalone-assets.js +72 -0
- package/dist/dashboard-companion/standalone-assets.js.map +1 -0
- package/dist/dashboard-companion/standalone-entry.d.ts +1 -0
- package/dist/dashboard-companion/standalone-entry.js +17 -0
- package/dist/dashboard-companion/standalone-entry.js.map +1 -0
- package/dist/dashboard-gateway/config.d.ts +9 -0
- package/dist/dashboard-gateway/config.js +44 -0
- package/dist/dashboard-gateway/config.js.map +1 -0
- package/dist/dashboard-gateway/index.d.ts +12 -0
- package/dist/dashboard-gateway/index.js +786 -0
- package/dist/dashboard-gateway/index.js.map +1 -0
- package/dist/dashboard-gateway/main.d.ts +1 -0
- package/dist/dashboard-gateway/main.js +25 -0
- package/dist/dashboard-gateway/main.js.map +1 -0
- package/dist/dashboard-pairing-token.d.ts +1 -0
- package/dist/dashboard-pairing-token.js +5 -0
- package/dist/dashboard-pairing-token.js.map +1 -0
- package/dist/elaris/client.d.ts +73 -0
- package/dist/elaris/client.js +825 -0
- package/dist/elaris/client.js.map +1 -0
- package/dist/elaris/config.d.ts +18 -0
- package/dist/elaris/config.js +75 -0
- package/dist/elaris/config.js.map +1 -0
- package/dist/elaris/errors.d.ts +41 -0
- package/dist/elaris/errors.js +205 -0
- package/dist/elaris/errors.js.map +1 -0
- package/dist/elaris/github-repo.d.ts +18 -0
- package/dist/elaris/github-repo.js +89 -0
- package/dist/elaris/github-repo.js.map +1 -0
- package/dist/elaris/index.d.ts +10 -0
- package/dist/elaris/index.js +11 -0
- package/dist/elaris/index.js.map +1 -0
- package/dist/elaris/redact.d.ts +89 -0
- package/dist/elaris/redact.js +423 -0
- package/dist/elaris/redact.js.map +1 -0
- package/dist/elaris/run-id.d.ts +5 -0
- package/dist/elaris/run-id.js +20 -0
- package/dist/elaris/run-id.js.map +1 -0
- package/dist/elaris/status.d.ts +45 -0
- package/dist/elaris/status.js +122 -0
- package/dist/elaris/status.js.map +1 -0
- package/dist/elaris/tool-schemas.d.ts +314 -0
- package/dist/elaris/tool-schemas.js +208 -0
- package/dist/elaris/tool-schemas.js.map +1 -0
- package/dist/elaris/tools.d.ts +73 -0
- package/dist/elaris/tools.js +1065 -0
- package/dist/elaris/tools.js.map +1 -0
- package/dist/elaris/types.d.ts +1541 -0
- package/dist/elaris/types.js +252 -0
- package/dist/elaris/types.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -1
- package/dist/handler.d.ts +4 -0
- package/dist/handler.js +15 -2
- package/dist/handler.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.js +154 -6
- package/dist/index.js.map +1 -1
- package/dist/local-clink-backend.d.ts +3 -0
- package/dist/local-clink-backend.js +4 -0
- package/dist/local-clink-backend.js.map +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +18 -3
- package/dist/logger.js.map +1 -1
- package/dist/package-info.d.ts +2 -0
- package/dist/package-info.js +18 -0
- package/dist/package-info.js.map +1 -0
- package/dist/parsers/agy-stream-json.d.ts +14 -0
- package/dist/parsers/agy-stream-json.js +172 -0
- package/dist/parsers/agy-stream-json.js.map +1 -0
- package/dist/parsers/codex-jsonl.js +48 -3
- package/dist/parsers/codex-jsonl.js.map +1 -1
- package/dist/parsers/extract.d.ts +10 -1
- package/dist/parsers/extract.js +16 -4
- package/dist/parsers/extract.js.map +1 -1
- package/dist/parsers/observed-invocation.d.ts +20 -0
- package/dist/parsers/observed-invocation.js +42 -0
- package/dist/parsers/observed-invocation.js.map +1 -0
- package/dist/pipeline.d.ts +17 -0
- package/dist/pipeline.js +181 -10
- package/dist/pipeline.js.map +1 -1
- package/dist/progress-report/lock.d.ts +74 -0
- package/dist/progress-report/lock.js +343 -0
- package/dist/progress-report/lock.js.map +1 -0
- package/dist/progress-report/schema.d.ts +808 -0
- package/dist/progress-report/schema.js +119 -0
- package/dist/progress-report/schema.js.map +1 -0
- package/dist/progress-report/store.d.ts +66 -0
- package/dist/progress-report/store.js +766 -0
- package/dist/progress-report/store.js.map +1 -0
- package/dist/progress-report/tools.d.ts +20 -0
- package/dist/progress-report/tools.js +141 -0
- package/dist/progress-report/tools.js.map +1 -0
- package/dist/prompt-mode.d.ts +1 -1
- package/dist/prompt-mode.js +7 -2
- package/dist/prompt-mode.js.map +1 -1
- package/dist/run-dir.d.ts +24 -0
- package/dist/run-dir.js +201 -2
- package/dist/run-dir.js.map +1 -1
- package/dist/runner.d.ts +20 -0
- package/dist/runner.js +192 -16
- package/dist/runner.js.map +1 -1
- package/dist/safety.d.ts +54 -4
- package/dist/safety.js +186 -5
- package/dist/safety.js.map +1 -1
- package/dist/schema.d.ts +15 -7
- package/dist/schema.js +20 -0
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +7 -1
- package/dist/server.js +451 -23
- package/dist/server.js.map +1 -1
- package/dist/session-log-stream.d.ts +18 -0
- package/dist/session-log-stream.js +566 -0
- package/dist/session-log-stream.js.map +1 -0
- package/dist/stdio-activity.d.ts +28 -0
- package/dist/stdio-activity.js +72 -0
- package/dist/stdio-activity.js.map +1 -0
- package/package.json +47 -5
- package/conf/adapters/gemini.json +0 -44
- package/conf/adapters/hapi/gemini.json +0 -47
- package/dist/parsers/gemini-json.d.ts +0 -2
- package/dist/parsers/gemini-json.js +0 -72
- package/dist/parsers/gemini-json.js.map +0 -1
|
@@ -5,10 +5,12 @@ import { isSamePathOrDescendant } from "../allowed-roots.js";
|
|
|
5
5
|
import { CancellationError } from "../errors.js";
|
|
6
6
|
import { CONTEXT_BUILDER_INTERNAL_CAP_DEFAULTS, } from "./config.js";
|
|
7
7
|
import { CONTEXT_BUILDER_REQUESTED_EVIDENCE_OMISSION_REASON, requestedEvidenceOmission, } from "./diagnostics.js";
|
|
8
|
+
import { CONTEXT_BUILDER_SCAN_PROGRESS_EVERY_FILES } from "./discovery-progress.js";
|
|
8
9
|
import { compileContextBuilderGlobs, CONTEXT_BUILDER_DEFAULT_EXCLUDE_GLOBS, } from "./globs.js";
|
|
9
10
|
import { normalizeContextBuilderRootRelativePath, rootRelativePathForAbsolutePath, } from "./paths.js";
|
|
10
11
|
import { directoryDistance, genericPathKind, isTestPath, normalizedPathStem, } from "./path-signals.js";
|
|
11
|
-
import {
|
|
12
|
+
import { buildContextReviewObligations, planRegressionHeadSliceCandidates, } from "./review-coverage.js";
|
|
13
|
+
import { sanitizeHighConfidenceSecretContent, scanSecretPath, } from "./secrets.js";
|
|
12
14
|
import { CONTEXT_BUILDER_PUBLIC_BUDGET_HARD_LIMITS, } from "./schema.js";
|
|
13
15
|
const SEARCH_WINDOW_LINES_BEFORE = 19;
|
|
14
16
|
const SEARCH_WINDOW_LINES_AFTER = 20;
|
|
@@ -16,13 +18,32 @@ const SEARCH_BRIDGE_GAP_LINES = 20;
|
|
|
16
18
|
const SEARCH_MAX_MERGED_SPAN_LINES = 160;
|
|
17
19
|
const DEFAULT_MAX_FULL_FOCUS_SLICE_BYTES = 48_000;
|
|
18
20
|
const DEFAULT_MAX_FULL_IMPLEMENTATION_FOCUS_SLICE_BYTES = 96_000;
|
|
21
|
+
// Non-silent, material signal for an explicitly-focused file that exceeded the
|
|
22
|
+
// bounded full-file focus size and had no per-file search evidence: instead of
|
|
23
|
+
// dropping it, we include a bounded head slice and record this reason so the
|
|
24
|
+
// receipt reflects a partial inclusion (not a silent omission).
|
|
25
|
+
const CONTEXT_BUILDER_FOCUS_SLICED_REASON = "focus_sliced";
|
|
26
|
+
// Non-silent, material signal for an explicitly-focused file whose FIRST logical
|
|
27
|
+
// line alone exceeds the bounded focus-slice cap. The line-range model cannot
|
|
28
|
+
// express a partial line, so emitting a head slice would blow the byte bound.
|
|
29
|
+
// We omit the file with this explicit material reason instead — honoring both
|
|
30
|
+
// the byte bound and "never silently drop an explicitly-focused file".
|
|
31
|
+
const CONTEXT_BUILDER_FOCUS_OVER_CAP_REASON = "focus_over_cap";
|
|
32
|
+
// Secret sanitization can run multi-second synchronous stretches. The walk
|
|
33
|
+
// yields a macrotask at least this often (and after every sanitize) so timers,
|
|
34
|
+
// cancellation notifications, and lock heartbeats keep running mid-scan.
|
|
35
|
+
const DISCOVERY_YIELD_EVERY_FILES = 32;
|
|
19
36
|
const IMPORT_EXPANSION_PASSES = 3;
|
|
37
|
+
const MAX_EXPANDED_SEARCH_TERMS = 128;
|
|
38
|
+
const MAX_EXPANDED_SEARCH_TERM_BYTES = 16_384;
|
|
39
|
+
const MAX_DERIVED_SEARCH_TERM_LENGTH = 256;
|
|
20
40
|
const PROJECT_SUPPORT_FILENAMES = Object.freeze([
|
|
21
41
|
"package.json",
|
|
22
42
|
"vitest.config.ts",
|
|
23
43
|
"vite.config.ts",
|
|
24
44
|
]);
|
|
25
45
|
export async function discoverContextBuilderCandidates(options) {
|
|
46
|
+
const allowSecrets = options.allowSecrets ?? true;
|
|
26
47
|
const internalCaps = options.internal_caps ?? CONTEXT_BUILDER_INTERNAL_CAP_DEFAULTS;
|
|
27
48
|
const matcher = compileContextBuilderGlobs({
|
|
28
49
|
include: [...(options.include_globs ?? [])],
|
|
@@ -37,6 +58,8 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
37
58
|
omissions: [],
|
|
38
59
|
requestedEvidenceOmissionKeys: new Set(),
|
|
39
60
|
processedFileKeys: new Set(),
|
|
61
|
+
traversedDirectoryKeys: new Set(),
|
|
62
|
+
focusScanExemptFiles: 0,
|
|
40
63
|
metrics: {
|
|
41
64
|
files_seen: 0,
|
|
42
65
|
files_considered: 0,
|
|
@@ -48,6 +71,9 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
48
71
|
bytes_read: 0,
|
|
49
72
|
},
|
|
50
73
|
stopped: false,
|
|
74
|
+
onProgress: options.onProgress,
|
|
75
|
+
filesSinceYield: 0,
|
|
76
|
+
filesSinceProgress: 0,
|
|
51
77
|
};
|
|
52
78
|
for (const root of options.roots) {
|
|
53
79
|
if (state.stopped) {
|
|
@@ -57,6 +83,7 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
57
83
|
await processExactFocusFiles({
|
|
58
84
|
root,
|
|
59
85
|
focusPaths: options.focus_paths ?? [],
|
|
86
|
+
allowSecrets,
|
|
60
87
|
matcher,
|
|
61
88
|
budget: options.budget,
|
|
62
89
|
internalCaps,
|
|
@@ -70,12 +97,31 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
70
97
|
},
|
|
71
98
|
state,
|
|
72
99
|
});
|
|
100
|
+
await processFocusDirectories({
|
|
101
|
+
root,
|
|
102
|
+
focusPaths: options.focus_paths ?? [],
|
|
103
|
+
allowSecrets,
|
|
104
|
+
matcher,
|
|
105
|
+
budget: options.budget,
|
|
106
|
+
internalCaps,
|
|
107
|
+
excludedRealRoots: options.excluded_real_roots ?? [],
|
|
108
|
+
...(options.signal == null ? {} : { signal: options.signal }),
|
|
109
|
+
fs: {
|
|
110
|
+
readdir: options.fs?.readdir ?? fsReaddir,
|
|
111
|
+
lstat: options.fs?.lstat ?? fsLstat,
|
|
112
|
+
open: options.fs?.open ?? fsOpen,
|
|
113
|
+
realpath: options.fs?.realpath ?? fsRealpath,
|
|
114
|
+
stat: options.fs?.stat ?? fsStat,
|
|
115
|
+
},
|
|
116
|
+
state,
|
|
117
|
+
});
|
|
73
118
|
await traverseDirectory({
|
|
74
119
|
root,
|
|
75
120
|
absoluteDir: root.path,
|
|
76
121
|
relativeDir: "",
|
|
77
122
|
matcher,
|
|
78
123
|
focusPaths: options.focus_paths ?? [],
|
|
124
|
+
allowSecrets,
|
|
79
125
|
budget: options.budget,
|
|
80
126
|
internalCaps,
|
|
81
127
|
excludedRealRoots: options.excluded_real_roots ?? [],
|
|
@@ -93,6 +139,7 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
93
139
|
root,
|
|
94
140
|
matcher,
|
|
95
141
|
focusPaths: options.focus_paths ?? [],
|
|
142
|
+
allowSecrets,
|
|
96
143
|
budget: options.budget,
|
|
97
144
|
internalCaps,
|
|
98
145
|
...(options.signal == null ? {} : { signal: options.signal }),
|
|
@@ -108,11 +155,12 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
108
155
|
}
|
|
109
156
|
state.tree.sort(compareTreeFiles);
|
|
110
157
|
state.contentCandidates.sort(compareContentCandidates);
|
|
158
|
+
const expandedSearchTerms = expandSearchTerms([...(options.search_terms ?? [])]);
|
|
111
159
|
const search = buildCandidateSearchRecords({
|
|
112
160
|
candidates: state.contentCandidates,
|
|
113
|
-
...(options.task == null ? {} : { task: options.task }),
|
|
114
161
|
focusPaths: [...(options.focus_paths ?? [])],
|
|
115
|
-
searchTerms:
|
|
162
|
+
searchTerms: expandedSearchTerms.terms,
|
|
163
|
+
callerTermCount: expandedSearchTerms.callerTermCount,
|
|
116
164
|
maxSearchResults: options.budget.max_search_results,
|
|
117
165
|
maxPreviewBytes: internalCaps.max_search_preview_bytes,
|
|
118
166
|
maxCandidateBytes: internalCaps.max_candidate_bytes,
|
|
@@ -135,6 +183,50 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
135
183
|
if (slices.capHit) {
|
|
136
184
|
state.metrics.candidate_cap_hit = true;
|
|
137
185
|
}
|
|
186
|
+
const reviewFocusPaths = (options.focus_paths ?? []).map((focus) => ({
|
|
187
|
+
root_index: focus.root_index,
|
|
188
|
+
path: focus.root_relative_path,
|
|
189
|
+
kind: focus.kind,
|
|
190
|
+
}));
|
|
191
|
+
let reviewObligations = buildContextReviewObligations({
|
|
192
|
+
candidates: state.contentCandidates,
|
|
193
|
+
focusPaths: reviewFocusPaths,
|
|
194
|
+
searchRecords: search.records,
|
|
195
|
+
slices: slices.records,
|
|
196
|
+
policy: options.coverage_policy,
|
|
197
|
+
});
|
|
198
|
+
if (reviewObligations != null) {
|
|
199
|
+
const headSlices = buildRegressionHeadSliceRecords({
|
|
200
|
+
candidates: state.contentCandidates,
|
|
201
|
+
planned: planRegressionHeadSliceCandidates({
|
|
202
|
+
candidates: state.contentCandidates,
|
|
203
|
+
searchRecords: search.records,
|
|
204
|
+
slices: slices.records,
|
|
205
|
+
obligations: reviewObligations,
|
|
206
|
+
}),
|
|
207
|
+
existingRecords: slices.records,
|
|
208
|
+
maxCandidateSlices: internalCaps.max_candidate_slices,
|
|
209
|
+
maxCandidateBytes: Math.max(0, internalCaps.max_candidate_bytes - search.candidateBytes),
|
|
210
|
+
maxBytesPerFile: options.budget.max_bytes_per_file,
|
|
211
|
+
});
|
|
212
|
+
if (headSlices.length > 0) {
|
|
213
|
+
slices.records.push(...headSlices);
|
|
214
|
+
reviewObligations = buildContextReviewObligations({
|
|
215
|
+
candidates: state.contentCandidates,
|
|
216
|
+
focusPaths: reviewFocusPaths,
|
|
217
|
+
searchRecords: search.records,
|
|
218
|
+
slices: slices.records,
|
|
219
|
+
policy: options.coverage_policy,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
classifyContextEvidenceCandidates({
|
|
224
|
+
candidates: state.contentCandidates,
|
|
225
|
+
focusPaths: options.focus_paths ?? [],
|
|
226
|
+
searchRecords: search.records,
|
|
227
|
+
policy: options.coverage_policy,
|
|
228
|
+
obligations: reviewObligations,
|
|
229
|
+
});
|
|
138
230
|
auditScanCapFocusedPaths({
|
|
139
231
|
focusPaths: [...(options.focus_paths ?? [])],
|
|
140
232
|
state,
|
|
@@ -146,30 +238,86 @@ export async function discoverContextBuilderCandidates(options) {
|
|
|
146
238
|
slices: slices.records,
|
|
147
239
|
omissions: state.omissions,
|
|
148
240
|
metrics: state.metrics,
|
|
241
|
+
search_coverage: search.coverage,
|
|
242
|
+
...(reviewObligations == null ? {} : { review_obligations: reviewObligations }),
|
|
149
243
|
};
|
|
150
244
|
}
|
|
151
|
-
function expandSearchTerms(searchTerms) {
|
|
245
|
+
export function expandSearchTerms(searchTerms) {
|
|
152
246
|
const expanded = [];
|
|
153
247
|
const seen = new Set();
|
|
248
|
+
let aggregateBytes = 0;
|
|
249
|
+
// Caller terms are admitted first and are never displaced by heuristic
|
|
250
|
+
// expansion. Public post-parse validation owns their individual/aggregate
|
|
251
|
+
// bounds; this function only bounds derived fan-out before stream creation.
|
|
252
|
+
for (const term of searchTerms) {
|
|
253
|
+
const added = addExpandedSearchTerm(expanded, seen, term);
|
|
254
|
+
aggregateBytes += added;
|
|
255
|
+
}
|
|
256
|
+
const callerTermCount = expanded.length;
|
|
154
257
|
for (const term of searchTerms) {
|
|
155
|
-
addExpandedSearchTerm(expanded, seen, term);
|
|
156
258
|
for (const derived of deriveGenericSearchTerms(term)) {
|
|
157
|
-
|
|
259
|
+
const normalized = derived.trim();
|
|
260
|
+
if (normalized.length > MAX_DERIVED_SEARCH_TERM_LENGTH ||
|
|
261
|
+
expanded.length >= MAX_EXPANDED_SEARCH_TERMS) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const bytes = Buffer.byteLength(normalized, "utf8");
|
|
265
|
+
if (aggregateBytes + bytes > MAX_EXPANDED_SEARCH_TERM_BYTES) {
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
aggregateBytes += addExpandedSearchTerm(expanded, seen, normalized);
|
|
158
269
|
}
|
|
159
270
|
}
|
|
160
|
-
return expanded;
|
|
271
|
+
return { terms: expanded, callerTermCount };
|
|
272
|
+
}
|
|
273
|
+
function classifyContextEvidenceCandidates(input) {
|
|
274
|
+
if (input.policy?.id == null) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const directSearchKeys = new Set(input.searchRecords.map(candidateKey));
|
|
278
|
+
const focusedFileKeys = new Set(input.focusPaths
|
|
279
|
+
.filter((focus) => focus.kind === "file")
|
|
280
|
+
.map((focus) => candidateKey({
|
|
281
|
+
root_index: focus.root_index,
|
|
282
|
+
path: focus.root_relative_path,
|
|
283
|
+
})));
|
|
284
|
+
const targetCandidateIds = new Set(input.obligations?.targets.map((target) => target.candidate_id) ?? []);
|
|
285
|
+
const regressionCandidateIds = new Set(input.obligations?.targets.flatMap((target) => target.regression_links.map((link) => link.candidate_id)) ?? []);
|
|
286
|
+
for (const candidate of input.candidates) {
|
|
287
|
+
const classes = [];
|
|
288
|
+
const key = candidateKey(candidate);
|
|
289
|
+
const packetCandidateId = `c:${String(candidate.root_index)}:${candidate.path}`;
|
|
290
|
+
const isReviewTarget = targetCandidateIds.has(packetCandidateId);
|
|
291
|
+
if (isReviewTarget) {
|
|
292
|
+
classes.push("review_target");
|
|
293
|
+
}
|
|
294
|
+
if (isTestPath(candidate.path) && regressionCandidateIds.has(packetCandidateId)) {
|
|
295
|
+
classes.push("regression_test");
|
|
296
|
+
}
|
|
297
|
+
const hasDiscoveryEvidence = directSearchKeys.has(key) ||
|
|
298
|
+
focusedFileKeys.has(key) ||
|
|
299
|
+
candidate.selection_hint != null;
|
|
300
|
+
if (genericPathKind(candidate.path) === "config" && hasDiscoveryEvidence) {
|
|
301
|
+
classes.push("configuration");
|
|
302
|
+
}
|
|
303
|
+
if (candidate.selection_hint === "local_dependency") {
|
|
304
|
+
classes.push("dependency");
|
|
305
|
+
}
|
|
306
|
+
candidate.evidence_classes = classes;
|
|
307
|
+
}
|
|
161
308
|
}
|
|
162
309
|
function addExpandedSearchTerm(expanded, seen, term) {
|
|
163
310
|
const normalized = term.trim();
|
|
164
311
|
if (normalized.length === 0) {
|
|
165
|
-
return;
|
|
312
|
+
return 0;
|
|
166
313
|
}
|
|
167
314
|
const key = normalized.toLowerCase();
|
|
168
315
|
if (seen.has(key)) {
|
|
169
|
-
return;
|
|
316
|
+
return 0;
|
|
170
317
|
}
|
|
171
318
|
expanded.push(normalized);
|
|
172
319
|
seen.add(key);
|
|
320
|
+
return Buffer.byteLength(normalized, "utf8");
|
|
173
321
|
}
|
|
174
322
|
function deriveGenericSearchTerms(term) {
|
|
175
323
|
const tokens = tokenizeGenericSearchTerm(term);
|
|
@@ -238,6 +386,7 @@ async function processImportAndSupportFiles(input) {
|
|
|
238
386
|
relativePath,
|
|
239
387
|
matcher: input.matcher,
|
|
240
388
|
focusPaths: input.focusPaths,
|
|
389
|
+
allowSecrets: input.allowSecrets,
|
|
241
390
|
budget: input.budget,
|
|
242
391
|
internalCaps: input.internalCaps,
|
|
243
392
|
ignoreIncludeGlob: true,
|
|
@@ -264,6 +413,7 @@ async function processImportAndSupportFiles(input) {
|
|
|
264
413
|
relativePath,
|
|
265
414
|
matcher: input.matcher,
|
|
266
415
|
focusPaths: input.focusPaths,
|
|
416
|
+
allowSecrets: input.allowSecrets,
|
|
267
417
|
budget: input.budget,
|
|
268
418
|
internalCaps: input.internalCaps,
|
|
269
419
|
ignoreIncludeGlob: true,
|
|
@@ -477,9 +627,51 @@ async function processExactFocusFiles(input) {
|
|
|
477
627
|
relativePath: focus.root_relative_path,
|
|
478
628
|
matcher: input.matcher,
|
|
479
629
|
focusPaths: input.focusPaths,
|
|
630
|
+
allowSecrets: input.allowSecrets,
|
|
480
631
|
budget: input.budget,
|
|
481
632
|
internalCaps: input.internalCaps,
|
|
482
|
-
|
|
633
|
+
focusScanExempt: true,
|
|
634
|
+
...(input.signal == null ? {} : { signal: input.signal }),
|
|
635
|
+
fs: input.fs,
|
|
636
|
+
state: input.state,
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
// Pre-walk explicitly-focused directories before global traversal so a focus
|
|
641
|
+
// directory late in sort order cannot be starved by max_scan_files exhaustion
|
|
642
|
+
// from unrelated trees. Files processed here are focus-scan-exempt (they never
|
|
643
|
+
// erode traversal headroom) but remain bounded by the discovery byte and
|
|
644
|
+
// candidate caps; glob/secret/binary semantics are unchanged because the walk
|
|
645
|
+
// reuses traverseDirectory/processFile verbatim.
|
|
646
|
+
async function processFocusDirectories(input) {
|
|
647
|
+
const focusDirectories = [...input.focusPaths]
|
|
648
|
+
.filter((focus) => focus.root_index === input.root.root_index)
|
|
649
|
+
.filter((focus) => focus.kind === "directory")
|
|
650
|
+
.sort(compareFocusPathsForDiscovery);
|
|
651
|
+
for (const focus of focusDirectories) {
|
|
652
|
+
assertNotAborted(input.signal);
|
|
653
|
+
// A root-level focus gains nothing from a pre-walk (global traversal
|
|
654
|
+
// starts there immediately), and pre-walking it would exempt the entire
|
|
655
|
+
// root from max_scan_files.
|
|
656
|
+
if (focus.root_relative_path === "") {
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
// Leave include-glob-pruned focus directories to global traversal, which
|
|
660
|
+
// emits the existing requested-evidence omission for them.
|
|
661
|
+
if (!input.matcher.canContainIncludedPath(focus.root_relative_path)) {
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
await traverseDirectory({
|
|
665
|
+
root: input.root,
|
|
666
|
+
absoluteDir: focus.absolute_path,
|
|
667
|
+
relativeDir: focus.root_relative_path,
|
|
668
|
+
matcher: input.matcher,
|
|
669
|
+
focusPaths: input.focusPaths,
|
|
670
|
+
allowSecrets: input.allowSecrets,
|
|
671
|
+
budget: input.budget,
|
|
672
|
+
internalCaps: input.internalCaps,
|
|
673
|
+
excludedRealRoots: input.excludedRealRoots,
|
|
674
|
+
focusScanExempt: true,
|
|
483
675
|
...(input.signal == null ? {} : { signal: input.signal }),
|
|
484
676
|
fs: input.fs,
|
|
485
677
|
state: input.state,
|
|
@@ -495,14 +687,41 @@ export function buildCandidateSearchRecords(input) {
|
|
|
495
687
|
let previewBytes = 0;
|
|
496
688
|
let candidateBytes = 0;
|
|
497
689
|
let capHit = false;
|
|
498
|
-
|
|
499
|
-
return { records, capHit, candidateBytes };
|
|
500
|
-
}
|
|
690
|
+
const callerTermCount = Math.max(0, Math.min(input.callerTermCount ?? 0, input.searchTerms.length));
|
|
501
691
|
const searchTerms = input.searchTerms
|
|
502
692
|
.map((term, index) => ({ term, index }))
|
|
503
693
|
.filter(({ term }) => term.trim().length > 0);
|
|
694
|
+
const callerTerms = searchTerms.filter(({ index }) => index < callerTermCount);
|
|
695
|
+
const derivedTerms = searchTerms.filter(({ index }) => index >= callerTermCount);
|
|
696
|
+
// Candidates whose content was examined for at least one term before a hard
|
|
697
|
+
// cap ended the walk. Key set is bounded by the candidate pool; only counts
|
|
698
|
+
// are surfaced.
|
|
699
|
+
const searchedCandidateKeys = new Set();
|
|
700
|
+
const callerTermCoverage = callerTerms.map(({ term, index }) => ({
|
|
701
|
+
term,
|
|
702
|
+
search_term_index: index,
|
|
703
|
+
hit_count: 0,
|
|
704
|
+
scan_complete: false,
|
|
705
|
+
}));
|
|
706
|
+
let callerRecordCount = 0;
|
|
707
|
+
const finalize = () => ({
|
|
708
|
+
records,
|
|
709
|
+
capHit,
|
|
710
|
+
candidateBytes,
|
|
711
|
+
coverage: {
|
|
712
|
+
eligible_candidate_count: input.candidates.length,
|
|
713
|
+
searched_candidate_count: searchedCandidateKeys.size,
|
|
714
|
+
unsearched_candidate_count: input.candidates.length - searchedCandidateKeys.size,
|
|
715
|
+
caller_term_count: callerTerms.length,
|
|
716
|
+
derived_term_count: derivedTerms.length,
|
|
717
|
+
caller_record_count: callerRecordCount,
|
|
718
|
+
derived_record_count: records.length - callerRecordCount,
|
|
719
|
+
caller_coverage_complete: callerTermCoverage.every((coverage) => coverage.scan_complete),
|
|
720
|
+
caller_terms: callerTermCoverage,
|
|
721
|
+
},
|
|
722
|
+
});
|
|
504
723
|
if (searchTerms.length === 0) {
|
|
505
|
-
return
|
|
724
|
+
return finalize();
|
|
506
725
|
}
|
|
507
726
|
const focusRank = new Map();
|
|
508
727
|
for (const focus of input.focusPaths ?? []) {
|
|
@@ -521,70 +740,154 @@ export function buildCandidateSearchRecords(input) {
|
|
|
521
740
|
const leftRank = focusRank.get(candidateKey(left)) ?? Number.MAX_SAFE_INTEGER;
|
|
522
741
|
const rightRank = focusRank.get(candidateKey(right)) ?? Number.MAX_SAFE_INTEGER;
|
|
523
742
|
return (leftRank - rightRank ||
|
|
524
|
-
discoveryTaskClosureRank(left.path, input.task ?? "") -
|
|
525
|
-
discoveryTaskClosureRank(right.path, input.task ?? "") ||
|
|
526
743
|
compareContentCandidates(left, right));
|
|
527
744
|
});
|
|
528
|
-
const
|
|
745
|
+
const candidateLines = [];
|
|
529
746
|
for (const candidate of candidates) {
|
|
530
747
|
assertNotAborted(input.signal);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
748
|
+
candidateLines.push(splitTextLines(candidate.content));
|
|
749
|
+
}
|
|
750
|
+
// Emits one found hit unless a hard cap rejects it. Cap semantics match the
|
|
751
|
+
// pre-phasing scheduler: the record/byte caps are checked after the hit is
|
|
752
|
+
// found, and tripping either one ends the whole search with capHit set.
|
|
753
|
+
const emitSearchHit = (stream, hit) => {
|
|
754
|
+
if (records.length >= input.maxSearchResults) {
|
|
755
|
+
capHit = true;
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
const preview = boundedPreview(hit.line, hit.columnIndex, stream.searchTerm.term.length);
|
|
759
|
+
const previewSize = Buffer.byteLength(preview, "utf8");
|
|
760
|
+
const bounded = previewBytes + previewSize <= maxPreviewBytes ? preview : "";
|
|
761
|
+
const record = {
|
|
762
|
+
root_index: stream.candidate.root_index,
|
|
763
|
+
path: stream.candidate.path,
|
|
764
|
+
line: hit.lineIndex + 1,
|
|
765
|
+
column: hit.columnIndex + 1,
|
|
766
|
+
search_term: stream.searchTerm.term,
|
|
767
|
+
search_term_index: stream.searchTerm.index,
|
|
768
|
+
preview: bounded,
|
|
769
|
+
};
|
|
770
|
+
const recordBytes = Buffer.byteLength(`${JSON.stringify(record)}\n`, "utf8");
|
|
771
|
+
if (candidateBytes + recordBytes > maxCandidateBytes) {
|
|
772
|
+
capHit = true;
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
previewBytes += Buffer.byteLength(bounded, "utf8");
|
|
776
|
+
candidateBytes += recordBytes;
|
|
777
|
+
records.push(record);
|
|
778
|
+
return true;
|
|
779
|
+
};
|
|
780
|
+
if (callerTerms.length > 0) {
|
|
781
|
+
// Phase 1 — exact caller terms get first claim on the record budget. One
|
|
782
|
+
// cursor per caller term walks the complete candidate list (focus rank
|
|
783
|
+
// first, one hit per candidate per pass), and the scheduler round-robins
|
|
784
|
+
// across the term cursors, so neither a common sibling term nor an early
|
|
785
|
+
// alphabetical candidate prefix can starve a rare late-path caller hit.
|
|
786
|
+
const cursors = callerTermCoverage.map((coverage) => ({
|
|
787
|
+
coverage,
|
|
788
|
+
streams: candidates.map((candidate, candidateIndex) => ({
|
|
534
789
|
candidate,
|
|
535
|
-
searchTerm,
|
|
536
|
-
lines,
|
|
790
|
+
searchTerm: { term: coverage.term, index: coverage.search_term_index },
|
|
791
|
+
lines: candidateLines[candidateIndex] ?? [],
|
|
537
792
|
lineIndex: 0,
|
|
538
793
|
fromIndex: 0,
|
|
539
794
|
done: false,
|
|
540
|
-
})
|
|
795
|
+
})),
|
|
796
|
+
cursor: 0,
|
|
797
|
+
active: candidates.length,
|
|
798
|
+
exhausted: false,
|
|
799
|
+
}));
|
|
800
|
+
let liveCursors = cursors.length;
|
|
801
|
+
while (liveCursors > 0) {
|
|
802
|
+
for (const cursor of cursors) {
|
|
803
|
+
assertNotAborted(input.signal);
|
|
804
|
+
if (cursor.exhausted) {
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
const next = nextCallerTermHit(cursor, searchedCandidateKeys);
|
|
808
|
+
if (next == null) {
|
|
809
|
+
// Natural exhaustion: this term's cursor examined every candidate.
|
|
810
|
+
cursor.exhausted = true;
|
|
811
|
+
cursor.coverage.scan_complete = true;
|
|
812
|
+
liveCursors--;
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
if (!emitSearchHit(next.stream, next.hit)) {
|
|
816
|
+
return finalize();
|
|
817
|
+
}
|
|
818
|
+
cursor.coverage.hit_count++;
|
|
819
|
+
callerRecordCount++;
|
|
820
|
+
}
|
|
541
821
|
}
|
|
542
822
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
823
|
+
if (derivedTerms.length > 0) {
|
|
824
|
+
// Phase 2 — derived/heuristic terms spend whatever budget remains, using
|
|
825
|
+
// the pre-existing candidate-major one-hit-per-stream round-robin.
|
|
826
|
+
const streams = [];
|
|
827
|
+
for (const [candidateIndex, candidate] of candidates.entries()) {
|
|
547
828
|
assertNotAborted(input.signal);
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
829
|
+
const lines = candidateLines[candidateIndex] ?? [];
|
|
830
|
+
for (const searchTerm of derivedTerms) {
|
|
831
|
+
streams.push({
|
|
832
|
+
candidate,
|
|
833
|
+
searchTerm,
|
|
834
|
+
lines,
|
|
835
|
+
lineIndex: 0,
|
|
836
|
+
fromIndex: 0,
|
|
837
|
+
done: false,
|
|
838
|
+
});
|
|
556
839
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
840
|
+
}
|
|
841
|
+
let activeStreams = streams.length;
|
|
842
|
+
while (activeStreams > 0) {
|
|
843
|
+
let foundInRound = false;
|
|
844
|
+
for (const stream of streams) {
|
|
845
|
+
assertNotAborted(input.signal);
|
|
846
|
+
if (stream.done) {
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
searchedCandidateKeys.add(candidateKey(stream.candidate));
|
|
850
|
+
const hit = nextSearchHit(stream);
|
|
851
|
+
if (hit == null) {
|
|
852
|
+
stream.done = true;
|
|
853
|
+
activeStreams--;
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
foundInRound = true;
|
|
857
|
+
if (!emitSearchHit(stream, hit)) {
|
|
858
|
+
return finalize();
|
|
859
|
+
}
|
|
561
860
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const bounded = previewBytes + previewSize <= maxPreviewBytes ? preview : "";
|
|
565
|
-
const record = {
|
|
566
|
-
root_index: stream.candidate.root_index,
|
|
567
|
-
path: stream.candidate.path,
|
|
568
|
-
line: hit.lineIndex + 1,
|
|
569
|
-
column: hit.columnIndex + 1,
|
|
570
|
-
search_term: stream.searchTerm.term,
|
|
571
|
-
search_term_index: stream.searchTerm.index,
|
|
572
|
-
preview: bounded,
|
|
573
|
-
};
|
|
574
|
-
const recordBytes = Buffer.byteLength(`${JSON.stringify(record)}\n`, "utf8");
|
|
575
|
-
if (candidateBytes + recordBytes > maxCandidateBytes) {
|
|
576
|
-
capHit = true;
|
|
577
|
-
return { records, capHit, candidateBytes };
|
|
861
|
+
if (!foundInRound) {
|
|
862
|
+
break;
|
|
578
863
|
}
|
|
579
|
-
previewBytes += Buffer.byteLength(bounded, "utf8");
|
|
580
|
-
candidateBytes += recordBytes;
|
|
581
|
-
records.push(record);
|
|
582
864
|
}
|
|
583
|
-
|
|
584
|
-
|
|
865
|
+
}
|
|
866
|
+
return finalize();
|
|
867
|
+
}
|
|
868
|
+
// Advances one caller term's cursor to its next hit, cycling the candidate
|
|
869
|
+
// list one hit per candidate per pass. Scanning is free — only emitted records
|
|
870
|
+
// consume the budget — so a rare term reaches late-sorting candidates even
|
|
871
|
+
// when earlier candidates are saturated with other terms' hits. Returns
|
|
872
|
+
// undefined exactly when every candidate stream is exhausted.
|
|
873
|
+
function nextCallerTermHit(cursor, searchedCandidateKeys) {
|
|
874
|
+
const total = cursor.streams.length;
|
|
875
|
+
for (let visited = 0; visited < total && cursor.active > 0; visited++) {
|
|
876
|
+
const stream = cursor.streams[cursor.cursor];
|
|
877
|
+
cursor.cursor = (cursor.cursor + 1) % total;
|
|
878
|
+
if (stream == null || stream.done) {
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
searchedCandidateKeys.add(candidateKey(stream.candidate));
|
|
882
|
+
const hit = nextSearchHit(stream);
|
|
883
|
+
if (hit == null) {
|
|
884
|
+
stream.done = true;
|
|
885
|
+
cursor.active--;
|
|
886
|
+
continue;
|
|
585
887
|
}
|
|
888
|
+
return { stream, hit };
|
|
586
889
|
}
|
|
587
|
-
return
|
|
890
|
+
return undefined;
|
|
588
891
|
}
|
|
589
892
|
export function buildCandidateSliceRecords(input) {
|
|
590
893
|
const maxCandidateSlices = input.maxCandidateSlices ??
|
|
@@ -603,7 +906,7 @@ export function buildCandidateSliceRecords(input) {
|
|
|
603
906
|
const expectedFocusedSearchRanges = new Map();
|
|
604
907
|
const survivedFocusedSearchRanges = new Map();
|
|
605
908
|
const focusSliceSurvivors = new Set();
|
|
606
|
-
const
|
|
909
|
+
const slicedLargeFocusedCandidates = new Set();
|
|
607
910
|
const omittedRequestedCandidates = new Set();
|
|
608
911
|
const pushRequestedCandidateOmission = (candidate, kind, message) => {
|
|
609
912
|
const key = candidateKey(candidate);
|
|
@@ -701,12 +1004,8 @@ export function buildCandidateSliceRecords(input) {
|
|
|
701
1004
|
(focus.kind === "directory" &&
|
|
702
1005
|
isRootRelativeDescendant(candidate.path, focus.root_relative_path)))) {
|
|
703
1006
|
const key = candidateKey(candidate);
|
|
704
|
-
if (candidate.byte_length >
|
|
705
|
-
if (
|
|
706
|
-
pushRequestedCandidateOmission(candidate, "too_large", "focused file exceeded bounded full-file focus size and had no per-file search evidence");
|
|
707
|
-
omittedLargeFocusedCandidates.add(key);
|
|
708
|
-
}
|
|
709
|
-
else if (searchRanges.has(key)) {
|
|
1007
|
+
if (candidate.byte_length > maxFullFocusSliceBytes) {
|
|
1008
|
+
if (searchRanges.has(key)) {
|
|
710
1009
|
focusedLargeSearchCandidates.set(key, candidate);
|
|
711
1010
|
expectedFocusedSearchRanges.set(key, mergeLineRanges(searchRanges.get(key) ?? [], {
|
|
712
1011
|
bridgeGapLines: SEARCH_BRIDGE_GAP_LINES,
|
|
@@ -714,6 +1013,27 @@ export function buildCandidateSliceRecords(input) {
|
|
|
714
1013
|
}));
|
|
715
1014
|
survivedFocusedSearchRanges.set(key, []);
|
|
716
1015
|
}
|
|
1016
|
+
else if (!slicedLargeFocusedCandidates.has(key)) {
|
|
1017
|
+
// Never silently drop an explicitly-focused file. With no per-file
|
|
1018
|
+
// search evidence, include a bounded head slice up to the focus
|
|
1019
|
+
// byte cap and record a material, non-silent partial-focus signal
|
|
1020
|
+
// instead of a too_large omission.
|
|
1021
|
+
if (firstLineExceedsCap(candidate.content, maxFullFocusSliceBytes)) {
|
|
1022
|
+
// The first logical line alone exceeds the cap (e.g. a minified
|
|
1023
|
+
// single-line file). The line-range model cannot express a partial
|
|
1024
|
+
// line, so a head slice would blow the byte bound. Omit the file
|
|
1025
|
+
// with an explicit material reason rather than exceeding the bound.
|
|
1026
|
+
omissions.push(focusOverCapNotice(candidate, maxFullFocusSliceBytes));
|
|
1027
|
+
slicedLargeFocusedCandidates.add(key);
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
const headEndLine = headSliceEndLine(candidate.content, maxFullFocusSliceBytes);
|
|
1031
|
+
const ranges = focusRanges.get(key) ?? [];
|
|
1032
|
+
ranges.push({ start_line: 1, end_line: headEndLine });
|
|
1033
|
+
focusRanges.set(key, ranges);
|
|
1034
|
+
omissions.push(focusSlicedNotice(candidate, headEndLine));
|
|
1035
|
+
slicedLargeFocusedCandidates.add(key);
|
|
1036
|
+
}
|
|
717
1037
|
continue;
|
|
718
1038
|
}
|
|
719
1039
|
const ranges = focusRanges.get(candidateKey(candidate)) ?? [];
|
|
@@ -735,6 +1055,30 @@ export function buildCandidateSliceRecords(input) {
|
|
|
735
1055
|
{ start_line: 1, end_line: Math.max(1, candidate.line_count) },
|
|
736
1056
|
]);
|
|
737
1057
|
}
|
|
1058
|
+
// Focus slices are appended FIRST so max_candidate_slices/max_candidate_bytes
|
|
1059
|
+
// pressure prunes search and dependency material before explicitly-focused
|
|
1060
|
+
// ranges — never the other way around.
|
|
1061
|
+
for (const [key, ranges] of [...focusRanges.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
1062
|
+
assertNotAborted(input.signal);
|
|
1063
|
+
const candidate = candidateByIdentity.get(key);
|
|
1064
|
+
if (candidate == null) {
|
|
1065
|
+
continue;
|
|
1066
|
+
}
|
|
1067
|
+
for (const range of mergeLineRanges(ranges)) {
|
|
1068
|
+
if (!append({
|
|
1069
|
+
root_index: candidate.root_index,
|
|
1070
|
+
path: candidate.path,
|
|
1071
|
+
start_line: range.start_line,
|
|
1072
|
+
end_line: range.end_line,
|
|
1073
|
+
source: "focus",
|
|
1074
|
+
content: sliceContent(candidate.content, range.start_line, range.end_line),
|
|
1075
|
+
})) {
|
|
1076
|
+
pushMissingFocusedRangeOmissions(focusRanges.keys());
|
|
1077
|
+
pushMissingFocusedSearchOmissions(focusedLargeSearchCandidates.keys());
|
|
1078
|
+
return { records, capHit, omissions };
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
738
1082
|
for (const [key, ranges] of [...searchRanges.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
739
1083
|
assertNotAborted(input.signal);
|
|
740
1084
|
const candidate = candidateByIdentity.get(key);
|
|
@@ -787,27 +1131,52 @@ export function buildCandidateSliceRecords(input) {
|
|
|
787
1131
|
}
|
|
788
1132
|
}
|
|
789
1133
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
1134
|
+
return { records, capHit, omissions };
|
|
1135
|
+
}
|
|
1136
|
+
// Head-slice line bound for synthesized regression evidence: enough to show a
|
|
1137
|
+
// test's imports and first cases without competing with real search windows.
|
|
1138
|
+
const REGRESSION_HEAD_SLICE_MAX_LINES = 60;
|
|
1139
|
+
/**
|
|
1140
|
+
* Materializes the tests chosen by `planRegressionHeadSliceCandidates` as real
|
|
1141
|
+
* slice records so selection, reconstruction, and rendering can carry them.
|
|
1142
|
+
* Source is `search` WITHOUT `search_term_index`: every slice consumer already
|
|
1143
|
+
* defaults a missing index to the lowest rank, and `focus` would wrongly mark
|
|
1144
|
+
* the test as caller-requested evidence. Content comes from the already
|
|
1145
|
+
* sanitized content candidate, so `allow_secrets:false` redaction applies
|
|
1146
|
+
* exactly as for other slices. Candidate slice/byte caps still bound the
|
|
1147
|
+
* total; a slice that does not fit is simply not synthesized.
|
|
1148
|
+
*/
|
|
1149
|
+
function buildRegressionHeadSliceRecords(input) {
|
|
1150
|
+
const candidateByIdentity = new Map(input.candidates.map((candidate) => [candidateKey(candidate), candidate]));
|
|
1151
|
+
let count = input.existingRecords.length;
|
|
1152
|
+
let bytes = input.existingRecords.reduce((total, record) => total + Buffer.byteLength(`${JSON.stringify(record)}\n`, "utf8"), 0);
|
|
1153
|
+
const records = [];
|
|
1154
|
+
for (const planned of input.planned) {
|
|
1155
|
+
const candidate = candidateByIdentity.get(candidateKey(planned));
|
|
1156
|
+
if (candidate == null ||
|
|
1157
|
+
candidate.line_count === 0 ||
|
|
1158
|
+
firstLineExceedsCap(candidate.content, input.maxBytesPerFile)) {
|
|
794
1159
|
continue;
|
|
795
1160
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
1161
|
+
const endLine = Math.min(candidate.line_count, REGRESSION_HEAD_SLICE_MAX_LINES, headSliceEndLine(candidate.content, input.maxBytesPerFile));
|
|
1162
|
+
const record = {
|
|
1163
|
+
root_index: candidate.root_index,
|
|
1164
|
+
path: candidate.path,
|
|
1165
|
+
start_line: 1,
|
|
1166
|
+
end_line: endLine,
|
|
1167
|
+
source: "search",
|
|
1168
|
+
content: sliceContent(candidate.content, 1, endLine),
|
|
1169
|
+
};
|
|
1170
|
+
const recordBytes = Buffer.byteLength(`${JSON.stringify(record)}\n`, "utf8");
|
|
1171
|
+
if (count >= input.maxCandidateSlices ||
|
|
1172
|
+
bytes + recordBytes > input.maxCandidateBytes) {
|
|
1173
|
+
continue;
|
|
808
1174
|
}
|
|
1175
|
+
records.push(record);
|
|
1176
|
+
count++;
|
|
1177
|
+
bytes += recordBytes;
|
|
809
1178
|
}
|
|
810
|
-
return
|
|
1179
|
+
return records;
|
|
811
1180
|
}
|
|
812
1181
|
export function splitTextLines(text) {
|
|
813
1182
|
if (text.length === 0) {
|
|
@@ -859,11 +1228,55 @@ export function mergeLineRanges(ranges, options = {}) {
|
|
|
859
1228
|
}
|
|
860
1229
|
return merged;
|
|
861
1230
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
1231
|
+
// Largest 1-based line count whose cumulative UTF-8 bytes (lines joined by
|
|
1232
|
+
// "\n", matching sliceContent) stay within capBytes. Always returns >= 1 so an
|
|
1233
|
+
// explicitly-focused file is never reduced to nothing.
|
|
1234
|
+
// CALLER COUPLING: line 1 is admitted unconditionally (the `count > 0 &&` guard
|
|
1235
|
+
// skips the cap check for the first line), so callers MUST pre-screen with
|
|
1236
|
+
// firstLineExceedsCap — otherwise an over-cap first line silently breaks the
|
|
1237
|
+
// byte bound.
|
|
1238
|
+
function headSliceEndLine(content, capBytes) {
|
|
1239
|
+
const lines = splitTextLines(content);
|
|
1240
|
+
let bytes = 0;
|
|
1241
|
+
let count = 0;
|
|
1242
|
+
for (const line of lines) {
|
|
1243
|
+
const next = bytes + (count === 0 ? 0 : 1) + Buffer.byteLength(line, "utf8");
|
|
1244
|
+
if (count > 0 && next > capBytes) {
|
|
1245
|
+
break;
|
|
1246
|
+
}
|
|
1247
|
+
bytes = next;
|
|
1248
|
+
count++;
|
|
1249
|
+
}
|
|
1250
|
+
return Math.max(1, count);
|
|
1251
|
+
}
|
|
1252
|
+
// True when even the first logical line's own UTF-8 byte length exceeds capBytes,
|
|
1253
|
+
// i.e. no head slice (which always covers at least line 1) can fit within the cap.
|
|
1254
|
+
function firstLineExceedsCap(content, capBytes) {
|
|
1255
|
+
const lines = splitTextLines(content);
|
|
1256
|
+
const first = lines[0];
|
|
1257
|
+
if (first == null) {
|
|
1258
|
+
return false;
|
|
865
1259
|
}
|
|
866
|
-
return
|
|
1260
|
+
return Buffer.byteLength(first, "utf8") > capBytes;
|
|
1261
|
+
}
|
|
1262
|
+
function focusOverCapNotice(candidate, capBytes) {
|
|
1263
|
+
return {
|
|
1264
|
+
root_index: candidate.root_index,
|
|
1265
|
+
reason: CONTEXT_BUILDER_FOCUS_OVER_CAP_REASON,
|
|
1266
|
+
message: "focused file's first line alone exceeded the bounded focus-slice cap " +
|
|
1267
|
+
`(${capBytes} bytes); omitted rather than exceeding the byte bound`,
|
|
1268
|
+
paths: [candidate.path],
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
function focusSlicedNotice(candidate, headEndLine) {
|
|
1272
|
+
return {
|
|
1273
|
+
root_index: candidate.root_index,
|
|
1274
|
+
reason: CONTEXT_BUILDER_FOCUS_SLICED_REASON,
|
|
1275
|
+
message: "focused file exceeded bounded full-file focus size and had no per-file " +
|
|
1276
|
+
`search evidence; included a bounded head slice (lines 1-${headEndLine}) ` +
|
|
1277
|
+
"instead of dropping it",
|
|
1278
|
+
paths: [candidate.path],
|
|
1279
|
+
};
|
|
867
1280
|
}
|
|
868
1281
|
function focusedSearchRangesCovered(expected, survived) {
|
|
869
1282
|
return expected.every((range) => rangeCoveredByRanges(range, survived));
|
|
@@ -889,6 +1302,14 @@ async function traverseDirectory(input) {
|
|
|
889
1302
|
if (input.state.stopped) {
|
|
890
1303
|
return;
|
|
891
1304
|
}
|
|
1305
|
+
const directoryKey = candidateKey({
|
|
1306
|
+
root_index: input.root.root_index,
|
|
1307
|
+
path: input.relativeDir,
|
|
1308
|
+
});
|
|
1309
|
+
if (input.state.traversedDirectoryKeys.has(directoryKey)) {
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
input.state.traversedDirectoryKeys.add(directoryKey);
|
|
892
1313
|
if (input.relativeDir !== "" &&
|
|
893
1314
|
(input.matcher.excludes(input.relativeDir) ||
|
|
894
1315
|
input.matcher.excludes(`${input.relativeDir}/__dir__`))) {
|
|
@@ -1025,6 +1446,35 @@ function pushDirectoryOmission(input, omission) {
|
|
|
1025
1446
|
});
|
|
1026
1447
|
}
|
|
1027
1448
|
async function processFile(input) {
|
|
1449
|
+
await processFileEntry(input);
|
|
1450
|
+
await settleDiscoveryFileBoundary(input.state, input.signal);
|
|
1451
|
+
}
|
|
1452
|
+
async function settleDiscoveryFileBoundary(state, signal) {
|
|
1453
|
+
state.filesSinceProgress++;
|
|
1454
|
+
if (state.onProgress != null &&
|
|
1455
|
+
state.filesSinceProgress >= CONTEXT_BUILDER_SCAN_PROGRESS_EVERY_FILES) {
|
|
1456
|
+
state.filesSinceProgress = 0;
|
|
1457
|
+
try {
|
|
1458
|
+
state.onProgress(Object.freeze({ ...state.metrics }));
|
|
1459
|
+
}
|
|
1460
|
+
catch {
|
|
1461
|
+
// Progress is observability only; a failing sink must never stop the walk.
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
assertNotAborted(signal);
|
|
1465
|
+
state.filesSinceYield++;
|
|
1466
|
+
if (state.filesSinceYield >= DISCOVERY_YIELD_EVERY_FILES) {
|
|
1467
|
+
await yieldDiscoveryToEventLoop(state, signal);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
async function yieldDiscoveryToEventLoop(state, signal) {
|
|
1471
|
+
state.filesSinceYield = 0;
|
|
1472
|
+
await new Promise((resolve) => {
|
|
1473
|
+
setImmediate(resolve);
|
|
1474
|
+
});
|
|
1475
|
+
assertNotAborted(signal);
|
|
1476
|
+
}
|
|
1477
|
+
async function processFileEntry(input) {
|
|
1028
1478
|
const fileKey = candidateKey({
|
|
1029
1479
|
root_index: input.root.root_index,
|
|
1030
1480
|
path: input.relativePath,
|
|
@@ -1038,7 +1488,7 @@ async function processFile(input) {
|
|
|
1038
1488
|
if (!alreadyProcessed) {
|
|
1039
1489
|
input.state.processedFileKeys.add(fileKey);
|
|
1040
1490
|
}
|
|
1041
|
-
const omitted = (reason, message) => {
|
|
1491
|
+
const omitted = (reason, message, secretFindings) => {
|
|
1042
1492
|
input.state.omissions.push({
|
|
1043
1493
|
root_index: input.root.root_index,
|
|
1044
1494
|
reason,
|
|
@@ -1051,7 +1501,7 @@ async function processFile(input) {
|
|
|
1051
1501
|
focusPaths: input.focusPaths,
|
|
1052
1502
|
state: input.state,
|
|
1053
1503
|
kind: requestedOmissionKindForDiscoveryReason(reason),
|
|
1054
|
-
message: sanitizedFocusedOmissionMessage(reason),
|
|
1504
|
+
message: sanitizedFocusedOmissionMessage(reason, secretFindings),
|
|
1055
1505
|
});
|
|
1056
1506
|
};
|
|
1057
1507
|
const requestedOmitted = (kind, message) => {
|
|
@@ -1103,8 +1553,13 @@ async function processFile(input) {
|
|
|
1103
1553
|
});
|
|
1104
1554
|
return;
|
|
1105
1555
|
}
|
|
1556
|
+
// files_seen stays accurate for observability, but focus-processed files are
|
|
1557
|
+
// subtracted from the cap check so explicit focus never consumes the
|
|
1558
|
+
// max_scan_files headroom reserved for global traversal.
|
|
1106
1559
|
if (input.ignoreScanCap !== true &&
|
|
1107
|
-
input.
|
|
1560
|
+
input.focusScanExempt !== true &&
|
|
1561
|
+
input.state.metrics.files_seen - input.state.focusScanExemptFiles >=
|
|
1562
|
+
input.budget.max_scan_files) {
|
|
1108
1563
|
input.state.metrics.scan_cap_hit = true;
|
|
1109
1564
|
pushRequestedFocusOmission({
|
|
1110
1565
|
root_index: input.root.root_index,
|
|
@@ -1118,9 +1573,12 @@ async function processFile(input) {
|
|
|
1118
1573
|
return;
|
|
1119
1574
|
}
|
|
1120
1575
|
input.state.metrics.files_seen++;
|
|
1121
|
-
|
|
1576
|
+
if (input.focusScanExempt === true) {
|
|
1577
|
+
input.state.focusScanExemptFiles++;
|
|
1578
|
+
}
|
|
1579
|
+
const pathSecrets = input.allowSecrets ? [] : scanSecretPath(input.relativePath);
|
|
1122
1580
|
if (pathSecrets.length > 0) {
|
|
1123
|
-
omitted("secret_path", `Secret-looking path omitted (${pathSecrets[0]?.provenance})
|
|
1581
|
+
omitted("secret_path", `Secret-looking path omitted (${pathSecrets[0]?.provenance})`, pathSecrets);
|
|
1124
1582
|
pushTree({
|
|
1125
1583
|
eligible: false,
|
|
1126
1584
|
content_eligible: false,
|
|
@@ -1235,10 +1693,15 @@ async function processFile(input) {
|
|
|
1235
1693
|
}
|
|
1236
1694
|
const rawContent = contentBuffer.toString("utf8");
|
|
1237
1695
|
input.state.metrics.bytes_read += contentBuffer.byteLength;
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1696
|
+
const sanitized = input.allowSecrets
|
|
1697
|
+
? { status: "unchanged", content: rawContent, findings: [] }
|
|
1698
|
+
: sanitizeHighConfidenceSecretContent(rawContent);
|
|
1699
|
+
if (!input.allowSecrets) {
|
|
1700
|
+
assertNotAborted(input.signal);
|
|
1701
|
+
await yieldDiscoveryToEventLoop(input.state, input.signal);
|
|
1702
|
+
}
|
|
1703
|
+
if (sanitized.status === "blocked") {
|
|
1704
|
+
omitted("content_secret", `Content omitted due to high-confidence secret (${summarizeSecretFindings(sanitized.findings)})`, sanitized.findings);
|
|
1242
1705
|
pushTree({
|
|
1243
1706
|
size_bytes: read.sizeBytes,
|
|
1244
1707
|
eligible: true,
|
|
@@ -1247,9 +1710,7 @@ async function processFile(input) {
|
|
|
1247
1710
|
});
|
|
1248
1711
|
return;
|
|
1249
1712
|
}
|
|
1250
|
-
const content =
|
|
1251
|
-
? redactHighConfidenceAssignmentSecrets(rawContent)
|
|
1252
|
-
: rawContent;
|
|
1713
|
+
const content = sanitized.content;
|
|
1253
1714
|
const contentBytes = Buffer.byteLength(content, "utf8");
|
|
1254
1715
|
if (input.state.contentCandidates.length >= input.internalCaps.max_discovery_candidates) {
|
|
1255
1716
|
input.state.metrics.discovery_candidate_cap_hit = true;
|
|
@@ -1403,74 +1864,6 @@ function compareTreeFiles(left, right) {
|
|
|
1403
1864
|
function compareContentCandidates(left, right) {
|
|
1404
1865
|
return left.root_index - right.root_index || left.path.localeCompare(right.path);
|
|
1405
1866
|
}
|
|
1406
|
-
function discoveryTaskClosureRank(path, task) {
|
|
1407
|
-
const normalizedTask = task.toLowerCase();
|
|
1408
|
-
if (normalizedTask.length === 0) {
|
|
1409
|
-
return 0;
|
|
1410
|
-
}
|
|
1411
|
-
const taskTokens = new Set(tokenizeGenericSearchTerm(normalizedTask));
|
|
1412
|
-
const normalizedPath = path.toLowerCase();
|
|
1413
|
-
if (/\b(discover|discovery)\b.*\b(provider-specific|provider\s+semantics|providers?|claude|agent|symmetry)\b|\b(provider-specific|provider\s+semantics|providers?|claude|agent|symmetry)\b.*\b(discover|discovery)\b/.test(normalizedTask) &&
|
|
1414
|
-
hasAnyToken(taskTokens, ["provider", "runtime", "claude", "agent", "symmetry"]) &&
|
|
1415
|
-
[/\/claude_agent\.py$/, /\/runtime\/base\.py$/].some((pattern) => pattern.test(normalizedPath))) {
|
|
1416
|
-
return -30;
|
|
1417
|
-
}
|
|
1418
|
-
if (/\b(discover|discovery)\b/.test(normalizedTask) &&
|
|
1419
|
-
hasAnyToken(taskTokens, ["queue", "migration", "runtime", "schema", "setting", "selector"]) &&
|
|
1420
|
-
[
|
|
1421
|
-
/\/tasks\/chat_processor\.py$/,
|
|
1422
|
-
/\/hooks\/usemessageactions\.ts$/,
|
|
1423
|
-
/\/hooks\/usechatstreaming\.ts$/,
|
|
1424
|
-
/\/hooks\/usechatruntimesettings\.ts$/,
|
|
1425
|
-
/\/components\/chat\/chat-window\/chat\.tsx$/,
|
|
1426
|
-
/\/components\/chat\/message-input\/input\.tsx$/,
|
|
1427
|
-
/\/components\/chat\/message-input\/inputsettingspopover\.tsx$/,
|
|
1428
|
-
/\/pages\/chatpage\.tsx$/,
|
|
1429
|
-
/\/landingpage\.tsx$/,
|
|
1430
|
-
/\/models\/db_models\/chat\.py$/,
|
|
1431
|
-
/\/[^/]*(permission|thinking).*selector[^/]*\.(ts|tsx)$/,
|
|
1432
|
-
/\/tests\/test_chat\.py$/,
|
|
1433
|
-
/\/tests?\/.*runtime.*\.(py|ts|tsx)$/,
|
|
1434
|
-
].some((pattern) => pattern.test(normalizedPath))) {
|
|
1435
|
-
return -24;
|
|
1436
|
-
}
|
|
1437
|
-
if (/\breview\b/.test(normalizedTask) &&
|
|
1438
|
-
hasAnyToken(taskTokens, ["codex", "approval", "permission", "session", "runtime"]) &&
|
|
1439
|
-
[
|
|
1440
|
-
/\/api\/endpoints\/permissions\.py$/,
|
|
1441
|
-
/\/services\/runtime\/codex_approval\.py$/,
|
|
1442
|
-
/\/services\/permission_manager\.py$/,
|
|
1443
|
-
/\/services\/chat\.py$/,
|
|
1444
|
-
/\/api\/endpoints\/chat\.py$/,
|
|
1445
|
-
/\/models\/db_models\/ai_model\.py$/,
|
|
1446
|
-
/\/services\/chatservice\.ts$/,
|
|
1447
|
-
/\/types\/chat\.types\.ts$/,
|
|
1448
|
-
/\/core\/config\.py$/,
|
|
1449
|
-
/\/constants\.py$/,
|
|
1450
|
-
/\/hooks\/usepermissionrequest\.ts$/,
|
|
1451
|
-
/\/tests\/test_permissions\.py$/,
|
|
1452
|
-
/(^|\/)docs?\/.*(codex|approval|permission|session|runtime).*\.md$/,
|
|
1453
|
-
].some((pattern) => pattern.test(normalizedPath))) {
|
|
1454
|
-
return -24;
|
|
1455
|
-
}
|
|
1456
|
-
if (/\b(debug|debugging|diagnose|diagnosis|diagnostic)\b/.test(normalizedTask) &&
|
|
1457
|
-
hasAnyToken(taskTokens, ["devtool", "trace", "archive", "message"]) &&
|
|
1458
|
-
[
|
|
1459
|
-
/\/api\/endpoints\/devtools\.py$/,
|
|
1460
|
-
/\/services\/session_trace_archive\.py$/,
|
|
1461
|
-
/\/models\/db_models\/session_trace_archive\.py$/,
|
|
1462
|
-
/\/.*trace.*archive.*\.test\.(ts|tsx|py)$/,
|
|
1463
|
-
/\/tests?\/.*trace.*archive.*\.(py|ts|tsx)$/,
|
|
1464
|
-
/\/messagerenderer\.tsx$/,
|
|
1465
|
-
/\/devtools\.types\.ts$/,
|
|
1466
|
-
].some((pattern) => pattern.test(normalizedPath))) {
|
|
1467
|
-
return -24;
|
|
1468
|
-
}
|
|
1469
|
-
return 0;
|
|
1470
|
-
}
|
|
1471
|
-
function hasAnyToken(tokens, candidates) {
|
|
1472
|
-
return candidates.some((candidate) => tokens.has(candidate));
|
|
1473
|
-
}
|
|
1474
1867
|
function compareSearchRecords(left, right) {
|
|
1475
1868
|
return (left.root_index - right.root_index ||
|
|
1476
1869
|
left.path.localeCompare(right.path) ||
|
|
@@ -1569,14 +1962,14 @@ function requestedEvidenceOmissionKey(rootIndex, relativePath) {
|
|
|
1569
1962
|
function requestedOmissionKindForDiscoveryReason(reason) {
|
|
1570
1963
|
return reason === "file_too_large" ? "too_large" : "unavailable";
|
|
1571
1964
|
}
|
|
1572
|
-
function sanitizedFocusedOmissionMessage(reason) {
|
|
1965
|
+
function sanitizedFocusedOmissionMessage(reason, secretFindings) {
|
|
1573
1966
|
switch (reason) {
|
|
1574
1967
|
case "caller_include_glob":
|
|
1575
1968
|
return "focused path was outside include globs";
|
|
1576
1969
|
case "exclude_glob":
|
|
1577
1970
|
return "focused path was omitted by exclude globs";
|
|
1578
1971
|
case "secret_path":
|
|
1579
|
-
return "focused path was omitted because it matched a secret-path rule";
|
|
1972
|
+
return withSecretFindingProvenance("focused path was omitted because it matched a secret-path rule", secretFindings);
|
|
1580
1973
|
case "symlink_omitted":
|
|
1581
1974
|
return "focused path was omitted because symlinks are not followed";
|
|
1582
1975
|
case "path_escape":
|
|
@@ -1591,13 +1984,32 @@ function sanitizedFocusedOmissionMessage(reason) {
|
|
|
1591
1984
|
case "binary_file":
|
|
1592
1985
|
return "focused binary file cannot be represented as text";
|
|
1593
1986
|
case "content_secret":
|
|
1594
|
-
return "focused file content was omitted because secret-like content was detected";
|
|
1987
|
+
return withSecretFindingProvenance("focused file content was omitted because secret-like content was detected", secretFindings);
|
|
1595
1988
|
case "file_too_large":
|
|
1596
1989
|
return "focused file exceeded max_bytes_per_file";
|
|
1597
1990
|
default:
|
|
1598
1991
|
return "focused path could not be represented as local evidence";
|
|
1599
1992
|
}
|
|
1600
1993
|
}
|
|
1994
|
+
const MAX_SECRET_FINDING_PROVENANCE_DETAILS = 3;
|
|
1995
|
+
// Appends detector provenance labels and line numbers (never matched secret
|
|
1996
|
+
// text or values) to a sanitized focused-omission message, e.g.
|
|
1997
|
+
// "... (aws_access_key_id at line 12)".
|
|
1998
|
+
function withSecretFindingProvenance(base, secretFindings) {
|
|
1999
|
+
const details = [];
|
|
2000
|
+
for (const finding of secretFindings ?? []) {
|
|
2001
|
+
const detail = finding.line == null
|
|
2002
|
+
? finding.provenance
|
|
2003
|
+
: `${finding.provenance} at line ${finding.line}`;
|
|
2004
|
+
if (!details.includes(detail)) {
|
|
2005
|
+
details.push(detail);
|
|
2006
|
+
}
|
|
2007
|
+
if (details.length >= MAX_SECRET_FINDING_PROVENANCE_DETAILS) {
|
|
2008
|
+
break;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
return details.length === 0 ? base : `${base} (${details.join(", ")})`;
|
|
2012
|
+
}
|
|
1601
2013
|
function candidateKey(candidate) {
|
|
1602
2014
|
return `${candidate.root_index}\u0000${candidate.path}`;
|
|
1603
2015
|
}
|