clinkx 0.2.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/LICENSE +10 -0
- package/README.md +113 -18
- 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/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 +2 -1
- package/clinkx-workflows/dist/clink-client.js +17 -4
- package/clinkx-workflows/dist/clink-client.js.map +1 -1
- package/clinkx-workflows/dist/config.d.ts +145 -16
- package/clinkx-workflows/dist/config.js +384 -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 +184 -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-expander.d.ts +1 -1
- package/clinkx-workflows/dist/council-expander.js +2 -1
- package/clinkx-workflows/dist/council-expander.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +165 -0
- package/clinkx-workflows/dist/dashboard/activity-contract.js +105 -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 +86 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js +480 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/api-routes.d.ts +36 -0
- package/clinkx-workflows/dist/dashboard/api-routes.js +1047 -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-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 +222 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js +1178 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/contracts.d.ts +8936 -0
- package/clinkx-workflows/dist/dashboard/contracts.js +1157 -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 +28 -0
- package/clinkx-workflows/dist/dashboard/index.js +16 -0
- package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +101 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js +748 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +303 -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 +581 -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 +28 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +110 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-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 +126 -0
- package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/scanner.d.ts +75 -0
- package/clinkx-workflows/dist/dashboard/scanner.js +1110 -0
- package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/server-factory.d.ts +50 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js +431 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2611 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.js +480 -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 +522 -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 +6 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js +367 -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-DOkMXTfB.js +25 -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-ChJsn0KD.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-validate.d.ts +78 -0
- package/clinkx-workflows/dist/delegate-validate.js +97 -0
- package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
- package/clinkx-workflows/dist/engine.d.ts +141 -0
- package/clinkx-workflows/dist/engine.js +882 -28
- package/clinkx-workflows/dist/engine.js.map +1 -1
- package/clinkx-workflows/dist/errors.d.ts +2 -0
- package/clinkx-workflows/dist/errors.js.map +1 -1
- package/clinkx-workflows/dist/fingerprint.d.ts +1 -1
- package/clinkx-workflows/dist/fingerprint.js +1 -1
- package/clinkx-workflows/dist/index.d.ts +19 -0
- package/clinkx-workflows/dist/index.js +15 -0
- 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/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/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 +76 -21
- package/clinkx-workflows/dist/schema.js +10 -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 +82 -52
- package/clinkx-workflows/dist/server.js.map +1 -1
- package/clinkx-workflows/dist/shutdown.d.ts +18 -20
- package/clinkx-workflows/dist/shutdown.js +43 -61
- package/clinkx-workflows/dist/shutdown.js.map +1 -1
- package/clinkx-workflows/dist/state-schema.d.ts +38 -0
- package/clinkx-workflows/dist/state.d.ts +170 -3
- package/clinkx-workflows/dist/state.js +1275 -28
- package/clinkx-workflows/dist/state.js.map +1 -1
- 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 +14 -2
- package/clinkx-workflows/dist/validators/council.d.ts +318 -85
- 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 +48 -3
- package/clinkx-workflows/dist/workflow-tools.js +1402 -59
- 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-specialist.txt +2 -1
- package/clinkx-workflows/templates/council/code-review-chairman.txt +13 -0
- package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +4 -1
- package/clinkx-workflows/templates/council/code-review-reviewer.txt +19 -3
- package/clinkx-workflows/templates/council/debug-debugger.txt +2 -1
- package/clinkx-workflows/templates/council/discover-analyst.txt +2 -1
- package/clinkx-workflows/templates/council/member.txt +2 -1
- package/clinkx-workflows/templates/council/plan-review-chairman.txt +68 -0
- package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +51 -0
- package/clinkx-workflows/templates/council/plan-review-reviewer.txt +60 -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 +97 -8
- package/clinkx-workflows/workflows/council-code-review.yaml +103 -8
- package/clinkx-workflows/workflows/council-debug.yaml +97 -8
- package/clinkx-workflows/workflows/council-default.yaml +97 -8
- package/clinkx-workflows/workflows/council-discover.yaml +97 -8
- package/clinkx-workflows/workflows/council-plan-review.yaml +250 -0
- package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
- package/conf/adapters/agy.json +49 -0
- package/conf/adapters/claude.json +5 -0
- package/conf/adapters/codex-app-server.json +44 -0
- package/conf/adapters/codex.json +7 -2
- package/conf/adapters/glm.json +5 -0
- package/conf/adapters/grok.json +60 -0
- package/conf/adapters/hapi/agy.json +52 -0
- package/conf/adapters/hapi/claude.json +5 -0
- package/conf/adapters/hapi/codex.json +7 -2
- package/conf/adapters/hapi/glm.json +5 -0
- package/conf/prompts/json-codereviewer.txt +1 -0
- package/conf/prompts/json.txt +1 -0
- package/dist/activity-journal.d.ts +42 -0
- package/dist/activity-journal.js +381 -0
- package/dist/activity-journal.js.map +1 -0
- package/dist/allowed-roots.d.ts +53 -0
- package/dist/allowed-roots.js +216 -0
- package/dist/allowed-roots.js.map +1 -0
- 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 +1270 -0
- package/dist/codex/agent-tools.js.map +1 -0
- package/dist/codex/app-server-client.d.ts +76 -0
- package/dist/codex/app-server-client.js +582 -0
- package/dist/codex/app-server-client.js.map +1 -0
- package/dist/codex/app-server-registry.d.ts +389 -0
- package/dist/codex/app-server-registry.js +1407 -0
- package/dist/codex/app-server-registry.js.map +1 -0
- package/dist/codex/client-types.d.ts +109 -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 +185 -19
- package/dist/config.js +82 -16
- package/dist/config.js.map +1 -1
- package/dist/context-builder/anchors.d.ts +12 -0
- package/dist/context-builder/anchors.js +22 -0
- package/dist/context-builder/anchors.js.map +1 -0
- package/dist/context-builder/bundle.d.ts +109 -0
- package/dist/context-builder/bundle.js +1498 -0
- package/dist/context-builder/bundle.js.map +1 -0
- package/dist/context-builder/codemap.d.ts +22 -0
- package/dist/context-builder/codemap.js +675 -0
- package/dist/context-builder/codemap.js.map +1 -0
- package/dist/context-builder/config.d.ts +61 -0
- package/dist/context-builder/config.js +216 -0
- package/dist/context-builder/config.js.map +1 -0
- 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-packet.d.ts +219 -0
- package/dist/context-builder/delegate-packet.js +1190 -0
- package/dist/context-builder/delegate-packet.js.map +1 -0
- package/dist/context-builder/delegate-reconstruction.d.ts +13 -0
- package/dist/context-builder/delegate-reconstruction.js +220 -0
- package/dist/context-builder/delegate-reconstruction.js.map +1 -0
- package/dist/context-builder/delegate-validation.d.ts +27 -0
- package/dist/context-builder/delegate-validation.js +479 -0
- package/dist/context-builder/delegate-validation.js.map +1 -0
- package/dist/context-builder/delegate.d.ts +26 -0
- package/dist/context-builder/delegate.js +134 -0
- package/dist/context-builder/delegate.js.map +1 -0
- package/dist/context-builder/diagnostics.d.ts +36 -0
- package/dist/context-builder/diagnostics.js +107 -0
- package/dist/context-builder/diagnostics.js.map +1 -0
- package/dist/context-builder/discovery.d.ts +146 -0
- package/dist/context-builder/discovery.js +2129 -0
- package/dist/context-builder/discovery.js.map +1 -0
- package/dist/context-builder/globs.d.ts +14 -0
- package/dist/context-builder/globs.js +175 -0
- package/dist/context-builder/globs.js.map +1 -0
- package/dist/context-builder/handler.d.ts +41 -0
- package/dist/context-builder/handler.js +2590 -0
- package/dist/context-builder/handler.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/path-signals.d.ts +7 -0
- package/dist/context-builder/path-signals.js +70 -0
- package/dist/context-builder/path-signals.js.map +1 -0
- package/dist/context-builder/paths.d.ts +30 -0
- package/dist/context-builder/paths.js +153 -0
- package/dist/context-builder/paths.js.map +1 -0
- package/dist/context-builder/progress.d.ts +17 -0
- package/dist/context-builder/progress.js +93 -0
- package/dist/context-builder/progress.js.map +1 -0
- package/dist/context-builder/receipt.d.ts +91 -0
- package/dist/context-builder/receipt.js +180 -0
- package/dist/context-builder/receipt.js.map +1 -0
- 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 +84 -0
- package/dist/context-builder/review-coverage.js +437 -0
- package/dist/context-builder/review-coverage.js.map +1 -0
- package/dist/context-builder/run-id.d.ts +7 -0
- package/dist/context-builder/run-id.js +31 -0
- package/dist/context-builder/run-id.js.map +1 -0
- package/dist/context-builder/schema.d.ts +669 -0
- package/dist/context-builder/schema.js +399 -0
- package/dist/context-builder/schema.js.map +1 -0
- package/dist/context-builder/secrets.d.ts +41 -0
- package/dist/context-builder/secrets.js +1651 -0
- package/dist/context-builder/secrets.js.map +1 -0
- package/dist/context-builder/selection.d.ts +56 -0
- package/dist/context-builder/selection.js +1111 -0
- package/dist/context-builder/selection.js.map +1 -0
- 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 +66 -0
- package/dist/context-builder/status.js +160 -0
- package/dist/context-builder/status.js.map +1 -0
- package/dist/context-builder/storage.d.ts +118 -0
- package/dist/context-builder/storage.js +1003 -0
- package/dist/context-builder/storage.js.map +1 -0
- package/dist/context-builder/token-estimate.d.ts +19 -0
- package/dist/context-builder/token-estimate.js +90 -0
- package/dist/context-builder/token-estimate.js.map +1 -0
- package/dist/context-builder/versions.d.ts +29 -0
- package/dist/context-builder/versions.js +30 -0
- package/dist/context-builder/versions.js.map +1 -0
- package/dist/context-builder/workflow-runner.d.ts +69 -0
- package/dist/context-builder/workflow-runner.js +1051 -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 +46 -0
- package/dist/dashboard-adapter-catalog.js.map +1 -0
- package/dist/dashboard-cli.d.ts +79 -0
- package/dist/dashboard-cli.js +585 -0
- package/dist/dashboard-cli.js.map +1 -0
- package/dist/dashboard-companion/client.d.ts +36 -0
- package/dist/dashboard-companion/client.js +210 -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 +455 -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 +11 -0
- package/dist/dashboard-gateway/index.js +755 -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 +10 -1
- package/dist/handler.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13 -3
- 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/package-info.d.ts +2 -0
- package/dist/package-info.js +18 -0
- package/dist/package-info.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 +11 -3
- package/dist/parsers/extract.js.map +1 -1
- package/dist/paths.d.ts +8 -0
- package/dist/paths.js +31 -43
- package/dist/paths.js.map +1 -1
- package/dist/pipeline.d.ts +51 -3
- package/dist/pipeline.js +264 -47
- package/dist/pipeline.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 +13 -0
- package/dist/runner.js +184 -15
- package/dist/runner.js.map +1 -1
- package/dist/safety.d.ts +4 -4
- package/dist/safety.js +4 -4
- package/dist/schema.d.ts +7 -7
- package/dist/server.d.ts +2 -0
- package/dist/server.js +396 -24
- package/dist/server.js.map +1 -1
- package/dist/session-log-stream.d.ts +18 -0
- package/dist/session-log-stream.js +319 -0
- package/dist/session-log-stream.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/artifacts.d.ts +0 -9
- package/dist/artifacts.js +0 -24
- package/dist/artifacts.js.map +0 -1
- 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
|
@@ -0,0 +1,1498 @@
|
|
|
1
|
+
import { boundContextBuilderOmissions, boundContextBuilderPathList, boundContextBuilderWarnings, sanitizeDiagnosticText, } from "./diagnostics.js";
|
|
2
|
+
import { createContextBuilderReceipt, cloneContextBuilderDelegateReceiptMetadata, } from "./receipt.js";
|
|
3
|
+
import { assertTaskSecretsGated, hasConservativeResidualSecret, } from "./secrets.js";
|
|
4
|
+
import { capEventsFromContextBuilderMetrics, reduceContextBuilderStatus, } from "./status.js";
|
|
5
|
+
import { writeContextBuilderArtifactsAndCommit, } from "./storage.js";
|
|
6
|
+
import { contextBuilderTokenCountingMethod, estimateContextBuilderTokens, } from "./token-estimate.js";
|
|
7
|
+
import { contextBuilderInternalCapsForManifest, } from "./config.js";
|
|
8
|
+
import { buildFileCodemap, remapCodemapToSourceCoordinates, renderCodemapJsonl, } from "./codemap.js";
|
|
9
|
+
// Folded into the cache key so bundle markdown format changes invalidate stale cache entries.
|
|
10
|
+
export const CONTEXT_BUILDER_RENDERER_VERSION = 2;
|
|
11
|
+
export function renderContextBuilderBundle(input) {
|
|
12
|
+
const allowSecrets = input.allowSecrets ?? true;
|
|
13
|
+
assertTaskSecretsGated(input.task, allowSecrets);
|
|
14
|
+
const selected = input.selected_context.map((file) => sanitizeSelectedFile(file, allowSecrets));
|
|
15
|
+
const tree = input.tree.map((file) => sanitizeTreeFile(file, allowSecrets));
|
|
16
|
+
const search = input.search.map((record) => sanitizeSearchRecord(record, allowSecrets));
|
|
17
|
+
const slices = input.slices.map((record) => sanitizeSliceRecord(record, allowSecrets));
|
|
18
|
+
const presentationSelected = promoteTaskPresentationEvidence(filterTaskPresentationSelected(selected, input.task), input.task, slices);
|
|
19
|
+
const omissions = boundContextBuilderOmissions([...(input.omissions ?? [])], contextBuilderInternalCapsForManifest(input.internal_caps));
|
|
20
|
+
const warnings = boundContextBuilderWarnings([...(input.warnings ?? [])], contextBuilderInternalCapsForManifest(input.internal_caps));
|
|
21
|
+
const presentationOmissions = reconcileSelectedOmissions(filterTaskPresentationOmissions(omissions, input.task), presentationSelected);
|
|
22
|
+
const openQuestions = buildPresentationOpenQuestions(boundOpenQuestions(input.open_questions ?? []), presentationSelected, presentationOmissions);
|
|
23
|
+
const showRootLabels = input.roots.length > 1;
|
|
24
|
+
return [
|
|
25
|
+
"# Context Bundle",
|
|
26
|
+
"",
|
|
27
|
+
"## Original Task",
|
|
28
|
+
"",
|
|
29
|
+
input.task,
|
|
30
|
+
"",
|
|
31
|
+
"## How To Use This Bundle",
|
|
32
|
+
"",
|
|
33
|
+
"- Start with top must-read ranges and verify the cited evidence directly.",
|
|
34
|
+
"- Inspect selected files, repository shape, and search evidence before editing.",
|
|
35
|
+
"- Treat omissions and open questions as follow-up checks, not as resolved facts.",
|
|
36
|
+
"",
|
|
37
|
+
"## Top Must-Read Ranges",
|
|
38
|
+
"",
|
|
39
|
+
renderTopMustReadRanges({
|
|
40
|
+
task: input.task,
|
|
41
|
+
selected: presentationSelected,
|
|
42
|
+
search,
|
|
43
|
+
showRootLabels,
|
|
44
|
+
}),
|
|
45
|
+
"",
|
|
46
|
+
"## Selected Files",
|
|
47
|
+
"",
|
|
48
|
+
renderSelectedFilesList({
|
|
49
|
+
task: input.task,
|
|
50
|
+
selected: presentationSelected,
|
|
51
|
+
search,
|
|
52
|
+
showRootLabels,
|
|
53
|
+
}),
|
|
54
|
+
"",
|
|
55
|
+
"## Repository Shape",
|
|
56
|
+
"",
|
|
57
|
+
renderRepositoryShape({
|
|
58
|
+
tree,
|
|
59
|
+
selected: presentationSelected,
|
|
60
|
+
showRootLabels,
|
|
61
|
+
}),
|
|
62
|
+
"",
|
|
63
|
+
"## Search Evidence",
|
|
64
|
+
"",
|
|
65
|
+
renderSearchEvidence({
|
|
66
|
+
search,
|
|
67
|
+
selected: presentationSelected,
|
|
68
|
+
showRootLabels,
|
|
69
|
+
}),
|
|
70
|
+
"",
|
|
71
|
+
"## File Context",
|
|
72
|
+
"",
|
|
73
|
+
renderFileContext(presentationSelected, search, showRootLabels),
|
|
74
|
+
"",
|
|
75
|
+
"## Open Questions",
|
|
76
|
+
"",
|
|
77
|
+
renderOpenQuestions(openQuestions),
|
|
78
|
+
"",
|
|
79
|
+
"## Omissions And Budget Notes",
|
|
80
|
+
"",
|
|
81
|
+
renderOmissionsAndBudgetNotes({
|
|
82
|
+
omissions: presentationOmissions,
|
|
83
|
+
warnings,
|
|
84
|
+
metrics: input.metrics,
|
|
85
|
+
}),
|
|
86
|
+
"",
|
|
87
|
+
].join("\n");
|
|
88
|
+
}
|
|
89
|
+
export function buildContextBuilderStatus(input) {
|
|
90
|
+
return reduceContextBuilderStatus(buildContextBuilderStatusEvidence(input));
|
|
91
|
+
}
|
|
92
|
+
export function buildContextBuilderStatusEvidence(input, boundedDiagnostics = {}) {
|
|
93
|
+
const omissions = boundedDiagnostics.omissions ?? input.omissions ?? [];
|
|
94
|
+
const warnings = boundedDiagnostics.warnings ?? input.warnings ?? [];
|
|
95
|
+
return {
|
|
96
|
+
...(input.status_evidence ?? {}),
|
|
97
|
+
omissions: [
|
|
98
|
+
...omissions.map(omissionEventFromDiagnostic),
|
|
99
|
+
...(input.status_evidence?.omissions ?? []),
|
|
100
|
+
],
|
|
101
|
+
warnings: [
|
|
102
|
+
...warnings.map(warningEventFromDiagnostic),
|
|
103
|
+
...(input.status_evidence?.warnings ?? []),
|
|
104
|
+
],
|
|
105
|
+
caps: [
|
|
106
|
+
...capEventsFromContextBuilderMetrics(input.metrics, input.search_coverage == null
|
|
107
|
+
? {}
|
|
108
|
+
: { search_coverage: input.search_coverage }),
|
|
109
|
+
...(input.status_evidence?.caps ?? []),
|
|
110
|
+
],
|
|
111
|
+
storage: [
|
|
112
|
+
...(input.metrics.truncated
|
|
113
|
+
? [{ reason: "artifact_truncated" }]
|
|
114
|
+
: []),
|
|
115
|
+
...(input.status_evidence?.storage ?? []),
|
|
116
|
+
],
|
|
117
|
+
delegate: [
|
|
118
|
+
...(input.delegate?.fallback_used === true
|
|
119
|
+
? [{ reason: "delegate_fallback", fallback: true }]
|
|
120
|
+
: []),
|
|
121
|
+
...(input.status_evidence?.delegate ?? []),
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export function renderContextBuilderArtifactContents(input) {
|
|
126
|
+
const allowSecrets = input.allowSecrets ?? true;
|
|
127
|
+
assertTaskSecretsGated(input.task, allowSecrets);
|
|
128
|
+
const tree = input.tree.map((file) => sanitizeTreeFile(file, allowSecrets));
|
|
129
|
+
const search = input.search.map((record) => sanitizeSearchRecord(record, allowSecrets));
|
|
130
|
+
const slices = input.slices.map((record) => sanitizeSliceRecord(record, allowSecrets));
|
|
131
|
+
const selectedContext = input.selected_context.map((file) => sanitizeSelectedFile(file, allowSecrets));
|
|
132
|
+
const summary = buildContextBuilderSummary(input);
|
|
133
|
+
return {
|
|
134
|
+
bundle_md: renderContextBuilderBundle(input),
|
|
135
|
+
selected_context_jsonl: renderSelectedContextJsonl(selectedContext),
|
|
136
|
+
tree_json: `${JSON.stringify({
|
|
137
|
+
schema_version: 1,
|
|
138
|
+
roots: input.roots.map((root) => sanitizeRoot(root, allowSecrets)),
|
|
139
|
+
files: tree,
|
|
140
|
+
})}\n`,
|
|
141
|
+
search_jsonl: renderJsonl(search),
|
|
142
|
+
slices_jsonl: renderJsonl(slices),
|
|
143
|
+
codemap_jsonl: renderCodemapJsonl(selectedContext.map((file) => remapCodemapToSourceCoordinates(buildFileCodemap(file.path, file.content), file.ranges))),
|
|
144
|
+
summary_json: `${JSON.stringify({
|
|
145
|
+
...summary,
|
|
146
|
+
selected_context: selectedContext.map(stripSelectedContent),
|
|
147
|
+
})}\n`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
export function buildContextBuilderManifestDraft(input) {
|
|
151
|
+
const allowSecrets = input.allowSecrets ?? true;
|
|
152
|
+
const internalCaps = contextBuilderInternalCapsForManifest(input.internal_caps);
|
|
153
|
+
const omissions = boundContextBuilderOmissions([...(input.omissions ?? [])], internalCaps);
|
|
154
|
+
const warnings = boundContextBuilderWarnings([...(input.warnings ?? [])], internalCaps);
|
|
155
|
+
const status = reduceContextBuilderStatus(buildContextBuilderStatusEvidence(input));
|
|
156
|
+
return {
|
|
157
|
+
status,
|
|
158
|
+
created_at: input.created_at,
|
|
159
|
+
task: validateTaskForRendering(input.task, allowSecrets),
|
|
160
|
+
// Echo the RESOLVED secret profile (per-call > workflow > env > true) so
|
|
161
|
+
// artifact-only readers do not have to infer it from omission behavior.
|
|
162
|
+
// Additive: manifest validation is required-key based and every known
|
|
163
|
+
// reader picks named keys.
|
|
164
|
+
allow_secrets_resolved: allowSecrets,
|
|
165
|
+
roots: input.roots.map((root) => sanitizeRoot(root, allowSecrets)),
|
|
166
|
+
inputs: sanitizeJsonValue(input.inputs, allowSecrets),
|
|
167
|
+
budget: { ...input.budget },
|
|
168
|
+
internal_caps: internalCaps,
|
|
169
|
+
token_counting: contextBuilderTokenCountingMethod(),
|
|
170
|
+
selected_context: input.selected_context
|
|
171
|
+
.map((file) => sanitizeSelectedFile(file, allowSecrets))
|
|
172
|
+
.map(stripSelectedContent),
|
|
173
|
+
omissions,
|
|
174
|
+
warnings,
|
|
175
|
+
metrics: { ...input.metrics },
|
|
176
|
+
...(input.search_coverage == null
|
|
177
|
+
? {}
|
|
178
|
+
: {
|
|
179
|
+
search_coverage: sanitizeSearchCoverage(input.search_coverage, allowSecrets),
|
|
180
|
+
}),
|
|
181
|
+
...(input.coverage == null ? {} : { coverage: input.coverage }),
|
|
182
|
+
...(input.parent_run_id == null
|
|
183
|
+
? {}
|
|
184
|
+
: { parent_run_id: input.parent_run_id }),
|
|
185
|
+
...(input.refine_ops == null
|
|
186
|
+
? {}
|
|
187
|
+
: { refine_ops: input.refine_ops.map((op) => ({ ...op })) }),
|
|
188
|
+
...(input.file_fingerprints == null
|
|
189
|
+
? {}
|
|
190
|
+
: {
|
|
191
|
+
file_fingerprints: input.file_fingerprints.map((fingerprint) => ({
|
|
192
|
+
...fingerprint,
|
|
193
|
+
})),
|
|
194
|
+
}),
|
|
195
|
+
...(input.delegate == null
|
|
196
|
+
? {}
|
|
197
|
+
: { delegate: cloneContextBuilderDelegateReceiptMetadata(input.delegate) }),
|
|
198
|
+
...(input.observability == null
|
|
199
|
+
? {}
|
|
200
|
+
: { observability: { ...input.observability } }),
|
|
201
|
+
...(input.debug === true
|
|
202
|
+
? {
|
|
203
|
+
debug_diagnostics: boundDebugDiagnostics(input.debug_diagnostics, internalCaps),
|
|
204
|
+
}
|
|
205
|
+
: {}),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
export async function writeContextBuilderFinalArtifacts(storage, input, options = {}) {
|
|
209
|
+
const { contents, metrics } = renderContentsWithStableByteMetric(input);
|
|
210
|
+
const writeInput = { ...input, metrics };
|
|
211
|
+
await writeContextBuilderArtifactsAndCommit(storage, contents, buildContextBuilderManifestDraft(writeInput), {
|
|
212
|
+
...(options.signal == null ? {} : { signal: options.signal }),
|
|
213
|
+
...(options.ownerNonce == null ? {} : { ownerNonce: options.ownerNonce }),
|
|
214
|
+
...(options.ops == null ? {} : { ops: options.ops }),
|
|
215
|
+
...(options.beforeManifestCommit == null
|
|
216
|
+
? {}
|
|
217
|
+
: { beforeManifestCommit: options.beforeManifestCommit }),
|
|
218
|
+
});
|
|
219
|
+
const internalCaps = contextBuilderInternalCapsForManifest(input.internal_caps);
|
|
220
|
+
const warnings = boundContextBuilderWarnings(input.warnings == null ? [] : [...input.warnings], internalCaps);
|
|
221
|
+
const omissions = boundContextBuilderOmissions(input.omissions == null ? [] : [...input.omissions], internalCaps);
|
|
222
|
+
return createContextBuilderReceipt({
|
|
223
|
+
run_id: storage.runId,
|
|
224
|
+
status: reduceContextBuilderStatus(buildContextBuilderStatusEvidence({ ...input, metrics })),
|
|
225
|
+
artifact_dir: storage.artifactDir,
|
|
226
|
+
artifacts: storage.artifacts,
|
|
227
|
+
metrics,
|
|
228
|
+
warnings,
|
|
229
|
+
omissions,
|
|
230
|
+
...(input.delegate == null
|
|
231
|
+
? {}
|
|
232
|
+
: { delegate: cloneContextBuilderDelegateReceiptMetadata(input.delegate) }),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function renderContentsWithStableByteMetric(input) {
|
|
236
|
+
let metrics = { ...input.metrics, bytes_written: 0 };
|
|
237
|
+
let contents = renderContextBuilderArtifactContents({ ...input, metrics });
|
|
238
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
239
|
+
const bytesWritten = Object.values(contents).reduce((total, content) => total + Buffer.byteLength(content, "utf8"), 0);
|
|
240
|
+
const nextMetrics = { ...metrics, bytes_written: bytesWritten };
|
|
241
|
+
const nextContents = renderContextBuilderArtifactContents({
|
|
242
|
+
...input,
|
|
243
|
+
metrics: nextMetrics,
|
|
244
|
+
});
|
|
245
|
+
if (bytesWritten === metrics.bytes_written &&
|
|
246
|
+
JSON.stringify(nextContents) === JSON.stringify(contents)) {
|
|
247
|
+
return { contents, metrics };
|
|
248
|
+
}
|
|
249
|
+
metrics = nextMetrics;
|
|
250
|
+
contents = nextContents;
|
|
251
|
+
}
|
|
252
|
+
return { contents, metrics };
|
|
253
|
+
}
|
|
254
|
+
function buildContextBuilderSummary(input) {
|
|
255
|
+
const allowSecrets = input.allowSecrets ?? true;
|
|
256
|
+
const selected = input.selected_context.map((file) => sanitizeSelectedFile(file, allowSecrets));
|
|
257
|
+
const omissions = reconcileSelectedOmissions(filterTaskPresentationOmissions(boundContextBuilderOmissions([...(input.omissions ?? [])], contextBuilderInternalCapsForManifest(input.internal_caps)), input.task), selected);
|
|
258
|
+
const openQuestions = buildPresentationOpenQuestions(boundOpenQuestions(input.open_questions ?? []), selected, omissions);
|
|
259
|
+
return {
|
|
260
|
+
schema_version: 1,
|
|
261
|
+
run_id: input.run_id,
|
|
262
|
+
created_at: input.created_at,
|
|
263
|
+
status: reduceContextBuilderStatus(buildContextBuilderStatusEvidence(input)),
|
|
264
|
+
// Mirror of the manifest's resolved secret-profile echo, so summary-only
|
|
265
|
+
// readers get the same explicit benchmark/run profile.
|
|
266
|
+
allow_secrets_resolved: allowSecrets,
|
|
267
|
+
token_counting: contextBuilderTokenCountingMethod(),
|
|
268
|
+
metrics: { ...input.metrics },
|
|
269
|
+
selected_file_count: input.selected_context.length,
|
|
270
|
+
warning_count: input.warnings?.length ?? 0,
|
|
271
|
+
omission_count: omissions.length,
|
|
272
|
+
open_questions: openQuestions,
|
|
273
|
+
...(input.search_coverage == null
|
|
274
|
+
? {}
|
|
275
|
+
: {
|
|
276
|
+
search_coverage: sanitizeSearchCoverage(input.search_coverage, allowSecrets),
|
|
277
|
+
}),
|
|
278
|
+
...(input.delegate == null
|
|
279
|
+
? {}
|
|
280
|
+
: { delegate: cloneContextBuilderDelegateReceiptMetadata(input.delegate) }),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function sanitizeRoot(root, allowSecrets) {
|
|
284
|
+
return {
|
|
285
|
+
root_index: root.root_index,
|
|
286
|
+
...(root.input_path == null
|
|
287
|
+
? {}
|
|
288
|
+
: { input_path: safePath(root.input_path, allowSecrets) }),
|
|
289
|
+
path: safePath(root.path, allowSecrets),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function sanitizeTreeFile(file, allowSecrets) {
|
|
293
|
+
return {
|
|
294
|
+
root_index: file.root_index,
|
|
295
|
+
path: safePath(file.path, allowSecrets),
|
|
296
|
+
size_bytes: file.size_bytes,
|
|
297
|
+
eligible: file.eligible,
|
|
298
|
+
content_eligible: file.content_eligible,
|
|
299
|
+
...(file.omission_reason == null
|
|
300
|
+
? {}
|
|
301
|
+
: { omission_reason: sanitizeDiagnosticText(file.omission_reason) }),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function sanitizeSearchRecord(record, allowSecrets) {
|
|
305
|
+
return {
|
|
306
|
+
root_index: record.root_index,
|
|
307
|
+
path: safePath(record.path, allowSecrets),
|
|
308
|
+
line: record.line,
|
|
309
|
+
column: record.column,
|
|
310
|
+
search_term: sanitizeDiagnosticText(record.search_term, allowSecrets),
|
|
311
|
+
search_term_index: record.search_term_index,
|
|
312
|
+
preview: safeContent(record.preview, allowSecrets),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// Defensive bound matching the public caller search-term cap; T1's coverage
|
|
316
|
+
// rows are already bounded by it, so this only guards a malformed producer.
|
|
317
|
+
const MAX_SEARCH_COVERAGE_CALLER_TERM_ROWS = 20;
|
|
318
|
+
function sanitizeSearchCoverage(coverage, allowSecrets) {
|
|
319
|
+
return {
|
|
320
|
+
eligible_candidate_count: coverage.eligible_candidate_count,
|
|
321
|
+
searched_candidate_count: coverage.searched_candidate_count,
|
|
322
|
+
unsearched_candidate_count: coverage.unsearched_candidate_count,
|
|
323
|
+
caller_term_count: coverage.caller_term_count,
|
|
324
|
+
derived_term_count: coverage.derived_term_count,
|
|
325
|
+
caller_record_count: coverage.caller_record_count,
|
|
326
|
+
derived_record_count: coverage.derived_record_count,
|
|
327
|
+
caller_coverage_complete: coverage.caller_coverage_complete,
|
|
328
|
+
caller_terms: coverage.caller_terms
|
|
329
|
+
.slice(0, MAX_SEARCH_COVERAGE_CALLER_TERM_ROWS)
|
|
330
|
+
.map((term) => ({
|
|
331
|
+
term: sanitizeDiagnosticText(term.term, allowSecrets),
|
|
332
|
+
search_term_index: term.search_term_index,
|
|
333
|
+
hit_count: term.hit_count,
|
|
334
|
+
scan_complete: term.scan_complete,
|
|
335
|
+
})),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function sanitizeSliceRecord(record, allowSecrets) {
|
|
339
|
+
return {
|
|
340
|
+
root_index: record.root_index,
|
|
341
|
+
path: safePath(record.path, allowSecrets),
|
|
342
|
+
start_line: record.start_line,
|
|
343
|
+
end_line: record.end_line,
|
|
344
|
+
source: record.source,
|
|
345
|
+
content: safeContent(record.content, allowSecrets),
|
|
346
|
+
...(record.search_term_index == null
|
|
347
|
+
? {}
|
|
348
|
+
: { search_term_index: record.search_term_index }),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function sanitizeSelectedFile(file, allowSecrets) {
|
|
352
|
+
return {
|
|
353
|
+
root_index: file.root_index,
|
|
354
|
+
path: safePath(file.path, allowSecrets),
|
|
355
|
+
ranges: file.ranges.map(sanitizeRange),
|
|
356
|
+
content: safeContent(file.content, allowSecrets),
|
|
357
|
+
bytes: file.bytes,
|
|
358
|
+
estimated_tokens: file.estimated_tokens > 0
|
|
359
|
+
? file.estimated_tokens
|
|
360
|
+
: estimateContextBuilderTokens(file.content),
|
|
361
|
+
source: file.source,
|
|
362
|
+
...(file.disposition == null ? {} : { disposition: file.disposition }),
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
function sanitizeRange(range) {
|
|
366
|
+
return {
|
|
367
|
+
start_line: range.start_line,
|
|
368
|
+
end_line: range.end_line,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function stripSelectedContent(file) {
|
|
372
|
+
return {
|
|
373
|
+
root_index: file.root_index,
|
|
374
|
+
path: file.path,
|
|
375
|
+
ranges: file.ranges.map(sanitizeRange),
|
|
376
|
+
bytes: file.bytes,
|
|
377
|
+
estimated_tokens: file.estimated_tokens,
|
|
378
|
+
source: file.source,
|
|
379
|
+
...(file.disposition == null ? {} : { disposition: file.disposition }),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function renderSelectedFilesList(input) {
|
|
383
|
+
const { task, selected, search, showRootLabels } = input;
|
|
384
|
+
if (selected.length === 0) {
|
|
385
|
+
return "- None selected.";
|
|
386
|
+
}
|
|
387
|
+
const visible = selected.slice(0, 18);
|
|
388
|
+
const hiddenCount = selected.length - visible.length;
|
|
389
|
+
const rendered = visible
|
|
390
|
+
.map((file) => {
|
|
391
|
+
return [
|
|
392
|
+
`- ${renderRootPrefix(file.root_index, showRootLabels)}${file.path} (${file.source})`,
|
|
393
|
+
` purpose: ${selectedFilePurpose(task, file, search)}`,
|
|
394
|
+
].join("\n");
|
|
395
|
+
})
|
|
396
|
+
.join("\n");
|
|
397
|
+
return hiddenCount > 0
|
|
398
|
+
? `${rendered}\n- ${hiddenCount} more selected files are listed in manifest.json and selected-context.jsonl.`
|
|
399
|
+
: rendered;
|
|
400
|
+
}
|
|
401
|
+
function selectedFilePurpose(_task, file, search) {
|
|
402
|
+
const source = file.source === "focus" ? "requested focus evidence" : "matched task anchors";
|
|
403
|
+
const clauses = [
|
|
404
|
+
source,
|
|
405
|
+
pathPurpose(file.path),
|
|
406
|
+
rangePurpose(file.ranges),
|
|
407
|
+
];
|
|
408
|
+
const symbols = selectedFileSymbols(file);
|
|
409
|
+
if (symbols.length > 0) {
|
|
410
|
+
clauses.push(`symbols: ${symbols.join(", ")}`);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
const terms = selectedFileSearchTerms(file, search);
|
|
414
|
+
if (terms.length > 0) {
|
|
415
|
+
clauses.push(`search-backed slice`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return `${clauses.join("; ")}.`;
|
|
419
|
+
}
|
|
420
|
+
function selectedFileRangeNotes(task, file, search) {
|
|
421
|
+
const sourceLines = splitSelectedFileContentByRange(file);
|
|
422
|
+
const searchTerms = selectedFileSearchTerms(file, search);
|
|
423
|
+
return file.ranges.slice(0, 4).map((range, index) => {
|
|
424
|
+
const symbols = symbolsFromLines(sourceLines[index] ?? []);
|
|
425
|
+
const rangeHits = search.filter((record) => record.root_index === file.root_index &&
|
|
426
|
+
record.path === file.path &&
|
|
427
|
+
record.line >= range.start_line &&
|
|
428
|
+
record.line <= range.end_line);
|
|
429
|
+
const label = range.start_line === range.end_line
|
|
430
|
+
? `${range.start_line}`
|
|
431
|
+
: `${range.start_line}-${range.end_line}`;
|
|
432
|
+
return `${label}: ${rangeEvidenceSummary({
|
|
433
|
+
task,
|
|
434
|
+
path: file.path,
|
|
435
|
+
source: file.source,
|
|
436
|
+
symbols,
|
|
437
|
+
searchTerms,
|
|
438
|
+
rangeHits,
|
|
439
|
+
})}`;
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
function rangeEvidenceSummary(input) {
|
|
443
|
+
const hitSummary = rangeHitSummary(input.rangeHits ?? []);
|
|
444
|
+
if (hitSummary != null) {
|
|
445
|
+
return hitSummary;
|
|
446
|
+
}
|
|
447
|
+
if (input.searchTerms.length > 0) {
|
|
448
|
+
return `${pathPurpose(input.path)} selected by matching task evidence`;
|
|
449
|
+
}
|
|
450
|
+
if (input.symbols.length > 0) {
|
|
451
|
+
return `${input.source} evidence around ${input.symbols.slice(0, 4).join(", ")}`;
|
|
452
|
+
}
|
|
453
|
+
return "bounded supporting evidence for the task";
|
|
454
|
+
}
|
|
455
|
+
function rangeHitSummary(hits) {
|
|
456
|
+
if (hits.length === 0) {
|
|
457
|
+
return undefined;
|
|
458
|
+
}
|
|
459
|
+
const byTerm = new Map();
|
|
460
|
+
for (const hit of hits) {
|
|
461
|
+
const term = hit.search_term.trim();
|
|
462
|
+
if (term.length === 0) {
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const lines = byTerm.get(term) ?? [];
|
|
466
|
+
if (!lines.includes(hit.line)) {
|
|
467
|
+
lines.push(hit.line);
|
|
468
|
+
}
|
|
469
|
+
byTerm.set(term, lines);
|
|
470
|
+
if (byTerm.size >= 3) {
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const rendered = [...byTerm.entries()]
|
|
475
|
+
.slice(0, 3)
|
|
476
|
+
.map(([term, lines]) => `"${term}" at ${lines.slice(0, 3).join(",")}`);
|
|
477
|
+
return rendered.length === 0 ? undefined : `matches ${rendered.join("; ")}`;
|
|
478
|
+
}
|
|
479
|
+
function selectedFileSymbols(file) {
|
|
480
|
+
return symbolsFromLines(splitTextLinesForBundle(file.content)).slice(0, 6);
|
|
481
|
+
}
|
|
482
|
+
function splitSelectedFileContentByRange(file) {
|
|
483
|
+
const lines = splitTextLinesForBundle(file.content);
|
|
484
|
+
if (file.ranges.length <= 1) {
|
|
485
|
+
return [lines];
|
|
486
|
+
}
|
|
487
|
+
const totalRangeLines = file.ranges.reduce((total, range) => total + Math.max(0, range.end_line - range.start_line + 1), 0);
|
|
488
|
+
if (totalRangeLines !== lines.length) {
|
|
489
|
+
return file.ranges.map(() => []);
|
|
490
|
+
}
|
|
491
|
+
const output = [];
|
|
492
|
+
let offset = 0;
|
|
493
|
+
for (const range of file.ranges) {
|
|
494
|
+
const count = Math.max(0, range.end_line - range.start_line + 1);
|
|
495
|
+
output.push(lines.slice(offset, offset + count));
|
|
496
|
+
offset += count;
|
|
497
|
+
}
|
|
498
|
+
return output;
|
|
499
|
+
}
|
|
500
|
+
function renderSelectedContextJsonl(selected) {
|
|
501
|
+
return renderJsonl(selected.flatMap((file) => {
|
|
502
|
+
const rangeBodies = splitSelectedFileContentByRange(file);
|
|
503
|
+
return file.ranges.map((range, index) => ({
|
|
504
|
+
root_index: file.root_index,
|
|
505
|
+
path: file.path,
|
|
506
|
+
start_line: range.start_line,
|
|
507
|
+
end_line: range.end_line,
|
|
508
|
+
source: file.source,
|
|
509
|
+
...(file.disposition == null ? {} : { disposition: file.disposition }),
|
|
510
|
+
content: isCodemapOnlyDisposition(file.disposition)
|
|
511
|
+
? ""
|
|
512
|
+
: (rangeBodies[index] ?? []).join("\n"),
|
|
513
|
+
}));
|
|
514
|
+
}));
|
|
515
|
+
}
|
|
516
|
+
function splitTextLinesForBundle(text) {
|
|
517
|
+
if (text.length === 0) {
|
|
518
|
+
return [];
|
|
519
|
+
}
|
|
520
|
+
const withoutFinalNewline = text.endsWith("\n")
|
|
521
|
+
? text.slice(0, text.endsWith("\r\n") ? -2 : -1)
|
|
522
|
+
: text;
|
|
523
|
+
return withoutFinalNewline.length === 0
|
|
524
|
+
? [""]
|
|
525
|
+
: withoutFinalNewline.split(/\r\n|\n/);
|
|
526
|
+
}
|
|
527
|
+
function symbolsFromLines(lines) {
|
|
528
|
+
const symbols = [];
|
|
529
|
+
const seen = new Set();
|
|
530
|
+
for (const line of lines) {
|
|
531
|
+
for (const symbol of symbolsFromLine(line)) {
|
|
532
|
+
if (seen.has(symbol)) {
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
seen.add(symbol);
|
|
536
|
+
symbols.push(symbol);
|
|
537
|
+
if (symbols.length >= 8) {
|
|
538
|
+
return symbols;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return symbols;
|
|
543
|
+
}
|
|
544
|
+
function symbolsFromLine(line) {
|
|
545
|
+
const patterns = [
|
|
546
|
+
/\b(?:async\s+)?(?:def|function|class)\s+([A-Za-z_][A-Za-z0-9_]*)/g,
|
|
547
|
+
/\b(?:const|let|var)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=/g,
|
|
548
|
+
/\bexport\s+(?:async\s+)?(?:function|class|const)\s+([A-Za-z_][A-Za-z0-9_]*)/g,
|
|
549
|
+
/\bit\(\s*['"]([^'"]{8,90})['"]/g,
|
|
550
|
+
/\bdescribe\(\s*['"]([^'"]{8,90})['"]/g,
|
|
551
|
+
];
|
|
552
|
+
const symbols = [];
|
|
553
|
+
for (const pattern of patterns) {
|
|
554
|
+
for (const match of line.matchAll(pattern)) {
|
|
555
|
+
const value = match[1]?.trim();
|
|
556
|
+
if (value != null && value.length > 0) {
|
|
557
|
+
symbols.push(value);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return symbols;
|
|
562
|
+
}
|
|
563
|
+
function selectedFileSearchTerms(file, search) {
|
|
564
|
+
const terms = [];
|
|
565
|
+
const seen = new Set();
|
|
566
|
+
for (const record of search) {
|
|
567
|
+
if (record.root_index !== file.root_index || record.path !== file.path) {
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
const term = record.search_term.trim();
|
|
571
|
+
if (term.length === 0 || seen.has(term)) {
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
seen.add(term);
|
|
575
|
+
terms.push(term);
|
|
576
|
+
if (terms.length >= 4) {
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return terms;
|
|
581
|
+
}
|
|
582
|
+
function pathPurpose(path) {
|
|
583
|
+
const normalized = path.toLowerCase();
|
|
584
|
+
const basename = normalized.split("/").at(-1) ?? normalized;
|
|
585
|
+
const language = languagePurpose(basename);
|
|
586
|
+
if (isTestPath(normalized, basename)) {
|
|
587
|
+
return `${language} test coverage`;
|
|
588
|
+
}
|
|
589
|
+
if (normalized.startsWith("docs/") || normalized.includes("/docs/")) {
|
|
590
|
+
return `${language} documentation`;
|
|
591
|
+
}
|
|
592
|
+
if (isClosurePath(normalized)) {
|
|
593
|
+
return `${language} contract or configuration`;
|
|
594
|
+
}
|
|
595
|
+
if (normalized.startsWith("frontend/") || normalized.includes("/frontend/")) {
|
|
596
|
+
return `${language} frontend implementation`;
|
|
597
|
+
}
|
|
598
|
+
if (normalized.startsWith("backend/") || normalized.includes("/backend/")) {
|
|
599
|
+
return `${language} backend implementation`;
|
|
600
|
+
}
|
|
601
|
+
if (normalized.startsWith("src/") || normalized.includes("/src/")) {
|
|
602
|
+
return `${language} source implementation`;
|
|
603
|
+
}
|
|
604
|
+
return `${language} selected context`;
|
|
605
|
+
}
|
|
606
|
+
function languagePurpose(basename) {
|
|
607
|
+
if (basename.endsWith(".tsx")) {
|
|
608
|
+
return "TSX";
|
|
609
|
+
}
|
|
610
|
+
if (basename.endsWith(".ts")) {
|
|
611
|
+
return "TypeScript";
|
|
612
|
+
}
|
|
613
|
+
if (basename.endsWith(".jsx")) {
|
|
614
|
+
return "JSX";
|
|
615
|
+
}
|
|
616
|
+
if (basename.endsWith(".js")) {
|
|
617
|
+
return "JavaScript";
|
|
618
|
+
}
|
|
619
|
+
if (basename.endsWith(".py")) {
|
|
620
|
+
return "Python";
|
|
621
|
+
}
|
|
622
|
+
if (basename.endsWith(".rs")) {
|
|
623
|
+
return "Rust";
|
|
624
|
+
}
|
|
625
|
+
if (basename.endsWith(".md") || basename.endsWith(".mdx")) {
|
|
626
|
+
return "Markdown";
|
|
627
|
+
}
|
|
628
|
+
if (basename.endsWith(".json")) {
|
|
629
|
+
return "JSON";
|
|
630
|
+
}
|
|
631
|
+
if (basename.endsWith(".yml") || basename.endsWith(".yaml")) {
|
|
632
|
+
return "YAML";
|
|
633
|
+
}
|
|
634
|
+
return "file";
|
|
635
|
+
}
|
|
636
|
+
function isTestPath(path, basename) {
|
|
637
|
+
return (path.startsWith("test/") ||
|
|
638
|
+
path.startsWith("tests/") ||
|
|
639
|
+
path.includes("/test/") ||
|
|
640
|
+
path.includes("/tests/") ||
|
|
641
|
+
path.includes("/__tests__/") ||
|
|
642
|
+
basename.includes(".test.") ||
|
|
643
|
+
basename.includes(".spec.") ||
|
|
644
|
+
basename.startsWith("test_"));
|
|
645
|
+
}
|
|
646
|
+
function rangePurpose(ranges) {
|
|
647
|
+
if (ranges.length === 0) {
|
|
648
|
+
return "full-file context";
|
|
649
|
+
}
|
|
650
|
+
const rendered = ranges
|
|
651
|
+
.slice(0, 3)
|
|
652
|
+
.map((range) => range.start_line === range.end_line
|
|
653
|
+
? `${range.start_line}`
|
|
654
|
+
: `${range.start_line}-${range.end_line}`);
|
|
655
|
+
const suffix = ranges.length > rendered.length ? ` +${ranges.length - rendered.length}` : "";
|
|
656
|
+
return `ranges ${rendered.join(", ")}${suffix}`;
|
|
657
|
+
}
|
|
658
|
+
function renderTopMustReadRanges(input) {
|
|
659
|
+
if (input.selected.length === 0) {
|
|
660
|
+
return "- No selected ranges available.";
|
|
661
|
+
}
|
|
662
|
+
const candidates = topMustReadRangeCandidates(input)
|
|
663
|
+
.sort((left, right) => right.score - left.score || left.order - right.order)
|
|
664
|
+
.slice(0, 8);
|
|
665
|
+
return candidates
|
|
666
|
+
.map((candidate, index) => {
|
|
667
|
+
const header = `${index + 1}. ${renderRootPrefix(candidate.file.root_index, input.showRootLabels)}${candidate.file.path}:${singleRangeLabel(candidate.range)} - ${candidate.reason}`;
|
|
668
|
+
const snippet = renderTopMustReadSnippet(candidate, index, input.task);
|
|
669
|
+
return snippet.length === 0 ? header : `${header}\n\n${snippet}`;
|
|
670
|
+
})
|
|
671
|
+
.join("\n");
|
|
672
|
+
}
|
|
673
|
+
function topMustReadRangeCandidates(input) {
|
|
674
|
+
const candidates = [];
|
|
675
|
+
let order = 0;
|
|
676
|
+
for (const file of input.selected) {
|
|
677
|
+
const searchTerms = selectedFileSearchTerms(file, input.search);
|
|
678
|
+
const searchHitCount = input.search.filter((record) => record.root_index === file.root_index && record.path === file.path).length;
|
|
679
|
+
const sourceLines = splitSelectedFileContentByRange(file);
|
|
680
|
+
for (const [rangeIndex, range] of file.ranges.entries()) {
|
|
681
|
+
const symbols = symbolsFromLines(sourceLines[rangeIndex] ?? []);
|
|
682
|
+
const summary = rangeEvidenceSummary({
|
|
683
|
+
task: input.task,
|
|
684
|
+
path: file.path,
|
|
685
|
+
source: file.source,
|
|
686
|
+
symbols,
|
|
687
|
+
searchTerms,
|
|
688
|
+
});
|
|
689
|
+
const score = (file.source === "focus" ? 40 : 20)
|
|
690
|
+
+ Math.min(searchHitCount, 6) * 3
|
|
691
|
+
+ (pathLooksLikeTest(file.path) ? 8 : 0)
|
|
692
|
+
- rangeIndex;
|
|
693
|
+
const hitText = searchHitCount === 0
|
|
694
|
+
? ""
|
|
695
|
+
: `; ${searchHitCount} selected-file search hit${searchHitCount === 1 ? "" : "s"}`;
|
|
696
|
+
candidates.push({
|
|
697
|
+
file,
|
|
698
|
+
range,
|
|
699
|
+
score,
|
|
700
|
+
order,
|
|
701
|
+
reason: `${summary}${hitText}`,
|
|
702
|
+
});
|
|
703
|
+
order += 1;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return candidates;
|
|
707
|
+
}
|
|
708
|
+
function singleRangeLabel(range) {
|
|
709
|
+
return range.start_line === range.end_line
|
|
710
|
+
? `${range.start_line}`
|
|
711
|
+
: `${range.start_line}-${range.end_line}`;
|
|
712
|
+
}
|
|
713
|
+
function renderTopMustReadSnippet(candidate, index, task) {
|
|
714
|
+
if (isCodemapOnlyDisposition(candidate.file.disposition)) {
|
|
715
|
+
return "";
|
|
716
|
+
}
|
|
717
|
+
if (index >= 3) {
|
|
718
|
+
return "";
|
|
719
|
+
}
|
|
720
|
+
const rangeIndex = candidate.file.ranges.findIndex((range) => range.start_line === candidate.range.start_line &&
|
|
721
|
+
range.end_line === candidate.range.end_line);
|
|
722
|
+
const rangeLines = splitSelectedFileContentByRange(candidate.file)[rangeIndex] ?? [];
|
|
723
|
+
const numbered = topMustReadSnippetLines(candidate.range, rangeLines, evidenceTermsForTask(task), candidate.file.path);
|
|
724
|
+
if (numbered.length === 0) {
|
|
725
|
+
return "";
|
|
726
|
+
}
|
|
727
|
+
return ["```text", ...numbered, "```"].join("\n");
|
|
728
|
+
}
|
|
729
|
+
function topMustReadSnippetLines(range, rangeLines, terms, path) {
|
|
730
|
+
const evidenceLines = rangeLines
|
|
731
|
+
.map((line, lineIndex) => ({
|
|
732
|
+
lineNumber: range.start_line + lineIndex,
|
|
733
|
+
rangeIndex: 0,
|
|
734
|
+
text: line.trimEnd(),
|
|
735
|
+
}))
|
|
736
|
+
.filter((line) => line.text.trim().length > 0);
|
|
737
|
+
const scored = evidenceLines
|
|
738
|
+
.map((line, index) => ({
|
|
739
|
+
index,
|
|
740
|
+
score: evidenceLineScore(line.text, terms, path),
|
|
741
|
+
}))
|
|
742
|
+
.filter((candidate) => candidate.score > 0)
|
|
743
|
+
.sort((left, right) => right.score - left.score ||
|
|
744
|
+
evidenceLines[left.index].lineNumber -
|
|
745
|
+
evidenceLines[right.index].lineNumber);
|
|
746
|
+
if (scored.length > 0) {
|
|
747
|
+
const rendered = renderEvidenceLineWindows(mergedEvidenceWindows(evidenceLines, scored.slice(0, 2).map((candidate) => candidate.index)), evidenceLines)
|
|
748
|
+
.split("\n")
|
|
749
|
+
.filter((line) => line.length > 0)
|
|
750
|
+
.slice(0, 8);
|
|
751
|
+
if (rendered.length > 0) {
|
|
752
|
+
return rendered;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return evidenceLines
|
|
756
|
+
.slice(0, 8)
|
|
757
|
+
.map((line) => `${line.lineNumber}: ${trimEvidenceLine(line.text)}`);
|
|
758
|
+
}
|
|
759
|
+
function pathLooksLikeTest(path) {
|
|
760
|
+
return /(?:^|\/)(?:tests?|__tests__)\//.test(path) || /\.test\.[^.]+$/.test(path);
|
|
761
|
+
}
|
|
762
|
+
const SOURCE_EVIDENCE_WINDOW_RADIUS = 4;
|
|
763
|
+
function mergedEvidenceWindows(lines, anchors) {
|
|
764
|
+
const windows = anchors
|
|
765
|
+
.map((anchor) => evidenceWindowAroundAnchor(lines, anchor))
|
|
766
|
+
.sort((left, right) => left.startIndex - right.startIndex);
|
|
767
|
+
const merged = [];
|
|
768
|
+
for (const window of windows) {
|
|
769
|
+
const previous = merged.at(-1);
|
|
770
|
+
if (previous != null &&
|
|
771
|
+
lines[previous.endIndex]?.rangeIndex === lines[window.startIndex]?.rangeIndex &&
|
|
772
|
+
window.startIndex <= previous.endIndex + 1) {
|
|
773
|
+
previous.endIndex = Math.max(previous.endIndex, window.endIndex);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
merged.push({ ...window });
|
|
777
|
+
}
|
|
778
|
+
return merged;
|
|
779
|
+
}
|
|
780
|
+
function evidenceWindowAroundAnchor(lines, anchor) {
|
|
781
|
+
const anchorLine = lines[anchor];
|
|
782
|
+
if (anchorLine == null) {
|
|
783
|
+
return { startIndex: anchor, endIndex: anchor };
|
|
784
|
+
}
|
|
785
|
+
let startIndex = anchor;
|
|
786
|
+
let before = SOURCE_EVIDENCE_WINDOW_RADIUS;
|
|
787
|
+
while (before > 0 &&
|
|
788
|
+
startIndex > 0 &&
|
|
789
|
+
lines[startIndex - 1]?.rangeIndex === anchorLine.rangeIndex) {
|
|
790
|
+
startIndex -= 1;
|
|
791
|
+
before -= 1;
|
|
792
|
+
}
|
|
793
|
+
let endIndex = anchor;
|
|
794
|
+
let after = SOURCE_EVIDENCE_WINDOW_RADIUS;
|
|
795
|
+
while (after > 0 &&
|
|
796
|
+
endIndex + 1 < lines.length &&
|
|
797
|
+
lines[endIndex + 1]?.rangeIndex === anchorLine.rangeIndex) {
|
|
798
|
+
endIndex += 1;
|
|
799
|
+
after -= 1;
|
|
800
|
+
}
|
|
801
|
+
return { startIndex, endIndex };
|
|
802
|
+
}
|
|
803
|
+
function renderEvidenceLineWindows(windows, lines) {
|
|
804
|
+
const rendered = [];
|
|
805
|
+
let previousRenderedLine;
|
|
806
|
+
for (const window of windows) {
|
|
807
|
+
for (let index = window.startIndex; index <= window.endIndex; index += 1) {
|
|
808
|
+
const line = lines[index];
|
|
809
|
+
if (line == null || line.text.trim().length === 0) {
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
if (previousRenderedLine != null &&
|
|
813
|
+
(previousRenderedLine.rangeIndex !== line.rangeIndex ||
|
|
814
|
+
previousRenderedLine.lineNumber !== line.lineNumber - 1) &&
|
|
815
|
+
rendered.at(-1) !== "...") {
|
|
816
|
+
rendered.push("...");
|
|
817
|
+
}
|
|
818
|
+
rendered.push(`${line.lineNumber}: ${trimEvidenceLine(line.text)}`);
|
|
819
|
+
previousRenderedLine = line;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return rendered.join("\n");
|
|
823
|
+
}
|
|
824
|
+
function evidenceTermsForTask(task) {
|
|
825
|
+
return task
|
|
826
|
+
.toLowerCase()
|
|
827
|
+
.split(/[^a-z0-9_]+/)
|
|
828
|
+
.filter((term) => term.length >= 4)
|
|
829
|
+
.slice(0, 8);
|
|
830
|
+
}
|
|
831
|
+
function evidenceLineScore(line, terms, _path) {
|
|
832
|
+
const normalized = line.toLowerCase();
|
|
833
|
+
let score = 0;
|
|
834
|
+
for (const term of terms) {
|
|
835
|
+
if (normalized.includes(term.toLowerCase())) {
|
|
836
|
+
score += 10;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (score === 0) {
|
|
840
|
+
return 0;
|
|
841
|
+
}
|
|
842
|
+
if (/^\s*import\b/.test(line)) {
|
|
843
|
+
score -= 20;
|
|
844
|
+
}
|
|
845
|
+
if (/^\s*(const|let|return|if|await|async|def|function|type|interface)\b/.test(line)) {
|
|
846
|
+
score += 4;
|
|
847
|
+
}
|
|
848
|
+
if (/[.=:(]\s*[^=]|=>|append|values|request|response|onChange|value=/.test(line)) {
|
|
849
|
+
score += 3;
|
|
850
|
+
}
|
|
851
|
+
return score;
|
|
852
|
+
}
|
|
853
|
+
function trimEvidenceLine(line) {
|
|
854
|
+
const maxLength = 180;
|
|
855
|
+
if (line.length <= maxLength) {
|
|
856
|
+
return line;
|
|
857
|
+
}
|
|
858
|
+
return `${line.slice(0, maxLength - 3)}...`;
|
|
859
|
+
}
|
|
860
|
+
function isClosurePath(path) {
|
|
861
|
+
const normalized = path.toLowerCase();
|
|
862
|
+
const basename = normalized.split("/").at(-1) ?? normalized;
|
|
863
|
+
return (normalized.includes("/types/") ||
|
|
864
|
+
normalized.includes("/schemas/") ||
|
|
865
|
+
normalized.includes("/constants.") ||
|
|
866
|
+
normalized.includes("/config.") ||
|
|
867
|
+
normalized.includes("/querykeys.") ||
|
|
868
|
+
basename.endsWith(".types.ts") ||
|
|
869
|
+
basename === "types.ts" ||
|
|
870
|
+
basename === "schema.ts" ||
|
|
871
|
+
basename === "schemas.ts" ||
|
|
872
|
+
basename === "constants.ts" ||
|
|
873
|
+
basename === "constants.py" ||
|
|
874
|
+
basename === "config.ts" ||
|
|
875
|
+
basename === "config.py" ||
|
|
876
|
+
basename === "querykeys.ts");
|
|
877
|
+
}
|
|
878
|
+
function renderRepositoryShape(input) {
|
|
879
|
+
const { tree, selected, showRootLabels } = input;
|
|
880
|
+
if (tree.length === 0) {
|
|
881
|
+
return "- No files discovered.";
|
|
882
|
+
}
|
|
883
|
+
const selectedKeys = selectedFileKeys(selected);
|
|
884
|
+
const selectedTree = tree.filter((file) => selectedKeys.has(fileKey(file)));
|
|
885
|
+
if (selectedTree.length === 0) {
|
|
886
|
+
return "- Full repository shape is available in tree.json; no selected files were present in the discovered tree.";
|
|
887
|
+
}
|
|
888
|
+
return [
|
|
889
|
+
"- Full repository shape is available in tree.json; inline shape is limited to selected files.",
|
|
890
|
+
...selectedTree
|
|
891
|
+
.map((file) => {
|
|
892
|
+
const flags = [
|
|
893
|
+
file.eligible ? "eligible" : "omitted",
|
|
894
|
+
file.content_eligible ? "content" : "metadata-only",
|
|
895
|
+
].join(", ");
|
|
896
|
+
return `- ${renderRootPrefix(file.root_index, showRootLabels)}${file.path} (${file.size_bytes} bytes; ${flags})`;
|
|
897
|
+
}),
|
|
898
|
+
].join("\n");
|
|
899
|
+
}
|
|
900
|
+
function renderSearchEvidence(input) {
|
|
901
|
+
const { search, selected, showRootLabels } = input;
|
|
902
|
+
if (search.length === 0) {
|
|
903
|
+
return "- No search hits recorded.";
|
|
904
|
+
}
|
|
905
|
+
const selectedPathKeys = selectedFileKeys(selected);
|
|
906
|
+
const selectedHits = search.filter((record) => selectedPathKeys.has(fileKey(record)));
|
|
907
|
+
const repoWideHits = search.filter((record) => !selectedPathKeys.has(fileKey(record)));
|
|
908
|
+
const lines = [];
|
|
909
|
+
lines.push(renderSelectedSearchSummary(selectedHits, showRootLabels));
|
|
910
|
+
if (repoWideHits.length > 0) {
|
|
911
|
+
lines.push(`- Repo-wide hits suppressed from inline bundle: ${repoWideHits.length} hits across ${countSearchPaths(repoWideHits)} unselected files; see search.jsonl.`);
|
|
912
|
+
}
|
|
913
|
+
return lines.join("\n");
|
|
914
|
+
}
|
|
915
|
+
function renderSelectedSearchSummary(selectedHits, showRootLabels) {
|
|
916
|
+
if (selectedHits.length === 0) {
|
|
917
|
+
return "- Selected-file hits: none.";
|
|
918
|
+
}
|
|
919
|
+
const countByPath = new Map();
|
|
920
|
+
for (const record of selectedHits) {
|
|
921
|
+
const path = `${renderRootPrefix(record.root_index, showRootLabels)}${record.path}`;
|
|
922
|
+
countByPath.set(path, (countByPath.get(path) ?? 0) + 1);
|
|
923
|
+
}
|
|
924
|
+
const topPaths = [...countByPath.entries()]
|
|
925
|
+
.sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]))
|
|
926
|
+
.slice(0, 12)
|
|
927
|
+
.map(([path, count]) => `${path}=${count}`)
|
|
928
|
+
.join(", ");
|
|
929
|
+
const suppressed = countByPath.size > 12 ? `; ${countByPath.size - 12} more selected files in search.jsonl` : "";
|
|
930
|
+
return `- Selected-file hits: ${selectedHits.length} hits across ${countByPath.size} selected files (${topPaths}${suppressed}).`;
|
|
931
|
+
}
|
|
932
|
+
function countSearchPaths(search) {
|
|
933
|
+
return new Set(search.map(fileKey)).size;
|
|
934
|
+
}
|
|
935
|
+
function renderFileContext(selected, search, showRootLabels) {
|
|
936
|
+
if (selected.length === 0) {
|
|
937
|
+
return "No file context selected.";
|
|
938
|
+
}
|
|
939
|
+
const totalRanges = selected.reduce((total, file) => total + file.ranges.length, 0);
|
|
940
|
+
const totalBytes = selected.reduce((total, file) => total + file.bytes, 0);
|
|
941
|
+
const previewFiles = selected.slice(0, 12).map((file) => {
|
|
942
|
+
const ranges = file.ranges
|
|
943
|
+
.slice(0, 4)
|
|
944
|
+
.map((range) => `${range.start_line}-${range.end_line}`)
|
|
945
|
+
.join(", ");
|
|
946
|
+
const suffix = file.ranges.length > 4 ? ` +${file.ranges.length - 4}` : "";
|
|
947
|
+
return `- ${renderRootPrefix(file.root_index, showRootLabels)}${file.path}: ${ranges}${suffix}`;
|
|
948
|
+
});
|
|
949
|
+
const hidden = selected.length > previewFiles.length
|
|
950
|
+
? [`- ${selected.length - previewFiles.length} more selected files are listed in manifest.json and selected-context.jsonl.`]
|
|
951
|
+
: [];
|
|
952
|
+
const selectedHitPreviews = renderSelectedHitPreviews({
|
|
953
|
+
selected,
|
|
954
|
+
search,
|
|
955
|
+
showRootLabels,
|
|
956
|
+
});
|
|
957
|
+
const selectedRangeLandmarks = selected.length > 12
|
|
958
|
+
? []
|
|
959
|
+
: renderSelectedRangeLandmarks({
|
|
960
|
+
selected,
|
|
961
|
+
showRootLabels,
|
|
962
|
+
});
|
|
963
|
+
const selectedCodemapOutlines = selected.length > 12
|
|
964
|
+
? []
|
|
965
|
+
: renderSelectedCodemapOutlines({
|
|
966
|
+
selected,
|
|
967
|
+
showRootLabels,
|
|
968
|
+
});
|
|
969
|
+
return [
|
|
970
|
+
"- Full selected source is stored in `selected-context.jsonl`; `slices.jsonl` is the bounded candidate/debug universe and may include unselected files or ranges.",
|
|
971
|
+
`- Selected source payload: ${selected.length} files, ${totalRanges} ranges, ${totalBytes} bytes before artifact serialization.`,
|
|
972
|
+
"- Range index:",
|
|
973
|
+
...previewFiles,
|
|
974
|
+
...hidden,
|
|
975
|
+
...(selectedRangeLandmarks.length === 0
|
|
976
|
+
? []
|
|
977
|
+
: ["", "- Range landmarks:", ...selectedRangeLandmarks]),
|
|
978
|
+
...(selectedCodemapOutlines.length === 0
|
|
979
|
+
? []
|
|
980
|
+
: ["", "- Codemap outlines:", ...selectedCodemapOutlines]),
|
|
981
|
+
...(selected.length > 12 || selectedHitPreviews.length === 0
|
|
982
|
+
? []
|
|
983
|
+
: ["", "- Selected hit previews:", ...selectedHitPreviews]),
|
|
984
|
+
].join("\n");
|
|
985
|
+
}
|
|
986
|
+
function renderSelectedRangeLandmarks(input) {
|
|
987
|
+
const rendered = [];
|
|
988
|
+
const seen = new Set();
|
|
989
|
+
for (const file of input.selected) {
|
|
990
|
+
if (isCodemapOnlyDisposition(file.disposition)) {
|
|
991
|
+
continue;
|
|
992
|
+
}
|
|
993
|
+
let fileCount = 0;
|
|
994
|
+
const rangeLines = splitSelectedFileContentByRange(file);
|
|
995
|
+
file.ranges.forEach((range, rangeIndex) => {
|
|
996
|
+
const lines = rangeLines[rangeIndex] ?? [];
|
|
997
|
+
let rangeCount = 0;
|
|
998
|
+
lines.forEach((line, offset) => {
|
|
999
|
+
const preview = line.trim();
|
|
1000
|
+
if (preview.length === 0 || !isRangeLandmarkLine(preview)) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const lineNumber = range.start_line + offset;
|
|
1004
|
+
const key = `${file.root_index}\u0000${file.path}\u0000${lineNumber}\u0000${preview}`;
|
|
1005
|
+
if (seen.has(key)) {
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
seen.add(key);
|
|
1009
|
+
rendered.push(` - ${renderRootPrefix(file.root_index, input.showRootLabels)}${file.path}:${lineNumber} ${preview}`);
|
|
1010
|
+
fileCount += 1;
|
|
1011
|
+
rangeCount += 1;
|
|
1012
|
+
});
|
|
1013
|
+
});
|
|
1014
|
+
if (fileCount >= 16 || rendered.length >= 48) {
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
return rendered.slice(0, 48);
|
|
1019
|
+
}
|
|
1020
|
+
function isRangeLandmarkLine(line) {
|
|
1021
|
+
return symbolsFromLine(line).length > 0;
|
|
1022
|
+
}
|
|
1023
|
+
function renderSelectedCodemapOutlines(input) {
|
|
1024
|
+
const rendered = [];
|
|
1025
|
+
for (const file of input.selected) {
|
|
1026
|
+
if (!isCodemapOnlyDisposition(file.disposition)) {
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
const map = selectedFileCodemap(file);
|
|
1030
|
+
const prefix = renderRootPrefix(file.root_index, input.showRootLabels);
|
|
1031
|
+
if (map.symbols.length === 0) {
|
|
1032
|
+
rendered.push(` - ${prefix}${file.path}: no symbols detected`);
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
rendered.push(` - ${prefix}${file.path}:`);
|
|
1036
|
+
rendered.push(...map.symbols
|
|
1037
|
+
.slice(0, 24)
|
|
1038
|
+
.map((symbol) => ` - ${renderCodemapSymbolLine(symbol)}`));
|
|
1039
|
+
if (map.symbols.length > 24) {
|
|
1040
|
+
rendered.push(` - +${map.symbols.length - 24} more symbols`);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
return rendered;
|
|
1044
|
+
}
|
|
1045
|
+
function selectedFileCodemap(file) {
|
|
1046
|
+
return remapCodemapToSourceCoordinates(buildFileCodemap(file.path, file.content), file.ranges);
|
|
1047
|
+
}
|
|
1048
|
+
function renderCodemapSymbolLine(symbol) {
|
|
1049
|
+
return `${symbol.kind} ${symbol.name} ${singleRangeLabel({
|
|
1050
|
+
start_line: symbol.start_line,
|
|
1051
|
+
end_line: symbol.end_line,
|
|
1052
|
+
})}`;
|
|
1053
|
+
}
|
|
1054
|
+
function isCodemapOnlyDisposition(disposition) {
|
|
1055
|
+
return disposition === "codemap_only";
|
|
1056
|
+
}
|
|
1057
|
+
function renderSelectedHitPreviews(input) {
|
|
1058
|
+
const selectedPaths = new Set(input.selected
|
|
1059
|
+
.filter((file) => !isCodemapOnlyDisposition(file.disposition))
|
|
1060
|
+
.map((file) => `${file.root_index}\u0000${file.path}`));
|
|
1061
|
+
const rendered = [];
|
|
1062
|
+
const seen = new Set();
|
|
1063
|
+
const perFileCount = new Map();
|
|
1064
|
+
for (const record of input.search) {
|
|
1065
|
+
const fileKey = `${record.root_index}\u0000${record.path}`;
|
|
1066
|
+
if (!selectedPaths.has(fileKey)) {
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
if ((perFileCount.get(fileKey) ?? 0) >= 4) {
|
|
1070
|
+
continue;
|
|
1071
|
+
}
|
|
1072
|
+
const preview = record.preview.trim();
|
|
1073
|
+
if (preview.length === 0) {
|
|
1074
|
+
continue;
|
|
1075
|
+
}
|
|
1076
|
+
const hitKey = `${fileKey}\u0000${record.line}\u0000${preview}`;
|
|
1077
|
+
if (seen.has(hitKey)) {
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
seen.add(hitKey);
|
|
1081
|
+
perFileCount.set(fileKey, (perFileCount.get(fileKey) ?? 0) + 1);
|
|
1082
|
+
rendered.push(` - ${renderRootPrefix(record.root_index, input.showRootLabels)}${record.path}:${record.line}:${record.column} matches "${record.search_term}": ${preview}`);
|
|
1083
|
+
if (rendered.length >= 24) {
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return rendered;
|
|
1088
|
+
}
|
|
1089
|
+
function renderRootPrefix(rootIndex, showRootLabels) {
|
|
1090
|
+
return showRootLabels ? `root ${rootIndex}: ` : "";
|
|
1091
|
+
}
|
|
1092
|
+
function renderOpenQuestions(questions) {
|
|
1093
|
+
if (questions.length === 0) {
|
|
1094
|
+
return "- None.";
|
|
1095
|
+
}
|
|
1096
|
+
return questions.map((question) => `- ${question}`).join("\n");
|
|
1097
|
+
}
|
|
1098
|
+
function renderOmissionsAndBudgetNotes(input) {
|
|
1099
|
+
const maxMaterialOmissions = 12;
|
|
1100
|
+
const maxPathsPerMaterialOmission = 5;
|
|
1101
|
+
const notes = [];
|
|
1102
|
+
notes.push(`- Metrics: selected ${input.metrics.files_selected} files, recorded ${input.omissions.length} omissions, estimated ${input.metrics.estimated_tokens} tokens.`);
|
|
1103
|
+
if (input.metrics.truncated) {
|
|
1104
|
+
notes.push("- Output was truncated or budget-limited.");
|
|
1105
|
+
}
|
|
1106
|
+
for (const warning of input.warnings.filter(isHumanUsefulWarning)) {
|
|
1107
|
+
notes.push(`- Warning ${warning.code}: ${warning.message}`);
|
|
1108
|
+
}
|
|
1109
|
+
const materialOmissions = input.omissions.filter(isMaterialOmission);
|
|
1110
|
+
const incidentalOmissions = input.omissions.filter((omission) => !isMaterialOmission(omission));
|
|
1111
|
+
if (materialOmissions.length > 0) {
|
|
1112
|
+
notes.push("- Material omissions:");
|
|
1113
|
+
}
|
|
1114
|
+
for (const omission of materialOmissions.slice(0, maxMaterialOmissions)) {
|
|
1115
|
+
notes.push(` - ${humanOmissionReason(omission.reason)}: ${omission.message}${renderOmissionPathSuffix(omission.paths, maxPathsPerMaterialOmission)}`);
|
|
1116
|
+
}
|
|
1117
|
+
if (materialOmissions.length > maxMaterialOmissions) {
|
|
1118
|
+
const hidden = materialOmissions.length - maxMaterialOmissions;
|
|
1119
|
+
const countByReason = summarizeOmissionReasons(materialOmissions.slice(maxMaterialOmissions));
|
|
1120
|
+
notes.push(` - ${hidden} additional material omissions summarized: ${countByReason}. Full details are in manifest.json and summary.json.`);
|
|
1121
|
+
}
|
|
1122
|
+
if (incidentalOmissions.length > 0) {
|
|
1123
|
+
notes.push(`- Incidental omissions summarized: ${summarizeOmissionReasons(incidentalOmissions)}.`);
|
|
1124
|
+
}
|
|
1125
|
+
return notes.join("\n");
|
|
1126
|
+
}
|
|
1127
|
+
function isHumanUsefulWarning(warning) {
|
|
1128
|
+
if (warning.code === "delegate_curator_warning" ||
|
|
1129
|
+
warning.code === "delegate_finalizer_warning") {
|
|
1130
|
+
const normalized = warning.message.toLowerCase();
|
|
1131
|
+
return !(normalized.includes("no filesystem inspection") ||
|
|
1132
|
+
normalized.includes("no filesystem discovery") ||
|
|
1133
|
+
normalized.includes("budget-pruned") ||
|
|
1134
|
+
normalized.includes("packet-provided") ||
|
|
1135
|
+
normalized.includes("packet candidates") ||
|
|
1136
|
+
normalized.includes("packet.candidates") ||
|
|
1137
|
+
normalized.includes("candidate ids and ranges") ||
|
|
1138
|
+
normalized.includes("packet budget") ||
|
|
1139
|
+
normalized.includes("packet ranges") ||
|
|
1140
|
+
normalized.includes("packet did not provide complete source") ||
|
|
1141
|
+
normalized.includes("partial because the packet") ||
|
|
1142
|
+
normalized.includes("empty excerpts") ||
|
|
1143
|
+
normalized.includes("large files were kept") ||
|
|
1144
|
+
normalized.includes("excerpt-only for many slices") ||
|
|
1145
|
+
normalized.includes("packet authority was enforced") ||
|
|
1146
|
+
normalized.includes("curator selected fewer local candidates") ||
|
|
1147
|
+
normalized.includes("server-expanded") ||
|
|
1148
|
+
normalized.includes("server-retained") ||
|
|
1149
|
+
normalized.includes("server-evicted") ||
|
|
1150
|
+
normalized.includes("full ranges were selected") ||
|
|
1151
|
+
normalized.includes("selection intentionally keeps deterministic candidates") ||
|
|
1152
|
+
normalized.includes("full source") ||
|
|
1153
|
+
normalized.includes("full excerpts") ||
|
|
1154
|
+
normalized.includes("expected anchor") ||
|
|
1155
|
+
normalized.includes("intentionally excluded") ||
|
|
1156
|
+
normalized.includes("intentionally excludes") ||
|
|
1157
|
+
normalized.includes("broad search") ||
|
|
1158
|
+
normalized.includes("search spillover") ||
|
|
1159
|
+
normalized.includes("packet slices") ||
|
|
1160
|
+
normalized.includes("short packet ranges") ||
|
|
1161
|
+
normalized.includes("narrow ranges") ||
|
|
1162
|
+
normalized.includes("search-discovered candidates") ||
|
|
1163
|
+
normalized.includes("partial deterministic ranges") ||
|
|
1164
|
+
normalized.includes("sparse for many deterministic ranges") ||
|
|
1165
|
+
normalized.includes("narrow eligible ranges") ||
|
|
1166
|
+
normalized.includes("targeted slices"));
|
|
1167
|
+
}
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
function renderOmissionPathSuffix(paths, limit) {
|
|
1171
|
+
if (paths == null || paths.length === 0) {
|
|
1172
|
+
return "";
|
|
1173
|
+
}
|
|
1174
|
+
const uniquePaths = [...new Set(paths)];
|
|
1175
|
+
const rendered = uniquePaths.slice(0, limit);
|
|
1176
|
+
const omitted = uniquePaths.length - rendered.length;
|
|
1177
|
+
return ` (${rendered.join(", ")}${omitted > 0 ? ` +${omitted} more` : ""})`;
|
|
1178
|
+
}
|
|
1179
|
+
function humanOmissionReason(reason) {
|
|
1180
|
+
if (reason === "target_estimated_tokens") {
|
|
1181
|
+
return "budget-limited";
|
|
1182
|
+
}
|
|
1183
|
+
if (reason === "max_files") {
|
|
1184
|
+
return "file-count-limited";
|
|
1185
|
+
}
|
|
1186
|
+
if (reason === "max_total_bytes" || reason === "max_bytes_per_file") {
|
|
1187
|
+
return "byte-budget-limited";
|
|
1188
|
+
}
|
|
1189
|
+
return reason;
|
|
1190
|
+
}
|
|
1191
|
+
function summarizeOmissionReasons(omissions) {
|
|
1192
|
+
const countByReason = new Map();
|
|
1193
|
+
for (const omission of omissions) {
|
|
1194
|
+
const reason = humanOmissionReason(omission.reason);
|
|
1195
|
+
countByReason.set(reason, (countByReason.get(reason) ?? 0) + 1);
|
|
1196
|
+
}
|
|
1197
|
+
return [...countByReason.entries()]
|
|
1198
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
1199
|
+
.map(([reason, count]) => `${reason}=${count}`)
|
|
1200
|
+
.join(", ");
|
|
1201
|
+
}
|
|
1202
|
+
function isMaterialOmission(omission) {
|
|
1203
|
+
if (new Set([
|
|
1204
|
+
"binary_file",
|
|
1205
|
+
"content_secret",
|
|
1206
|
+
"exclude_glob",
|
|
1207
|
+
"secret_path",
|
|
1208
|
+
"symlink",
|
|
1209
|
+
]).has(omission.reason)) {
|
|
1210
|
+
return false;
|
|
1211
|
+
}
|
|
1212
|
+
return omissionEventBaseFromReason(omission.reason).material === true;
|
|
1213
|
+
}
|
|
1214
|
+
function reconcileSelectedOmissions(omissions, selected) {
|
|
1215
|
+
if (omissions.length === 0 || selected.length === 0) {
|
|
1216
|
+
return [...omissions];
|
|
1217
|
+
}
|
|
1218
|
+
const selectedKeys = selectedFileKeys(selected);
|
|
1219
|
+
const selectedPaths = new Set(selected.map((file) => file.path));
|
|
1220
|
+
const reconciled = [];
|
|
1221
|
+
for (const omission of omissions) {
|
|
1222
|
+
if (omission.paths == null || omission.paths.length === 0) {
|
|
1223
|
+
reconciled.push(omission);
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1226
|
+
const paths = omission.paths.filter((path) => {
|
|
1227
|
+
if (omission.root_index == null) {
|
|
1228
|
+
return !selectedPaths.has(path);
|
|
1229
|
+
}
|
|
1230
|
+
return !selectedKeys.has(fileKey({ root_index: omission.root_index, path }));
|
|
1231
|
+
});
|
|
1232
|
+
if (paths.length > 0) {
|
|
1233
|
+
reconciled.push({ ...omission, paths });
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
return reconciled;
|
|
1237
|
+
}
|
|
1238
|
+
function filterTaskPresentationOmissions(omissions, _task) {
|
|
1239
|
+
return [...omissions];
|
|
1240
|
+
}
|
|
1241
|
+
function filterTaskPresentationSelected(selected, _task) {
|
|
1242
|
+
return [...selected];
|
|
1243
|
+
}
|
|
1244
|
+
function promoteTaskPresentationEvidence(selected, _task, _slices) {
|
|
1245
|
+
return [...selected];
|
|
1246
|
+
}
|
|
1247
|
+
function reconcileSelectedOpenQuestions(questions, selected) {
|
|
1248
|
+
if (questions.length === 0 || selected.length === 0) {
|
|
1249
|
+
return [...questions];
|
|
1250
|
+
}
|
|
1251
|
+
const refs = selectedQuestionReferences(selected);
|
|
1252
|
+
return questions.filter((question) => {
|
|
1253
|
+
if (isConceptualQuestionAnsweredBySelectedContext(question, selected)) {
|
|
1254
|
+
return false;
|
|
1255
|
+
}
|
|
1256
|
+
if (!isSelectedEvidenceQuestion(question)) {
|
|
1257
|
+
return true;
|
|
1258
|
+
}
|
|
1259
|
+
return !questionReferencesSelectedContext(question, refs);
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
function buildPresentationOpenQuestions(questions, selected, omissions) {
|
|
1263
|
+
const reconciled = reconcileSelectedOpenQuestions(questions, selected);
|
|
1264
|
+
const seen = new Set(reconciled);
|
|
1265
|
+
const output = [...reconciled];
|
|
1266
|
+
for (const question of omissionFollowUpQuestions(omissions)) {
|
|
1267
|
+
if (seen.has(question)) {
|
|
1268
|
+
continue;
|
|
1269
|
+
}
|
|
1270
|
+
seen.add(question);
|
|
1271
|
+
output.push(question);
|
|
1272
|
+
if (output.length >= 20) {
|
|
1273
|
+
break;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return output;
|
|
1277
|
+
}
|
|
1278
|
+
function omissionFollowUpQuestions(omissions) {
|
|
1279
|
+
return omissions
|
|
1280
|
+
.filter(isMaterialOmission)
|
|
1281
|
+
.slice(0, 3)
|
|
1282
|
+
.map((omission) => {
|
|
1283
|
+
const reason = humanOmissionReason(omission.reason);
|
|
1284
|
+
const paths = renderOmissionQuestionPaths(omission.paths);
|
|
1285
|
+
if (paths.length === 0) {
|
|
1286
|
+
return `What task-relevant evidence is missing from the ${reason} omission: ${omission.message}?`;
|
|
1287
|
+
}
|
|
1288
|
+
return `Can the omitted ${reason} paths (${paths}) change the answer, risk assessment, or required tests for this task?`;
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
function renderOmissionQuestionPaths(paths) {
|
|
1292
|
+
if (paths == null || paths.length === 0) {
|
|
1293
|
+
return "";
|
|
1294
|
+
}
|
|
1295
|
+
const uniquePaths = [...new Set(paths)];
|
|
1296
|
+
const rendered = uniquePaths.slice(0, 3);
|
|
1297
|
+
const omitted = uniquePaths.length - rendered.length;
|
|
1298
|
+
return `${rendered.join(", ")}${omitted > 0 ? ` +${omitted} more` : ""}`;
|
|
1299
|
+
}
|
|
1300
|
+
function isConceptualQuestionAnsweredBySelectedContext(_question, _selected) {
|
|
1301
|
+
return false;
|
|
1302
|
+
}
|
|
1303
|
+
function isSelectedEvidenceQuestion(question) {
|
|
1304
|
+
return /\b(?:missing|missed|omitted|not selected|not present|unavailable|outside packet|need|needs|verify|confirm|include|includes|contain|contains|selected|available|additional|represented|constraints?|excerpt)\b/i.test(question);
|
|
1305
|
+
}
|
|
1306
|
+
function selectedQuestionReferences(selected) {
|
|
1307
|
+
const refs = new Set();
|
|
1308
|
+
for (const file of selected) {
|
|
1309
|
+
for (const value of selectedQuestionReferenceValues(file.path)) {
|
|
1310
|
+
const normalized = normalizeQuestionReference(value);
|
|
1311
|
+
if (isConcreteQuestionReference(normalized)) {
|
|
1312
|
+
refs.add(normalized);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return refs;
|
|
1317
|
+
}
|
|
1318
|
+
function selectedQuestionReferenceValues(path) {
|
|
1319
|
+
const parts = path.split("/");
|
|
1320
|
+
const basename = parts.at(-1) ?? path;
|
|
1321
|
+
const stem = basename.split(".")[0] ?? basename;
|
|
1322
|
+
return [path, basename, stem];
|
|
1323
|
+
}
|
|
1324
|
+
function questionReferencesSelectedContext(question, refs) {
|
|
1325
|
+
const normalized = normalizeQuestionReference(question);
|
|
1326
|
+
for (const ref of refs) {
|
|
1327
|
+
if (normalized.includes(ref)) {
|
|
1328
|
+
return true;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
return false;
|
|
1332
|
+
}
|
|
1333
|
+
function normalizeQuestionReference(value) {
|
|
1334
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
1335
|
+
}
|
|
1336
|
+
function isConcreteQuestionReference(value) {
|
|
1337
|
+
if (value.length < 4) {
|
|
1338
|
+
return false;
|
|
1339
|
+
}
|
|
1340
|
+
return !new Set([
|
|
1341
|
+
"backend",
|
|
1342
|
+
"frontend",
|
|
1343
|
+
"schema",
|
|
1344
|
+
"schemas",
|
|
1345
|
+
"service",
|
|
1346
|
+
"services",
|
|
1347
|
+
"source",
|
|
1348
|
+
"test",
|
|
1349
|
+
"tests",
|
|
1350
|
+
"types",
|
|
1351
|
+
]).has(value);
|
|
1352
|
+
}
|
|
1353
|
+
function selectedFileKeys(selected) {
|
|
1354
|
+
return new Set(selected.map(fileKey));
|
|
1355
|
+
}
|
|
1356
|
+
function fileKey(file) {
|
|
1357
|
+
return `${file.root_index}\u0000${file.path}`;
|
|
1358
|
+
}
|
|
1359
|
+
function boundOpenQuestions(questions) {
|
|
1360
|
+
return questions.slice(0, 20).map((question) => sanitizeDiagnosticText(typeof question === "string" ? question : question.question));
|
|
1361
|
+
}
|
|
1362
|
+
function omissionEventFromDiagnostic(omission) {
|
|
1363
|
+
const base = omissionEventBaseFromReason(omission.reason);
|
|
1364
|
+
const rootIndex = omission.root_index;
|
|
1365
|
+
return {
|
|
1366
|
+
...base,
|
|
1367
|
+
...(rootIndex !== undefined && Number.isInteger(rootIndex) && rootIndex >= 0
|
|
1368
|
+
? { root_index: rootIndex }
|
|
1369
|
+
: {}),
|
|
1370
|
+
...(omission.paths == null || omission.paths.length === 0
|
|
1371
|
+
? {}
|
|
1372
|
+
: { paths: [...omission.paths] }),
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
function warningEventFromDiagnostic(warning) {
|
|
1376
|
+
return {
|
|
1377
|
+
reason: "non_material_notice",
|
|
1378
|
+
material: false,
|
|
1379
|
+
code: warning.code,
|
|
1380
|
+
message: warning.message,
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
function omissionEventBaseFromReason(reason) {
|
|
1384
|
+
if (reason === "excluded" ||
|
|
1385
|
+
reason === "exclude_glob" ||
|
|
1386
|
+
reason === "caller_include_glob" ||
|
|
1387
|
+
reason === "symlink_omitted" ||
|
|
1388
|
+
reason === "symlink_file" ||
|
|
1389
|
+
reason === "binary_file" ||
|
|
1390
|
+
reason === "duplicate_root") {
|
|
1391
|
+
return { reason: "incidental_skip", material: false };
|
|
1392
|
+
}
|
|
1393
|
+
if (reason === "noisy_file" ||
|
|
1394
|
+
reason === "default_exclude" ||
|
|
1395
|
+
reason === "default_noisy_exclude") {
|
|
1396
|
+
return { reason: "default_noisy_exclude", material: false };
|
|
1397
|
+
}
|
|
1398
|
+
if (reason === "focus_sliced" || reason === "focus_over_cap") {
|
|
1399
|
+
return { reason: "budget_omission", material: true };
|
|
1400
|
+
}
|
|
1401
|
+
if (reason.includes("secret")) {
|
|
1402
|
+
return { reason: "secret_skip", material: true };
|
|
1403
|
+
}
|
|
1404
|
+
if (reason.includes("unreadable")) {
|
|
1405
|
+
return { reason: "unreadable_file", material: true };
|
|
1406
|
+
}
|
|
1407
|
+
if (reason.includes("max_scan_files") ||
|
|
1408
|
+
reason.includes("max_discovery_bytes") ||
|
|
1409
|
+
reason.includes("max_candidate") ||
|
|
1410
|
+
reason.includes("discovery_byte_cap") ||
|
|
1411
|
+
reason.includes("candidate_cap") ||
|
|
1412
|
+
reason.includes("search_cap") ||
|
|
1413
|
+
reason.includes("scan_cap")) {
|
|
1414
|
+
return { reason: "cap_omission", material: true };
|
|
1415
|
+
}
|
|
1416
|
+
if (reason.startsWith("max_") ||
|
|
1417
|
+
reason.includes("budget") ||
|
|
1418
|
+
reason === "target_estimated_tokens" ||
|
|
1419
|
+
reason === "file_too_large") {
|
|
1420
|
+
return { reason: "budget_omission", material: true };
|
|
1421
|
+
}
|
|
1422
|
+
return { reason: "requested_evidence_omission", material: true };
|
|
1423
|
+
}
|
|
1424
|
+
function boundDebugDiagnostics(diagnostics, caps) {
|
|
1425
|
+
if (diagnostics == null) {
|
|
1426
|
+
return {};
|
|
1427
|
+
}
|
|
1428
|
+
return {
|
|
1429
|
+
...(diagnostics.notes == null
|
|
1430
|
+
? {}
|
|
1431
|
+
: {
|
|
1432
|
+
notes: diagnostics.notes
|
|
1433
|
+
.slice(0, caps.max_warnings)
|
|
1434
|
+
.map((note) => sanitizeDiagnosticText(note)),
|
|
1435
|
+
}),
|
|
1436
|
+
...(diagnostics.counters == null
|
|
1437
|
+
? {}
|
|
1438
|
+
: { counters: sanitizeCounters(diagnostics.counters) }),
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
function sanitizeCounters(counters) {
|
|
1442
|
+
return Object.fromEntries(Object.entries(counters)
|
|
1443
|
+
.slice(0, 50)
|
|
1444
|
+
.map(([key, value]) => [
|
|
1445
|
+
sanitizeDiagnosticText(key),
|
|
1446
|
+
typeof value === "string" ? sanitizeDiagnosticText(value) : value,
|
|
1447
|
+
]));
|
|
1448
|
+
}
|
|
1449
|
+
function renderJsonl(records) {
|
|
1450
|
+
return records.map((record) => JSON.stringify(record)).join("\n")
|
|
1451
|
+
+ (records.length === 0 ? "" : "\n");
|
|
1452
|
+
}
|
|
1453
|
+
function validateTaskForRendering(task, allowSecrets) {
|
|
1454
|
+
assertTaskSecretsGated(task, allowSecrets);
|
|
1455
|
+
return task;
|
|
1456
|
+
}
|
|
1457
|
+
function safePath(path, allowSecrets) {
|
|
1458
|
+
if (allowSecrets) {
|
|
1459
|
+
return path;
|
|
1460
|
+
}
|
|
1461
|
+
return boundContextBuilderPathList([path], 1)[0] ?? "[redacted-sensitive-path]";
|
|
1462
|
+
}
|
|
1463
|
+
function safeContent(content, allowSecrets) {
|
|
1464
|
+
if (allowSecrets) {
|
|
1465
|
+
return content;
|
|
1466
|
+
}
|
|
1467
|
+
return hasConservativeResidualSecret(content)
|
|
1468
|
+
? "[redacted-sensitive-content]"
|
|
1469
|
+
: content;
|
|
1470
|
+
}
|
|
1471
|
+
function sanitizeJsonValue(value, allowSecrets) {
|
|
1472
|
+
if (typeof value === "string") {
|
|
1473
|
+
const pathSafe = safePath(value, allowSecrets);
|
|
1474
|
+
return pathSafe === "[redacted-sensitive-path]"
|
|
1475
|
+
? pathSafe
|
|
1476
|
+
: sanitizeDiagnosticText(value, allowSecrets);
|
|
1477
|
+
}
|
|
1478
|
+
if (typeof value === "number" || typeof value === "boolean" || value == null) {
|
|
1479
|
+
return value;
|
|
1480
|
+
}
|
|
1481
|
+
if (Array.isArray(value)) {
|
|
1482
|
+
return value.slice(0, 200).map((item) => sanitizeJsonValue(item, allowSecrets));
|
|
1483
|
+
}
|
|
1484
|
+
if (typeof value === "object") {
|
|
1485
|
+
return Object.fromEntries(Object.entries(value)
|
|
1486
|
+
.slice(0, 200)
|
|
1487
|
+
.map(([key, entryValue]) => [
|
|
1488
|
+
sanitizeDiagnosticText(key, allowSecrets),
|
|
1489
|
+
sanitizeJsonValue(entryValue, allowSecrets),
|
|
1490
|
+
]));
|
|
1491
|
+
}
|
|
1492
|
+
return String(value);
|
|
1493
|
+
}
|
|
1494
|
+
function markdownFenceFor(content) {
|
|
1495
|
+
const longest = Math.max(3, ...Array.from(content.matchAll(/`+/g), (match) => match[0].length + 1));
|
|
1496
|
+
return "`".repeat(longest);
|
|
1497
|
+
}
|
|
1498
|
+
//# sourceMappingURL=bundle.js.map
|