@event4u/agent-config 14.6.0 → 14.8.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +255 -145
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/inbox.md +264 -10
- package/dist/agent-src/commands/analyze.md +1 -1
- package/dist/agent-src/commands/evals/git-pr-merge.json +13 -0
- package/dist/agent-src/commands/evals/roadmap.json +17 -1
- package/dist/agent-src/commands/pr/create.md +14 -2
- package/dist/agent-src/commands/pr/merge.md +379 -0
- package/dist/agent-src/commands/roadmap/process-full.md +272 -32
- package/dist/agent-src/commands/roadmap.md +1 -1
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +46 -36
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +37 -2
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +95 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +289 -106
- package/dist/agent-src/rules/artifact-drafting-protocol.md +5 -1
- package/dist/agent-src/rules/context-hygiene.md +2 -0
- package/dist/agent-src/rules/decision-revisit-gate.md +67 -32
- package/dist/agent-src/rules/fix-what-you-see.md +108 -0
- package/dist/agent-src/rules/no-roadmap-references.md +0 -5
- package/dist/agent-src/rules/recurring-criticism.md +110 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +20 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -2
- package/dist/agent-src/rules/self-repair-loop.md +17 -0
- package/dist/agent-src/rules/skill-quality.md +0 -2
- package/dist/agent-src/rules/source-confidentiality.md +37 -7
- package/dist/agent-src/scripts/archival_sweep.ts +117 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
- package/dist/agent-src/scripts/dashboard_mode.ts +212 -0
- package/dist/agent-src/scripts/gate_budget.ts +282 -0
- package/dist/agent-src/scripts/gate_execute.ts +72 -31
- package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
- package/dist/agent-src/scripts/update_roadmap_progress.ts +296 -53
- package/dist/agent-src/skills/adr-create/SKILL.md +124 -5
- package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
- package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
- package/dist/agent-src/skills/decision-record/SKILL.md +61 -3
- package/dist/agent-src/skills/decision-review/SKILL.md +65 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +26 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
- package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
- package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
- package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
- package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
- package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
- package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
- package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
- package/dist/agent-src/skills/security/SKILL.md +8 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +12 -1
- package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
- package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
- package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
- package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +65 -4
- package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/dist/cli/registry.js +2 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
- package/dist/cli-delegate/{chunk-P6LQDIWK.js → chunk-7PRE6ZV2.js} +338 -0
- package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
- package/dist/cli-delegate/chunk-E4XIZDIB.js +402 -0
- package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-EEJUMCDZ.js} +16 -16
- package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
- package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-H4VIVD4C.js} +385 -284
- package/dist/cli-delegate/chunk-I3EIN2YG.js +36 -0
- package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-LPPWO5CE.js} +12 -8
- package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
- package/dist/cli-delegate/{chunk-UEZ7D35A.js → chunk-N7CDDGI3.js} +4 -23
- package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-PMEKGDED.js} +74 -167
- package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
- package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
- package/dist/cli-delegate/cmd_adr_effective.js +1162 -0
- package/dist/cli-delegate/cmd_conformance.js +466 -716
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +10 -10
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +10 -9
- package/dist/cli-delegate/cmd_handoff.js +10 -9
- package/dist/cli-delegate/cmd_memory_get.js +2 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +5 -5
- package/dist/cli-delegate/cmd_prune.js +11 -10
- package/dist/cli-delegate/cmd_route_audit.js +6 -5
- package/dist/cli-delegate/cmd_route_explain.js +3 -3
- package/dist/cli-delegate/cmd_session_recycle.js +840 -30
- package/dist/cli-delegate/cmd_settings_get.js +3 -3
- package/dist/cli-delegate/cmd_settings_migrate.js +10 -9
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +11 -10
- package/dist/cli-delegate/cmd_uninstall.js +13 -11
- package/dist/cli-delegate/cmd_update.js +4 -4
- package/dist/cli-delegate/cmd_upgrade.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +11 -10
- package/dist/cli-delegate/cmd_versions.js +3 -3
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +111 -37
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +15 -12
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +11 -8
- package/dist/hooks/dispatch.js +3165 -2192
- package/dist/install/claudePathsPlan.js +187 -0
- package/dist/install/claudePathsPlan.js.map +1 -0
- package/dist/install/globalRuleLayers.js +169 -0
- package/dist/install/globalRuleLayers.js.map +1 -0
- package/dist/install/hostLayerFingerprint.js +136 -0
- package/dist/install/hostLayerFingerprint.js.map +1 -0
- package/dist/install/install.mjs +553 -425
- package/dist/install/partitionEligibility.js +432 -0
- package/dist/install/partitionEligibility.js.map +1 -0
- package/dist/install/ruleLayerPartition.js +157 -0
- package/dist/install/ruleLayerPartition.js.map +1 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1863 -1234
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_src.js +41 -0
- package/dist/scripts/_lib/agent_src.js.map +1 -1
- package/dist/scripts/_lib/install_layout.js +83 -0
- package/dist/scripts/_lib/install_layout.js.map +1 -0
- package/dist/scripts/_lib/installed_lock.js +444 -0
- package/dist/scripts/_lib/installed_lock.js.map +1 -0
- package/dist/scripts/_lib/prune_empty_dirs.js +85 -0
- package/dist/scripts/_lib/prune_empty_dirs.js.map +1 -0
- package/dist/scripts/condense.js +63 -251
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/contracts/settings-classes.md +12 -6
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +45 -1
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
- package/docs/guidelines/agent-infra/false-green.md +47 -1
- package/docs/guidelines/agent-infra/memory-access.md +17 -0
- package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
- package/package.json +1 -1
- package/src/agent-src/scripts/archival_sweep.ts +117 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
- package/src/agent-src/scripts/dashboard_mode.ts +212 -0
- package/src/agent-src/scripts/gate_budget.ts +282 -0
- package/src/agent-src/scripts/gate_execute.ts +72 -31
- package/src/agent-src/scripts/roadmap_gates.ts +74 -3
- package/src/agent-src/scripts/update_roadmap_progress.ts +296 -53
- package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/src/config/agent-settings.template.yml +27 -2
- package/src/config/ci-local-parity.yml +39 -0
- package/src/config/estate-count-budget.json +612 -3
- package/src/config/evaluator-budgets.json +3 -3
- package/src/config/gate-coverage.yml +220 -12
- package/src/config/gate-violation-baselines.json +73 -63
- package/src/config/gitignore-block.txt +15 -2
- package/src/config/hook-latency-budget.json +5 -0
- package/src/config/rule-activation-census.json +14 -6
- package/src/config/rule-stub-ceilings.json +34 -7
- package/src/install/claudePathsPlan.ts +196 -0
- package/src/install/globalRuleLayers.ts +197 -0
- package/src/install/hostLayerFingerprint.ts +145 -0
- package/src/install/partitionEligibility.ts +502 -0
- package/src/install/ruleLayerPartition.ts +212 -0
- package/src/scripts/_cli/cmd_adr_effective.ts +484 -0
- package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
- package/src/scripts/_dispatch.bash +17 -1
- package/src/scripts/_lib/ac_heading.ts +30 -0
- package/src/scripts/_lib/adr_frontmatter.test.ts +365 -0
- package/src/scripts/_lib/adr_frontmatter.ts +459 -0
- package/src/scripts/_lib/agent_src.ts +42 -0
- package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
- package/src/scripts/_lib/envelope_grounding.ts +49 -9
- package/src/scripts/_lib/installed_lock.ts +50 -5
- package/src/scripts/_lib/layer_overlap_notice.ts +11 -2
- package/src/scripts/_lib/md_section.ts +129 -0
- package/src/scripts/_lib/prune_empty_dirs.ts +80 -0
- package/src/scripts/_lib/scope_guard.sh +26 -3
- package/src/scripts/_lib/self_repair.ts +19 -0
- package/src/scripts/_lib/self_repair_class_b.ts +171 -0
- package/src/scripts/adr/evidence_census.ts +899 -0
- package/src/scripts/adr/regenerate_index.ts +12 -32
- package/src/scripts/adr_cite_check.ts +540 -39
- package/src/scripts/ai_council/cli_help.ts +55 -0
- package/src/scripts/audit_adr_coverage.ts +103 -17
- package/src/scripts/before_complete_hook.ts +153 -28
- package/src/scripts/bench_ab_v2_complexity.ts +27 -7
- package/src/scripts/bench_hook_latency.ts +204 -0
- package/src/scripts/build_archive_index.ts +34 -0
- package/src/scripts/check_adr_frontmatter.ts +574 -39
- package/src/scripts/check_hook_bundle_content.ts +219 -0
- package/src/scripts/check_new_adr_evidence.ts +529 -0
- package/src/scripts/check_references.ts +78 -0
- package/src/scripts/check_release_published.ts +32 -11
- package/src/scripts/check_rule_layer_partition.ts +531 -0
- package/src/scripts/check_single_delivery.ts +194 -17
- package/src/scripts/check_standing_rule_delivery.ts +8 -2
- package/src/scripts/ci_settle.ts +170 -0
- package/src/scripts/condense.ts +79 -259
- package/src/scripts/council_cli.ts +3 -3
- package/src/scripts/dispatch_r2_reviewer.ts +6 -14
- package/src/scripts/external_sources_denylist.json +4 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +77 -14
- package/src/scripts/hooks/block_no_verify.ts +61 -10
- package/src/scripts/hooks/block_unauthorized_git.ts +21 -1
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/dispatch_hook.ts +154 -187
- package/src/scripts/hooks/dispatch_issues.ts +38 -19
- package/src/scripts/hooks/fallback_yaml.ts +66 -0
- package/src/scripts/hooks/host_semantics.ts +21 -0
- package/src/scripts/hooks/injection_budget.ts +13 -3
- package/src/scripts/hooks/py_json_dumps.ts +103 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
- package/src/scripts/hooks/run_continuation_hook.ts +8 -5
- package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
- package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
- package/src/scripts/hooks/state_io.ts +870 -21
- package/src/scripts/hooks/stdin_failure_policy.ts +96 -0
- package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
- package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
- package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
- package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
- package/src/scripts/injection_scan_hook.ts +137 -5
- package/src/scripts/install.ts +16 -11
- package/src/scripts/language_mirror_hook.ts +561 -25
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_hook_manifest.ts +49 -0
- package/src/scripts/lint_plan_risk_register.ts +4 -3
- package/src/scripts/lint_provenance_vocabulary.ts +472 -4
- package/src/scripts/lint_skill_router_head.ts +4 -4
- package/src/scripts/mcp_server/tools.ts +2 -2
- package/src/scripts/new_roadmap.ts +136 -0
- package/src/scripts/pack_mcp_content.ts +20 -5
- package/src/scripts/release.ts +37 -38
- package/src/scripts/report_layer_overlap.ts +6 -0
- package/src/scripts/routing_doctor.ts +5 -1
- package/src/scripts/self_repair_hook.ts +37 -5
- package/src/scripts/session_register_hook.ts +11 -0
- package/src/scripts/skill_usage_collect.ts +11 -1
- package/src/scripts/skill_usage_report.ts +278 -8
- package/src/scripts/sync_pr_branch.ts +170 -20
- package/src/server/schemas/settings.ts +8 -0
- package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
- package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
- package/dist/cli-delegate/{chunk-PPQO4NGR.js → chunk-6RJA2F5A.js} +3 -3
- package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
- package/dist/cli-delegate/{chunk-FBKL6JWT.js → chunk-MMSGVZKV.js} +3 -3
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `json.dumps(obj, indent=n)` byte-for-byte, extracted from `dispatch_hook.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Pure and self-contained: it recurses into itself and calls nothing else, which
|
|
5
|
+
* is what made it safe to move out of a dispatcher that runs on every tool call.
|
|
6
|
+
* Extracted because dispatch_hook.ts sits at the 1500-line source ceiling.
|
|
7
|
+
*
|
|
8
|
+
* For anyone tempted to share it: mcp_telemetry_store, mcp_telemetry_query and
|
|
9
|
+
* mcp_telemetry_health each define their OWN `_py_json_dumps`. They were left
|
|
10
|
+
* alone — unifying four copies is a change with its own risk, not a merge-time
|
|
11
|
+
* side effect.
|
|
12
|
+
*/
|
|
13
|
+
// Python json.dumps(record, indent=2) byte-for-byte (ensure_ascii=True).
|
|
14
|
+
export function _py_json_dumps(value: unknown, indent: number): string {
|
|
15
|
+
const pad = " ".repeat(indent);
|
|
16
|
+
const escapeString = (s: string): string => {
|
|
17
|
+
let out = '"';
|
|
18
|
+
for (const ch of s) {
|
|
19
|
+
const code = ch.codePointAt(0) as number;
|
|
20
|
+
switch (ch) {
|
|
21
|
+
case '"':
|
|
22
|
+
out += '\\"';
|
|
23
|
+
break;
|
|
24
|
+
case "\\":
|
|
25
|
+
out += "\\\\";
|
|
26
|
+
break;
|
|
27
|
+
case "\n":
|
|
28
|
+
out += "\\n";
|
|
29
|
+
break;
|
|
30
|
+
case "\r":
|
|
31
|
+
out += "\\r";
|
|
32
|
+
break;
|
|
33
|
+
case "\t":
|
|
34
|
+
out += "\\t";
|
|
35
|
+
break;
|
|
36
|
+
case "\b":
|
|
37
|
+
out += "\\b";
|
|
38
|
+
break;
|
|
39
|
+
case "\f":
|
|
40
|
+
out += "\\f";
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
if (code < 0x20 || code > 0x7e) {
|
|
44
|
+
if (code > 0xffff) {
|
|
45
|
+
const c = code - 0x10000;
|
|
46
|
+
const hi = 0xd800 + (c >> 10);
|
|
47
|
+
const lo = 0xdc00 + (c & 0x3ff);
|
|
48
|
+
out +=
|
|
49
|
+
"\\u" +
|
|
50
|
+
hi.toString(16).padStart(4, "0") +
|
|
51
|
+
"\\u" +
|
|
52
|
+
lo.toString(16).padStart(4, "0");
|
|
53
|
+
} else {
|
|
54
|
+
out += "\\u" + code.toString(16).padStart(4, "0");
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
out += ch;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return out + '"';
|
|
62
|
+
};
|
|
63
|
+
const render = (v: unknown, depth: number): string => {
|
|
64
|
+
if (v === null || v === undefined) return "null";
|
|
65
|
+
if (typeof v === "boolean") return v ? "true" : "false";
|
|
66
|
+
if (typeof v === "number") {
|
|
67
|
+
if (!Number.isFinite(v)) {
|
|
68
|
+
if (Number.isNaN(v)) return "NaN";
|
|
69
|
+
return v > 0 ? "Infinity" : "-Infinity";
|
|
70
|
+
}
|
|
71
|
+
return String(v);
|
|
72
|
+
}
|
|
73
|
+
if (typeof v === "string") return escapeString(v);
|
|
74
|
+
const curPad = pad.repeat(depth + 1);
|
|
75
|
+
const closePad = pad.repeat(depth);
|
|
76
|
+
if (Array.isArray(v)) {
|
|
77
|
+
if (v.length === 0) return "[]";
|
|
78
|
+
return (
|
|
79
|
+
"[\n" +
|
|
80
|
+
v.map((item) => curPad + render(item, depth + 1)).join(",\n") +
|
|
81
|
+
"\n" +
|
|
82
|
+
closePad +
|
|
83
|
+
"]"
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (typeof v === "object") {
|
|
87
|
+
const obj = v as Record<string, unknown>;
|
|
88
|
+
const keys = Object.keys(obj);
|
|
89
|
+
if (keys.length === 0) return "{}";
|
|
90
|
+
return (
|
|
91
|
+
"{\n" +
|
|
92
|
+
keys
|
|
93
|
+
.map((k) => curPad + escapeString(k) + ": " + render(obj[k], depth + 1))
|
|
94
|
+
.join(",\n") +
|
|
95
|
+
"\n" +
|
|
96
|
+
closePad +
|
|
97
|
+
"}"
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
throw new TypeError(`Object of type ${typeof v} is not JSON serializable`);
|
|
101
|
+
};
|
|
102
|
+
return render(value, 0);
|
|
103
|
+
}
|
|
@@ -155,14 +155,19 @@ export function classify(command: string): Eligibility {
|
|
|
155
155
|
|
|
156
156
|
let tokens: string[];
|
|
157
157
|
try {
|
|
158
|
-
tokens = shlexSplit(cmd);
|
|
158
|
+
tokens = shlexSplit(cmd, true);
|
|
159
159
|
} catch (e) {
|
|
160
160
|
if (e instanceof ShlexError) return { eligible: false, reason_skip: "parse-error" };
|
|
161
161
|
throw e;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
// Compound / piped → don't wrap (rtk wraps a single command). `_split_subcommands`
|
|
165
|
-
// splits on && || ; | — more than one group means a pipeline/chain.
|
|
165
|
+
// splits on && || ; | & — more than one group means a pipeline/chain.
|
|
166
|
+
// `splitOperators` is REQUIRED here: POSIX shlex leaves a separator attached
|
|
167
|
+
// to the preceding word, so `foo; bar` tokenised to one group and read as a
|
|
168
|
+
// single command. Same construct as the block_no_verify defect measured
|
|
169
|
+
// 2026-08-20; found by the sibling search for that fix, 2 call sites, both
|
|
170
|
+
// in this file.
|
|
166
171
|
const groups = _split_subcommands(tokens);
|
|
167
172
|
if (groups.length !== 1) return { eligible: false, reason_skip: "compound-or-piped" };
|
|
168
173
|
|
|
@@ -256,7 +261,7 @@ export function classifyCap(
|
|
|
256
261
|
if (!cmd) return null;
|
|
257
262
|
let tokens: string[];
|
|
258
263
|
try {
|
|
259
|
-
tokens = shlexSplit(cmd);
|
|
264
|
+
tokens = shlexSplit(cmd, true);
|
|
260
265
|
} catch (e) {
|
|
261
266
|
if (e instanceof ShlexError) return null;
|
|
262
267
|
throw e;
|
|
@@ -72,12 +72,15 @@
|
|
|
72
72
|
* duplicate, whatever the counts say.
|
|
73
73
|
* scope complete (0 open,
|
|
74
74
|
* none blocked) → allow (event: complete; state cleared)
|
|
75
|
-
*
|
|
76
|
-
* (0 open, ≥1
|
|
75
|
+
* remaining work externally
|
|
76
|
+
* impossible (0 open, ≥1
|
|
77
|
+
* blocked) → allow (event: blocked, ONCE per run, guarded by
|
|
77
78
|
* the LEDGER: the state is cleared like `complete`,
|
|
78
|
-
* so no field there outlives the event.
|
|
79
|
-
*
|
|
80
|
-
* `HALT_ACTIONS`, never stamped into `halted
|
|
79
|
+
* so no field there outlives the event. A terminal
|
|
80
|
+
* outcome — not a sixth halt, never in
|
|
81
|
+
* `HALT_ACTIONS`, never stamped into `halted`.
|
|
82
|
+
* ADR-237 narrows what may legally wear a
|
|
83
|
+
* `blocked-by:` marker; semantics unchanged.)
|
|
81
84
|
* iterations ≥ MAX (25) → allow (event: halt-max-iterations)
|
|
82
85
|
* wall clock ≥ cap (4 h) → allow (event: halt-wall-clock)
|
|
83
86
|
* stall (3 engagements, no
|
|
@@ -33,6 +33,7 @@ import path from 'node:path';
|
|
|
33
33
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
34
34
|
|
|
35
35
|
import { readHookStdin } from './hook_stdin.js';
|
|
36
|
+
import { isPayloadStub } from './payload_stub.js';
|
|
36
37
|
import { atomic_write_json } from './state_io.js';
|
|
37
38
|
|
|
38
39
|
export const STATE_FILE = path.join('agents', 'state', 'ship-diff-volume.json');
|
|
@@ -89,31 +90,96 @@ export function correctedVolume(numstat: string): { volume: number; excluded: nu
|
|
|
89
90
|
return { volume, excluded, files };
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Tools that carry a shell command. Mirrors `block_unauthorized_git`'s set.
|
|
95
|
+
*
|
|
96
|
+
* `SHIP_PATTERNS` are unanchored, so without this gate a `grep` for the string
|
|
97
|
+
* `git push` spawns two `git` subprocesses on a blocking slot. ALLOW-list: a
|
|
98
|
+
* named tool outside it is declined, so an unlisted host shell goes dark until
|
|
99
|
+
* added — the trade that sibling already makes while BLOCKING. A payload naming
|
|
100
|
+
* no tool still reads; that is the bare-host shape, with nothing to gate on.
|
|
101
|
+
*/
|
|
102
|
+
const COMMAND_TOOLS: ReadonlySet<string> = new Set([
|
|
103
|
+
'launch-process',
|
|
104
|
+
'launch_process',
|
|
105
|
+
'Bash',
|
|
106
|
+
'BashTool',
|
|
107
|
+
'run-process',
|
|
108
|
+
'runProcess',
|
|
109
|
+
'shell',
|
|
110
|
+
'execute_shell',
|
|
111
|
+
'RunShellCommand',
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
function isObj(v: unknown): v is Record<string, unknown> {
|
|
115
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Descend to the platform payload.
|
|
120
|
+
*
|
|
121
|
+
* The dispatcher nests the host-shaped tool fields under `payload`
|
|
122
|
+
* (`_build_envelope`); a bare host invocation puts them at the top level. This
|
|
123
|
+
* concern shipped reading the top level ONLY, so under the real dispatcher it
|
|
124
|
+
* found nothing and returned `''` every time — it ran, cost a dispatch, and
|
|
125
|
+
* could never fire.
|
|
126
|
+
*
|
|
127
|
+
* Deliberately NOT `envelope.ts`'s shared `unwrap`, which descends only when all
|
|
128
|
+
* four `ENVELOPE_KEYS` are present: a partial envelope would return this concern
|
|
129
|
+
* to its pre-fix dead state with no test noticing. `design-slop` and
|
|
130
|
+
* `ui-route-nudge` each carry their own local descent for the same reason.
|
|
131
|
+
*/
|
|
132
|
+
function payloadOf(root: Record<string, unknown>): Record<string, unknown> {
|
|
133
|
+
const inner = root['payload'];
|
|
134
|
+
return isObj(inner) ? inner : root;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The ship command, or `''` when this payload does not carry one. */
|
|
138
|
+
function shipCommandFrom(payload: Record<string, unknown>): string {
|
|
139
|
+
const toolRaw = payload['tool_name'] ?? payload['toolName'] ?? payload['tool'];
|
|
140
|
+
if (typeof toolRaw === 'string' && !COMMAND_TOOLS.has(toolRaw)) return '';
|
|
141
|
+
|
|
142
|
+
const ti = payload['tool_input'] ?? payload['toolInput'];
|
|
143
|
+
if (isPayloadStub(ti)) {
|
|
144
|
+
// Body omitted despite `needs_payload_bodies: [input]`. A bare '' here is
|
|
145
|
+
// indistinguishable from "no ship verb" — the silent death this file was
|
|
146
|
+
// fixed to remove — so say so instead of dying quietly again.
|
|
147
|
+
process.stderr.write(
|
|
148
|
+
'ship-diff-volume: tool_input arrived stubbed; the concern declares ' +
|
|
149
|
+
'needs_payload_bodies: [input] and cannot read a command without it.\n',
|
|
150
|
+
);
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
if (isObj(ti)) {
|
|
154
|
+
const c = ti['command'];
|
|
96
155
|
if (typeof c === 'string') return c;
|
|
97
156
|
}
|
|
98
|
-
const c =
|
|
157
|
+
const c = payload['command'];
|
|
99
158
|
return typeof c === 'string' ? c : '';
|
|
100
159
|
}
|
|
101
160
|
|
|
161
|
+
/**
|
|
162
|
+
* The stdin boundary: raw concern stdin → the ship command. Exported so a
|
|
163
|
+
* regression drives the boundary rather than the extractor. Never throws.
|
|
164
|
+
*/
|
|
165
|
+
export function commandFromStdin(raw: string): string {
|
|
166
|
+
if (!raw.trim()) return '';
|
|
167
|
+
let root: unknown;
|
|
168
|
+
try {
|
|
169
|
+
root = JSON.parse(raw);
|
|
170
|
+
} catch {
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
if (!isObj(root)) return '';
|
|
174
|
+
return shipCommandFrom(payloadOf(root));
|
|
175
|
+
}
|
|
176
|
+
|
|
102
177
|
export function main(argv?: string[]): number {
|
|
103
178
|
const args = argv ?? process.argv.slice(2);
|
|
104
179
|
const idx = args.indexOf('--command');
|
|
105
180
|
let cmd = idx >= 0 && args[idx + 1] !== undefined ? args[idx + 1]! : '';
|
|
106
181
|
if (!cmd) {
|
|
107
|
-
|
|
108
|
-
let envelope: Record<string, unknown> = {};
|
|
109
|
-
if (raw.trim()) {
|
|
110
|
-
try {
|
|
111
|
-
envelope = JSON.parse(raw) as Record<string, unknown>;
|
|
112
|
-
} catch {
|
|
113
|
-
envelope = {};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
cmd = extractCommand(envelope);
|
|
182
|
+
cmd = commandFromStdin(readHookStdin());
|
|
117
183
|
}
|
|
118
184
|
if (!isShipCommand(cmd)) return 0;
|
|
119
185
|
|