project-tiny-context-harness 0.2.84 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -428
- package/assets/README.md +283 -455
- package/assets/README.zh-CN.md +199 -123
- package/assets/agents/AGENTS_CORE.md +54 -67
- package/assets/context_templates/context.toml +3 -0
- package/assets/context_templates/global.md +6 -6
- package/assets/github/harness.yml +2 -2
- package/assets/skills/context_development_engineer/SKILL.md +91 -107
- package/assets/skills/context_product_plan/SKILL.md +18 -28
- package/assets/skills/context_surface_contract/SKILL.md +35 -38
- package/assets/skills/context_uiux_design/SKILL.md +31 -30
- package/assets/skills/long-task-workflow/SKILL.md +76 -0
- package/assets/skills/long-task-workflow/agents/openai.yaml +4 -0
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +41 -0
- package/assets/skills/long-task-workflow/references/contract-authoring.md +62 -0
- package/assets/skills/long-task-workflow/references/evidence-design.md +45 -0
- package/assets/skills/normal-long-task/SKILL.md +12 -489
- package/assets/skills/source-plan-authoring/SKILL.md +379 -0
- package/assets/tools/validate_context.py +293 -127
- package/dist/cli.js +3 -1
- package/dist/commands/check-modularity.js +33 -10
- package/dist/commands/composite-campaign.d.ts +1 -0
- package/dist/commands/composite-campaign.js +8 -0
- package/dist/commands/composite-long-task.d.ts +1 -6
- package/dist/commands/composite-long-task.js +7 -157
- package/dist/commands/delivery-set.d.ts +1 -0
- package/dist/commands/delivery-set.js +8 -0
- package/dist/commands/disable.d.ts +1 -0
- package/dist/commands/disable.js +15 -0
- package/dist/commands/enable.d.ts +1 -0
- package/dist/commands/enable.js +14 -0
- package/dist/commands/export-context-args.js +13 -4
- package/dist/commands/export-context.js +18 -7
- package/dist/commands/index.js +42 -30
- package/dist/commands/init.js +12 -6
- package/dist/commands/long-task-authoring.d.ts +3 -0
- package/dist/commands/long-task-authoring.js +92 -0
- package/dist/commands/long-task-explain.d.ts +1 -0
- package/dist/commands/long-task-explain.js +52 -0
- package/dist/commands/long-task.d.ts +1 -0
- package/dist/commands/long-task.js +226 -0
- package/dist/commands/package-source.js +2 -2
- package/dist/commands/upgrade.js +10 -10
- package/dist/index.d.ts +11 -1
- package/dist/index.js +8 -0
- package/dist/lib/config.js +34 -8
- package/dist/lib/context-default-footprint.d.ts +16 -0
- package/dist/lib/context-default-footprint.js +107 -0
- package/dist/lib/context-export.js +105 -41
- package/dist/lib/context-graph-snapshot.d.ts +18 -0
- package/dist/lib/context-graph-snapshot.js +171 -0
- package/dist/lib/context-manifest-schema.d.ts +28 -0
- package/dist/lib/context-manifest-schema.js +150 -0
- package/dist/lib/context-manifest.js +28 -20
- package/dist/lib/context-templates.js +5 -5
- package/dist/lib/design-md.js +1 -1
- package/dist/lib/doctor.js +54 -1
- package/dist/lib/harness-root.js +25 -8
- package/dist/lib/init.js +6 -3
- package/dist/lib/legacy-managed-scan.js +23 -7
- package/dist/lib/legacy-sdlc-migration.js +21 -11
- package/dist/lib/long-task-acceptance-reference.d.ts +22 -0
- package/dist/lib/long-task-acceptance-reference.js +46 -0
- package/dist/lib/long-task-acceptance-shape.d.ts +5 -0
- package/dist/lib/long-task-acceptance-shape.js +131 -0
- package/dist/lib/long-task-activation-validation.d.ts +21 -0
- package/dist/lib/long-task-activation-validation.js +136 -0
- package/dist/lib/long-task-artifacts.d.ts +5 -0
- package/dist/lib/long-task-artifacts.js +34 -0
- package/dist/lib/long-task-assertions-v2.d.ts +22 -0
- package/dist/lib/long-task-assertions-v2.js +212 -0
- package/dist/lib/long-task-authoring-authority-preview.d.ts +5 -0
- package/dist/lib/long-task-authoring-authority-preview.js +85 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.d.ts +8 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.js +179 -0
- package/dist/lib/long-task-authoring-preflight-repair-order.d.ts +8 -0
- package/dist/lib/long-task-authoring-preflight-repair-order.js +95 -0
- package/dist/lib/long-task-authoring-preflight-types.d.ts +46 -0
- package/dist/lib/long-task-authoring-preflight-types.js +38 -0
- package/dist/lib/long-task-authoring-preflight.d.ts +3 -0
- package/dist/lib/long-task-authoring-preflight.js +44 -0
- package/dist/lib/long-task-authority-material-diff.d.ts +17 -0
- package/dist/lib/long-task-authority-material-diff.js +152 -0
- package/dist/lib/long-task-authority-materials.d.ts +7 -0
- package/dist/lib/long-task-authority-materials.js +83 -0
- package/dist/lib/long-task-authority-policy.d.ts +168 -0
- package/dist/lib/long-task-authority-policy.js +181 -0
- package/dist/lib/long-task-authority-revision-details.d.ts +19 -0
- package/dist/lib/long-task-authority-revision-details.js +192 -0
- package/dist/lib/long-task-authority-revision-enforcement.d.ts +3 -0
- package/dist/lib/long-task-authority-revision-enforcement.js +41 -0
- package/dist/lib/long-task-authority-revision-types.d.ts +50 -0
- package/dist/lib/long-task-authority-revision-types.js +1 -0
- package/dist/lib/long-task-authority-revision.d.ts +4 -0
- package/dist/lib/long-task-authority-revision.js +188 -0
- package/dist/lib/long-task-authority-transition-policy.d.ts +62 -0
- package/dist/lib/long-task-authority-transition-policy.js +62 -0
- package/dist/lib/long-task-authority-types.d.ts +96 -0
- package/dist/lib/long-task-authority-types.js +1 -0
- package/dist/lib/long-task-authority.d.ts +7 -0
- package/dist/lib/long-task-authority.js +142 -0
- package/dist/lib/long-task-boundary-check.d.ts +15 -0
- package/dist/lib/long-task-boundary-check.js +9 -0
- package/dist/lib/long-task-check-evidence-decoder.d.ts +3 -0
- package/dist/lib/long-task-check-evidence-decoder.js +74 -0
- package/dist/lib/long-task-check-execution-policy.d.ts +18 -0
- package/dist/lib/long-task-check-execution-policy.js +36 -0
- package/dist/lib/long-task-check-runner.d.ts +2 -0
- package/dist/lib/long-task-check-runner.js +181 -0
- package/dist/lib/long-task-check-shape.d.ts +2 -0
- package/dist/lib/long-task-check-shape.js +136 -0
- package/dist/lib/long-task-claim-definitions.d.ts +7 -0
- package/dist/lib/long-task-claim-definitions.js +78 -0
- package/dist/lib/long-task-claim-proof-policy.d.ts +4 -0
- package/dist/lib/long-task-claim-proof-policy.js +57 -0
- package/dist/lib/long-task-claims.d.ts +10 -0
- package/dist/lib/long-task-claims.js +187 -0
- package/dist/lib/long-task-context-authority-topology.d.ts +7 -0
- package/dist/lib/long-task-context-authority-topology.js +37 -0
- package/dist/lib/long-task-context-authority.d.ts +14 -0
- package/dist/lib/long-task-context-authority.js +66 -0
- package/dist/lib/long-task-contract-types.d.ts +203 -0
- package/dist/lib/long-task-contract-types.js +1 -0
- package/dist/lib/long-task-counterfactual-claim-policy.d.ts +10 -0
- package/dist/lib/long-task-counterfactual-claim-policy.js +57 -0
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +6 -0
- package/dist/lib/long-task-counterfactual-sandbox.js +87 -0
- package/dist/lib/long-task-counterfactual-types.d.ts +24 -0
- package/dist/lib/long-task-counterfactual-types.js +1 -0
- package/dist/lib/long-task-delivery-compiler.d.ts +10 -0
- package/dist/lib/long-task-delivery-compiler.js +129 -0
- package/dist/lib/long-task-delivery-parser.d.ts +13 -0
- package/dist/lib/long-task-delivery-parser.js +90 -0
- package/dist/lib/long-task-delivery-preflight.d.ts +5 -0
- package/dist/lib/long-task-delivery-preflight.js +151 -0
- package/dist/lib/long-task-delivery-shape.d.ts +5 -0
- package/dist/lib/long-task-delivery-shape.js +5 -0
- package/dist/lib/long-task-delivery-types.d.ts +8 -0
- package/dist/lib/long-task-delivery-types.js +8 -0
- package/dist/lib/long-task-delivery-validation.d.ts +3 -0
- package/dist/lib/long-task-delivery-validation.js +175 -0
- package/dist/lib/long-task-evidence-adapter-policy.d.ts +4 -0
- package/dist/lib/long-task-evidence-adapter-policy.js +15 -0
- package/dist/lib/long-task-evidence-adapter-types.d.ts +1 -0
- package/dist/lib/long-task-evidence-adapter-types.js +1 -0
- package/dist/lib/long-task-evidence-findings.d.ts +5 -0
- package/dist/lib/long-task-evidence-findings.js +113 -0
- package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +4 -0
- package/dist/lib/long-task-evidence-sensitivity-policy.js +98 -0
- package/dist/lib/long-task-evidence-v2.d.ts +5 -0
- package/dist/lib/long-task-evidence-v2.js +226 -0
- package/dist/lib/long-task-explain-acceptance-link.d.ts +46 -0
- package/dist/lib/long-task-explain-acceptance-link.js +96 -0
- package/dist/lib/long-task-explain-claim-links.d.ts +45 -0
- package/dist/lib/long-task-explain-claim-links.js +88 -0
- package/dist/lib/long-task-explain-source-links.d.ts +93 -0
- package/dist/lib/long-task-explain-source-links.js +51 -0
- package/dist/lib/long-task-final-v2.d.ts +2 -0
- package/dist/lib/long-task-final-v2.js +124 -0
- package/dist/lib/long-task-finding-context.d.ts +3 -0
- package/dist/lib/long-task-finding-context.js +63 -0
- package/dist/lib/long-task-freshness.d.ts +3 -0
- package/dist/lib/long-task-freshness.js +80 -0
- package/dist/lib/long-task-hook-install.d.ts +9 -0
- package/dist/lib/long-task-hook-install.js +184 -0
- package/dist/lib/long-task-hook-preflight.d.ts +7 -0
- package/dist/lib/long-task-hook-preflight.js +58 -0
- package/dist/lib/long-task-observation-ownership.d.ts +2 -0
- package/dist/lib/long-task-observation-ownership.js +22 -0
- package/dist/lib/long-task-outcome-parser.d.ts +4 -0
- package/dist/lib/long-task-outcome-parser.js +100 -0
- package/dist/lib/long-task-paths.d.ts +49 -0
- package/dist/lib/long-task-paths.js +418 -0
- package/dist/lib/long-task-playwright-counterfactual-policy.d.ts +7 -0
- package/dist/lib/long-task-playwright-counterfactual-policy.js +125 -0
- package/dist/lib/long-task-playwright-evidence.d.ts +6 -0
- package/dist/lib/long-task-playwright-evidence.js +244 -0
- package/dist/lib/long-task-product-shape.d.ts +6 -0
- package/dist/lib/long-task-product-shape.js +73 -0
- package/dist/lib/long-task-progress.d.ts +4 -0
- package/dist/lib/long-task-progress.js +114 -0
- package/dist/lib/long-task-protected-files.d.ts +1 -0
- package/dist/lib/long-task-protected-files.js +30 -0
- package/dist/lib/long-task-required-proof-surfaces.d.ts +2 -0
- package/dist/lib/long-task-required-proof-surfaces.js +13 -0
- package/dist/lib/long-task-requirement-shape.d.ts +2 -0
- package/dist/lib/long-task-requirement-shape.js +18 -0
- package/dist/lib/long-task-risk-surfaces.d.ts +2 -0
- package/dist/lib/long-task-risk-surfaces.js +60 -0
- package/dist/lib/long-task-risk-types.d.ts +5 -0
- package/dist/lib/long-task-risk-types.js +12 -0
- package/dist/lib/long-task-risk.d.ts +9 -0
- package/dist/lib/long-task-risk.js +132 -0
- package/dist/lib/long-task-root-shape.d.ts +4 -0
- package/dist/lib/long-task-root-shape.js +86 -0
- package/dist/lib/long-task-runner-environment.d.ts +7 -0
- package/dist/lib/long-task-runner-environment.js +57 -0
- package/dist/lib/long-task-runner-files.d.ts +3 -0
- package/dist/lib/long-task-runner-files.js +39 -0
- package/dist/lib/long-task-runner-freeze.d.ts +2 -0
- package/dist/lib/long-task-runner-freeze.js +168 -0
- package/dist/lib/long-task-runtime-types.d.ts +214 -0
- package/dist/lib/long-task-runtime-types.js +1 -0
- package/dist/lib/long-task-shape-primitives.d.ts +17 -0
- package/dist/lib/long-task-shape-primitives.js +81 -0
- package/dist/lib/long-task-source-authority-types.d.ts +13 -0
- package/dist/lib/long-task-source-authority-types.js +1 -0
- package/dist/lib/long-task-source-claim-validation.d.ts +5 -0
- package/dist/lib/long-task-source-claim-validation.js +96 -0
- package/dist/lib/long-task-source-continuity.d.ts +4 -0
- package/dist/lib/long-task-source-continuity.js +57 -0
- package/dist/lib/long-task-source-inventory.d.ts +2 -0
- package/dist/lib/long-task-source-inventory.js +21 -0
- package/dist/lib/long-task-source-item-parser.d.ts +3 -0
- package/dist/lib/long-task-source-item-parser.js +112 -0
- package/dist/lib/long-task-source-shape.d.ts +2 -0
- package/dist/lib/long-task-source-shape.js +56 -0
- package/dist/lib/long-task-source-target-continuity.d.ts +4 -0
- package/dist/lib/long-task-source-target-continuity.js +80 -0
- package/dist/lib/long-task-source-target-index.d.ts +12 -0
- package/dist/lib/long-task-source-target-index.js +76 -0
- package/dist/lib/long-task-source-validation.d.ts +3 -0
- package/dist/lib/long-task-source-validation.js +46 -0
- package/dist/lib/long-task-state.d.ts +91 -0
- package/dist/lib/long-task-state.js +611 -0
- package/dist/lib/long-task-status-projection.d.ts +21 -0
- package/dist/lib/long-task-status-projection.js +116 -0
- package/dist/lib/long-task-status-v2.d.ts +37 -0
- package/dist/lib/long-task-status-v2.js +306 -0
- package/dist/lib/long-task-technical-shape.d.ts +3 -0
- package/dist/lib/long-task-technical-shape.js +44 -0
- package/dist/lib/long-task-verifier-authority.d.ts +12 -0
- package/dist/lib/long-task-verifier-authority.js +47 -0
- package/dist/lib/long-task-verifier-identity.d.ts +2 -0
- package/dist/lib/long-task-verifier-identity.js +55 -0
- package/dist/lib/long-task-verifier-v2.d.ts +13 -0
- package/dist/lib/long-task-verifier-v2.js +266 -0
- package/dist/lib/long-task-workspace-runtime-types.d.ts +23 -0
- package/dist/lib/long-task-workspace-runtime-types.js +1 -0
- package/dist/lib/long-task-workspace.d.ts +25 -0
- package/dist/lib/long-task-workspace.js +366 -0
- package/dist/lib/managed-file.js +20 -5
- package/dist/lib/migrations.js +156 -32
- package/dist/lib/modularity.d.ts +27 -1
- package/dist/lib/modularity.js +499 -23
- package/dist/lib/package-json-config.js +14 -5
- package/dist/lib/package-source.js +15 -3
- package/dist/lib/profiles.d.ts +13 -0
- package/dist/lib/profiles.js +66 -0
- package/dist/lib/schema-guard.js +4 -2
- package/dist/lib/source-files.js +14 -7
- package/dist/lib/source-pack-classify.js +91 -19
- package/dist/lib/source-pack-config.js +25 -8
- package/dist/lib/source-pack-export.js +84 -25
- package/dist/lib/source-pack-manifest.js +18 -6
- package/dist/lib/source-pack-records.js +35 -11
- package/dist/lib/source-pack-render.js +47 -18
- package/dist/lib/stable-json.d.ts +2 -0
- package/dist/lib/stable-json.js +21 -0
- package/dist/lib/strict-codec.d.ts +4 -0
- package/dist/lib/strict-codec.js +65 -0
- package/dist/lib/sync-engine.js +76 -24
- package/dist/lib/types.d.ts +8 -1
- package/dist/lib/upgrade.js +4 -3
- package/dist/lib/validators.js +218 -191
- package/dist/long-task-hook.d.ts +2 -0
- package/dist/long-task-hook.js +55 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +340 -0
- package/dist/schemas/long-task-delivery-v2/long-task-outcomes-v2.schema.json +18 -0
- package/migrations/README.md +8 -3
- package/package.json +17 -6
- package/source-mappings.yaml +0 -3
- package/assets/protected-harness-baseline.json +0 -20
- package/assets/skills/composite-long-task-workflow/SKILL.md +0 -244
- package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +0 -57
- package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +0 -17
- package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +0 -675
- package/dist/commands/superpowers.d.ts +0 -1
- package/dist/commands/superpowers.js +0 -8
- package/dist/lib/composite-long-task-renderer.d.ts +0 -12
- package/dist/lib/composite-long-task-renderer.js +0 -109
- package/dist/lib/plan-acceptance-artifacts.d.ts +0 -1
- package/dist/lib/plan-acceptance-artifacts.js +0 -220
- package/dist/lib/plan-acceptance-evidence.d.ts +0 -2
- package/dist/lib/plan-acceptance-evidence.js +0 -108
- package/dist/lib/plan-acceptance-json.d.ts +0 -15
- package/dist/lib/plan-acceptance-json.js +0 -133
- package/dist/lib/plan-acceptance-validator.d.ts +0 -2
- package/dist/lib/plan-acceptance-validator.js +0 -209
- package/dist/lib/plan-contract-validator.d.ts +0 -2
- package/dist/lib/plan-contract-validator.js +0 -127
- package/dist/lib/plan-validator-common.d.ts +0 -24
- package/dist/lib/plan-validator-common.js +0 -196
- package/dist/lib/superpowers-task-ac010.d.ts +0 -6
- package/dist/lib/superpowers-task-ac010.js +0 -26
- package/dist/lib/superpowers-task-assertion-normalizers.d.ts +0 -3
- package/dist/lib/superpowers-task-assertion-normalizers.js +0 -74
- package/dist/lib/superpowers-task-assertions.d.ts +0 -20
- package/dist/lib/superpowers-task-assertions.js +0 -257
- package/dist/lib/superpowers-task-attempt.d.ts +0 -4
- package/dist/lib/superpowers-task-attempt.js +0 -102
- package/dist/lib/superpowers-task-command-run-correlation.d.ts +0 -8
- package/dist/lib/superpowers-task-command-run-correlation.js +0 -103
- package/dist/lib/superpowers-task-command-specs.d.ts +0 -3
- package/dist/lib/superpowers-task-command-specs.js +0 -52
- package/dist/lib/superpowers-task-compile-diagnostics.d.ts +0 -5
- package/dist/lib/superpowers-task-compile-diagnostics.js +0 -20
- package/dist/lib/superpowers-task-compile-guards.d.ts +0 -2
- package/dist/lib/superpowers-task-compile-guards.js +0 -66
- package/dist/lib/superpowers-task-compile.d.ts +0 -6
- package/dist/lib/superpowers-task-compile.js +0 -133
- package/dist/lib/superpowers-task-completion-output.d.ts +0 -52
- package/dist/lib/superpowers-task-completion-output.js +0 -228
- package/dist/lib/superpowers-task-conformance.d.ts +0 -2
- package/dist/lib/superpowers-task-conformance.js +0 -24
- package/dist/lib/superpowers-task-contradictions.d.ts +0 -6
- package/dist/lib/superpowers-task-contradictions.js +0 -126
- package/dist/lib/superpowers-task-current-evidence.d.ts +0 -3
- package/dist/lib/superpowers-task-current-evidence.js +0 -176
- package/dist/lib/superpowers-task-delivery.d.ts +0 -4
- package/dist/lib/superpowers-task-delivery.js +0 -96
- package/dist/lib/superpowers-task-derive.d.ts +0 -14
- package/dist/lib/superpowers-task-derive.js +0 -382
- package/dist/lib/superpowers-task-events.d.ts +0 -1
- package/dist/lib/superpowers-task-events.js +0 -13
- package/dist/lib/superpowers-task-evidence-kernel.d.ts +0 -19
- package/dist/lib/superpowers-task-evidence-kernel.js +0 -347
- package/dist/lib/superpowers-task-evidence-records.d.ts +0 -2
- package/dist/lib/superpowers-task-evidence-records.js +0 -55
- package/dist/lib/superpowers-task-evidence.d.ts +0 -10
- package/dist/lib/superpowers-task-evidence.js +0 -147
- package/dist/lib/superpowers-task-fields.d.ts +0 -22
- package/dist/lib/superpowers-task-fields.js +0 -276
- package/dist/lib/superpowers-task-final-card.d.ts +0 -3
- package/dist/lib/superpowers-task-final-card.js +0 -24
- package/dist/lib/superpowers-task-gates.d.ts +0 -12
- package/dist/lib/superpowers-task-gates.js +0 -155
- package/dist/lib/superpowers-task-harness-drift.d.ts +0 -11
- package/dist/lib/superpowers-task-harness-drift.js +0 -90
- package/dist/lib/superpowers-task-next-slices.d.ts +0 -1
- package/dist/lib/superpowers-task-next-slices.js +0 -12
- package/dist/lib/superpowers-task-protected-baseline.d.ts +0 -10
- package/dist/lib/superpowers-task-protected-baseline.js +0 -66
- package/dist/lib/superpowers-task-source-compile.d.ts +0 -5
- package/dist/lib/superpowers-task-source-compile.js +0 -226
- package/dist/lib/superpowers-task-source-parser.d.ts +0 -23
- package/dist/lib/superpowers-task-source-parser.js +0 -218
- package/dist/lib/superpowers-task-state-schema.d.ts +0 -440
- package/dist/lib/superpowers-task-state-schema.js +0 -66
- package/dist/lib/superpowers-task-state-shape.d.ts +0 -3
- package/dist/lib/superpowers-task-state-shape.js +0 -50
- package/dist/lib/superpowers-task-state.d.ts +0 -16
- package/dist/lib/superpowers-task-state.js +0 -246
- package/dist/lib/superpowers-task-status.d.ts +0 -2
- package/dist/lib/superpowers-task-status.js +0 -24
- package/dist/lib/superpowers-task-under-specified.d.ts +0 -7
- package/dist/lib/superpowers-task-under-specified.js +0 -61
- package/dist/lib/superpowers-task-unregistered-evidence.d.ts +0 -11
- package/dist/lib/superpowers-task-unregistered-evidence.js +0 -72
- package/dist/lib/superpowers-task-validator.d.ts +0 -5
- package/dist/lib/superpowers-task-validator.js +0 -290
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { artifactReport, buildManifest, pruneTimestampedExports, readPackageVersion, writeArtifactSet } from "./source-pack-manifest.js";
|
|
3
|
-
import { mergePatterns, parseContextAreas, readSourcePackProfile, validatePatternList } from "./source-pack-config.js";
|
|
4
|
-
import { collectCodeRecords, collectContextArtifacts, countRedactionWarnings, repoRelative } from "./source-pack-records.js";
|
|
5
|
-
import { renderBundleArtifact, renderCodeIndexArtifact, renderFullProjectContextArtifact, renderTaskContextArtifact } from "./source-pack-render.js";
|
|
2
|
+
import { artifactReport, buildManifest, pruneTimestampedExports, readPackageVersion, writeArtifactSet, } from "./source-pack-manifest.js";
|
|
3
|
+
import { mergePatterns, parseContextAreas, readSourcePackProfile, validatePatternList, } from "./source-pack-config.js";
|
|
4
|
+
import { collectCodeRecords, collectContextArtifacts, countRedactionWarnings, repoRelative, } from "./source-pack-records.js";
|
|
5
|
+
import { renderBundleArtifact, renderCodeIndexArtifact, renderFullProjectContextArtifact, renderTaskContextArtifact, } from "./source-pack-render.js";
|
|
6
6
|
const DEFAULT_EXPORT_DIR = "tmp/ty-context/context-exports";
|
|
7
7
|
const DEFAULT_MAX_PACK_FILES = 5;
|
|
8
8
|
const DEFAULT_MAX_BUNDLE_CHARACTERS = 800_000;
|
|
@@ -18,20 +18,27 @@ export async function runSourcePackExport(projectRoot, options) {
|
|
|
18
18
|
const includeCode = mergePatterns(profile.code, validatePatternList(options.includeCode ?? [], "include code path"));
|
|
19
19
|
const includeContext = mergePatterns(profile.context, validatePatternList(options.includeContext ?? [], "include context path"));
|
|
20
20
|
const exclude = mergePatterns(profile.exclude);
|
|
21
|
-
const maxBundleCharacters = options.maxBundleCharacters ??
|
|
21
|
+
const maxBundleCharacters = options.maxBundleCharacters ??
|
|
22
|
+
profile.maxBundleCharacters ??
|
|
23
|
+
DEFAULT_MAX_BUNDLE_CHARACTERS;
|
|
22
24
|
const bundleStrategy = options.bundleStrategy ?? "auto";
|
|
23
25
|
const records = await collectCodeRecords(projectRoot, warnings, {
|
|
24
26
|
include: includeCode.length > 0 ? includeCode : undefined,
|
|
25
27
|
exclude,
|
|
26
|
-
areas
|
|
28
|
+
areas,
|
|
27
29
|
});
|
|
28
|
-
const contexts = await collectContextArtifacts(projectRoot, warnings, options.mode === "task-context" && includeContext.length > 0
|
|
30
|
+
const contexts = await collectContextArtifacts(projectRoot, warnings, options.mode === "task-context" && includeContext.length > 0
|
|
31
|
+
? includeContext
|
|
32
|
+
: undefined);
|
|
29
33
|
const taskName = options.taskName ?? "";
|
|
30
34
|
const command = options.command ?? commandFor(options);
|
|
31
35
|
const toolVersion = await readPackageVersion();
|
|
32
36
|
const recommendedUploadSets = uploadSets(options.mode, taskName);
|
|
33
37
|
const artifacts = [];
|
|
34
|
-
if (options.mode === "code-index" ||
|
|
38
|
+
if (options.mode === "code-index" ||
|
|
39
|
+
options.mode === "source-pack" ||
|
|
40
|
+
options.mode === "code-bundles" ||
|
|
41
|
+
options.mode === "task-context") {
|
|
35
42
|
assignBundles(records, maxBundleCharacters, bundleStrategy);
|
|
36
43
|
artifacts.push(markdownArtifact("code-index", "code-index.md", renderCodeIndexArtifact(records, areas, warnings, meta(generatedAt, "code-index.md", command, toolVersion)), records.length, sumLines(records), warnings.length));
|
|
37
44
|
}
|
|
@@ -52,10 +59,13 @@ export async function runSourcePackExport(projectRoot, options) {
|
|
|
52
59
|
generatedAt,
|
|
53
60
|
command,
|
|
54
61
|
maxPackFiles,
|
|
55
|
-
artifacts: nonManifestArtifacts.map((artifact) => ({
|
|
62
|
+
artifacts: nonManifestArtifacts.map((artifact) => ({
|
|
63
|
+
...artifact,
|
|
64
|
+
relativePath: `${DEFAULT_EXPORT_DIR}/latest/${artifact.name}`,
|
|
65
|
+
})),
|
|
56
66
|
warnings,
|
|
57
67
|
omitted,
|
|
58
|
-
recommendedUploadSets
|
|
68
|
+
recommendedUploadSets,
|
|
59
69
|
});
|
|
60
70
|
artifacts.unshift({
|
|
61
71
|
kind: "manifest",
|
|
@@ -64,7 +74,7 @@ export async function runSourcePackExport(projectRoot, options) {
|
|
|
64
74
|
content: manifest,
|
|
65
75
|
sourceCount: 0,
|
|
66
76
|
sourceLineCount: 0,
|
|
67
|
-
warningCount: warnings.length
|
|
77
|
+
warningCount: warnings.length,
|
|
68
78
|
});
|
|
69
79
|
for (const artifact of artifacts) {
|
|
70
80
|
if (!artifact.relativePath) {
|
|
@@ -95,7 +105,7 @@ export async function runSourcePackExport(projectRoot, options) {
|
|
|
95
105
|
warnings,
|
|
96
106
|
omitted,
|
|
97
107
|
recommendedUploadSets,
|
|
98
|
-
wrote: !options.check
|
|
108
|
+
wrote: !options.check,
|
|
99
109
|
};
|
|
100
110
|
}
|
|
101
111
|
function addDefaultBundles(artifacts, records, contexts, maxPackFiles, warnings, generatedAt, command, toolVersion) {
|
|
@@ -160,12 +170,18 @@ function assignTaskBundles(records, maxCharacters) {
|
|
|
160
170
|
function sortedRecords(records, bundleStrategy) {
|
|
161
171
|
return [...records].sort((left, right) => {
|
|
162
172
|
if (bundleStrategy === "area" || bundleStrategy === "config") {
|
|
163
|
-
return left.bucket.localeCompare(right.bucket) ||
|
|
173
|
+
return (left.bucket.localeCompare(right.bucket) ||
|
|
174
|
+
right.score - left.score ||
|
|
175
|
+
left.relative.localeCompare(right.relative));
|
|
164
176
|
}
|
|
165
177
|
if (bundleStrategy === "topdir") {
|
|
166
|
-
return topDir(left).localeCompare(topDir(right)) ||
|
|
178
|
+
return (topDir(left).localeCompare(topDir(right)) ||
|
|
179
|
+
right.score - left.score ||
|
|
180
|
+
left.relative.localeCompare(right.relative));
|
|
167
181
|
}
|
|
168
|
-
return right.score - left.score ||
|
|
182
|
+
return (right.score - left.score ||
|
|
183
|
+
left.bucket.localeCompare(right.bucket) ||
|
|
184
|
+
left.relative.localeCompare(right.relative));
|
|
169
185
|
});
|
|
170
186
|
}
|
|
171
187
|
function topDir(record) {
|
|
@@ -173,23 +189,55 @@ function topDir(record) {
|
|
|
173
189
|
}
|
|
174
190
|
function omittedSummary(records) {
|
|
175
191
|
const omitted = records.filter((record) => record.bundle === "omitted");
|
|
176
|
-
return {
|
|
192
|
+
return {
|
|
193
|
+
source_file_count: omitted.length,
|
|
194
|
+
reason_counts: omitted.length > 0 ? { bundle_budget: omitted.length } : {},
|
|
195
|
+
};
|
|
177
196
|
}
|
|
178
197
|
function markdownArtifact(kind, name, content, sourceCount, sourceLineCount, warningCount) {
|
|
179
|
-
return {
|
|
198
|
+
return {
|
|
199
|
+
kind,
|
|
200
|
+
name,
|
|
201
|
+
relativePath: "",
|
|
202
|
+
content,
|
|
203
|
+
sourceCount,
|
|
204
|
+
sourceLineCount,
|
|
205
|
+
warningCount,
|
|
206
|
+
};
|
|
180
207
|
}
|
|
181
208
|
function meta(generatedAt, artifactName, command, toolVersion) {
|
|
182
|
-
return {
|
|
209
|
+
return {
|
|
210
|
+
generatedAt,
|
|
211
|
+
outputPath: `tmp/ty-context/context-exports/latest/${artifactName}`,
|
|
212
|
+
command,
|
|
213
|
+
toolVersion,
|
|
214
|
+
};
|
|
183
215
|
}
|
|
184
216
|
function uploadSets(mode, taskName) {
|
|
185
217
|
const base = `${DEFAULT_EXPORT_DIR}/latest`;
|
|
186
218
|
const sets = {
|
|
187
|
-
daily_planning: [
|
|
188
|
-
|
|
189
|
-
|
|
219
|
+
daily_planning: [
|
|
220
|
+
`${base}/full-project-context.md`,
|
|
221
|
+
`${base}/code-index.md`,
|
|
222
|
+
],
|
|
223
|
+
cross_module_review: [
|
|
224
|
+
`${base}/full-project-context.md`,
|
|
225
|
+
`${base}/code-index.md`,
|
|
226
|
+
`${base}/code-bundle-core.md`,
|
|
227
|
+
`${base}/code-bundle-extended.md`,
|
|
228
|
+
],
|
|
229
|
+
full_fallback: [
|
|
230
|
+
`${base}/full-project-context.md`,
|
|
231
|
+
`${base}/code-index.md`,
|
|
232
|
+
`${DEFAULT_EXPORT_DIR}/code-level-implementation-<timestamp>/code-level-implementation.md`,
|
|
233
|
+
],
|
|
190
234
|
};
|
|
191
235
|
if (mode === "task-context") {
|
|
192
|
-
sets.focused_task_handoff = [
|
|
236
|
+
sets.focused_task_handoff = [
|
|
237
|
+
`${base}/full-project-context.md`,
|
|
238
|
+
`${base}/code-index.md`,
|
|
239
|
+
`${base}/task-contexts/task-context-${taskSlug(taskName)}.md`,
|
|
240
|
+
];
|
|
193
241
|
}
|
|
194
242
|
return sets;
|
|
195
243
|
}
|
|
@@ -200,17 +248,28 @@ function validateMaxPackFiles(mode, maxPackFiles) {
|
|
|
200
248
|
if (maxPackFiles > DEFAULT_MAX_PACK_FILES) {
|
|
201
249
|
throw new Error("export-context --max-pack-files cannot exceed 5 for Source Pack modes");
|
|
202
250
|
}
|
|
203
|
-
const required = mode === "code-index"
|
|
251
|
+
const required = mode === "code-index"
|
|
252
|
+
? 2
|
|
253
|
+
: mode === "task-context"
|
|
254
|
+
? 4
|
|
255
|
+
: mode === "code-bundles"
|
|
256
|
+
? 3
|
|
257
|
+
: 3;
|
|
204
258
|
if (maxPackFiles < required) {
|
|
205
259
|
throw new Error(`export-context ${mode} requires --max-pack-files >= ${required}`);
|
|
206
260
|
}
|
|
207
261
|
}
|
|
208
262
|
function commandFor(options) {
|
|
209
|
-
const flag = options.mode === "task-context"
|
|
263
|
+
const flag = options.mode === "task-context"
|
|
264
|
+
? `--task-context ${options.taskName ?? ""}`
|
|
265
|
+
: `--${options.mode}`;
|
|
210
266
|
return `ty-context export-context ${flag}`;
|
|
211
267
|
}
|
|
212
268
|
function taskSlug(value) {
|
|
213
|
-
return value
|
|
269
|
+
return (value
|
|
270
|
+
.toLowerCase()
|
|
271
|
+
.replace(/[^a-z0-9._-]+/g, "-")
|
|
272
|
+
.replace(/^-+|-+$/g, "") || "task");
|
|
214
273
|
}
|
|
215
274
|
function sumLines(records) {
|
|
216
275
|
return records.reduce((sum, record) => sum + record.lines, 0);
|
|
@@ -19,7 +19,7 @@ export async function buildManifest(params) {
|
|
|
19
19
|
artifacts: params.artifacts.map((artifact) => artifactReport(artifact)),
|
|
20
20
|
warnings: params.warnings,
|
|
21
21
|
omitted: params.omitted,
|
|
22
|
-
recommended_upload_sets: params.recommendedUploadSets
|
|
22
|
+
recommended_upload_sets: params.recommendedUploadSets,
|
|
23
23
|
};
|
|
24
24
|
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
25
25
|
}
|
|
@@ -32,7 +32,7 @@ export function artifactReport(artifact) {
|
|
|
32
32
|
characters: artifact.content.length,
|
|
33
33
|
source_count: artifact.sourceCount,
|
|
34
34
|
source_line_count: artifact.sourceLineCount,
|
|
35
|
-
warning_count: artifact.warningCount
|
|
35
|
+
warning_count: artifact.warningCount,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
export async function writeArtifactSet(projectRoot, outputDir, artifacts) {
|
|
@@ -55,13 +55,22 @@ export async function pruneTimestampedExports(projectRoot, keepCount) {
|
|
|
55
55
|
catch {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
const timestampDirs = entries
|
|
58
|
+
const timestampDirs = entries
|
|
59
|
+
.filter((entry) => /^\d{8}T\d{6}Z$/.test(entry))
|
|
60
|
+
.sort()
|
|
61
|
+
.reverse();
|
|
59
62
|
for (const entry of timestampDirs.slice(keepCount)) {
|
|
60
|
-
await fs.rm(path.join(exportsRoot, entry), {
|
|
63
|
+
await fs.rm(path.join(exportsRoot, entry), {
|
|
64
|
+
recursive: true,
|
|
65
|
+
force: true,
|
|
66
|
+
});
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
export function timestampForFile(now) {
|
|
64
|
-
return now
|
|
70
|
+
return now
|
|
71
|
+
.toISOString()
|
|
72
|
+
.replace(/[-:]/g, "")
|
|
73
|
+
.replace(/\.\d{3}Z$/, "Z");
|
|
65
74
|
}
|
|
66
75
|
async function writeArtifacts(projectRoot, outputDir, artifacts) {
|
|
67
76
|
for (const artifact of artifacts) {
|
|
@@ -78,7 +87,10 @@ async function gitInfo(projectRoot) {
|
|
|
78
87
|
try {
|
|
79
88
|
const shaResult = await execFileAsync("git", ["-C", projectRoot, "rev-parse", "HEAD"], { encoding: "utf8" });
|
|
80
89
|
const dirtyResult = await execFileAsync("git", ["-C", projectRoot, "status", "--porcelain"], { encoding: "utf8" });
|
|
81
|
-
return {
|
|
90
|
+
return {
|
|
91
|
+
sha: shaResult.stdout.trim() || null,
|
|
92
|
+
dirty: dirtyResult.stdout.trim().length > 0,
|
|
93
|
+
};
|
|
82
94
|
}
|
|
83
95
|
catch {
|
|
84
96
|
return { sha: null, dirty: false };
|
|
@@ -4,7 +4,7 @@ import { promises as fs } from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
import { listFiles, pathExists, readText } from "./fs.js";
|
|
7
|
-
import { shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix } from "./source-files.js";
|
|
7
|
+
import { shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix, } from "./source-files.js";
|
|
8
8
|
import { classifyCodeFile } from "./source-pack-classify.js";
|
|
9
9
|
import { matchesAny } from "./source-pack-config.js";
|
|
10
10
|
const execFileAsync = promisify(execFile);
|
|
@@ -16,10 +16,13 @@ export async function collectCodeRecords(projectRoot, warnings, options = {}) {
|
|
|
16
16
|
const records = [];
|
|
17
17
|
for (const file of candidates) {
|
|
18
18
|
const relative = repoRelative(projectRoot, file);
|
|
19
|
-
if (!shouldIncludeCodeFile(relative) ||
|
|
19
|
+
if (!shouldIncludeCodeFile(relative) ||
|
|
20
|
+
matchesAny(relative, options.exclude ?? [])) {
|
|
20
21
|
continue;
|
|
21
22
|
}
|
|
22
|
-
if (options.include &&
|
|
23
|
+
if (options.include &&
|
|
24
|
+
options.include.length > 0 &&
|
|
25
|
+
!matchesAny(relative, options.include)) {
|
|
23
26
|
continue;
|
|
24
27
|
}
|
|
25
28
|
if (!(await isRegularFile(file))) {
|
|
@@ -44,26 +47,36 @@ export async function collectCodeRecords(projectRoot, warnings, options = {}) {
|
|
|
44
47
|
routes: classification.routes,
|
|
45
48
|
score: classification.score,
|
|
46
49
|
bucket: classification.bucket,
|
|
47
|
-
bundle: "omitted"
|
|
50
|
+
bundle: "omitted",
|
|
48
51
|
});
|
|
49
52
|
}
|
|
50
53
|
return records.sort((left, right) => left.relative.localeCompare(right.relative));
|
|
51
54
|
}
|
|
52
55
|
export async function collectContextArtifacts(projectRoot, warnings, includePatterns) {
|
|
53
56
|
const files = new Set();
|
|
54
|
-
for (const relative of [
|
|
57
|
+
for (const relative of [
|
|
58
|
+
"AGENTS.md",
|
|
59
|
+
"README.md",
|
|
60
|
+
"DESIGN.md",
|
|
61
|
+
"project_context/global.md",
|
|
62
|
+
"project_context/architecture.md",
|
|
63
|
+
"project_context/context.toml",
|
|
64
|
+
]) {
|
|
55
65
|
await addIfExists(projectRoot, files, warnings, relative, relative.startsWith("project_context/"));
|
|
56
66
|
}
|
|
57
67
|
for (const file of await listFiles(path.join(projectRoot, "project_context"))) {
|
|
58
68
|
const relative = repoRelative(projectRoot, file);
|
|
59
|
-
if ((relative.endsWith(".md") || relative.endsWith(".toml")) &&
|
|
69
|
+
if ((relative.endsWith(".md") || relative.endsWith(".toml")) &&
|
|
70
|
+
!shouldExcludeRelativePath(relative)) {
|
|
60
71
|
files.add(file);
|
|
61
72
|
}
|
|
62
73
|
}
|
|
63
74
|
const artifacts = [];
|
|
64
75
|
for (const file of [...files].sort((a, b) => repoRelative(projectRoot, a).localeCompare(repoRelative(projectRoot, b)))) {
|
|
65
76
|
const relative = repoRelative(projectRoot, file);
|
|
66
|
-
if (includePatterns &&
|
|
77
|
+
if (includePatterns &&
|
|
78
|
+
includePatterns.length > 0 &&
|
|
79
|
+
!matchesAny(relative, includePatterns)) {
|
|
67
80
|
continue;
|
|
68
81
|
}
|
|
69
82
|
const rawContent = await readText(file);
|
|
@@ -75,7 +88,7 @@ export async function collectContextArtifacts(projectRoot, warnings, includePatt
|
|
|
75
88
|
relative,
|
|
76
89
|
content: redacted.content,
|
|
77
90
|
lines: countLines(redacted.content),
|
|
78
|
-
characters: redacted.content.length
|
|
91
|
+
characters: redacted.content.length,
|
|
79
92
|
});
|
|
80
93
|
}
|
|
81
94
|
return artifacts;
|
|
@@ -103,11 +116,22 @@ async function addIfExists(projectRoot, files, warnings, relative, required) {
|
|
|
103
116
|
}
|
|
104
117
|
async function listGitCandidateFiles(projectRoot) {
|
|
105
118
|
try {
|
|
106
|
-
const result = await execFileAsync("git", [
|
|
119
|
+
const result = await execFileAsync("git", [
|
|
120
|
+
"-C",
|
|
121
|
+
projectRoot,
|
|
122
|
+
"ls-files",
|
|
123
|
+
"--cached",
|
|
124
|
+
"--others",
|
|
125
|
+
"--exclude-standard",
|
|
126
|
+
"-z",
|
|
127
|
+
], {
|
|
107
128
|
encoding: "utf8",
|
|
108
|
-
maxBuffer: GIT_LS_MAX_BUFFER
|
|
129
|
+
maxBuffer: GIT_LS_MAX_BUFFER,
|
|
109
130
|
});
|
|
110
|
-
return result.stdout
|
|
131
|
+
return result.stdout
|
|
132
|
+
.split("\0")
|
|
133
|
+
.filter(Boolean)
|
|
134
|
+
.map((relative) => path.join(projectRoot, ...toPosix(relative).split("/")));
|
|
111
135
|
}
|
|
112
136
|
catch {
|
|
113
137
|
return undefined;
|
|
@@ -22,7 +22,7 @@ export function renderFullProjectContextArtifact(contexts, warnings, meta) {
|
|
|
22
22
|
"## Context Sources",
|
|
23
23
|
"",
|
|
24
24
|
...contexts.map(renderContextArtifact),
|
|
25
|
-
""
|
|
25
|
+
"",
|
|
26
26
|
].join("\n");
|
|
27
27
|
}
|
|
28
28
|
export function renderCodeIndexArtifact(records, areas, warnings, meta) {
|
|
@@ -52,7 +52,11 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
|
|
|
52
52
|
"## Context Area Mapping",
|
|
53
53
|
"",
|
|
54
54
|
"Inferred buckets below are export routing only; they are not durable architecture or product ownership facts.",
|
|
55
|
-
areas.length > 0
|
|
55
|
+
areas.length > 0
|
|
56
|
+
? areas
|
|
57
|
+
.map((area) => `- ${area.id}: root=${area.root}; context=${area.context}`)
|
|
58
|
+
.join("\n")
|
|
59
|
+
: "- No Context area mappings found.",
|
|
56
60
|
"",
|
|
57
61
|
"## Key Entry Points",
|
|
58
62
|
"",
|
|
@@ -68,7 +72,9 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
|
|
|
68
72
|
"",
|
|
69
73
|
"## CLI / Worker / Script Index",
|
|
70
74
|
"",
|
|
71
|
-
renderRecordList(records
|
|
75
|
+
renderRecordList(records
|
|
76
|
+
.filter((record) => record.tags.includes("cli") || record.tags.includes("worker"))
|
|
77
|
+
.slice(0, 30)),
|
|
72
78
|
"",
|
|
73
79
|
"## Test / Verification Index",
|
|
74
80
|
"",
|
|
@@ -76,12 +82,14 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
|
|
|
76
82
|
"",
|
|
77
83
|
"## Oversized Files",
|
|
78
84
|
"",
|
|
79
|
-
renderRecordList(records
|
|
85
|
+
renderRecordList(records
|
|
86
|
+
.filter((record) => record.tags.includes("oversized"))
|
|
87
|
+
.slice(0, 30)),
|
|
80
88
|
"",
|
|
81
89
|
"## Source File Index",
|
|
82
90
|
"",
|
|
83
91
|
renderSourceFileIndex(records),
|
|
84
|
-
""
|
|
92
|
+
"",
|
|
85
93
|
].join("\n");
|
|
86
94
|
}
|
|
87
95
|
export function renderBundleArtifact(title, records, contexts, omitted, warnings, meta, policy) {
|
|
@@ -109,16 +117,21 @@ export function renderBundleArtifact(title, records, contexts, omitted, warnings
|
|
|
109
117
|
"",
|
|
110
118
|
"## Related Context Paths",
|
|
111
119
|
"",
|
|
112
|
-
contexts.length > 0
|
|
120
|
+
contexts.length > 0
|
|
121
|
+
? contexts
|
|
122
|
+
.map((context) => `- ${context.relative} (${context.lines} lines)`)
|
|
123
|
+
.join("\n")
|
|
124
|
+
: "- No related Context files selected.",
|
|
113
125
|
"",
|
|
114
126
|
"## Source Files",
|
|
115
127
|
"",
|
|
116
|
-
records.map(renderSourceRecord).join("\n\n") ||
|
|
128
|
+
records.map(renderSourceRecord).join("\n\n") ||
|
|
129
|
+
"- No source files selected for this bundle.",
|
|
117
130
|
"",
|
|
118
131
|
"## Omitted Files Summary",
|
|
119
132
|
"",
|
|
120
133
|
renderOmittedSummary(omitted),
|
|
121
|
-
""
|
|
134
|
+
"",
|
|
122
135
|
].join("\n");
|
|
123
136
|
}
|
|
124
137
|
export function renderTaskContextArtifact(taskName, contexts, records, verification, omitted, warnings, meta) {
|
|
@@ -150,21 +163,31 @@ export function renderTaskContextArtifact(taskName, contexts, records, verificat
|
|
|
150
163
|
"",
|
|
151
164
|
"## Selected Source Files",
|
|
152
165
|
"",
|
|
153
|
-
records.map(renderSourceRecord).join("\n\n") ||
|
|
166
|
+
records.map(renderSourceRecord).join("\n\n") ||
|
|
167
|
+
"- No selected source files matched the task filters.",
|
|
154
168
|
"",
|
|
155
169
|
"## Verification Entry Points",
|
|
156
170
|
"",
|
|
157
|
-
verification.length > 0
|
|
171
|
+
verification.length > 0
|
|
172
|
+
? verification.map((entry) => `- ${entry}`).join("\n")
|
|
173
|
+
: "- No profile verification entries selected.",
|
|
158
174
|
"",
|
|
159
175
|
"## Omitted / Support Notes",
|
|
160
176
|
"",
|
|
161
177
|
renderOmittedSummary(omitted),
|
|
162
|
-
""
|
|
178
|
+
"",
|
|
163
179
|
].join("\n");
|
|
164
180
|
}
|
|
165
181
|
function renderContextArtifact(context) {
|
|
166
182
|
const fence = fenceFor(context.content);
|
|
167
|
-
return [
|
|
183
|
+
return [
|
|
184
|
+
`### ${context.relative}`,
|
|
185
|
+
"",
|
|
186
|
+
`${fence}markdown`,
|
|
187
|
+
context.content.trimEnd(),
|
|
188
|
+
fence,
|
|
189
|
+
"",
|
|
190
|
+
].join("\n");
|
|
168
191
|
}
|
|
169
192
|
function renderSourceRecord(record) {
|
|
170
193
|
const fence = fenceFor(record.content);
|
|
@@ -183,7 +206,7 @@ function renderSourceRecord(record) {
|
|
|
183
206
|
"",
|
|
184
207
|
`${fence}${record.language}`,
|
|
185
208
|
record.content.trimEnd(),
|
|
186
|
-
fence
|
|
209
|
+
fence,
|
|
187
210
|
].join("\n");
|
|
188
211
|
}
|
|
189
212
|
function renderSourceFileIndex(records) {
|
|
@@ -193,7 +216,7 @@ function renderSourceFileIndex(records) {
|
|
|
193
216
|
return [
|
|
194
217
|
"| Path | Type | Lines | Characters | SHA256 | Summary | Bundle | Tags |",
|
|
195
218
|
"|---|---:|---:|---:|---|---|---|---|",
|
|
196
|
-
...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} | ${record.bundle} | ${escapeTableCell(record.tags.join(", "))} |`)
|
|
219
|
+
...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} | ${record.bundle} | ${escapeTableCell(record.tags.join(", "))} |`),
|
|
197
220
|
].join("\n");
|
|
198
221
|
}
|
|
199
222
|
function renderRepositoryShape(records) {
|
|
@@ -202,10 +225,10 @@ function renderRepositoryShape(records) {
|
|
|
202
225
|
const top = record.relative.split("/")[0] || ".";
|
|
203
226
|
counts.set(top, (counts.get(top) ?? 0) + 1);
|
|
204
227
|
}
|
|
205
|
-
return [...counts.entries()]
|
|
228
|
+
return ([...counts.entries()]
|
|
206
229
|
.sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]))
|
|
207
230
|
.map(([name, count]) => `- ${name}: ${count} source file(s)`)
|
|
208
|
-
.join("\n") || "- No source files matched.";
|
|
231
|
+
.join("\n") || "- No source files matched.");
|
|
209
232
|
}
|
|
210
233
|
function renderRecordList(records, includeRoutes = false) {
|
|
211
234
|
if (records.length === 0) {
|
|
@@ -216,13 +239,19 @@ function renderRecordList(records, includeRoutes = false) {
|
|
|
216
239
|
.join("\n");
|
|
217
240
|
}
|
|
218
241
|
function renderWarningList(warnings) {
|
|
219
|
-
return warnings.length > 0
|
|
242
|
+
return warnings.length > 0
|
|
243
|
+
? warnings.map((warning) => ` - ${warning}`)
|
|
244
|
+
: [" - none"];
|
|
220
245
|
}
|
|
221
246
|
function renderOmittedSummary(omitted) {
|
|
222
247
|
const reasons = Object.entries(omitted.reason_counts)
|
|
223
248
|
.sort((left, right) => left[0].localeCompare(right[0]))
|
|
224
249
|
.map(([reason, count]) => ` - ${reason}: ${count}`);
|
|
225
|
-
return [
|
|
250
|
+
return [
|
|
251
|
+
`- omitted_source_file_count: ${omitted.source_file_count}`,
|
|
252
|
+
"- reason_counts:",
|
|
253
|
+
...(reasons.length > 0 ? reasons : [" - none: 0"]),
|
|
254
|
+
].join("\n");
|
|
226
255
|
}
|
|
227
256
|
function fenceFor(content) {
|
|
228
257
|
let fence = "```";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export function stableJson(value) {
|
|
3
|
+
return JSON.stringify(sortJson(value), null, 2);
|
|
4
|
+
}
|
|
5
|
+
export function sha256(value) {
|
|
6
|
+
return createHash("sha256").update(value).digest("hex");
|
|
7
|
+
}
|
|
8
|
+
function sortJson(value) {
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return value.map(sortJson);
|
|
11
|
+
}
|
|
12
|
+
if (!isRecord(value)) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
return Object.fromEntries(Object.keys(value)
|
|
16
|
+
.sort()
|
|
17
|
+
.map((key) => [key, sortJson(value[key])]));
|
|
18
|
+
}
|
|
19
|
+
function isRecord(value) {
|
|
20
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
21
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function canonicalJson(value: unknown): string;
|
|
2
|
+
export declare function canonicalValueJson(value: unknown): string;
|
|
3
|
+
export declare function sha256Hex(value: string | Uint8Array): string;
|
|
4
|
+
export declare function parseStrictYaml(content: string): unknown;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import YAML, { isAlias, isMap, isPair, isScalar, isSeq, visit, } from "yaml";
|
|
3
|
+
export function canonicalJson(value) {
|
|
4
|
+
return `${JSON.stringify(sortCanonical(value), null, 2)}\n`;
|
|
5
|
+
}
|
|
6
|
+
export function canonicalValueJson(value) {
|
|
7
|
+
return JSON.stringify(sortCanonical(value));
|
|
8
|
+
}
|
|
9
|
+
export function sha256Hex(value) {
|
|
10
|
+
return createHash("sha256").update(value).digest("hex");
|
|
11
|
+
}
|
|
12
|
+
export function parseStrictYaml(content) {
|
|
13
|
+
if (content.charCodeAt(0) === 0xfeff)
|
|
14
|
+
throw new Error("YAML byte-order marks are not allowed");
|
|
15
|
+
if (/^%(?:YAML|TAG)\b/m.test(content))
|
|
16
|
+
throw new Error("YAML directives are not allowed");
|
|
17
|
+
const documents = YAML.parseAllDocuments(content, {
|
|
18
|
+
merge: false,
|
|
19
|
+
schema: "core",
|
|
20
|
+
strict: true,
|
|
21
|
+
stringKeys: true,
|
|
22
|
+
uniqueKeys: true,
|
|
23
|
+
});
|
|
24
|
+
const document = assertSingleDocument(documents);
|
|
25
|
+
if (document.directives.yaml.explicit ||
|
|
26
|
+
Object.keys(document.directives.tags).some((handle) => handle !== "!!"))
|
|
27
|
+
throw new Error("YAML directives are not allowed");
|
|
28
|
+
visit(document, (_key, node) => inspectNode(node));
|
|
29
|
+
return document.toJS({ maxAliasCount: 0 });
|
|
30
|
+
}
|
|
31
|
+
function assertSingleDocument(documents) {
|
|
32
|
+
if (documents.length !== 1)
|
|
33
|
+
throw new Error("YAML must contain exactly one document");
|
|
34
|
+
const document = documents[0];
|
|
35
|
+
const issue = document.errors[0] ?? document.warnings[0];
|
|
36
|
+
if (issue)
|
|
37
|
+
throw new Error(`Invalid YAML: ${issue.message}`);
|
|
38
|
+
return document;
|
|
39
|
+
}
|
|
40
|
+
function inspectNode(node) {
|
|
41
|
+
if (isAlias(node))
|
|
42
|
+
throw new Error("YAML aliases are not allowed");
|
|
43
|
+
const tagged = node;
|
|
44
|
+
if (tagged.anchor)
|
|
45
|
+
throw new Error("YAML anchors are not allowed");
|
|
46
|
+
if (tagged.tag)
|
|
47
|
+
throw new Error("YAML explicit tags are not allowed");
|
|
48
|
+
if (isPair(node) && isScalar(node.key) && node.key.value === "<<")
|
|
49
|
+
throw new Error("YAML merge keys are not allowed");
|
|
50
|
+
if (isMap(node) || isSeq(node) || isScalar(node) || isPair(node))
|
|
51
|
+
return;
|
|
52
|
+
throw new Error("Unsupported YAML node");
|
|
53
|
+
}
|
|
54
|
+
function sortCanonical(value) {
|
|
55
|
+
if (Array.isArray(value))
|
|
56
|
+
return value.map(sortCanonical);
|
|
57
|
+
if (value && typeof value === "object")
|
|
58
|
+
return Object.fromEntries(Object.keys(value)
|
|
59
|
+
.sort()
|
|
60
|
+
.map((key) => [
|
|
61
|
+
key,
|
|
62
|
+
sortCanonical(value[key]),
|
|
63
|
+
]));
|
|
64
|
+
return value;
|
|
65
|
+
}
|