@event4u/agent-config 16.2.0 → 16.3.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +89 -237
- package/README.md +14 -12
- package/dist/agent-src/commands/analyze/inbox.md +1 -1
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/feature/plan.md +1 -1
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +1 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/process-full.md +4 -4
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
- package/dist/agent-src/rules/active-remediation.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -0
- package/dist/agent-src/rules/broken-access-control.md +1 -0
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
- package/dist/agent-src/rules/context-hygiene.md +1 -1
- package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
- package/dist/agent-src/rules/design-fidelity.md +13 -16
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
- package/dist/agent-src/rules/domain-safety-pii.md +1 -0
- package/dist/agent-src/rules/domain-safety-retention.md +1 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
- package/dist/agent-src/rules/finance-safety-floor.md +1 -0
- package/dist/agent-src/rules/git-history-discipline.md +1 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
- package/dist/agent-src/rules/legal-safety-floor.md +3 -2
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/media-governance-routing.md +14 -17
- package/dist/agent-src/rules/persona-governance.md +2 -2
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
- package/dist/agent-src/rules/question-not-instruction.md +1 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
- package/dist/agent-src/rules/session-canary.md +8 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
- package/dist/agent-src/rules/source-confidentiality.md +1 -0
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
- package/dist/agent-src/rules/tool-safety.md +1 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +12 -1
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-JQVYKIZA.js} +10 -0
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
- package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-NQ7WT43P.js} +1186 -244
- package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
- package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
- package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-RQNNW7IF.js} +1314 -560
- package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-S4UMZNES.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
- package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-TRI6DQZ6.js} +2781 -340
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +1167 -234
- package/dist/cli-delegate/cmd_doctor.js +13 -6
- package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
- package/dist/cli-delegate/cmd_explain.js +5 -5
- package/dist/cli-delegate/cmd_export.js +11 -8
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +10 -7
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +11 -8
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +8 -6
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +4 -3
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +11 -8
- package/dist/cli-delegate/cmd_uninstall.js +11 -8
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +11 -8
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_execute.js +2 -2
- package/dist/cli-delegate/roadmap_gates.js +5 -5
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +127 -75
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +5357 -6656
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2080 -1024
- package/dist/install/installThinLayer.js +261 -0
- package/dist/install/installedRuleLinks.js +176 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +31965 -27154
- package/dist/scripts/_lib/agent_settings.js +11 -0
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/installed_layer.js +378 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/thin_rules.js +458 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/schemas/settings.js +6 -0
- package/dist/shared/skillRanking.js +74 -13
- package/docs/contracts/settings-classes.md +7 -5
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/config/agent-settings.template.yml +62 -22
- package/src/config/continuity-surface.json +7 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +96 -3
- package/src/config/gate-violation-baselines.json +17 -9
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-token-budget.json +6 -1
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/routing-coverage-seed.json +24 -3
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +99 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +312 -0
- package/src/install/installedRuleLinks.ts +220 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_doctor.ts +23 -71
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
- package/src/scripts/_dispatch.bash +16 -2
- package/src/scripts/_lib/agent_settings.ts +11 -0
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
- package/src/scripts/_lib/graph_feeder_record.ts +214 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +538 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/thin_rules.ts +540 -0
- package/src/scripts/_lib/touched_file_quality.ts +434 -0
- package/src/scripts/_lib/turn_end_refusals.ts +77 -2
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +1 -1
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/before_complete_hook.ts +243 -12
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/check_enforcement_matrix.ts +377 -20
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_finding_dispositions.ts +116 -4
- package/src/scripts/check_hook_bundle_composition.ts +370 -0
- package/src/scripts/check_kernel_edit_ratified.ts +49 -11
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_standing_rule_delivery.ts +33 -13
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/compile_hook_manifest.ts +33 -1
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/generate_host_cost_table.ts +1 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +150 -9
- package/src/scripts/hooks/block_config_weakening.ts +67 -2
- package/src/scripts/hooks/block_plumbing_writes.ts +29 -1
- package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/dispatch_hook.ts +52 -52
- package/src/scripts/hooks/exit_codes.ts +2 -1
- package/src/scripts/hooks/host_lowering.json +1 -1
- package/src/scripts/hooks/host_lowering.ts +19 -1
- package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/rule_inject_hook.ts +757 -63
- package/src/scripts/hooks/table_fingerprint.ts +21 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +64 -8
- package/src/scripts/hooks/turn_end_gate_hook.ts +84 -0
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install.ts +72 -185
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_hook_manifest.ts +53 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +63 -5
- package/src/scripts/lint_rule_law_section.ts +517 -0
- package/src/scripts/lint_workflow_security.ts +161 -5
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +216 -8
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/model_rule_injection.ts +52 -5
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +157 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_obligation_mechanism.ts +230 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_ranker_confusion.ts +442 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/review-findings.schema.json +3 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/self_review_gate.ts +62 -7
- package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/trigger_eval_grandfather.json +0 -5
- package/src/server/schemas/settings.ts +10 -0
- package/src/shared/skillRanking.ts +117 -11
- package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
readRecentEntries
|
|
4
|
+
} from "./chunk-NYX3L2PZ.js";
|
|
2
5
|
import {
|
|
3
6
|
NO_RED_EVIDENCE_REASON,
|
|
4
7
|
deriveSessionKey,
|
|
@@ -17,17 +20,24 @@ import {
|
|
|
17
20
|
readTurnRunState,
|
|
18
21
|
sessionRefusalFile,
|
|
19
22
|
sessionShadowFile,
|
|
23
|
+
shadowSetBy,
|
|
20
24
|
statePathFor,
|
|
21
25
|
validateAssumption
|
|
22
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-NQ7WT43P.js";
|
|
23
27
|
import {
|
|
24
28
|
readHookStdin
|
|
25
29
|
} from "./chunk-F7DQWYR5.js";
|
|
26
30
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
LexicalIndex,
|
|
32
|
+
isSqliteAvailableSync,
|
|
33
|
+
loadSqliteSync,
|
|
34
|
+
readUserVersion,
|
|
35
|
+
stampUserVersion,
|
|
36
|
+
tokenize
|
|
37
|
+
} from "./chunk-ZBZV2G5R.js";
|
|
38
|
+
import {
|
|
39
|
+
detectToolPresence
|
|
40
|
+
} from "./chunk-A4QJ6ENT.js";
|
|
31
41
|
import {
|
|
32
42
|
ArgparseExit,
|
|
33
43
|
STATUS_SYMBOLS,
|
|
@@ -44,16 +54,22 @@ import {
|
|
|
44
54
|
comparePair,
|
|
45
55
|
frontmatterPaths,
|
|
46
56
|
proseEqual,
|
|
57
|
+
resolveSessionRole,
|
|
47
58
|
splitFrontmatter
|
|
48
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-TRI6DQZ6.js";
|
|
49
60
|
import "./chunk-FTAISGDQ.js";
|
|
50
|
-
import "./chunk-
|
|
61
|
+
import "./chunk-6V6TA25H.js";
|
|
51
62
|
import "./chunk-ROYYTEZU.js";
|
|
52
63
|
import "./chunk-BTWUYDGN.js";
|
|
53
64
|
import {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
} from "./chunk-
|
|
65
|
+
atomicAppendLine,
|
|
66
|
+
probeHostCapabilities
|
|
67
|
+
} from "./chunk-S4YWNRKO.js";
|
|
68
|
+
import "./chunk-ULQRUR23.js";
|
|
69
|
+
import {
|
|
70
|
+
hardenedSpawnEnv,
|
|
71
|
+
projectStoreSlug
|
|
72
|
+
} from "./chunk-EEHDXSYD.js";
|
|
57
73
|
import {
|
|
58
74
|
atomic_write_json,
|
|
59
75
|
atomic_write_text,
|
|
@@ -64,26 +80,22 @@ import {
|
|
|
64
80
|
prune_stale_session_states,
|
|
65
81
|
session_state_file
|
|
66
82
|
} from "./chunk-E4XIZDIB.js";
|
|
67
|
-
import {
|
|
68
|
-
artefact_roots
|
|
69
|
-
} from "./chunk-NUHLI2RX.js";
|
|
70
|
-
import {
|
|
71
|
-
readRecentEntries
|
|
72
|
-
} from "./chunk-5R7HOLAF.js";
|
|
73
|
-
import {
|
|
74
|
-
detectToolPresence
|
|
75
|
-
} from "./chunk-A4QJ6ENT.js";
|
|
76
|
-
import {
|
|
77
|
-
atomicAppendLine,
|
|
78
|
-
probeHostCapabilities
|
|
79
|
-
} from "./chunk-6KM6ORRY.js";
|
|
80
83
|
import "./chunk-T7L2QK3K.js";
|
|
81
84
|
import "./chunk-DMSZHXZS.js";
|
|
85
|
+
import "./chunk-NXEILF2K.js";
|
|
86
|
+
import "./chunk-DEIV7XP7.js";
|
|
87
|
+
import "./chunk-KB5FZ655.js";
|
|
88
|
+
import "./chunk-JQOM7TTM.js";
|
|
82
89
|
import {
|
|
83
90
|
manifest_path,
|
|
84
91
|
read_manifest
|
|
85
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-OKJUIAPS.js";
|
|
86
93
|
import "./chunk-MWRD5YOH.js";
|
|
94
|
+
import {
|
|
95
|
+
DeadScopeError,
|
|
96
|
+
assertScanned,
|
|
97
|
+
reportScanned
|
|
98
|
+
} from "./chunk-I3EIN2YG.js";
|
|
87
99
|
import {
|
|
88
100
|
require_dist
|
|
89
101
|
} from "./chunk-OY53J6II.js";
|
|
@@ -92,17 +104,20 @@ import {
|
|
|
92
104
|
} from "./chunk-MCJYCQPF.js";
|
|
93
105
|
import {
|
|
94
106
|
load_agent_settings
|
|
95
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-JY2I2DXV.js";
|
|
96
108
|
import "./chunk-NDJLNC6Q.js";
|
|
109
|
+
import {
|
|
110
|
+
artefact_roots
|
|
111
|
+
} from "./chunk-YCU3TIXH.js";
|
|
97
112
|
import {
|
|
98
113
|
__toESM
|
|
99
114
|
} from "./chunk-J55WI3RR.js";
|
|
100
115
|
|
|
101
116
|
// src/scripts/_cli/cmd_conformance.ts
|
|
102
117
|
var YAML = __toESM(require_dist(), 1);
|
|
103
|
-
import * as
|
|
118
|
+
import * as fs20 from "node:fs";
|
|
104
119
|
import * as os7 from "node:os";
|
|
105
|
-
import * as
|
|
120
|
+
import * as path18 from "node:path";
|
|
106
121
|
import process5 from "node:process";
|
|
107
122
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
108
123
|
import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL14 } from "node:url";
|
|
@@ -118,10 +133,10 @@ var ROUTE_TARGET_TEMPLATES = Object.freeze({
|
|
|
118
133
|
])
|
|
119
134
|
});
|
|
120
135
|
function parseRouteTarget(target) {
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
const kind = target.slice(0,
|
|
124
|
-
const id = target.slice(
|
|
136
|
+
const sep3 = target.indexOf(":");
|
|
137
|
+
if (sep3 <= 0) return null;
|
|
138
|
+
const kind = target.slice(0, sep3);
|
|
139
|
+
const id = target.slice(sep3 + 1);
|
|
125
140
|
if (!id) return null;
|
|
126
141
|
if (!Object.prototype.hasOwnProperty.call(ROUTE_TARGET_TEMPLATES, kind)) return null;
|
|
127
142
|
return { kind, id };
|
|
@@ -133,17 +148,17 @@ function routeTargetPathsPosix(target) {
|
|
|
133
148
|
}
|
|
134
149
|
|
|
135
150
|
// src/scripts/report_conformance_funnel.ts
|
|
136
|
-
import * as
|
|
151
|
+
import * as fs19 from "node:fs";
|
|
137
152
|
import * as os6 from "node:os";
|
|
138
|
-
import * as
|
|
153
|
+
import * as path17 from "node:path";
|
|
139
154
|
import process4 from "node:process";
|
|
140
155
|
import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
|
|
141
156
|
|
|
142
157
|
// src/scripts/conformance_scan.ts
|
|
143
|
-
import { createHash as
|
|
144
|
-
import
|
|
158
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
159
|
+
import fs15 from "node:fs";
|
|
145
160
|
import os2 from "node:os";
|
|
146
|
-
import
|
|
161
|
+
import path13 from "node:path";
|
|
147
162
|
import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
|
|
148
163
|
|
|
149
164
|
// src/scripts/_lib/transcript_entry.ts
|
|
@@ -191,7 +206,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
191
206
|
// src/scripts/_lib/prompt_shape.ts
|
|
192
207
|
function isSyntheticPrompt(prompt) {
|
|
193
208
|
const head = prompt.trimStart().slice(0, 400);
|
|
194
|
-
return head.startsWith("[SYSTEM NOTIFICATION - NOT USER INPUT]") || head.startsWith("<task-notification>") || head.startsWith("<system-reminder>") || head.startsWith("<local-command-caveat>") || /^\[SYSTEM NOTIFICATION\b/.test(head);
|
|
209
|
+
return head.startsWith("[SYSTEM NOTIFICATION - NOT USER INPUT]") || head.startsWith("<task-notification>") || head.startsWith("<system-reminder>") || head.startsWith("<local-command-caveat>") || head.startsWith("<agent-message") || head.startsWith("Your claude.ai usage limit has reset") || /^\[SYSTEM NOTIFICATION\b/.test(head);
|
|
195
210
|
}
|
|
196
211
|
var DOCUMENT_HEAD = /^\s*(#{1,6}\s|-{3,}\s*$|={3,}\s*$|<[A-Za-z][\w-]*>\s*$)/;
|
|
197
212
|
function humanAuthoredLead(text) {
|
|
@@ -348,7 +363,7 @@ This is the WEAKER of the two provenances \u2014 it reflects the machine, not th
|
|
|
348
363
|
return `<language-pin>
|
|
349
364
|
The user submitted this turn's prompt in ${name}. That is the mirror target for EVERY user-visible token of your replies this turn \u2014 including the short inter-tool lines between tool calls, headings, table cells, bullets, status lines, and the recommendation label under any numbered-options block.
|
|
350
365
|
|
|
351
|
-
|
|
366
|
+
Tool output, file contents, and an injected skill body are NOT the trigger \u2014 this pin is.
|
|
352
367
|
</language-pin>`;
|
|
353
368
|
}
|
|
354
369
|
function _loadState(target) {
|
|
@@ -716,7 +731,8 @@ import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from
|
|
|
716
731
|
// src/scripts/_lib/machine_wake.ts
|
|
717
732
|
var MACHINE_WAKE_PREFIXES = [
|
|
718
733
|
"<task-notification>",
|
|
719
|
-
"<system-reminder>"
|
|
734
|
+
"<system-reminder>",
|
|
735
|
+
"<agent-message"
|
|
720
736
|
];
|
|
721
737
|
function humanTypedThisTurn(prompt) {
|
|
722
738
|
const head = prompt.trimStart();
|
|
@@ -1927,8 +1943,8 @@ var COMMAND_OBJECTS = {
|
|
|
1927
1943
|
};
|
|
1928
1944
|
|
|
1929
1945
|
// src/scripts/hooks/turn_end_gate_hook.ts
|
|
1930
|
-
import * as
|
|
1931
|
-
import * as
|
|
1946
|
+
import * as fs12 from "node:fs";
|
|
1947
|
+
import * as path10 from "node:path";
|
|
1932
1948
|
import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
1933
1949
|
|
|
1934
1950
|
// src/scripts/check_reply_consistency.ts
|
|
@@ -2307,6 +2323,891 @@ function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
|
|
|
2307
2323
|
return null;
|
|
2308
2324
|
}
|
|
2309
2325
|
|
|
2326
|
+
// src/scripts/_lib/graph_feeder_record.ts
|
|
2327
|
+
import * as fs7 from "node:fs";
|
|
2328
|
+
import * as path6 from "node:path";
|
|
2329
|
+
|
|
2330
|
+
// src/scripts/code_graph/detect.ts
|
|
2331
|
+
import { execFileSync } from "node:child_process";
|
|
2332
|
+
import * as fs4 from "node:fs";
|
|
2333
|
+
import * as path4 from "node:path";
|
|
2334
|
+
|
|
2335
|
+
// src/scripts/code_graph/types.ts
|
|
2336
|
+
var GUESS_RESOLVED_VIA = /* @__PURE__ */ new Set([
|
|
2337
|
+
"name-lookup",
|
|
2338
|
+
"dynamic",
|
|
2339
|
+
// The accepted-edge filter is a DENYLIST, so a new value is accepted by
|
|
2340
|
+
// default — which is exactly backwards for this one. `foreign` must be
|
|
2341
|
+
// listed here or a consumer's graph would silently answer the gate verbs
|
|
2342
|
+
// as if this package had resolved its edges.
|
|
2343
|
+
"foreign"
|
|
2344
|
+
]);
|
|
2345
|
+
function isStatedResolution(resolved_via) {
|
|
2346
|
+
return !GUESS_RESOLVED_VIA.has(resolved_via);
|
|
2347
|
+
}
|
|
2348
|
+
var SCHEMA_VERSION = 4;
|
|
2349
|
+
var EXT_LANG = {
|
|
2350
|
+
".php": "php",
|
|
2351
|
+
".ts": "typescript",
|
|
2352
|
+
".tsx": "typescript",
|
|
2353
|
+
".mts": "typescript",
|
|
2354
|
+
".cts": "typescript",
|
|
2355
|
+
".js": "javascript",
|
|
2356
|
+
".jsx": "javascript",
|
|
2357
|
+
".mjs": "javascript",
|
|
2358
|
+
".cjs": "javascript"
|
|
2359
|
+
};
|
|
2360
|
+
|
|
2361
|
+
// src/scripts/code_graph/validate.ts
|
|
2362
|
+
var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member", "tests"]);
|
|
2363
|
+
var CONFIDENCES = /* @__PURE__ */ new Set(["EXTRACTED", "INFERRED", "AMBIGUOUS"]);
|
|
2364
|
+
var RESOLVED_VIA = /* @__PURE__ */ new Set([
|
|
2365
|
+
"same-file",
|
|
2366
|
+
"import-specifier",
|
|
2367
|
+
"path-alias",
|
|
2368
|
+
"psr4",
|
|
2369
|
+
"route-table",
|
|
2370
|
+
"test-import",
|
|
2371
|
+
"name-lookup",
|
|
2372
|
+
"dynamic",
|
|
2373
|
+
// Adapted from a consumer's own graph file; see `foreign.ts`.
|
|
2374
|
+
"foreign"
|
|
2375
|
+
]);
|
|
2376
|
+
var PROVIDERS = /* @__PURE__ */ new Set(["native", "foreign"]);
|
|
2377
|
+
var KINDS = /* @__PURE__ */ new Set([
|
|
2378
|
+
"file",
|
|
2379
|
+
"class",
|
|
2380
|
+
"interface",
|
|
2381
|
+
"trait",
|
|
2382
|
+
"function",
|
|
2383
|
+
"method",
|
|
2384
|
+
"constant",
|
|
2385
|
+
"type",
|
|
2386
|
+
"enum",
|
|
2387
|
+
"skipped"
|
|
2388
|
+
]);
|
|
2389
|
+
function validateGraph(g) {
|
|
2390
|
+
const errors = [];
|
|
2391
|
+
const push = (m) => {
|
|
2392
|
+
if (errors.length < 50) errors.push(m);
|
|
2393
|
+
};
|
|
2394
|
+
if (typeof g !== "object" || g === null) return { ok: false, errors: ["graph is not an object"] };
|
|
2395
|
+
const obj = g;
|
|
2396
|
+
if (typeof obj["schema_version"] !== "number") push("schema_version must be a number");
|
|
2397
|
+
if (typeof obj["source_checksum"] !== "string") push("source_checksum must be a string");
|
|
2398
|
+
if (!Array.isArray(obj["nodes"])) push("nodes must be an array");
|
|
2399
|
+
if (!Array.isArray(obj["edges"])) push("edges must be an array");
|
|
2400
|
+
if (errors.length) return { ok: false, errors };
|
|
2401
|
+
const nodes = obj["nodes"];
|
|
2402
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2403
|
+
nodes.forEach((n, i) => {
|
|
2404
|
+
if (typeof n !== "object" || n === null) return push(`node[${i}] not an object`);
|
|
2405
|
+
const nn = n;
|
|
2406
|
+
if (typeof nn["id"] !== "string") push(`node[${i}].id must be a string`);
|
|
2407
|
+
else ids.add(nn["id"]);
|
|
2408
|
+
if (!KINDS.has(nn["kind"])) push(`node[${i}].kind invalid: ${String(nn["kind"])}`);
|
|
2409
|
+
if (typeof nn["source_file"] !== "string") push(`node[${i}].source_file must be a string`);
|
|
2410
|
+
if (!Array.isArray(nn["source_location"])) push(`node[${i}].source_location must be an array`);
|
|
2411
|
+
});
|
|
2412
|
+
obj["edges"].forEach((e, i) => {
|
|
2413
|
+
if (typeof e !== "object" || e === null) return push(`edge[${i}] not an object`);
|
|
2414
|
+
const ee = e;
|
|
2415
|
+
if (typeof ee["source"] !== "string") push(`edge[${i}].source must be a string`);
|
|
2416
|
+
if (typeof ee["target"] !== "string") push(`edge[${i}].target must be a string`);
|
|
2417
|
+
if (!RELATIONS.has(ee["relation"])) push(`edge[${i}].relation invalid: ${String(ee["relation"])}`);
|
|
2418
|
+
if (!CONFIDENCES.has(ee["confidence"]))
|
|
2419
|
+
push(`edge[${i}].confidence invalid: ${String(ee["confidence"])}`);
|
|
2420
|
+
if (ee["resolved_via"] === void 0) push(`edge[${i}].resolved_via is required`);
|
|
2421
|
+
else if (!RESOLVED_VIA.has(ee["resolved_via"]))
|
|
2422
|
+
push(`edge[${i}].resolved_via invalid: ${String(ee["resolved_via"])}`);
|
|
2423
|
+
if (ee["provider"] === void 0) push(`edge[${i}].provider is required`);
|
|
2424
|
+
else if (!PROVIDERS.has(ee["provider"]))
|
|
2425
|
+
push(`edge[${i}].provider invalid: ${String(ee["provider"])}`);
|
|
2426
|
+
if (typeof ee["source"] === "string" && !ids.has(ee["source"]))
|
|
2427
|
+
push(`edge[${i}].source is not a known node: ${String(ee["source"])}`);
|
|
2428
|
+
if (ee["candidates"] !== void 0 && !Array.isArray(ee["candidates"]))
|
|
2429
|
+
push(`edge[${i}].candidates must be an array when present`);
|
|
2430
|
+
});
|
|
2431
|
+
return { ok: errors.length === 0, errors };
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
// src/scripts/code_graph/detect.ts
|
|
2435
|
+
var CONSUMER_CANDIDATES = ["graph.json", "code-graph.json", ".code-graph/graph.json"];
|
|
2436
|
+
function consumerCandidates(root) {
|
|
2437
|
+
let declared;
|
|
2438
|
+
try {
|
|
2439
|
+
const settings = load_agent_settings({ cwd: root }) ?? {};
|
|
2440
|
+
const section = settings["code_graph"];
|
|
2441
|
+
declared = section !== null && typeof section === "object" && !Array.isArray(section) ? section["consumer_index_paths"] : void 0;
|
|
2442
|
+
} catch {
|
|
2443
|
+
declared = void 0;
|
|
2444
|
+
}
|
|
2445
|
+
const extra = Array.isArray(declared) ? declared.filter(
|
|
2446
|
+
(p) => typeof p === "string" && p !== "" && !path4.isAbsolute(p) && !path4.normalize(p).startsWith("..")
|
|
2447
|
+
) : [];
|
|
2448
|
+
return [...CONSUMER_CANDIDATES, ...extra.filter((p) => !CONSUMER_CANDIDATES.includes(p))];
|
|
2449
|
+
}
|
|
2450
|
+
function gitLastCommitEpoch(root) {
|
|
2451
|
+
try {
|
|
2452
|
+
const out = execFileSync("git", ["-C", root, "log", "-1", "--format=%ct"], {
|
|
2453
|
+
env: hardenedSpawnEnv(),
|
|
2454
|
+
encoding: "utf-8",
|
|
2455
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2456
|
+
}).trim();
|
|
2457
|
+
const n = Number(out);
|
|
2458
|
+
return Number.isFinite(n) ? n : null;
|
|
2459
|
+
} catch {
|
|
2460
|
+
return null;
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
function commitsBehind(root, sha) {
|
|
2464
|
+
try {
|
|
2465
|
+
const out = execFileSync("git", ["-C", root, "rev-list", "--count", `${sha}..HEAD`], {
|
|
2466
|
+
env: hardenedSpawnEnv(),
|
|
2467
|
+
encoding: "utf-8",
|
|
2468
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2469
|
+
}).trim();
|
|
2470
|
+
const n = Number(out);
|
|
2471
|
+
return Number.isFinite(n) ? n : null;
|
|
2472
|
+
} catch {
|
|
2473
|
+
return null;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
function freshness(root, file, embeddedSha) {
|
|
2477
|
+
if (embeddedSha) {
|
|
2478
|
+
const behind = commitsBehind(root, embeddedSha);
|
|
2479
|
+
if (behind !== null) return { stale: behind > 0, commits_behind: behind };
|
|
2480
|
+
}
|
|
2481
|
+
const last = gitLastCommitEpoch(root);
|
|
2482
|
+
if (last === null) return {};
|
|
2483
|
+
try {
|
|
2484
|
+
const mtime = Math.floor(fs4.statSync(file).mtimeMs / 1e3);
|
|
2485
|
+
return { stale: mtime < last };
|
|
2486
|
+
} catch {
|
|
2487
|
+
return {};
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
function looksLikeGraph(p) {
|
|
2491
|
+
try {
|
|
2492
|
+
const raw = JSON.parse(fs4.readFileSync(p, "utf-8"));
|
|
2493
|
+
if (validateGraph(raw).ok) return { ok: true, sha: raw["head_at_build"] ?? null };
|
|
2494
|
+
const nodes = raw["nodes"];
|
|
2495
|
+
const edges = raw["edges"] ?? raw["links"];
|
|
2496
|
+
const okShape = Array.isArray(nodes) && Array.isArray(edges) && (edges.length === 0 || typeof edges[0] === "object" && edges[0] !== null && "source" in edges[0] && "target" in edges[0]);
|
|
2497
|
+
return { ok: okShape, sha: raw["head_at_build"] ?? null };
|
|
2498
|
+
} catch {
|
|
2499
|
+
return { ok: false, sha: null };
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
function detectSources(root, nativeCache) {
|
|
2503
|
+
const abs = path4.resolve(root);
|
|
2504
|
+
const out = [];
|
|
2505
|
+
for (const rel of consumerCandidates(abs)) {
|
|
2506
|
+
const p = path4.join(abs, rel);
|
|
2507
|
+
if (fs4.existsSync(p)) {
|
|
2508
|
+
const { ok, sha } = looksLikeGraph(p);
|
|
2509
|
+
if (ok) out.push({ kind: "consumer", path: p, present: true, ...freshness(abs, p, sha) });
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
const scipCandidates = [path4.join(abs, "index.scip")];
|
|
2513
|
+
try {
|
|
2514
|
+
for (const e of fs4.readdirSync(abs)) if (e.endsWith(".scip")) scipCandidates.push(path4.join(abs, e));
|
|
2515
|
+
} catch {
|
|
2516
|
+
}
|
|
2517
|
+
const scip = scipCandidates.find((p) => fs4.existsSync(p));
|
|
2518
|
+
if (scip) out.push({ kind: "scip", path: scip, present: true, note: "SCIP detected \u2014 peer tooling required (no owned reader)" });
|
|
2519
|
+
if (fs4.existsSync(nativeCache)) out.push({ kind: "native", path: nativeCache, present: true, ...freshness(abs, nativeCache, null) });
|
|
2520
|
+
return out;
|
|
2521
|
+
}
|
|
2522
|
+
function pickSource(verdicts) {
|
|
2523
|
+
const consumer = verdicts.find((v) => v.kind === "consumer" && v.stale !== true);
|
|
2524
|
+
if (consumer) return consumer;
|
|
2525
|
+
const native = verdicts.find((v) => v.kind === "native");
|
|
2526
|
+
if (native) return native;
|
|
2527
|
+
return verdicts.find((v) => v.kind === "consumer") ?? null;
|
|
2528
|
+
}
|
|
2529
|
+
var NATIVE_CACHE_REL = path4.join("agents", "runtime", "state", "code-graph-v1.json");
|
|
2530
|
+
function hasUncommittedIndexedEdit(root) {
|
|
2531
|
+
let out;
|
|
2532
|
+
try {
|
|
2533
|
+
out = execFileSync("git", ["-C", root, "status", "--porcelain", "--untracked-files=all"], {
|
|
2534
|
+
env: hardenedSpawnEnv(),
|
|
2535
|
+
encoding: "utf-8",
|
|
2536
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
2537
|
+
// Both bounds are the review's: Node's 1 MB default would throw
|
|
2538
|
+
// ENOBUFS on a large working tree, the catch below would return
|
|
2539
|
+
// false, and the state would read `fresh` — a second silent
|
|
2540
|
+
// under-report on a probe that runs at PreToolUse and at every stop.
|
|
2541
|
+
// The timeout bounds the other failure: this probe sits in front of
|
|
2542
|
+
// a tool call, so a hung git must not hold one up.
|
|
2543
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
2544
|
+
timeout: 5e3
|
|
2545
|
+
});
|
|
2546
|
+
} catch {
|
|
2547
|
+
return false;
|
|
2548
|
+
}
|
|
2549
|
+
for (const raw of out.split("\n")) {
|
|
2550
|
+
if (raw.length < 4) continue;
|
|
2551
|
+
let p = raw.slice(3);
|
|
2552
|
+
const arrow = p.indexOf(" -> ");
|
|
2553
|
+
if (arrow !== -1) p = p.slice(arrow + 4);
|
|
2554
|
+
p = p.trim().replace(/^"|"$/g, "");
|
|
2555
|
+
const dot = p.lastIndexOf(".");
|
|
2556
|
+
if (dot === -1) continue;
|
|
2557
|
+
if (p.slice(dot).toLowerCase() in EXT_LANG) return true;
|
|
2558
|
+
}
|
|
2559
|
+
return false;
|
|
2560
|
+
}
|
|
2561
|
+
function graphState(root, nativeCache) {
|
|
2562
|
+
const picked = pickSource(detectSources(root, nativeCache ?? path4.join(root, NATIVE_CACHE_REL)));
|
|
2563
|
+
if (!picked) return "absent";
|
|
2564
|
+
if (picked.stale === true) {
|
|
2565
|
+
const behind = picked.commits_behind;
|
|
2566
|
+
return `behind:${typeof behind === "number" ? behind : 0}`;
|
|
2567
|
+
}
|
|
2568
|
+
return hasUncommittedIndexedEdit(root) ? "edited" : "fresh";
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
// src/scripts/code_graph/query.ts
|
|
2572
|
+
import * as fs6 from "node:fs";
|
|
2573
|
+
|
|
2574
|
+
// src/scripts/code_graph/sqlite_store.ts
|
|
2575
|
+
import * as fs5 from "node:fs";
|
|
2576
|
+
var GRAPH_STORE_VERSION = 4;
|
|
2577
|
+
var INDEXED_READ_MIN_EDGES = 5e4;
|
|
2578
|
+
function sqliteTwinPath(jsonPath) {
|
|
2579
|
+
return jsonPath.endsWith(".json") ? `${jsonPath.slice(0, -5)}.sqlite3` : `${jsonPath}.sqlite3`;
|
|
2580
|
+
}
|
|
2581
|
+
function emitSqliteTwin(graph, serialized, jsonPath) {
|
|
2582
|
+
if (!isSqliteAvailableSync()) return false;
|
|
2583
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
2584
|
+
const tmp = `${twin}.tmp-${process.pid}`;
|
|
2585
|
+
try {
|
|
2586
|
+
const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
|
|
2587
|
+
let stat;
|
|
2588
|
+
try {
|
|
2589
|
+
stat = fs5.statSync(jsonPath);
|
|
2590
|
+
} catch {
|
|
2591
|
+
return false;
|
|
2592
|
+
}
|
|
2593
|
+
fs5.rmSync(tmp, { force: true });
|
|
2594
|
+
const db = new DatabaseSync(tmp);
|
|
2595
|
+
try {
|
|
2596
|
+
db.exec("PRAGMA journal_mode = MEMORY");
|
|
2597
|
+
db.exec(
|
|
2598
|
+
"CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);CREATE TABLE nodes (id TEXT PRIMARY KEY, label TEXT NOT NULL, kind TEXT, source_file TEXT, l0 INTEGER, l1 INTEGER, l2 INTEGER, l3 INTEGER);CREATE TABLE edges (source TEXT NOT NULL, target TEXT NOT NULL, relation TEXT NOT NULL, confidence TEXT NOT NULL, candidates TEXT, ambiguity_reason TEXT, resolved_via TEXT, provider TEXT);CREATE INDEX edges_source ON edges(source);CREATE INDEX edges_target ON edges(target);CREATE INDEX nodes_label ON nodes(label);CREATE INDEX nodes_source_file ON nodes(source_file);"
|
|
2599
|
+
);
|
|
2600
|
+
const meta = db.prepare("INSERT INTO meta (key, value) VALUES (?, ?)");
|
|
2601
|
+
meta.run("source_checksum", graph.source_checksum);
|
|
2602
|
+
meta.run("json_size", String(stat.size));
|
|
2603
|
+
meta.run("json_mtime_ms", String(stat.mtimeMs));
|
|
2604
|
+
meta.run("graph_json", serialized);
|
|
2605
|
+
meta.run("node_count", String(graph.nodes.length));
|
|
2606
|
+
meta.run("edge_count", String(graph.edges.length));
|
|
2607
|
+
const insNode = db.prepare(
|
|
2608
|
+
"INSERT INTO nodes (id, label, kind, source_file, l0, l1, l2, l3) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
2609
|
+
);
|
|
2610
|
+
for (const n of graph.nodes) {
|
|
2611
|
+
const loc = n.source_location ?? [];
|
|
2612
|
+
insNode.run(
|
|
2613
|
+
n.id,
|
|
2614
|
+
n.label,
|
|
2615
|
+
n.kind ?? null,
|
|
2616
|
+
n.source_file ?? null,
|
|
2617
|
+
loc[0] ?? null,
|
|
2618
|
+
loc[1] ?? null,
|
|
2619
|
+
loc[2] ?? null,
|
|
2620
|
+
loc[3] ?? null
|
|
2621
|
+
);
|
|
2622
|
+
}
|
|
2623
|
+
const insEdge = db.prepare(
|
|
2624
|
+
"INSERT INTO edges (source, target, relation, confidence, candidates, ambiguity_reason, resolved_via, provider) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
2625
|
+
);
|
|
2626
|
+
for (const e of graph.edges) {
|
|
2627
|
+
insEdge.run(
|
|
2628
|
+
e.source,
|
|
2629
|
+
e.target,
|
|
2630
|
+
e.relation,
|
|
2631
|
+
e.confidence,
|
|
2632
|
+
e.candidates ? JSON.stringify(e.candidates) : null,
|
|
2633
|
+
e.ambiguity_reason ?? null,
|
|
2634
|
+
e.resolved_via,
|
|
2635
|
+
e.provider
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
stampUserVersion(db, GRAPH_STORE_VERSION);
|
|
2639
|
+
} finally {
|
|
2640
|
+
db.close();
|
|
2641
|
+
}
|
|
2642
|
+
fs5.renameSync(tmp, twin);
|
|
2643
|
+
return true;
|
|
2644
|
+
} catch {
|
|
2645
|
+
fs5.rmSync(tmp, { force: true });
|
|
2646
|
+
return false;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
function loadSerializedFromTwin(jsonPath) {
|
|
2650
|
+
if (!isSqliteAvailableSync()) return null;
|
|
2651
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
2652
|
+
if (!fs5.existsSync(twin)) return null;
|
|
2653
|
+
let stat;
|
|
2654
|
+
try {
|
|
2655
|
+
stat = fs5.statSync(jsonPath);
|
|
2656
|
+
} catch {
|
|
2657
|
+
return null;
|
|
2658
|
+
}
|
|
2659
|
+
try {
|
|
2660
|
+
const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
|
|
2661
|
+
const db = new DatabaseSync(twin, { readOnly: true });
|
|
2662
|
+
try {
|
|
2663
|
+
if (readUserVersion(db) !== GRAPH_STORE_VERSION) return null;
|
|
2664
|
+
const rows = db.prepare("SELECT key, value FROM meta").all();
|
|
2665
|
+
const meta = new Map(rows.map((r) => [r.key, r.value]));
|
|
2666
|
+
if (meta.get("json_size") !== String(stat.size)) return null;
|
|
2667
|
+
if (meta.get("json_mtime_ms") !== String(stat.mtimeMs)) return null;
|
|
2668
|
+
const serialized = meta.get("graph_json");
|
|
2669
|
+
return serialized && serialized.length > 0 ? serialized : null;
|
|
2670
|
+
} finally {
|
|
2671
|
+
db.close();
|
|
2672
|
+
}
|
|
2673
|
+
} catch {
|
|
2674
|
+
fs5.rmSync(twin, { force: true });
|
|
2675
|
+
return null;
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
function toNode(r) {
|
|
2679
|
+
const loc = [r.l0, r.l1, r.l2, r.l3].filter((v) => typeof v === "number");
|
|
2680
|
+
return {
|
|
2681
|
+
id: r.id,
|
|
2682
|
+
label: r.label,
|
|
2683
|
+
kind: r.kind ?? "file",
|
|
2684
|
+
source_file: r.source_file ?? "",
|
|
2685
|
+
source_location: loc
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
function toEdge(r) {
|
|
2689
|
+
const e = {
|
|
2690
|
+
source: r.source,
|
|
2691
|
+
target: r.target,
|
|
2692
|
+
relation: r.relation,
|
|
2693
|
+
confidence: r.confidence,
|
|
2694
|
+
// The SQL columns are nullable, the TypeScript fields are not. A null
|
|
2695
|
+
// can only come from a twin emitted before these fields existed, which
|
|
2696
|
+
// GRAPH_STORE_VERSION already refuses — so this coalesce is unreachable
|
|
2697
|
+
// in a healthy tree and is written to fail READABLE rather than to
|
|
2698
|
+
// fabricate: `name-lookup` is the weakest mechanism, so a mislabelled
|
|
2699
|
+
// edge is under-trusted rather than over-trusted by Phase 3's filter.
|
|
2700
|
+
resolved_via: r.resolved_via ?? "name-lookup",
|
|
2701
|
+
provider: r.provider ?? "native"
|
|
2702
|
+
};
|
|
2703
|
+
if (r.candidates) e.candidates = JSON.parse(r.candidates);
|
|
2704
|
+
if (r.ambiguity_reason === "receiver-unknown" || r.ambiguity_reason === "hierarchy-unresolved") {
|
|
2705
|
+
e.ambiguity_reason = r.ambiguity_reason;
|
|
2706
|
+
}
|
|
2707
|
+
return e;
|
|
2708
|
+
}
|
|
2709
|
+
function openGraphIndex(jsonPath) {
|
|
2710
|
+
if (!isSqliteAvailableSync()) return null;
|
|
2711
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
2712
|
+
if (!fs5.existsSync(twin)) return null;
|
|
2713
|
+
let stat;
|
|
2714
|
+
try {
|
|
2715
|
+
stat = fs5.statSync(jsonPath);
|
|
2716
|
+
} catch {
|
|
2717
|
+
return null;
|
|
2718
|
+
}
|
|
2719
|
+
try {
|
|
2720
|
+
const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
|
|
2721
|
+
const db = new DatabaseSync(twin, { readOnly: true });
|
|
2722
|
+
try {
|
|
2723
|
+
if (readUserVersion(db) !== GRAPH_STORE_VERSION) {
|
|
2724
|
+
db.close();
|
|
2725
|
+
return null;
|
|
2726
|
+
}
|
|
2727
|
+
const rows = db.prepare("SELECT key, value FROM meta").all();
|
|
2728
|
+
const meta = new Map(rows.map((r) => [r.key, r.value]));
|
|
2729
|
+
if (meta.get("json_size") !== String(stat.size) || meta.get("json_mtime_ms") !== String(stat.mtimeMs)) {
|
|
2730
|
+
db.close();
|
|
2731
|
+
return null;
|
|
2732
|
+
}
|
|
2733
|
+
const nodeCount = Number(meta.get("node_count") ?? NaN);
|
|
2734
|
+
const edgeCount = Number(meta.get("edge_count") ?? NaN);
|
|
2735
|
+
if (!Number.isFinite(nodeCount) || !Number.isFinite(edgeCount)) {
|
|
2736
|
+
db.close();
|
|
2737
|
+
return null;
|
|
2738
|
+
}
|
|
2739
|
+
const qNode = db.prepare("SELECT * FROM nodes WHERE id = ?");
|
|
2740
|
+
const qFrom = db.prepare("SELECT * FROM edges WHERE source = ?");
|
|
2741
|
+
const qTo = db.prepare("SELECT * FROM edges WHERE target = ?");
|
|
2742
|
+
const qLabel = db.prepare("SELECT id FROM nodes WHERE label = ? LIMIT ?");
|
|
2743
|
+
return {
|
|
2744
|
+
nodeCount,
|
|
2745
|
+
edgeCount,
|
|
2746
|
+
sourceChecksum: meta.get("source_checksum") ?? "",
|
|
2747
|
+
getNode(id) {
|
|
2748
|
+
const r = qNode.get(id);
|
|
2749
|
+
return r ? toNode(r) : void 0;
|
|
2750
|
+
},
|
|
2751
|
+
hasNode(id) {
|
|
2752
|
+
return qNode.get(id) !== void 0;
|
|
2753
|
+
},
|
|
2754
|
+
edgesFrom(id) {
|
|
2755
|
+
return qFrom.all(id).map(toEdge);
|
|
2756
|
+
},
|
|
2757
|
+
edgesTo(id) {
|
|
2758
|
+
return qTo.all(id).map(toEdge);
|
|
2759
|
+
},
|
|
2760
|
+
idsByLabel(labelText, limit) {
|
|
2761
|
+
return qLabel.all(labelText, limit).map((r) => r.id);
|
|
2762
|
+
},
|
|
2763
|
+
idsInFiles(files) {
|
|
2764
|
+
if (files.length === 0) return [];
|
|
2765
|
+
const out = [];
|
|
2766
|
+
const CHUNK = 400;
|
|
2767
|
+
for (let i = 0; i < files.length; i += CHUNK) {
|
|
2768
|
+
const slice = files.slice(i, i + CHUNK);
|
|
2769
|
+
const marks = slice.map(() => "?").join(",");
|
|
2770
|
+
const stmt = db.prepare(
|
|
2771
|
+
`SELECT id FROM nodes WHERE kind != 'file' AND source_file IN (${marks})`
|
|
2772
|
+
);
|
|
2773
|
+
for (const r of stmt.all(...slice)) out.push(r.id);
|
|
2774
|
+
}
|
|
2775
|
+
return out;
|
|
2776
|
+
},
|
|
2777
|
+
allNodeIds() {
|
|
2778
|
+
return db.prepare("SELECT id FROM nodes ORDER BY id").all().map(
|
|
2779
|
+
(r) => r.id
|
|
2780
|
+
);
|
|
2781
|
+
},
|
|
2782
|
+
lexicalCorpus() {
|
|
2783
|
+
return db.prepare("SELECT id, label FROM nodes").all().map(
|
|
2784
|
+
(r) => ({ id: r.id, text: `${r.label} ${r.id}` })
|
|
2785
|
+
);
|
|
2786
|
+
},
|
|
2787
|
+
close() {
|
|
2788
|
+
db.close();
|
|
2789
|
+
}
|
|
2790
|
+
};
|
|
2791
|
+
} catch (err) {
|
|
2792
|
+
db.close();
|
|
2793
|
+
throw err;
|
|
2794
|
+
}
|
|
2795
|
+
} catch {
|
|
2796
|
+
return null;
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
// src/scripts/code_graph/foreign.ts
|
|
2801
|
+
import { createHash } from "node:crypto";
|
|
2802
|
+
var RELATION_MAP = {
|
|
2803
|
+
calls: "calls",
|
|
2804
|
+
call: "calls",
|
|
2805
|
+
invokes: "calls",
|
|
2806
|
+
imports: "imports",
|
|
2807
|
+
import: "imports",
|
|
2808
|
+
requires: "imports",
|
|
2809
|
+
uses: "uses",
|
|
2810
|
+
use: "uses",
|
|
2811
|
+
references: "uses",
|
|
2812
|
+
inherits: "inherits",
|
|
2813
|
+
extends: "inherits",
|
|
2814
|
+
implements: "inherits",
|
|
2815
|
+
member: "member",
|
|
2816
|
+
contains: "member",
|
|
2817
|
+
tests: "tests",
|
|
2818
|
+
test: "tests"
|
|
2819
|
+
};
|
|
2820
|
+
var KINDS2 = /* @__PURE__ */ new Set([
|
|
2821
|
+
"file",
|
|
2822
|
+
"class",
|
|
2823
|
+
"interface",
|
|
2824
|
+
"trait",
|
|
2825
|
+
"function",
|
|
2826
|
+
"method",
|
|
2827
|
+
"constant",
|
|
2828
|
+
"type",
|
|
2829
|
+
"enum",
|
|
2830
|
+
"skipped"
|
|
2831
|
+
]);
|
|
2832
|
+
function isObject(v) {
|
|
2833
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2834
|
+
}
|
|
2835
|
+
function looksForeign(doc) {
|
|
2836
|
+
if (!isObject(doc)) return false;
|
|
2837
|
+
if (!Array.isArray(doc["nodes"])) return false;
|
|
2838
|
+
if (Array.isArray(doc["links"])) return true;
|
|
2839
|
+
return Array.isArray(doc["edges"]) && typeof doc["schema_version"] !== "number";
|
|
2840
|
+
}
|
|
2841
|
+
function adaptForeignGraph(doc) {
|
|
2842
|
+
if (!isObject(doc)) return null;
|
|
2843
|
+
const rawNodes = doc["nodes"];
|
|
2844
|
+
const rawEdges = doc["links"] ?? doc["edges"];
|
|
2845
|
+
if (!Array.isArray(rawNodes) || !Array.isArray(rawEdges)) return null;
|
|
2846
|
+
const nodes = [];
|
|
2847
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2848
|
+
for (const n of rawNodes) {
|
|
2849
|
+
if (!isObject(n)) continue;
|
|
2850
|
+
const id = n["id"];
|
|
2851
|
+
if (typeof id !== "string" || id === "") continue;
|
|
2852
|
+
const kind = typeof n["kind"] === "string" && KINDS2.has(n["kind"]) ? n["kind"] : "skipped";
|
|
2853
|
+
const sourceFile = typeof n["source_file"] === "string" ? n["source_file"] : typeof n["file"] === "string" ? n["file"] : "";
|
|
2854
|
+
nodes.push({
|
|
2855
|
+
id,
|
|
2856
|
+
label: typeof n["label"] === "string" ? n["label"] : id,
|
|
2857
|
+
kind,
|
|
2858
|
+
source_file: sourceFile,
|
|
2859
|
+
// A foreign node rarely carries a span. An empty one is honest —
|
|
2860
|
+
// it says "no location recorded", where a fabricated [1,1] would
|
|
2861
|
+
// point a reader at the top of a file for no reason.
|
|
2862
|
+
source_location: Array.isArray(n["source_location"]) ? n["source_location"] : []
|
|
2863
|
+
});
|
|
2864
|
+
ids.add(id);
|
|
2865
|
+
}
|
|
2866
|
+
const edges = [];
|
|
2867
|
+
const unmapped = {};
|
|
2868
|
+
let malformed = 0;
|
|
2869
|
+
for (const e of rawEdges) {
|
|
2870
|
+
if (!isObject(e)) {
|
|
2871
|
+
malformed += 1;
|
|
2872
|
+
continue;
|
|
2873
|
+
}
|
|
2874
|
+
const source = e["source"];
|
|
2875
|
+
const target = e["target"];
|
|
2876
|
+
if (typeof source !== "string" || typeof target !== "string" || !ids.has(source)) {
|
|
2877
|
+
malformed += 1;
|
|
2878
|
+
continue;
|
|
2879
|
+
}
|
|
2880
|
+
const rawRelation = typeof e["relation"] === "string" ? e["relation"] : "";
|
|
2881
|
+
const relation = RELATION_MAP[rawRelation.toLowerCase()];
|
|
2882
|
+
if (relation === void 0) {
|
|
2883
|
+
const key = rawRelation === "" ? "(none)" : rawRelation;
|
|
2884
|
+
unmapped[key] = (unmapped[key] ?? 0) + 1;
|
|
2885
|
+
continue;
|
|
2886
|
+
}
|
|
2887
|
+
edges.push({
|
|
2888
|
+
source,
|
|
2889
|
+
target,
|
|
2890
|
+
relation,
|
|
2891
|
+
// Not EXTRACTED: this package did not extract it and cannot say
|
|
2892
|
+
// how the tool that did arrived at it.
|
|
2893
|
+
confidence: "AMBIGUOUS",
|
|
2894
|
+
resolved_via: "foreign",
|
|
2895
|
+
provider: "foreign"
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2898
|
+
const counts = { EXTRACTED: 0, INFERRED: 0, AMBIGUOUS: edges.length };
|
|
2899
|
+
const graph = {
|
|
2900
|
+
schema_version: SCHEMA_VERSION,
|
|
2901
|
+
source_checksum: createHash("sha256").update(JSON.stringify(doc), "utf-8").digest("hex"),
|
|
2902
|
+
languages: [],
|
|
2903
|
+
grammar_abi: 0,
|
|
2904
|
+
edge_confidence_counts: counts,
|
|
2905
|
+
suppressed_edge_counts: { dynamic_no_candidate: 0 },
|
|
2906
|
+
nodes,
|
|
2907
|
+
edges
|
|
2908
|
+
};
|
|
2909
|
+
return { graph, unmapped_relations: unmapped, malformed_edges: malformed };
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
// src/scripts/code_graph/query.ts
|
|
2913
|
+
function indexBackedGraph(index, source, answeredBy) {
|
|
2914
|
+
const nodeCache = /* @__PURE__ */ new Map();
|
|
2915
|
+
const readNode = (id) => {
|
|
2916
|
+
if (nodeCache.has(id)) return nodeCache.get(id);
|
|
2917
|
+
const n = index.getNode(id);
|
|
2918
|
+
nodeCache.set(id, n);
|
|
2919
|
+
return n;
|
|
2920
|
+
};
|
|
2921
|
+
let lexical = null;
|
|
2922
|
+
return {
|
|
2923
|
+
graph: null,
|
|
2924
|
+
source,
|
|
2925
|
+
answeredBy,
|
|
2926
|
+
byId: { get: readNode, has: (id) => readNode(id) !== void 0 },
|
|
2927
|
+
out: { get: (id) => index.edgesFrom(id) },
|
|
2928
|
+
in: { get: (id) => index.edgesTo(id) },
|
|
2929
|
+
idsByLabel: (labelText, limit) => index.idsByLabel(labelText, limit),
|
|
2930
|
+
idsInFiles: (files) => index.idsInFiles(files),
|
|
2931
|
+
allNodeIds: () => index.allNodeIds(),
|
|
2932
|
+
lex: () => {
|
|
2933
|
+
lexical ??= new LexicalIndex(index.lexicalCorpus());
|
|
2934
|
+
return lexical;
|
|
2935
|
+
},
|
|
2936
|
+
close: () => index.close()
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2939
|
+
function loadGraph(graphPath, source = graphPath) {
|
|
2940
|
+
const index = openGraphIndex(graphPath);
|
|
2941
|
+
if (index) {
|
|
2942
|
+
if (index.edgeCount >= INDEXED_READ_MIN_EDGES) return indexBackedGraph(index, source, graphPath);
|
|
2943
|
+
index.close();
|
|
2944
|
+
}
|
|
2945
|
+
const fromTwin = loadSerializedFromTwin(graphPath);
|
|
2946
|
+
const raw = fromTwin ?? fs6.readFileSync(graphPath, "utf-8");
|
|
2947
|
+
const parsed = JSON.parse(raw);
|
|
2948
|
+
let foreignAdapted = false;
|
|
2949
|
+
let candidate = parsed;
|
|
2950
|
+
if (looksForeign(parsed)) {
|
|
2951
|
+
const adapted = adaptForeignGraph(parsed);
|
|
2952
|
+
if (adapted !== null) {
|
|
2953
|
+
candidate = adapted.graph;
|
|
2954
|
+
foreignAdapted = true;
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
const v = validateGraph(candidate);
|
|
2958
|
+
if (!v.ok) throw new Error(`invalid graph at ${graphPath}: ${v.errors.slice(0, 3).join("; ")}`);
|
|
2959
|
+
const graph = candidate;
|
|
2960
|
+
if (fromTwin === null && !foreignAdapted) {
|
|
2961
|
+
emitSqliteTwin(graph, raw, graphPath);
|
|
2962
|
+
}
|
|
2963
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
2964
|
+
const outM = /* @__PURE__ */ new Map();
|
|
2965
|
+
const inM = /* @__PURE__ */ new Map();
|
|
2966
|
+
const add = (m, k, e) => {
|
|
2967
|
+
const arr = m.get(k);
|
|
2968
|
+
if (arr) arr.push(e);
|
|
2969
|
+
else m.set(k, [e]);
|
|
2970
|
+
};
|
|
2971
|
+
for (const e of graph.edges) {
|
|
2972
|
+
add(outM, e.source, e);
|
|
2973
|
+
add(inM, e.target, e);
|
|
2974
|
+
}
|
|
2975
|
+
const lex = new LexicalIndex(graph.nodes.map((n) => ({ id: n.id, text: `${n.label} ${n.id}` })));
|
|
2976
|
+
return {
|
|
2977
|
+
graph,
|
|
2978
|
+
source,
|
|
2979
|
+
answeredBy: graphPath,
|
|
2980
|
+
byId,
|
|
2981
|
+
out: outM,
|
|
2982
|
+
in: inM,
|
|
2983
|
+
idsByLabel: (labelText, limit) => graph.nodes.filter((n) => n.label === labelText).slice(0, limit).map((n) => n.id),
|
|
2984
|
+
idsInFiles: (files) => {
|
|
2985
|
+
const set = new Set(files);
|
|
2986
|
+
return graph.nodes.filter((n) => set.has(n.source_file) && n.kind !== "file").map((n) => n.id);
|
|
2987
|
+
},
|
|
2988
|
+
allNodeIds: () => graph.nodes.map((n) => n.id).sort((a, b) => a < b ? -1 : a > b ? 1 : 0),
|
|
2989
|
+
lex: () => lex,
|
|
2990
|
+
close: () => {
|
|
2991
|
+
}
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2994
|
+
function resolveSeedsTiered(g, seed, limit = 5) {
|
|
2995
|
+
if (g.byId.has(seed)) return { ids: [seed], weak: false };
|
|
2996
|
+
const exactLabel = g.idsByLabel(seed, limit);
|
|
2997
|
+
if (exactLabel.length) return { ids: exactLabel, weak: false };
|
|
2998
|
+
const ranked = g.lex().rank(tokenize(seed)).filter((r) => r.score > 0);
|
|
2999
|
+
return { ids: ranked.slice(0, limit).map((r) => r.id), weak: true };
|
|
3000
|
+
}
|
|
3001
|
+
function resolveSeeds(g, seed, limit = 5) {
|
|
3002
|
+
return resolveSeedsTiered(g, seed, limit).ids;
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
// src/scripts/code_graph/verbs.ts
|
|
3006
|
+
import * as path5 from "node:path";
|
|
3007
|
+
function isAcceptedEdge(e) {
|
|
3008
|
+
return isStatedResolution(e.resolved_via);
|
|
3009
|
+
}
|
|
3010
|
+
function foreignRefusal(g) {
|
|
3011
|
+
const edges = g.graph?.edges ?? [];
|
|
3012
|
+
if (edges.length === 0) return null;
|
|
3013
|
+
if (!edges.every((e) => e.resolved_via === "foreign")) return null;
|
|
3014
|
+
return 'every edge in this graph was read from a file this package did not build, so all of them are guesses and none is gate-grade. A gate verb would accept no edge and report an empty answer, which reads as "nothing found" rather than "nothing trusted". Build a native graph (`agent-config graph build`) to use this verb, or use `query` and `explain`, which answer from foreign edges and say so.';
|
|
3015
|
+
}
|
|
3016
|
+
function viaHistogram(edges) {
|
|
3017
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3018
|
+
for (const e of edges) counts.set(e.resolved_via, (counts.get(e.resolved_via) ?? 0) + 1);
|
|
3019
|
+
if (counts.size === 0) return "(none)";
|
|
3020
|
+
return [...counts.entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)).map(([via, n]) => `${via} ${n}`).join(" \xB7 ");
|
|
3021
|
+
}
|
|
3022
|
+
function readFor(g, id) {
|
|
3023
|
+
const n = g.byId.get(id);
|
|
3024
|
+
if (!n) return null;
|
|
3025
|
+
const loc = n.source_location;
|
|
3026
|
+
return { path: n.source_file, lines: loc.length >= 3 ? [loc[0], loc[2]] : null };
|
|
3027
|
+
}
|
|
3028
|
+
function dedupeReads(reads) {
|
|
3029
|
+
const m = /* @__PURE__ */ new Map();
|
|
3030
|
+
for (const r of reads) {
|
|
3031
|
+
if (!r) continue;
|
|
3032
|
+
m.set(r.lines ? `${r.path}:${r.lines[0]}-${r.lines[1]}` : r.path, r);
|
|
3033
|
+
}
|
|
3034
|
+
return [...m.values()];
|
|
3035
|
+
}
|
|
3036
|
+
function seedsForFiles(g, files) {
|
|
3037
|
+
const symbols = g.idsInFiles(files);
|
|
3038
|
+
const seeds = new Set(symbols);
|
|
3039
|
+
const unresolved = [];
|
|
3040
|
+
const notIndexed = [];
|
|
3041
|
+
for (const f of files) {
|
|
3042
|
+
if (g.byId.has(f)) {
|
|
3043
|
+
seeds.add(f);
|
|
3044
|
+
continue;
|
|
3045
|
+
}
|
|
3046
|
+
if (symbols.some((s) => s.startsWith(`${f}#`))) continue;
|
|
3047
|
+
if (EXT_LANG[path5.extname(f).toLowerCase()] === void 0) notIndexed.push(f);
|
|
3048
|
+
else unresolved.push(f);
|
|
3049
|
+
}
|
|
3050
|
+
return {
|
|
3051
|
+
seeds: [...seeds].sort(),
|
|
3052
|
+
unresolved: unresolved.sort(),
|
|
3053
|
+
not_indexed: notIndexed.sort()
|
|
3054
|
+
};
|
|
3055
|
+
}
|
|
3056
|
+
function testsFor(g, symbol, state) {
|
|
3057
|
+
const seeds = resolveSeeds(g, symbol);
|
|
3058
|
+
const targets = new Set(seeds);
|
|
3059
|
+
for (const s of seeds) {
|
|
3060
|
+
const f = g.byId.get(s)?.source_file;
|
|
3061
|
+
if (f && g.byId.has(f)) targets.add(f);
|
|
3062
|
+
}
|
|
3063
|
+
const accepted = [];
|
|
3064
|
+
const rejected = [];
|
|
3065
|
+
const tests = /* @__PURE__ */ new Set();
|
|
3066
|
+
for (const t of targets) {
|
|
3067
|
+
for (const e of g.in.get(t) ?? []) {
|
|
3068
|
+
if (e.relation !== "tests") continue;
|
|
3069
|
+
if (!isAcceptedEdge(e)) {
|
|
3070
|
+
rejected.push(e);
|
|
3071
|
+
continue;
|
|
3072
|
+
}
|
|
3073
|
+
accepted.push(e);
|
|
3074
|
+
tests.add(e.source);
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
const list = [...tests].sort();
|
|
3078
|
+
return {
|
|
3079
|
+
source: g.source,
|
|
3080
|
+
state,
|
|
3081
|
+
accepted_via: viaHistogram(accepted),
|
|
3082
|
+
rejected_via: viaHistogram(rejected),
|
|
3083
|
+
seeds,
|
|
3084
|
+
tests: list,
|
|
3085
|
+
accepted_edges: accepted,
|
|
3086
|
+
rejected_edges: rejected,
|
|
3087
|
+
lines: list,
|
|
3088
|
+
recommended_reads: dedupeReads(list.map((t) => readFor(g, t)))
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
function untested(g, files, state) {
|
|
3092
|
+
const foreign = foreignRefusal(g);
|
|
3093
|
+
if (foreign !== null) {
|
|
3094
|
+
return {
|
|
3095
|
+
source: g.source,
|
|
3096
|
+
state,
|
|
3097
|
+
accepted_via: "(none)",
|
|
3098
|
+
rejected_via: "(none)",
|
|
3099
|
+
refusal: foreign,
|
|
3100
|
+
refusal_reason: "foreign-edges-not-accepted",
|
|
3101
|
+
seeds: [],
|
|
3102
|
+
unresolved_files: [],
|
|
3103
|
+
not_indexed_files: [],
|
|
3104
|
+
untested: [],
|
|
3105
|
+
tested: [],
|
|
3106
|
+
lines: [],
|
|
3107
|
+
recommended_reads: []
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
const { seeds, unresolved, not_indexed } = seedsForFiles(g, files);
|
|
3111
|
+
const accepted = [];
|
|
3112
|
+
const rejected = [];
|
|
3113
|
+
const tested = [];
|
|
3114
|
+
const bare = [];
|
|
3115
|
+
for (const s of seeds) {
|
|
3116
|
+
if (g.byId.get(s)?.kind === "file") continue;
|
|
3117
|
+
const r = testsFor(g, s, state);
|
|
3118
|
+
accepted.push(...r.accepted_edges);
|
|
3119
|
+
rejected.push(...r.rejected_edges);
|
|
3120
|
+
if (r.tests.length) tested.push(s);
|
|
3121
|
+
else bare.push(s);
|
|
3122
|
+
}
|
|
3123
|
+
return {
|
|
3124
|
+
source: g.source,
|
|
3125
|
+
state,
|
|
3126
|
+
accepted_via: viaHistogram(accepted),
|
|
3127
|
+
rejected_via: viaHistogram(rejected),
|
|
3128
|
+
refusal: null,
|
|
3129
|
+
refusal_reason: null,
|
|
3130
|
+
seeds,
|
|
3131
|
+
unresolved_files: unresolved,
|
|
3132
|
+
not_indexed_files: not_indexed,
|
|
3133
|
+
untested: bare.sort(),
|
|
3134
|
+
tested: tested.sort(),
|
|
3135
|
+
lines: bare.sort(),
|
|
3136
|
+
recommended_reads: dedupeReads(bare.map((b) => readFor(g, b)))
|
|
3137
|
+
};
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3140
|
+
// src/scripts/_lib/graph_feeder_record.ts
|
|
3141
|
+
var MAX_PATHS = 5;
|
|
3142
|
+
var MAX_ROWS_PER_SESSION = 200;
|
|
3143
|
+
function feederFile(workspaceRoot, sessionKey) {
|
|
3144
|
+
return path6.join(workspaceRoot, "agents", "state", "graph-feeder", `${sessionKey}.jsonl`);
|
|
3145
|
+
}
|
|
3146
|
+
function graphUntestedVerdict(root, state, paths) {
|
|
3147
|
+
const none = { verdict: null, untested: 0, tested: 0 };
|
|
3148
|
+
if (state !== "fresh" && state !== "edited") return none;
|
|
3149
|
+
if (paths.length === 0) return none;
|
|
3150
|
+
let picked;
|
|
3151
|
+
try {
|
|
3152
|
+
picked = pickSource(detectSources(root, path6.join(root, NATIVE_CACHE_REL)));
|
|
3153
|
+
} catch {
|
|
3154
|
+
return none;
|
|
3155
|
+
}
|
|
3156
|
+
if (!picked || picked.kind === "scip") return none;
|
|
3157
|
+
let g;
|
|
3158
|
+
try {
|
|
3159
|
+
g = loadGraph(picked.path, `${picked.kind}:${path6.relative(root, picked.path)}`);
|
|
3160
|
+
} catch {
|
|
3161
|
+
return none;
|
|
3162
|
+
}
|
|
3163
|
+
try {
|
|
3164
|
+
const r = untested(g, paths, state);
|
|
3165
|
+
if (r.seeds.length === 0) return { verdict: "no-seeds", untested: 0, tested: 0 };
|
|
3166
|
+
return {
|
|
3167
|
+
verdict: r.untested.length > 0 ? "untested" : "tested",
|
|
3168
|
+
untested: r.untested.length,
|
|
3169
|
+
tested: r.tested.length
|
|
3170
|
+
};
|
|
3171
|
+
} catch {
|
|
3172
|
+
return none;
|
|
3173
|
+
} finally {
|
|
3174
|
+
try {
|
|
3175
|
+
g.close();
|
|
3176
|
+
} catch {
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
function appendFeederRow(workspaceRoot, sessionKey, row) {
|
|
3181
|
+
try {
|
|
3182
|
+
const file = feederFile(workspaceRoot, sessionKey);
|
|
3183
|
+
let existing = 0;
|
|
3184
|
+
try {
|
|
3185
|
+
existing = fs7.readFileSync(file, "utf-8").split("\n").filter((l) => l.trim() !== "").length;
|
|
3186
|
+
} catch {
|
|
3187
|
+
}
|
|
3188
|
+
if (existing >= MAX_ROWS_PER_SESSION) return;
|
|
3189
|
+
fs7.mkdirSync(path6.dirname(file), { recursive: true });
|
|
3190
|
+
fs7.appendFileSync(file, `${JSON.stringify(row)}
|
|
3191
|
+
`);
|
|
3192
|
+
} catch {
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
function buildFeederRow(input) {
|
|
3196
|
+
return {
|
|
3197
|
+
at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
3198
|
+
turn: input.turn,
|
|
3199
|
+
layer: input.layer,
|
|
3200
|
+
graph_state: input.state,
|
|
3201
|
+
f: input.fFired,
|
|
3202
|
+
f_mode: input.fMode,
|
|
3203
|
+
graph: input.graph.verdict,
|
|
3204
|
+
graph_untested: input.graph.untested,
|
|
3205
|
+
graph_tested: input.graph.tested,
|
|
3206
|
+
paths: input.paths.slice(0, MAX_PATHS).map((p) => p),
|
|
3207
|
+
path_count: input.paths.length
|
|
3208
|
+
};
|
|
3209
|
+
}
|
|
3210
|
+
|
|
2310
3211
|
// src/scripts/hooks/envelope.ts
|
|
2311
3212
|
var ENVELOPE_KEYS = [
|
|
2312
3213
|
"schema_version",
|
|
@@ -2363,8 +3264,8 @@ function unwrap(stdin_text, default_platform = "generic") {
|
|
|
2363
3264
|
|
|
2364
3265
|
// src/scripts/hooks/subagent_ledger_hook.ts
|
|
2365
3266
|
import * as crypto from "node:crypto";
|
|
2366
|
-
import * as
|
|
2367
|
-
import * as
|
|
3267
|
+
import * as fs8 from "node:fs";
|
|
3268
|
+
import * as path7 from "node:path";
|
|
2368
3269
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
2369
3270
|
|
|
2370
3271
|
// src/scripts/_lib/subagent_response.ts
|
|
@@ -2498,15 +3399,15 @@ var EXIT_CODES = Object.freeze([
|
|
|
2498
3399
|
name: "error",
|
|
2499
3400
|
meaning: "the concern crashed, timed out, or could not decide \u2014 any rc >= 3. The dispatcher resolves it by the concern`s declared severity, never by the number itself",
|
|
2500
3401
|
owner: "no concern emits this on purpose; the runtime does",
|
|
2501
|
-
authorizedBy: "hook_manifest.yaml `
|
|
3402
|
+
authorizedBy: "hook_manifest.yaml `severity` alone \u2014 blocking refuses, anything else fails open; `fail_closed` is no longer read on this branch. See docs/contracts/hook-architecture-v1.md \xA7 Exit-code semantics"
|
|
2502
3403
|
})
|
|
2503
3404
|
]);
|
|
2504
3405
|
|
|
2505
3406
|
// src/scripts/hooks/subagent_ledger_hook.ts
|
|
2506
|
-
function
|
|
3407
|
+
function isObject2(v) {
|
|
2507
3408
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2508
3409
|
}
|
|
2509
|
-
var LEDGER_DIR =
|
|
3410
|
+
var LEDGER_DIR = path7.join("agents", "runtime", "state", "subagent-ledger");
|
|
2510
3411
|
var OPEN_SUBDIR = "open";
|
|
2511
3412
|
var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2512
3413
|
function refFor(agentId) {
|
|
@@ -2514,7 +3415,7 @@ function refFor(agentId) {
|
|
|
2514
3415
|
}
|
|
2515
3416
|
function unwrapPayload(envelope) {
|
|
2516
3417
|
const inner = envelope["payload"];
|
|
2517
|
-
return
|
|
3418
|
+
return isObject2(inner) ? inner : envelope;
|
|
2518
3419
|
}
|
|
2519
3420
|
function str(payload, ...keys) {
|
|
2520
3421
|
for (const k of keys) {
|
|
@@ -2527,7 +3428,7 @@ function extractParentId(payload, ownId) {
|
|
|
2527
3428
|
const explicit = str(payload, "parent_agent_id", "parentAgentId");
|
|
2528
3429
|
if (explicit) return explicit;
|
|
2529
3430
|
const session = payload["session"];
|
|
2530
|
-
if (
|
|
3431
|
+
if (isObject2(session)) {
|
|
2531
3432
|
const sessionAgent = str(session, "agent_id", "agentId");
|
|
2532
3433
|
if (sessionAgent && sessionAgent !== ownId) return sessionAgent;
|
|
2533
3434
|
}
|
|
@@ -2596,14 +3497,14 @@ function _jsonObjectCandidates(message) {
|
|
|
2596
3497
|
return out;
|
|
2597
3498
|
}
|
|
2598
3499
|
function openDir(root) {
|
|
2599
|
-
return
|
|
3500
|
+
return path7.join(root, LEDGER_DIR, OPEN_SUBDIR);
|
|
2600
3501
|
}
|
|
2601
3502
|
function openFile(root, ref) {
|
|
2602
|
-
return
|
|
3503
|
+
return path7.join(openDir(root), `${ref}.json`);
|
|
2603
3504
|
}
|
|
2604
3505
|
var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
|
|
2605
3506
|
function _asOpenRecord(value, expectedRef) {
|
|
2606
|
-
if (!
|
|
3507
|
+
if (!isObject2(value)) return null;
|
|
2607
3508
|
const ref = value["ref"];
|
|
2608
3509
|
if (typeof ref !== "string" || ref !== expectedRef) return null;
|
|
2609
3510
|
if (typeof value["started_at"] !== "string") return null;
|
|
@@ -2626,7 +3527,7 @@ function readOpenRecords(root) {
|
|
|
2626
3527
|
const out = /* @__PURE__ */ new Map();
|
|
2627
3528
|
let names;
|
|
2628
3529
|
try {
|
|
2629
|
-
names =
|
|
3530
|
+
names = fs8.readdirSync(openDir(root));
|
|
2630
3531
|
} catch {
|
|
2631
3532
|
return out;
|
|
2632
3533
|
}
|
|
@@ -2634,7 +3535,7 @@ function readOpenRecords(root) {
|
|
|
2634
3535
|
if (!name.endsWith(".json")) continue;
|
|
2635
3536
|
const expectedRef = name.slice(0, -".json".length);
|
|
2636
3537
|
try {
|
|
2637
|
-
const raw =
|
|
3538
|
+
const raw = fs8.readFileSync(path7.join(openDir(root), name), "utf8");
|
|
2638
3539
|
const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
|
|
2639
3540
|
if (rec) out.set(rec.ref, rec);
|
|
2640
3541
|
} catch {
|
|
@@ -2649,13 +3550,13 @@ function resolveDepth(parentRef, open) {
|
|
|
2649
3550
|
return { depth: parent.depth + 1, depth_basis: "observed" };
|
|
2650
3551
|
}
|
|
2651
3552
|
function ledgerFileFor2(root, ts) {
|
|
2652
|
-
return
|
|
3553
|
+
return path7.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
|
|
2653
3554
|
}
|
|
2654
3555
|
function appendLedgerLine(root, ts, line) {
|
|
2655
3556
|
if (is_replay_mode()) return;
|
|
2656
3557
|
const file = ledgerFileFor2(root, ts);
|
|
2657
|
-
|
|
2658
|
-
|
|
3558
|
+
fs8.mkdirSync(path7.dirname(file), { recursive: true });
|
|
3559
|
+
fs8.appendFileSync(file, `${JSON.stringify(line)}
|
|
2659
3560
|
`, "utf8");
|
|
2660
3561
|
}
|
|
2661
3562
|
var WALL_CLOCK_ARMS_MS = [
|
|
@@ -2669,7 +3570,7 @@ function armsExceeded(elapsedMs) {
|
|
|
2669
3570
|
return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
|
|
2670
3571
|
}
|
|
2671
3572
|
function openRecordStats(root, nowMs = Date.now()) {
|
|
2672
|
-
const ledgerPresent =
|
|
3573
|
+
const ledgerPresent = fs8.existsSync(path7.join(root, LEDGER_DIR));
|
|
2673
3574
|
const open = readOpenRecords(root);
|
|
2674
3575
|
let maxDepth = 0;
|
|
2675
3576
|
let counted = 0;
|
|
@@ -2697,13 +3598,13 @@ function writeOpenRecord(root, rec) {
|
|
|
2697
3598
|
function removeOpenRecord(root, ref) {
|
|
2698
3599
|
if (is_replay_mode()) return;
|
|
2699
3600
|
try {
|
|
2700
|
-
|
|
3601
|
+
fs8.unlinkSync(openFile(root, ref));
|
|
2701
3602
|
} catch {
|
|
2702
3603
|
}
|
|
2703
3604
|
}
|
|
2704
3605
|
function countOpen(root) {
|
|
2705
3606
|
try {
|
|
2706
|
-
return
|
|
3607
|
+
return fs8.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
|
|
2707
3608
|
} catch {
|
|
2708
3609
|
return 0;
|
|
2709
3610
|
}
|
|
@@ -2830,7 +3731,7 @@ function handleStop(root, payload, nowIso, sessionId) {
|
|
|
2830
3731
|
}
|
|
2831
3732
|
function processEnvelope(envelope, consumerRoot) {
|
|
2832
3733
|
try {
|
|
2833
|
-
if (!
|
|
3734
|
+
if (!isObject2(envelope)) return EXIT_ALLOW3;
|
|
2834
3735
|
const event = envelope["event"];
|
|
2835
3736
|
if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW3;
|
|
2836
3737
|
const payload = unwrapPayload(envelope);
|
|
@@ -2845,7 +3746,7 @@ function processEnvelope(envelope, consumerRoot) {
|
|
|
2845
3746
|
return EXIT_ALLOW3;
|
|
2846
3747
|
}
|
|
2847
3748
|
function resolveConsumerRoot(envelope) {
|
|
2848
|
-
if (
|
|
3749
|
+
if (isObject2(envelope)) {
|
|
2849
3750
|
const pr = str(envelope, "workspace_root", "project_root");
|
|
2850
3751
|
if (pr) return pr;
|
|
2851
3752
|
const payload = unwrapPayload(envelope);
|
|
@@ -2869,10 +3770,10 @@ function _isCliEntry4() {
|
|
|
2869
3770
|
return false;
|
|
2870
3771
|
}
|
|
2871
3772
|
if (process.argv[1] === void 0) return false;
|
|
2872
|
-
const argvUrl = pathToFileURL4(
|
|
3773
|
+
const argvUrl = pathToFileURL4(path7.resolve(process.argv[1])).href;
|
|
2873
3774
|
if (import.meta.url === argvUrl) return true;
|
|
2874
3775
|
try {
|
|
2875
|
-
return
|
|
3776
|
+
return fs8.realpathSync(fileURLToPath4(import.meta.url)) === fs8.realpathSync(path7.resolve(process.argv[1]));
|
|
2876
3777
|
} catch {
|
|
2877
3778
|
return false;
|
|
2878
3779
|
}
|
|
@@ -2880,20 +3781,20 @@ function _isCliEntry4() {
|
|
|
2880
3781
|
if (_isCliEntry4()) process.exit(main4());
|
|
2881
3782
|
|
|
2882
3783
|
// src/scripts/_lib/turn_end_transcript.ts
|
|
2883
|
-
import * as
|
|
3784
|
+
import * as fs11 from "node:fs";
|
|
2884
3785
|
|
|
2885
3786
|
// src/scripts/hooks/end_review_nudge_hook.ts
|
|
2886
3787
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
2887
3788
|
import * as crypto2 from "node:crypto";
|
|
2888
|
-
import * as
|
|
3789
|
+
import * as fs10 from "node:fs";
|
|
2889
3790
|
import * as os from "node:os";
|
|
2890
|
-
import * as
|
|
3791
|
+
import * as path9 from "node:path";
|
|
2891
3792
|
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL5 } from "node:url";
|
|
2892
3793
|
|
|
2893
3794
|
// src/scripts/_lib/review_baseline.ts
|
|
2894
3795
|
import { spawnSync } from "node:child_process";
|
|
2895
|
-
import * as
|
|
2896
|
-
import * as
|
|
3796
|
+
import * as fs9 from "node:fs";
|
|
3797
|
+
import * as path8 from "node:path";
|
|
2897
3798
|
function currentHeadSha(cwd) {
|
|
2898
3799
|
try {
|
|
2899
3800
|
const r = spawnSync("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
|
|
@@ -2904,12 +3805,12 @@ function currentHeadSha(cwd) {
|
|
|
2904
3805
|
return null;
|
|
2905
3806
|
}
|
|
2906
3807
|
}
|
|
2907
|
-
var BASELINE_STATE_REL =
|
|
3808
|
+
var BASELINE_STATE_REL = path8.join("agents", "runtime", "state", "review-baseline");
|
|
2908
3809
|
function baselineStateDir(workspaceRoot) {
|
|
2909
|
-
return
|
|
3810
|
+
return path8.join(workspaceRoot, BASELINE_STATE_REL);
|
|
2910
3811
|
}
|
|
2911
3812
|
function baselineStateFile(workspaceRoot, sessionKey) {
|
|
2912
|
-
return
|
|
3813
|
+
return path8.join(baselineStateDir(workspaceRoot), `${sessionKey}.json`);
|
|
2913
3814
|
}
|
|
2914
3815
|
function parseBaseline(raw) {
|
|
2915
3816
|
let decoded;
|
|
@@ -2937,7 +3838,7 @@ function readBaseline(workspaceRoot, sessionKey) {
|
|
|
2937
3838
|
const file = baselineStateFile(workspaceRoot, sessionKey);
|
|
2938
3839
|
let raw;
|
|
2939
3840
|
try {
|
|
2940
|
-
raw =
|
|
3841
|
+
raw = fs9.readFileSync(file, "utf-8");
|
|
2941
3842
|
} catch (exc) {
|
|
2942
3843
|
const code = exc?.code;
|
|
2943
3844
|
return code === "ENOENT" ? "absent" : "unreadable";
|
|
@@ -3047,13 +3948,13 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
|
|
|
3047
3948
|
const homeDir = opts.homeDir ?? os.homedir();
|
|
3048
3949
|
const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
|
|
3049
3950
|
try {
|
|
3050
|
-
const realHome =
|
|
3051
|
-
const realPath =
|
|
3052
|
-
const
|
|
3053
|
-
if (
|
|
3951
|
+
const realHome = fs10.realpathSync(homeDir);
|
|
3952
|
+
const realPath = fs10.realpathSync(rawPath);
|
|
3953
|
+
const relative5 = path9.relative(realHome, realPath);
|
|
3954
|
+
if (relative5 === "" || relative5.startsWith("..") || path9.isAbsolute(relative5)) {
|
|
3054
3955
|
return false;
|
|
3055
3956
|
}
|
|
3056
|
-
const { size } =
|
|
3957
|
+
const { size } = fs10.statSync(realPath);
|
|
3057
3958
|
return size <= maxBytes;
|
|
3058
3959
|
} catch {
|
|
3059
3960
|
return false;
|
|
@@ -3111,13 +4012,13 @@ var BINARY_PROBE_BYTES = 8e3;
|
|
|
3111
4012
|
var UNTRACKED_FILE_READ_CAP_BYTES = 8 * 1024 * 1024;
|
|
3112
4013
|
function untrackedFileLineCount(cwd, relPath) {
|
|
3113
4014
|
try {
|
|
3114
|
-
const abs =
|
|
3115
|
-
const size =
|
|
4015
|
+
const abs = path9.resolve(cwd, relPath);
|
|
4016
|
+
const size = fs10.statSync(abs).size;
|
|
3116
4017
|
if (size === 0) return 0;
|
|
3117
4018
|
if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
|
|
3118
4019
|
return MUTATION_LINE_THRESHOLD + 1;
|
|
3119
4020
|
}
|
|
3120
|
-
const buf =
|
|
4021
|
+
const buf = fs10.readFileSync(abs);
|
|
3121
4022
|
if (buf.length === 0) return 0;
|
|
3122
4023
|
const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
|
|
3123
4024
|
if (probe.includes(0)) return 0;
|
|
@@ -3143,7 +4044,7 @@ function totalNonDocMutatedLinesWithMeasure(cwd) {
|
|
|
3143
4044
|
);
|
|
3144
4045
|
return { lines: trackedLines + untrackedLines, measure: "exact" };
|
|
3145
4046
|
}
|
|
3146
|
-
function
|
|
4047
|
+
function isObject3(v) {
|
|
3147
4048
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3148
4049
|
}
|
|
3149
4050
|
function str2(v) {
|
|
@@ -3163,16 +4064,16 @@ function scanTranscriptForReviewer(transcriptText) {
|
|
|
3163
4064
|
} catch {
|
|
3164
4065
|
continue;
|
|
3165
4066
|
}
|
|
3166
|
-
if (!
|
|
4067
|
+
if (!isObject3(obj) || obj["type"] !== "assistant") continue;
|
|
3167
4068
|
const msg = obj["message"];
|
|
3168
|
-
if (!
|
|
4069
|
+
if (!isObject3(msg)) continue;
|
|
3169
4070
|
const content = msg["content"];
|
|
3170
4071
|
if (!Array.isArray(content)) continue;
|
|
3171
4072
|
for (const blk of content) {
|
|
3172
|
-
if (!
|
|
4073
|
+
if (!isObject3(blk) || blk["type"] !== "tool_use") continue;
|
|
3173
4074
|
const name = str2(blk["name"]);
|
|
3174
4075
|
const input = blk["input"];
|
|
3175
|
-
const inputObj =
|
|
4076
|
+
const inputObj = isObject3(input) ? input : {};
|
|
3176
4077
|
if (DISPATCH_TOOL_RE.test(name)) {
|
|
3177
4078
|
const label = [
|
|
3178
4079
|
str2(inputObj["description"]),
|
|
@@ -3208,19 +4109,19 @@ function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure,
|
|
|
3208
4109
|
});
|
|
3209
4110
|
if (errors.length || line === null) return;
|
|
3210
4111
|
try {
|
|
3211
|
-
const dir =
|
|
3212
|
-
|
|
3213
|
-
const file =
|
|
3214
|
-
|
|
4112
|
+
const dir = path9.join(workspaceRoot, "agents", "runtime", "state", "audit");
|
|
4113
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
4114
|
+
const file = path9.join(dir, `${ts.slice(0, 7)}.jsonl`);
|
|
4115
|
+
fs10.appendFileSync(file, `${JSON.stringify(line)}
|
|
3215
4116
|
`, "utf8");
|
|
3216
4117
|
} catch {
|
|
3217
4118
|
}
|
|
3218
4119
|
}
|
|
3219
4120
|
function sessionStateDir(workspaceRoot) {
|
|
3220
|
-
return
|
|
4121
|
+
return path9.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
|
|
3221
4122
|
}
|
|
3222
4123
|
function sessionStateFile(workspaceRoot, sessionKey) {
|
|
3223
|
-
return
|
|
4124
|
+
return path9.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
|
|
3224
4125
|
}
|
|
3225
4126
|
function deriveSessionKey2(envelope, payload) {
|
|
3226
4127
|
const raw = str2(envelope["session_id"]) || str2(payload["transcript_path"] ?? payload["transcriptPath"]);
|
|
@@ -3229,7 +4130,7 @@ function deriveSessionKey2(envelope, payload) {
|
|
|
3229
4130
|
}
|
|
3230
4131
|
function hasFiredThisSession(workspaceRoot, sessionKey) {
|
|
3231
4132
|
try {
|
|
3232
|
-
return
|
|
4133
|
+
return fs10.existsSync(sessionStateFile(workspaceRoot, sessionKey));
|
|
3233
4134
|
} catch {
|
|
3234
4135
|
return false;
|
|
3235
4136
|
}
|
|
@@ -3291,7 +4192,7 @@ function main5() {
|
|
|
3291
4192
|
let reviewerRan = false;
|
|
3292
4193
|
if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
|
|
3293
4194
|
try {
|
|
3294
|
-
reviewerRan = scanTranscriptForReviewer(
|
|
4195
|
+
reviewerRan = scanTranscriptForReviewer(fs10.readFileSync(transcriptPath, "utf-8"));
|
|
3295
4196
|
} catch {
|
|
3296
4197
|
reviewerRan = false;
|
|
3297
4198
|
}
|
|
@@ -3326,13 +4227,13 @@ function _isCliEntry5() {
|
|
|
3326
4227
|
if (process.argv[1] === void 0) {
|
|
3327
4228
|
return false;
|
|
3328
4229
|
}
|
|
3329
|
-
const argvUrl = pathToFileURL5(
|
|
4230
|
+
const argvUrl = pathToFileURL5(path9.resolve(process.argv[1])).href;
|
|
3330
4231
|
if (import.meta.url === argvUrl) {
|
|
3331
4232
|
return true;
|
|
3332
4233
|
}
|
|
3333
4234
|
try {
|
|
3334
|
-
const here =
|
|
3335
|
-
const argv =
|
|
4235
|
+
const here = fs10.realpathSync(fileURLToPath5(import.meta.url));
|
|
4236
|
+
const argv = fs10.realpathSync(path9.resolve(process.argv[1]));
|
|
3336
4237
|
return here === argv;
|
|
3337
4238
|
} catch {
|
|
3338
4239
|
return false;
|
|
@@ -3353,10 +4254,10 @@ function readTranscriptTail(transcriptPath, opts = {}) {
|
|
|
3353
4254
|
if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
|
|
3354
4255
|
let lines;
|
|
3355
4256
|
try {
|
|
3356
|
-
if (opts.maxBytes !== void 0 &&
|
|
4257
|
+
if (opts.maxBytes !== void 0 && fs11.statSync(transcriptPath).size > opts.maxBytes) {
|
|
3357
4258
|
return empty;
|
|
3358
4259
|
}
|
|
3359
|
-
lines =
|
|
4260
|
+
lines = fs11.readFileSync(transcriptPath, "utf-8").split("\n");
|
|
3360
4261
|
} catch {
|
|
3361
4262
|
return empty;
|
|
3362
4263
|
}
|
|
@@ -3543,7 +4444,7 @@ function detectPromissory(reply) {
|
|
|
3543
4444
|
function readCiSettled(workspaceRoot, session_id) {
|
|
3544
4445
|
if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
|
|
3545
4446
|
try {
|
|
3546
|
-
const raw =
|
|
4447
|
+
const raw = fs12.readFileSync(path10.join(workspaceRoot, statePathFor(session_id)), "utf-8");
|
|
3547
4448
|
const decoded = JSON.parse(raw);
|
|
3548
4449
|
if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
|
|
3549
4450
|
if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
|
|
@@ -3579,8 +4480,8 @@ function detectCompletionClaim(reply, ci) {
|
|
|
3579
4480
|
function readLanguagePin(workspaceRoot, session_id) {
|
|
3580
4481
|
if (!hasStableSessionId(session_id)) return "und";
|
|
3581
4482
|
try {
|
|
3582
|
-
const raw =
|
|
3583
|
-
|
|
4483
|
+
const raw = fs12.readFileSync(
|
|
4484
|
+
path10.join(workspaceRoot, statePathFor2(session_id)),
|
|
3584
4485
|
"utf-8"
|
|
3585
4486
|
);
|
|
3586
4487
|
const decoded = JSON.parse(raw);
|
|
@@ -3689,7 +4590,7 @@ function sessionStateFile2(workspaceRoot, sessionKey) {
|
|
|
3689
4590
|
}
|
|
3690
4591
|
function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
|
|
3691
4592
|
try {
|
|
3692
|
-
const raw =
|
|
4593
|
+
const raw = fs12.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
|
|
3693
4594
|
const decoded = JSON.parse(raw);
|
|
3694
4595
|
if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
|
|
3695
4596
|
return decoded["refused_turn"] === turnOrdinal;
|
|
@@ -3703,7 +4604,7 @@ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors, prom
|
|
|
3703
4604
|
const file = sessionStateFile2(workspaceRoot, sessionKey);
|
|
3704
4605
|
let prev = null;
|
|
3705
4606
|
try {
|
|
3706
|
-
prev = parseRecord(
|
|
4607
|
+
prev = parseRecord(fs12.readFileSync(file, "utf-8"));
|
|
3707
4608
|
} catch {
|
|
3708
4609
|
}
|
|
3709
4610
|
let version;
|
|
@@ -3806,14 +4707,44 @@ function runDetectors(inputs) {
|
|
|
3806
4707
|
}
|
|
3807
4708
|
return findings;
|
|
3808
4709
|
}
|
|
4710
|
+
function recordGraphFeeder(inputs, findings, layer) {
|
|
4711
|
+
if (is_replay_mode()) return;
|
|
4712
|
+
try {
|
|
4713
|
+
let state;
|
|
4714
|
+
try {
|
|
4715
|
+
state = graphState(inputs.workspaceRoot);
|
|
4716
|
+
} catch {
|
|
4717
|
+
return;
|
|
4718
|
+
}
|
|
4719
|
+
if (state === "absent") return;
|
|
4720
|
+
const paths = inputs.toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path).filter(_isProductionSource);
|
|
4721
|
+
const f = findings.find((x) => x.detector === "untested");
|
|
4722
|
+
appendFeederRow(
|
|
4723
|
+
inputs.workspaceRoot,
|
|
4724
|
+
inputs.sessionKey,
|
|
4725
|
+
buildFeederRow({
|
|
4726
|
+
turn: inputs.turnOrdinal,
|
|
4727
|
+
layer,
|
|
4728
|
+
state,
|
|
4729
|
+
fFired: f !== void 0,
|
|
4730
|
+
fMode: f?.mode ?? null,
|
|
4731
|
+
paths,
|
|
4732
|
+
graph: graphUntestedVerdict(inputs.workspaceRoot, state, paths)
|
|
4733
|
+
})
|
|
4734
|
+
);
|
|
4735
|
+
} catch {
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
3809
4738
|
function recordShadow(inputs, layer) {
|
|
3810
4739
|
if (is_replay_mode()) return;
|
|
3811
4740
|
try {
|
|
3812
4741
|
const findings = runDetectors(inputs);
|
|
4742
|
+
const setBy = layer === "refused_turn" ? "ours" : shadowSetBy(inputs.workspaceRoot, inputs.sessionKey);
|
|
4743
|
+
recordGraphFeeder(inputs, findings, layer);
|
|
3813
4744
|
const file = sessionShadowFile(inputs.workspaceRoot, inputs.sessionKey);
|
|
3814
4745
|
let prev = null;
|
|
3815
4746
|
try {
|
|
3816
|
-
prev = parseShadowRecord(
|
|
4747
|
+
prev = parseShadowRecord(fs12.readFileSync(file, "utf-8"));
|
|
3817
4748
|
} catch {
|
|
3818
4749
|
}
|
|
3819
4750
|
atomic_write_json(
|
|
@@ -3822,7 +4753,8 @@ function recordShadow(inputs, layer) {
|
|
|
3822
4753
|
detectors: findings.map((f) => f.detector),
|
|
3823
4754
|
turnOrdinal: inputs.turnOrdinal,
|
|
3824
4755
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3825
|
-
layer
|
|
4756
|
+
layer,
|
|
4757
|
+
setBy
|
|
3826
4758
|
})
|
|
3827
4759
|
);
|
|
3828
4760
|
} catch {
|
|
@@ -3851,6 +4783,7 @@ function main6() {
|
|
|
3851
4783
|
return EXIT_ALLOW3;
|
|
3852
4784
|
}
|
|
3853
4785
|
const findings = runDetectors(inputs);
|
|
4786
|
+
recordGraphFeeder(inputs, findings, "live");
|
|
3854
4787
|
if (findings.length === 0) return EXIT_ALLOW3;
|
|
3855
4788
|
markRefusedTurn(
|
|
3856
4789
|
inputs.workspaceRoot,
|
|
@@ -3879,13 +4812,13 @@ function _isCliEntry6() {
|
|
|
3879
4812
|
if (process.argv[1] === void 0) {
|
|
3880
4813
|
return false;
|
|
3881
4814
|
}
|
|
3882
|
-
const argvUrl = pathToFileURL6(
|
|
4815
|
+
const argvUrl = pathToFileURL6(path10.resolve(process.argv[1])).href;
|
|
3883
4816
|
if (import.meta.url === argvUrl) {
|
|
3884
4817
|
return true;
|
|
3885
4818
|
}
|
|
3886
4819
|
try {
|
|
3887
|
-
const here =
|
|
3888
|
-
const argv =
|
|
4820
|
+
const here = fs12.realpathSync(fileURLToPath6(import.meta.url));
|
|
4821
|
+
const argv = fs12.realpathSync(path10.resolve(process.argv[1]));
|
|
3889
4822
|
return here === argv;
|
|
3890
4823
|
} catch {
|
|
3891
4824
|
return false;
|
|
@@ -3898,8 +4831,8 @@ if (_isCliEntry6()) {
|
|
|
3898
4831
|
// src/scripts/hooks/evidence_independence.ts
|
|
3899
4832
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
3900
4833
|
import crypto3 from "node:crypto";
|
|
3901
|
-
import
|
|
3902
|
-
import
|
|
4834
|
+
import fs13 from "node:fs";
|
|
4835
|
+
import path11 from "node:path";
|
|
3903
4836
|
import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
|
|
3904
4837
|
|
|
3905
4838
|
// src/scripts/_lib/test_delta.ts
|
|
@@ -3918,7 +4851,7 @@ function isTestPath(p) {
|
|
|
3918
4851
|
}
|
|
3919
4852
|
|
|
3920
4853
|
// src/scripts/hooks/evidence_independence.ts
|
|
3921
|
-
var STATE_FILE3 =
|
|
4854
|
+
var STATE_FILE3 = path11.join("agents", "state", "evidence-dispatch.json");
|
|
3922
4855
|
function _isObject5(v) {
|
|
3923
4856
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3924
4857
|
}
|
|
@@ -3986,8 +4919,8 @@ function extractDispatch(envelope) {
|
|
|
3986
4919
|
}
|
|
3987
4920
|
function _ledgerStamp(consumer_root) {
|
|
3988
4921
|
try {
|
|
3989
|
-
const raw =
|
|
3990
|
-
|
|
4922
|
+
const raw = fs13.readFileSync(
|
|
4923
|
+
path11.join(consumer_root, "agents", "state", "git-authorization.json"),
|
|
3991
4924
|
"utf8"
|
|
3992
4925
|
);
|
|
3993
4926
|
const d = JSON.parse(raw);
|
|
@@ -3998,7 +4931,7 @@ function _ledgerStamp(consumer_root) {
|
|
|
3998
4931
|
}
|
|
3999
4932
|
function _load(target) {
|
|
4000
4933
|
try {
|
|
4001
|
-
const decoded = JSON.parse(
|
|
4934
|
+
const decoded = JSON.parse(fs13.readFileSync(target, "utf8"));
|
|
4002
4935
|
if (_isObject5(decoded) && Array.isArray(decoded["evaluations"])) {
|
|
4003
4936
|
return decoded;
|
|
4004
4937
|
}
|
|
@@ -4082,7 +5015,7 @@ function run3(stdin_text, options) {
|
|
|
4082
5015
|
return EXIT_ALLOW3;
|
|
4083
5016
|
}
|
|
4084
5017
|
}
|
|
4085
|
-
const target =
|
|
5018
|
+
const target = path11.join(options.consumer_root, STATE_FILE3);
|
|
4086
5019
|
const state = _load(target);
|
|
4087
5020
|
const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
|
|
4088
5021
|
const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
|
|
@@ -4150,13 +5083,13 @@ function _isCliEntry7() {
|
|
|
4150
5083
|
if (process.argv[1] === void 0) {
|
|
4151
5084
|
return false;
|
|
4152
5085
|
}
|
|
4153
|
-
const argvUrl = pathToFileURL7(
|
|
5086
|
+
const argvUrl = pathToFileURL7(path11.resolve(process.argv[1])).href;
|
|
4154
5087
|
if (import.meta.url === argvUrl) {
|
|
4155
5088
|
return true;
|
|
4156
5089
|
}
|
|
4157
5090
|
try {
|
|
4158
|
-
const here =
|
|
4159
|
-
const argv =
|
|
5091
|
+
const here = fs13.realpathSync(fileURLToPath7(import.meta.url));
|
|
5092
|
+
const argv = fs13.realpathSync(path11.resolve(process.argv[1]));
|
|
4160
5093
|
return here === argv;
|
|
4161
5094
|
} catch {
|
|
4162
5095
|
return false;
|
|
@@ -4167,8 +5100,8 @@ if (_isCliEntry7()) {
|
|
|
4167
5100
|
}
|
|
4168
5101
|
|
|
4169
5102
|
// src/scripts/hooks/delegation_nudge_hook.ts
|
|
4170
|
-
import
|
|
4171
|
-
import
|
|
5103
|
+
import fs14 from "node:fs";
|
|
5104
|
+
import path12 from "node:path";
|
|
4172
5105
|
import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
|
|
4173
5106
|
|
|
4174
5107
|
// src/scripts/_lib/auto_dispatch.ts
|
|
@@ -4668,13 +5601,13 @@ function _isCliEntry8() {
|
|
|
4668
5601
|
if (process.argv[1] === void 0) {
|
|
4669
5602
|
return false;
|
|
4670
5603
|
}
|
|
4671
|
-
const argvUrl = pathToFileURL8(
|
|
5604
|
+
const argvUrl = pathToFileURL8(path12.resolve(process.argv[1])).href;
|
|
4672
5605
|
if (import.meta.url === argvUrl) {
|
|
4673
5606
|
return true;
|
|
4674
5607
|
}
|
|
4675
5608
|
try {
|
|
4676
|
-
const here =
|
|
4677
|
-
const argv =
|
|
5609
|
+
const here = fs14.realpathSync(fileURLToPath8(import.meta.url));
|
|
5610
|
+
const argv = fs14.realpathSync(path12.resolve(process.argv[1]));
|
|
4678
5611
|
return here === argv;
|
|
4679
5612
|
} catch {
|
|
4680
5613
|
return false;
|
|
@@ -4685,7 +5618,7 @@ if (_isCliEntry8()) {
|
|
|
4685
5618
|
}
|
|
4686
5619
|
|
|
4687
5620
|
// src/scripts/conformance_scan.ts
|
|
4688
|
-
var REPO_ROOT =
|
|
5621
|
+
var REPO_ROOT = path13.resolve(path13.dirname(fileURLToPath9(import.meta.url)), "..", "..");
|
|
4689
5622
|
var OBSERVED_BAND = { low: 9.1, high: 39.2 };
|
|
4690
5623
|
var BAND_MIN_TURNS = 1978;
|
|
4691
5624
|
var CARRIER_CHANGES = [
|
|
@@ -5051,7 +5984,7 @@ function scanSession(sessionId, lines) {
|
|
|
5051
5984
|
closeWindow();
|
|
5052
5985
|
return report;
|
|
5053
5986
|
}
|
|
5054
|
-
var DEFAULT_RATE_SERIES =
|
|
5987
|
+
var DEFAULT_RATE_SERIES = path13.join(
|
|
5055
5988
|
REPO_ROOT,
|
|
5056
5989
|
"agents",
|
|
5057
5990
|
"runtime",
|
|
@@ -5060,7 +5993,7 @@ var DEFAULT_RATE_SERIES = path10.join(
|
|
|
5060
5993
|
);
|
|
5061
5994
|
function defaultStore(projectDir) {
|
|
5062
5995
|
const slug = projectStoreSlug(projectDir);
|
|
5063
|
-
return
|
|
5996
|
+
return path13.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
|
|
5064
5997
|
}
|
|
5065
5998
|
function _tokens(chars) {
|
|
5066
5999
|
return Math.round(chars / 4);
|
|
@@ -5071,13 +6004,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
|
|
|
5071
6004
|
return {
|
|
5072
6005
|
project: {
|
|
5073
6006
|
dir: projectRulesDir,
|
|
5074
|
-
present:
|
|
6007
|
+
present: fs15.existsSync(projectRulesDir),
|
|
5075
6008
|
files: p.files,
|
|
5076
6009
|
tokens: _tokens(p.chars)
|
|
5077
6010
|
},
|
|
5078
6011
|
global: {
|
|
5079
6012
|
dir: globalRulesDir,
|
|
5080
|
-
present:
|
|
6013
|
+
present: fs15.existsSync(globalRulesDir),
|
|
5081
6014
|
files: g.files,
|
|
5082
6015
|
tokens: _tokens(g.chars)
|
|
5083
6016
|
},
|
|
@@ -5085,13 +6018,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
|
|
|
5085
6018
|
};
|
|
5086
6019
|
}
|
|
5087
6020
|
function storeKey(store) {
|
|
5088
|
-
return
|
|
6021
|
+
return createHash4("sha256").update(path13.resolve(store)).digest("hex").slice(0, 12);
|
|
5089
6022
|
}
|
|
5090
6023
|
function scanStore(store, limit) {
|
|
5091
|
-
const files =
|
|
6024
|
+
const files = fs15.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs15.statSync(path13.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
|
|
5092
6025
|
const per_session = [];
|
|
5093
6026
|
for (const f of files) {
|
|
5094
|
-
const lines =
|
|
6027
|
+
const lines = fs15.readFileSync(path13.join(store, f), "utf8").split("\n");
|
|
5095
6028
|
const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
|
|
5096
6029
|
if (r.assistant_turns > 0) {
|
|
5097
6030
|
per_session.push(r);
|
|
@@ -5119,10 +6052,10 @@ function scanStore(store, limit) {
|
|
|
5119
6052
|
const task_completeness_rate_pct = completeness_windows === 0 ? 0 : Number((100 * task_completeness / completeness_windows).toFixed(1));
|
|
5120
6053
|
const era = spansCarrierChange(per_session.map((s) => s.first_at));
|
|
5121
6054
|
const delivered = measureDelivered(
|
|
5122
|
-
|
|
5123
|
-
|
|
6055
|
+
path13.join(REPO_ROOT, ".claude", "rules"),
|
|
6056
|
+
path13.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
|
|
5124
6057
|
);
|
|
5125
|
-
const ownStore =
|
|
6058
|
+
const ownStore = path13.resolve(store) === path13.resolve(defaultStore(REPO_ROOT));
|
|
5126
6059
|
return {
|
|
5127
6060
|
scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5128
6061
|
store,
|
|
@@ -5152,8 +6085,8 @@ function scanStore(store, limit) {
|
|
|
5152
6085
|
};
|
|
5153
6086
|
}
|
|
5154
6087
|
function recordRate(file, scanned_at, rate) {
|
|
5155
|
-
|
|
5156
|
-
|
|
6088
|
+
fs15.mkdirSync(path13.dirname(file), { recursive: true });
|
|
6089
|
+
fs15.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
|
|
5157
6090
|
`, "utf8");
|
|
5158
6091
|
}
|
|
5159
6092
|
function render(report) {
|
|
@@ -5284,14 +6217,14 @@ function main9(argv) {
|
|
|
5284
6217
|
return 2;
|
|
5285
6218
|
}
|
|
5286
6219
|
const resolved = store ?? defaultStore(process.cwd());
|
|
5287
|
-
if (!
|
|
6220
|
+
if (!fs15.existsSync(resolved)) {
|
|
5288
6221
|
process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
|
|
5289
6222
|
`);
|
|
5290
6223
|
return 1;
|
|
5291
6224
|
}
|
|
5292
6225
|
const report = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
|
|
5293
6226
|
if (out) {
|
|
5294
|
-
|
|
6227
|
+
fs15.writeFileSync(out, `${JSON.stringify(report, null, 2)}
|
|
5295
6228
|
`, "utf8");
|
|
5296
6229
|
}
|
|
5297
6230
|
if (record) {
|
|
@@ -5299,7 +6232,7 @@ function main9(argv) {
|
|
|
5299
6232
|
}
|
|
5300
6233
|
if (why !== null) {
|
|
5301
6234
|
const id = why;
|
|
5302
|
-
|
|
6235
|
+
fs15.writeSync(
|
|
5303
6236
|
1,
|
|
5304
6237
|
json ? `${JSON.stringify(
|
|
5305
6238
|
{
|
|
@@ -5319,7 +6252,7 @@ function main9(argv) {
|
|
|
5319
6252
|
);
|
|
5320
6253
|
return 0;
|
|
5321
6254
|
}
|
|
5322
|
-
|
|
6255
|
+
fs15.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
|
|
5323
6256
|
` : `${render(report)}
|
|
5324
6257
|
`);
|
|
5325
6258
|
return 0;
|
|
@@ -5331,13 +6264,13 @@ function _isCliEntry9() {
|
|
|
5331
6264
|
if (process.argv[1] === void 0) {
|
|
5332
6265
|
return false;
|
|
5333
6266
|
}
|
|
5334
|
-
const argvUrl = pathToFileURL9(
|
|
6267
|
+
const argvUrl = pathToFileURL9(path13.resolve(process.argv[1])).href;
|
|
5335
6268
|
if (import.meta.url === argvUrl) {
|
|
5336
6269
|
return true;
|
|
5337
6270
|
}
|
|
5338
6271
|
try {
|
|
5339
|
-
const here =
|
|
5340
|
-
const argv =
|
|
6272
|
+
const here = fs15.realpathSync(fileURLToPath9(import.meta.url));
|
|
6273
|
+
const argv = fs15.realpathSync(path13.resolve(process.argv[1]));
|
|
5341
6274
|
return here === argv;
|
|
5342
6275
|
} catch {
|
|
5343
6276
|
return false;
|
|
@@ -5348,19 +6281,19 @@ if (_isCliEntry9()) {
|
|
|
5348
6281
|
}
|
|
5349
6282
|
|
|
5350
6283
|
// src/scripts/report_carrier_divergence.ts
|
|
5351
|
-
import * as
|
|
6284
|
+
import * as fs16 from "node:fs";
|
|
5352
6285
|
import * as os3 from "node:os";
|
|
5353
|
-
import * as
|
|
6286
|
+
import * as path14 from "node:path";
|
|
5354
6287
|
import process2 from "node:process";
|
|
5355
6288
|
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
|
|
5356
6289
|
var _HERE2 = fileURLToPath10(import.meta.url);
|
|
5357
|
-
var REPO_ROOT2 =
|
|
5358
|
-
var PROJECT_RULES =
|
|
5359
|
-
var PROJECTION_SOURCE =
|
|
5360
|
-
var GLOBAL_RULES =
|
|
6290
|
+
var REPO_ROOT2 = path14.resolve(path14.dirname(_HERE2), "..", "..");
|
|
6291
|
+
var PROJECT_RULES = path14.join(".claude", "rules");
|
|
6292
|
+
var PROJECTION_SOURCE = path14.join("dist", "agent-src", "rules");
|
|
6293
|
+
var GLOBAL_RULES = path14.join(".claude", "rules");
|
|
5361
6294
|
function _listRules(dir) {
|
|
5362
6295
|
try {
|
|
5363
|
-
return
|
|
6296
|
+
return fs16.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
5364
6297
|
} catch {
|
|
5365
6298
|
return [];
|
|
5366
6299
|
}
|
|
@@ -5368,7 +6301,7 @@ function _listRules(dir) {
|
|
|
5368
6301
|
function _ruleType(file) {
|
|
5369
6302
|
let text;
|
|
5370
6303
|
try {
|
|
5371
|
-
text =
|
|
6304
|
+
text = fs16.readFileSync(file, "utf-8");
|
|
5372
6305
|
} catch {
|
|
5373
6306
|
return "";
|
|
5374
6307
|
}
|
|
@@ -5379,8 +6312,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
|
|
|
5379
6312
|
const out = {
|
|
5380
6313
|
projectDir,
|
|
5381
6314
|
globalDir,
|
|
5382
|
-
globalPresent:
|
|
5383
|
-
projectPresent:
|
|
6315
|
+
globalPresent: fs16.existsSync(globalDir),
|
|
6316
|
+
projectPresent: fs16.existsSync(projectDir),
|
|
5384
6317
|
shared: 0,
|
|
5385
6318
|
identical: [],
|
|
5386
6319
|
provenanceOnly: [],
|
|
@@ -5403,7 +6336,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
|
|
|
5403
6336
|
}
|
|
5404
6337
|
if (!inP && inG) {
|
|
5405
6338
|
out.globalOnly.push(rule);
|
|
5406
|
-
if (sourceDir !== void 0 && _ruleType(
|
|
6339
|
+
if (sourceDir !== void 0 && _ruleType(path14.join(sourceDir, rule)) === "manual") {
|
|
5407
6340
|
out.manualOnlyGlobal.push(rule);
|
|
5408
6341
|
}
|
|
5409
6342
|
continue;
|
|
@@ -5413,8 +6346,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
|
|
|
5413
6346
|
let projectCopy;
|
|
5414
6347
|
let globalCopy;
|
|
5415
6348
|
try {
|
|
5416
|
-
projectCopy =
|
|
5417
|
-
globalCopy =
|
|
6349
|
+
projectCopy = fs16.readFileSync(path14.join(projectDir, rule));
|
|
6350
|
+
globalCopy = fs16.readFileSync(path14.join(globalDir, rule));
|
|
5418
6351
|
verdict = comparePair(projectCopy, globalCopy);
|
|
5419
6352
|
} catch {
|
|
5420
6353
|
out.shared -= 1;
|
|
@@ -5561,9 +6494,9 @@ function render2(d) {
|
|
|
5561
6494
|
}
|
|
5562
6495
|
function main10(argv) {
|
|
5563
6496
|
const args = argv ?? process2.argv.slice(2);
|
|
5564
|
-
let projectDir =
|
|
5565
|
-
let globalDir =
|
|
5566
|
-
let sourceDir =
|
|
6497
|
+
let projectDir = path14.join(REPO_ROOT2, PROJECT_RULES);
|
|
6498
|
+
let globalDir = path14.join(os3.homedir(), GLOBAL_RULES);
|
|
6499
|
+
let sourceDir = path14.join(REPO_ROOT2, PROJECTION_SOURCE);
|
|
5567
6500
|
const value = (i) => {
|
|
5568
6501
|
const v = args[i + 1];
|
|
5569
6502
|
return v === void 0 || v.startsWith("-") ? null : v;
|
|
@@ -5577,7 +6510,7 @@ function main10(argv) {
|
|
|
5577
6510
|
`);
|
|
5578
6511
|
return 1;
|
|
5579
6512
|
}
|
|
5580
|
-
const resolved =
|
|
6513
|
+
const resolved = path14.resolve(v);
|
|
5581
6514
|
if (a === "--project") projectDir = resolved;
|
|
5582
6515
|
else if (a === "--global") globalDir = resolved;
|
|
5583
6516
|
else sourceDir = resolved;
|
|
@@ -5599,9 +6532,9 @@ function main10(argv) {
|
|
|
5599
6532
|
}
|
|
5600
6533
|
function _isCliEntry10() {
|
|
5601
6534
|
if (process2.argv[1] === void 0) return false;
|
|
5602
|
-
if (import.meta.url === pathToFileURL10(
|
|
6535
|
+
if (import.meta.url === pathToFileURL10(path14.resolve(process2.argv[1])).href) return true;
|
|
5603
6536
|
try {
|
|
5604
|
-
return
|
|
6537
|
+
return fs16.realpathSync(_HERE2) === fs16.realpathSync(path14.resolve(process2.argv[1]));
|
|
5605
6538
|
} catch {
|
|
5606
6539
|
return false;
|
|
5607
6540
|
}
|
|
@@ -5611,12 +6544,12 @@ if (_isCliEntry10()) {
|
|
|
5611
6544
|
}
|
|
5612
6545
|
|
|
5613
6546
|
// src/scripts/report_skill_activation.ts
|
|
5614
|
-
import * as
|
|
6547
|
+
import * as fs17 from "node:fs";
|
|
5615
6548
|
import * as os4 from "node:os";
|
|
5616
|
-
import * as
|
|
6549
|
+
import * as path15 from "node:path";
|
|
5617
6550
|
import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
|
|
5618
6551
|
var _HERE3 = fileURLToPath11(import.meta.url);
|
|
5619
|
-
var REPO_ROOT3 =
|
|
6552
|
+
var REPO_ROOT3 = path15.resolve(path15.dirname(_HERE3), "..", "..");
|
|
5620
6553
|
var SKILLS_ROOT = "src/skills";
|
|
5621
6554
|
var TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
|
|
5622
6555
|
var DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
|
|
@@ -5627,25 +6560,25 @@ function censusSkills(root) {
|
|
|
5627
6560
|
withTriggerCorpus: [],
|
|
5628
6561
|
withDeterministicObligation: []
|
|
5629
6562
|
};
|
|
5630
|
-
if (!
|
|
6563
|
+
if (!fs17.existsSync(root)) {
|
|
5631
6564
|
return out;
|
|
5632
6565
|
}
|
|
5633
|
-
for (const entry of
|
|
6566
|
+
for (const entry of fs17.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
5634
6567
|
if (!entry.isDirectory()) {
|
|
5635
6568
|
continue;
|
|
5636
6569
|
}
|
|
5637
|
-
const file =
|
|
5638
|
-
if (!
|
|
6570
|
+
const file = path15.join(root, entry.name, "SKILL.md");
|
|
6571
|
+
if (!fs17.existsSync(file)) {
|
|
5639
6572
|
continue;
|
|
5640
6573
|
}
|
|
5641
6574
|
out.total += 1;
|
|
5642
|
-
const text =
|
|
6575
|
+
const text = fs17.readFileSync(file, "utf8");
|
|
5643
6576
|
const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
|
|
5644
6577
|
const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
|
|
5645
6578
|
if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
|
|
5646
6579
|
out.withTriggerKey.push(entry.name);
|
|
5647
6580
|
}
|
|
5648
|
-
if (
|
|
6581
|
+
if (fs17.existsSync(path15.join(root, entry.name, "evals", "triggers.json"))) {
|
|
5649
6582
|
out.withTriggerCorpus.push(entry.name);
|
|
5650
6583
|
}
|
|
5651
6584
|
const body = fmEnd === -1 ? text : text.slice(fmEnd + 4);
|
|
@@ -5656,17 +6589,17 @@ function censusSkills(root) {
|
|
|
5656
6589
|
return out;
|
|
5657
6590
|
}
|
|
5658
6591
|
function defaultStore2(cwd) {
|
|
5659
|
-
return
|
|
6592
|
+
return path15.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
|
|
5660
6593
|
}
|
|
5661
6594
|
function measureUsage(store, limit) {
|
|
5662
6595
|
const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
|
|
5663
|
-
if (!
|
|
6596
|
+
if (!fs17.existsSync(store)) {
|
|
5664
6597
|
return rep;
|
|
5665
6598
|
}
|
|
5666
|
-
const files =
|
|
6599
|
+
const files = fs17.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path15.join(store, f)).sort((a, b) => fs17.statSync(b).mtimeMs - fs17.statSync(a).mtimeMs).slice(0, limit);
|
|
5667
6600
|
rep.sessions = files.length;
|
|
5668
6601
|
for (const file of files) {
|
|
5669
|
-
for (const line of
|
|
6602
|
+
for (const line of fs17.readFileSync(file, "utf8").split("\n")) {
|
|
5670
6603
|
if (!line.trim()) {
|
|
5671
6604
|
continue;
|
|
5672
6605
|
}
|
|
@@ -5739,15 +6672,15 @@ function buildRecord(census, usage, today) {
|
|
|
5739
6672
|
assistant_turns: usage.reduce((a, u) => a + u.assistantTurns, 0),
|
|
5740
6673
|
invocations: usage.reduce((a, u) => a + u.invocations, 0),
|
|
5741
6674
|
distinct_skills_invoked: distinct.size,
|
|
5742
|
-
stores: usage.map((u) =>
|
|
6675
|
+
stores: usage.map((u) => path15.basename(u.store))
|
|
5743
6676
|
};
|
|
5744
6677
|
}
|
|
5745
6678
|
function readRecord(repoRoot) {
|
|
5746
|
-
const file =
|
|
5747
|
-
if (!
|
|
6679
|
+
const file = path15.join(repoRoot, RECORD_PATH);
|
|
6680
|
+
if (!fs17.existsSync(file)) {
|
|
5748
6681
|
return null;
|
|
5749
6682
|
}
|
|
5750
|
-
return JSON.parse(
|
|
6683
|
+
return JSON.parse(fs17.readFileSync(file, "utf8"));
|
|
5751
6684
|
}
|
|
5752
6685
|
function render3(census, usage, published = null) {
|
|
5753
6686
|
const lines = [];
|
|
@@ -5782,7 +6715,7 @@ function render3(census, usage, published = null) {
|
|
|
5782
6715
|
}
|
|
5783
6716
|
totalInv += u.invocations;
|
|
5784
6717
|
lines.push(
|
|
5785
|
-
` ${
|
|
6718
|
+
` ${path15.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
|
|
5786
6719
|
);
|
|
5787
6720
|
}
|
|
5788
6721
|
lines.push("");
|
|
@@ -5886,7 +6819,7 @@ function main11(argv) {
|
|
|
5886
6819
|
if (stores.length === 0) {
|
|
5887
6820
|
stores.push(defaultStore2(REPO_ROOT3));
|
|
5888
6821
|
}
|
|
5889
|
-
const census = censusSkills(
|
|
6822
|
+
const census = censusSkills(path15.join(root, SKILLS_ROOT));
|
|
5890
6823
|
const usage = stores.map((s) => measureUsage(s, limit));
|
|
5891
6824
|
process.stdout.write(`${render3(census, usage, readRecord(root))}
|
|
5892
6825
|
`);
|
|
@@ -5907,27 +6840,27 @@ function main11(argv) {
|
|
|
5907
6840
|
return 1;
|
|
5908
6841
|
}
|
|
5909
6842
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5910
|
-
const file =
|
|
5911
|
-
|
|
5912
|
-
|
|
6843
|
+
const file = path15.join(root, RECORD_PATH);
|
|
6844
|
+
fs17.mkdirSync(path15.dirname(file), { recursive: true });
|
|
6845
|
+
fs17.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
|
|
5913
6846
|
`);
|
|
5914
6847
|
process.stdout.write(`
|
|
5915
6848
|
wrote ${RECORD_PATH} (measured ${today})
|
|
5916
6849
|
`);
|
|
5917
6850
|
return 0;
|
|
5918
6851
|
}
|
|
5919
|
-
if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(
|
|
6852
|
+
if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(path15.resolve(process.argv[1])).href) {
|
|
5920
6853
|
process.exit(main11(process.argv.slice(2)));
|
|
5921
6854
|
}
|
|
5922
6855
|
|
|
5923
6856
|
// src/scripts/report_skill_obligation_violations.ts
|
|
5924
|
-
import * as
|
|
6857
|
+
import * as fs18 from "node:fs";
|
|
5925
6858
|
import * as os5 from "node:os";
|
|
5926
|
-
import * as
|
|
6859
|
+
import * as path16 from "node:path";
|
|
5927
6860
|
import process3 from "node:process";
|
|
5928
6861
|
import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
|
|
5929
6862
|
var _HERE4 = fileURLToPath12(import.meta.url);
|
|
5930
|
-
var REPO_ROOT4 =
|
|
6863
|
+
var REPO_ROOT4 = path16.resolve(path16.dirname(_HERE4), "..", "..");
|
|
5931
6864
|
var OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
|
|
5932
6865
|
var PATH_RE = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
|
|
5933
6866
|
var CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
|
|
@@ -5965,7 +6898,7 @@ function _artefacts(line) {
|
|
|
5965
6898
|
return out;
|
|
5966
6899
|
}
|
|
5967
6900
|
function extractObligations(repoRoot) {
|
|
5968
|
-
const skillsRoot =
|
|
6901
|
+
const skillsRoot = path16.join(repoRoot, SKILLS_ROOT);
|
|
5969
6902
|
const census = censusSkills(skillsRoot);
|
|
5970
6903
|
const out = {
|
|
5971
6904
|
skills: census.withDeterministicObligation,
|
|
@@ -5979,7 +6912,7 @@ function extractObligations(repoRoot) {
|
|
|
5979
6912
|
for (const skill of census.withDeterministicObligation) {
|
|
5980
6913
|
let text;
|
|
5981
6914
|
try {
|
|
5982
|
-
text =
|
|
6915
|
+
text = fs18.readFileSync(path16.join(skillsRoot, skill, "SKILL.md"), "utf-8");
|
|
5983
6916
|
} catch {
|
|
5984
6917
|
continue;
|
|
5985
6918
|
}
|
|
@@ -6095,7 +7028,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
|
|
|
6095
7028
|
return flags;
|
|
6096
7029
|
}
|
|
6097
7030
|
function defaultStore3(cwd) {
|
|
6098
|
-
return
|
|
7031
|
+
return path16.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
|
|
6099
7032
|
}
|
|
6100
7033
|
function scanStore2(repoRoot, store, limit) {
|
|
6101
7034
|
const census = extractObligations(repoRoot);
|
|
@@ -6108,14 +7041,14 @@ function scanStore2(repoRoot, store, limit) {
|
|
|
6108
7041
|
};
|
|
6109
7042
|
let files;
|
|
6110
7043
|
try {
|
|
6111
|
-
files =
|
|
7044
|
+
files = fs18.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path16.join(store, f), m: fs18.statSync(path16.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
|
|
6112
7045
|
} catch {
|
|
6113
7046
|
return report;
|
|
6114
7047
|
}
|
|
6115
7048
|
report.sessions = files.length;
|
|
6116
7049
|
for (const file of files) {
|
|
6117
|
-
const lines =
|
|
6118
|
-
const id =
|
|
7050
|
+
const lines = fs18.readFileSync(file, "utf-8").split("\n");
|
|
7051
|
+
const id = path16.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
|
|
6119
7052
|
const entries = _parseSession(lines);
|
|
6120
7053
|
if (loadedSkillsFrom(entries).size > 0) report.sessionsWithASkill += 1;
|
|
6121
7054
|
report.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
|
|
@@ -6240,9 +7173,9 @@ function main12(argv) {
|
|
|
6240
7173
|
}
|
|
6241
7174
|
function _isCliEntry11() {
|
|
6242
7175
|
if (process3.argv[1] === void 0) return false;
|
|
6243
|
-
if (import.meta.url === pathToFileURL12(
|
|
7176
|
+
if (import.meta.url === pathToFileURL12(path16.resolve(process3.argv[1])).href) return true;
|
|
6244
7177
|
try {
|
|
6245
|
-
return
|
|
7178
|
+
return fs18.realpathSync(_HERE4) === fs18.realpathSync(path16.resolve(process3.argv[1]));
|
|
6246
7179
|
} catch {
|
|
6247
7180
|
return false;
|
|
6248
7181
|
}
|
|
@@ -6253,20 +7186,20 @@ if (_isCliEntry11()) {
|
|
|
6253
7186
|
|
|
6254
7187
|
// src/scripts/report_conformance_funnel.ts
|
|
6255
7188
|
var _HERE5 = fileURLToPath13(import.meta.url);
|
|
6256
|
-
var REPO_ROOT5 =
|
|
7189
|
+
var REPO_ROOT5 = path17.resolve(path17.dirname(_HERE5), "..", "..");
|
|
6257
7190
|
function buildFunnel(opts = {}) {
|
|
6258
7191
|
const repoRoot = opts.repoRoot ?? REPO_ROOT5;
|
|
6259
|
-
const projectRulesDir = opts.projectRulesDir ??
|
|
6260
|
-
const globalRulesDir = opts.globalRulesDir ??
|
|
6261
|
-
const sourceDir = opts.sourceDir ??
|
|
7192
|
+
const projectRulesDir = opts.projectRulesDir ?? path17.join(repoRoot, PROJECT_RULES);
|
|
7193
|
+
const globalRulesDir = opts.globalRulesDir ?? path17.join(os6.homedir(), GLOBAL_RULES);
|
|
7194
|
+
const sourceDir = opts.sourceDir ?? path17.join(repoRoot, PROJECTION_SOURCE);
|
|
6262
7195
|
const store = opts.store ?? defaultStore(repoRoot);
|
|
6263
7196
|
const limit = opts.limit ?? 30;
|
|
6264
7197
|
return {
|
|
6265
7198
|
delivered: measureDelivered(projectRulesDir, globalRulesDir),
|
|
6266
7199
|
divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
|
|
6267
|
-
skills: censusSkills(
|
|
7200
|
+
skills: censusSkills(path17.join(repoRoot, SKILLS_ROOT)),
|
|
6268
7201
|
usage: measureUsage(store, limit),
|
|
6269
|
-
storePresent:
|
|
7202
|
+
storePresent: fs19.existsSync(store),
|
|
6270
7203
|
sk2: scanStore2(repoRoot, store, limit)
|
|
6271
7204
|
};
|
|
6272
7205
|
}
|
|
@@ -6407,7 +7340,7 @@ function main13(argv) {
|
|
|
6407
7340
|
`);
|
|
6408
7341
|
return 1;
|
|
6409
7342
|
}
|
|
6410
|
-
const resolved =
|
|
7343
|
+
const resolved = path17.resolve(v);
|
|
6411
7344
|
if (a === "--store") opts.store = resolved;
|
|
6412
7345
|
else if (a === "--project") opts.projectRulesDir = resolved;
|
|
6413
7346
|
else if (a === "--global") opts.globalRulesDir = resolved;
|
|
@@ -6439,9 +7372,9 @@ function main13(argv) {
|
|
|
6439
7372
|
}
|
|
6440
7373
|
function _isCliEntry12() {
|
|
6441
7374
|
if (process4.argv[1] === void 0) return false;
|
|
6442
|
-
if (import.meta.url === pathToFileURL13(
|
|
7375
|
+
if (import.meta.url === pathToFileURL13(path17.resolve(process4.argv[1])).href) return true;
|
|
6443
7376
|
try {
|
|
6444
|
-
return
|
|
7377
|
+
return fs19.realpathSync(_HERE5) === fs19.realpathSync(path17.resolve(process4.argv[1]));
|
|
6445
7378
|
} catch {
|
|
6446
7379
|
return false;
|
|
6447
7380
|
}
|
|
@@ -6478,20 +7411,20 @@ function conformanceLogPath() {
|
|
|
6478
7411
|
if (override && override.trim().length > 0) {
|
|
6479
7412
|
return override;
|
|
6480
7413
|
}
|
|
6481
|
-
return
|
|
7414
|
+
return path18.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
|
|
6482
7415
|
}
|
|
6483
7416
|
function installLogPath() {
|
|
6484
7417
|
const override = process5.env["AGENT_CONFIG_INSTALL_LOG"];
|
|
6485
7418
|
if (override && override.trim().length > 0) {
|
|
6486
7419
|
return override;
|
|
6487
7420
|
}
|
|
6488
|
-
return
|
|
7421
|
+
return path18.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
|
|
6489
7422
|
}
|
|
6490
7423
|
function _installLogExpected(projectRoot) {
|
|
6491
|
-
return
|
|
7424
|
+
return fs20.existsSync(manifest_path(projectRoot));
|
|
6492
7425
|
}
|
|
6493
7426
|
function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
|
|
6494
|
-
const entries =
|
|
7427
|
+
const entries = fs20.existsSync(logPath) ? readRecentEntries(logPath) : [];
|
|
6495
7428
|
if (entries.length === 0) {
|
|
6496
7429
|
if (projectRoot !== null && _installLogExpected(projectRoot)) {
|
|
6497
7430
|
return {
|
|
@@ -6525,11 +7458,11 @@ function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
|
|
|
6525
7458
|
};
|
|
6526
7459
|
}
|
|
6527
7460
|
function routeTargetPaths(target) {
|
|
6528
|
-
return routeTargetPathsPosix(target).map((rel) =>
|
|
7461
|
+
return routeTargetPathsPosix(target).map((rel) => path18.join(...rel.split("/")));
|
|
6529
7462
|
}
|
|
6530
7463
|
function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
|
|
6531
|
-
const routerPath =
|
|
6532
|
-
if (!
|
|
7464
|
+
const routerPath = path18.join(packageRoot, "dist", "router.json");
|
|
7465
|
+
if (!fs20.existsSync(routerPath)) {
|
|
6533
7466
|
return {
|
|
6534
7467
|
id: "router-pointers",
|
|
6535
7468
|
status: "fail",
|
|
@@ -6539,7 +7472,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
|
|
|
6539
7472
|
}
|
|
6540
7473
|
let router;
|
|
6541
7474
|
try {
|
|
6542
|
-
router = JSON.parse(
|
|
7475
|
+
router = JSON.parse(fs20.readFileSync(routerPath, "utf8"));
|
|
6543
7476
|
} catch (exc) {
|
|
6544
7477
|
return {
|
|
6545
7478
|
id: "router-pointers",
|
|
@@ -6548,13 +7481,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
|
|
|
6548
7481
|
remedy: "reinstall the package \u2014 dist/router.json is corrupt"
|
|
6549
7482
|
};
|
|
6550
7483
|
}
|
|
6551
|
-
const rulesDir =
|
|
7484
|
+
const rulesDir = path18.join(packageRoot, "dist", "agent-src", "rules");
|
|
6552
7485
|
const broken = [];
|
|
6553
7486
|
let ids = 0;
|
|
6554
7487
|
let targets = 0;
|
|
6555
7488
|
for (const kernelId of router["kernel"] ?? []) {
|
|
6556
7489
|
ids += 1;
|
|
6557
|
-
if (!
|
|
7490
|
+
if (!fs20.existsSync(path18.join(rulesDir, `${kernelId}.md`))) {
|
|
6558
7491
|
broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
|
|
6559
7492
|
}
|
|
6560
7493
|
}
|
|
@@ -6562,7 +7495,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
|
|
|
6562
7495
|
for (const entry of router[tier] ?? []) {
|
|
6563
7496
|
const ruleId = String(entry["id"] ?? "");
|
|
6564
7497
|
ids += 1;
|
|
6565
|
-
if (!
|
|
7498
|
+
if (!fs20.existsSync(path18.join(rulesDir, `${ruleId}.md`))) {
|
|
6566
7499
|
broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
|
|
6567
7500
|
}
|
|
6568
7501
|
for (const target of entry["routes_to"] ?? []) {
|
|
@@ -6572,7 +7505,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
|
|
|
6572
7505
|
broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
|
|
6573
7506
|
continue;
|
|
6574
7507
|
}
|
|
6575
|
-
if (!candidates.some((rel) =>
|
|
7508
|
+
if (!candidates.some((rel) => fs20.existsSync(path18.join(packageRoot, rel)))) {
|
|
6576
7509
|
broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
|
|
6577
7510
|
}
|
|
6578
7511
|
}
|
|
@@ -6604,9 +7537,9 @@ function detectSmokePlatform(projectRoot) {
|
|
|
6604
7537
|
return "claude";
|
|
6605
7538
|
}
|
|
6606
7539
|
function dispatcherRunner(packageRoot) {
|
|
6607
|
-
const localTsx =
|
|
6608
|
-
const script =
|
|
6609
|
-
if (
|
|
7540
|
+
const localTsx = path18.join(packageRoot, "node_modules", ".bin", "tsx");
|
|
7541
|
+
const script = path18.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
|
|
7542
|
+
if (fs20.existsSync(localTsx)) {
|
|
6610
7543
|
return [localTsx, script];
|
|
6611
7544
|
}
|
|
6612
7545
|
return ["npx", "tsx", script];
|
|
@@ -6656,12 +7589,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT, opts =
|
|
|
6656
7589
|
};
|
|
6657
7590
|
}
|
|
6658
7591
|
function readSettingsMode(projectRoot) {
|
|
6659
|
-
const settingsPath =
|
|
6660
|
-
if (!
|
|
7592
|
+
const settingsPath = path18.join(projectRoot, ".agent-settings.yml");
|
|
7593
|
+
if (!fs20.existsSync(settingsPath)) {
|
|
6661
7594
|
return "eager-all";
|
|
6662
7595
|
}
|
|
6663
7596
|
try {
|
|
6664
|
-
const parsed = YAML.parse(
|
|
7597
|
+
const parsed = YAML.parse(fs20.readFileSync(settingsPath, "utf8"));
|
|
6665
7598
|
const lean = parsed?.["lean_projection"] ?? null;
|
|
6666
7599
|
const mode = lean?.["mode"];
|
|
6667
7600
|
return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
|
|
@@ -6672,7 +7605,7 @@ function readSettingsMode(projectRoot) {
|
|
|
6672
7605
|
function kernelIdsFromRouter(packageRoot) {
|
|
6673
7606
|
try {
|
|
6674
7607
|
const router = JSON.parse(
|
|
6675
|
-
|
|
7608
|
+
fs20.readFileSync(path18.join(packageRoot, "dist", "router.json"), "utf8")
|
|
6676
7609
|
);
|
|
6677
7610
|
return new Set((router["kernel"] ?? []).map(String));
|
|
6678
7611
|
} catch {
|
|
@@ -6689,8 +7622,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
|
|
|
6689
7622
|
remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
|
|
6690
7623
|
};
|
|
6691
7624
|
}
|
|
6692
|
-
const rulesDir = projectedRulesDir ??
|
|
6693
|
-
if (!
|
|
7625
|
+
const rulesDir = projectedRulesDir ?? path18.join(projectRoot, ".augment", "rules");
|
|
7626
|
+
if (!fs20.existsSync(rulesDir)) {
|
|
6694
7627
|
return {
|
|
6695
7628
|
id: "lean-projection",
|
|
6696
7629
|
status: "skipped",
|
|
@@ -6699,7 +7632,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
|
|
|
6699
7632
|
};
|
|
6700
7633
|
}
|
|
6701
7634
|
const kernel = kernelIdsFromRouter(packageRoot);
|
|
6702
|
-
const files =
|
|
7635
|
+
const files = fs20.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
|
|
6703
7636
|
const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
|
|
6704
7637
|
if (nonKernel.length === 0) {
|
|
6705
7638
|
return {
|
|
@@ -6713,7 +7646,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
|
|
|
6713
7646
|
for (const f of nonKernel) {
|
|
6714
7647
|
let text = "";
|
|
6715
7648
|
try {
|
|
6716
|
-
text =
|
|
7649
|
+
text = fs20.readFileSync(path18.join(rulesDir, f), "utf8");
|
|
6717
7650
|
} catch {
|
|
6718
7651
|
continue;
|
|
6719
7652
|
}
|
|
@@ -6744,8 +7677,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
|
|
|
6744
7677
|
function _check_host_manifest(projectRoot) {
|
|
6745
7678
|
const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
|
|
6746
7679
|
const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
|
|
6747
|
-
const settingsPath =
|
|
6748
|
-
if (!
|
|
7680
|
+
const settingsPath = path18.join(projectRoot, ".agent-settings.yml");
|
|
7681
|
+
if (!fs20.existsSync(settingsPath)) {
|
|
6749
7682
|
return {
|
|
6750
7683
|
id: "host-manifest",
|
|
6751
7684
|
status: "ok",
|
|
@@ -6755,7 +7688,7 @@ function _check_host_manifest(projectRoot) {
|
|
|
6755
7688
|
}
|
|
6756
7689
|
let parsed = null;
|
|
6757
7690
|
try {
|
|
6758
|
-
parsed = YAML.parse(
|
|
7691
|
+
parsed = YAML.parse(fs20.readFileSync(settingsPath, "utf8"));
|
|
6759
7692
|
} catch (exc) {
|
|
6760
7693
|
return {
|
|
6761
7694
|
id: "host-manifest",
|
|
@@ -6929,13 +7862,13 @@ function _isCliEntry13() {
|
|
|
6929
7862
|
if (process5.argv[1] === void 0) {
|
|
6930
7863
|
return false;
|
|
6931
7864
|
}
|
|
6932
|
-
const argvUrl = pathToFileURL14(
|
|
7865
|
+
const argvUrl = pathToFileURL14(path18.resolve(process5.argv[1])).href;
|
|
6933
7866
|
if (import.meta.url === argvUrl) {
|
|
6934
7867
|
return true;
|
|
6935
7868
|
}
|
|
6936
7869
|
try {
|
|
6937
|
-
const here =
|
|
6938
|
-
const argv =
|
|
7870
|
+
const here = fs20.realpathSync(fileURLToPath14(import.meta.url));
|
|
7871
|
+
const argv = fs20.realpathSync(path18.resolve(process5.argv[1]));
|
|
6939
7872
|
return here === argv;
|
|
6940
7873
|
} catch {
|
|
6941
7874
|
return false;
|