@event4u/agent-config 14.18.0 → 14.20.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 +120 -129
- package/README.md +71 -149
- package/dist/agent-src/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +44 -43
- package/dist/agent-src/commands/review/changes.md +19 -19
- package/dist/agent-src/commands/review.md +2 -2
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +37 -4
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +1 -1
- package/dist/agent-src/rules/session-canary.md +2 -2
- package/dist/agent-src/rules/token-efficiency.md +1 -1
- package/dist/agent-src/rules/untrusted-input-defense.md +0 -2
- package/dist/agent-src/skills/adversarial-review/SKILL.md +0 -8
- package/dist/agent-src/skills/canvas-design/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/data/app-interface.csv +1 -1
- package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -17
- package/dist/agent-src/skills/design-intelligence/data/ux-guidelines.csv +2 -2
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +17 -0
- package/dist/agent-src/skills/design-intelligence/references/design-rules-checklist.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/design-variations/SKILL.md +1 -1
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +32 -5
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +7 -0
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +47 -2
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +3 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +0 -6
- package/dist/agent-src/skills/react-native-setup/SKILL.md +3 -3
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +18 -8
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +28 -6
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -3
- package/dist/agent-src/skills/ui-apply-generic/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +17 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +14 -1
- package/dist/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/dist/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/dist/cli/commands/recordTriggerEval.js +2 -2
- package/dist/cli/main.js +1 -1
- package/dist/cli/mcp/dispatch.js +10 -0
- package/dist/cli/mcp/stdio.js +33 -2
- package/dist/cli/mcp/telemetry.js +227 -0
- package/dist/cli-delegate/{chunk-AKJGUQNO.js → chunk-C6IPZRDA.js} +484 -353
- package/dist/cli-delegate/{chunk-CYH5SP6M.js → chunk-I6RHFQEG.js} +151 -16
- package/dist/cli-delegate/{chunk-7RXIKF62.js → chunk-NUMQHLS5.js} +304 -136
- package/dist/cli-delegate/{chunk-PMEKGDED.js → chunk-PI2GU3DP.js} +163 -1
- package/dist/cli-delegate/{chunk-7PRE6ZV2.js → chunk-YS6XTLEK.js} +199 -4
- package/dist/cli-delegate/chunk-ZVBOHSVF.js +1109 -0
- package/dist/cli-delegate/cmd_adr_effective.js +318 -81
- package/dist/cli-delegate/cmd_conformance.js +489 -121
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +42 -12
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_session_recycle.js +59 -902
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +34 -33
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +4455 -3025
- package/dist/install/install.mjs +975 -689
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2087 -1134
- package/dist/scripts/_lib/model_tier.js +1 -1
- package/dist/scripts/mcp_server/telemetry.js +148 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/naming.md +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/security-lint-containment.md +46 -6
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +4 -4
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +1 -1
- package/docs/guidelines/design-antipatterns.md +87 -64
- package/docs/guidelines/redundancy-taxonomy.md +28 -0
- package/package.json +1 -1
- package/src/agent-src/README.md +1 -1
- package/src/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/src/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/src/config/assurance-capability-registry.json +9 -0
- package/src/config/ci-local-parity.yml +6 -0
- package/src/config/gate-coverage.yml +225 -0
- package/src/config/gate-violation-baselines.json +18 -6
- package/src/config/release-gate-locality.yml +12 -0
- package/src/scripts/_cli/cmd_doctor.ts +2 -2
- package/src/scripts/_cli/cmd_handoff.ts +1 -1
- package/src/scripts/_cli/cmd_session_recycle.ts +51 -3
- package/src/scripts/_cli/cmd_update.ts +1 -1
- package/src/scripts/_cli/cmd_versions.ts +1 -1
- package/src/scripts/_lib/adr_frontmatter.ts +44 -0
- package/src/scripts/_lib/audit_field_provenance.ts +44 -3
- package/src/scripts/_lib/consequence_objects.ts +152 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +2 -2
- package/src/scripts/_lib/host_capability.ts +38 -0
- package/src/scripts/_lib/host_permission_checks.ts +251 -0
- package/src/scripts/_lib/install_reach_checks.ts +33 -1
- package/src/scripts/_lib/mcp_bridge.ts +222 -10
- package/src/scripts/_lib/mcp_consent_residual.ts +173 -0
- package/src/scripts/_lib/model_tier.ts +1 -1
- package/src/scripts/_lib/obligation_frequency.ts +2 -2
- package/src/scripts/_lib/orchestration_record.ts +23 -1
- package/src/scripts/_lib/recycle_envelope_paths.ts +190 -0
- package/src/scripts/_lib/release_highlights.ts +93 -0
- package/src/scripts/_lib/release_material.ts +64 -1
- package/src/scripts/_lib/release_position.ts +96 -0
- package/src/scripts/_lib/review_skipped_record.ts +17 -1
- package/src/scripts/_lib/runtime_journal.ts +26 -3
- package/src/scripts/_lib/runtime_wiring_checks.ts +12 -1
- package/src/scripts/_lib/security_lint.ts +179 -7
- package/src/scripts/_lib/self_repair.ts +141 -6
- package/src/scripts/_lib/self_repair_store.ts +273 -7
- package/src/scripts/_lib/session_register.ts +11 -6
- package/src/scripts/_lib/sqlite_schema.ts +22 -0
- package/src/scripts/_lib/subagent_capsule.ts +155 -3
- package/src/scripts/_lib/surface.ts +86 -0
- package/src/scripts/_lib/ui_authority.ts +116 -0
- package/src/scripts/adr/regenerate_index.ts +54 -1
- package/src/scripts/adr_cite_check.ts +71 -15
- package/src/scripts/ai_council/clients.ts +1 -1
- package/src/scripts/autonomy_friction_corpus.ts +229 -0
- package/src/scripts/build_proof.ts +15 -2
- package/src/scripts/build_rule_trigger_matrix.ts +5 -0
- package/src/scripts/check_beta_review_markers.ts +141 -17
- package/src/scripts/check_enforcement_coverage.ts +1 -1
- package/src/scripts/check_enforcement_denominator.ts +121 -11
- package/src/scripts/check_finding_dispositions.ts +66 -9
- package/src/scripts/check_gate_coverage.ts +96 -0
- package/src/scripts/check_mcp_doc_drift.ts +217 -0
- package/src/scripts/check_pack_size.ts +321 -3
- package/src/scripts/check_release_highlights.ts +74 -1
- package/src/scripts/check_skill_activation_claim.ts +179 -0
- package/src/scripts/check_trigger_evals.ts +1 -1
- package/src/scripts/conformance_scan.ts +44 -3
- package/src/scripts/explain_run.ts +1 -1
- package/src/scripts/generate_capability_matrix.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +75 -1
- package/src/scripts/handoff_context_hook.ts +54 -7
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +14 -11
- package/src/scripts/hooks/augment-dispatcher.sh +1 -1
- package/src/scripts/hooks/category_a.ts +291 -0
- package/src/scripts/hooks/cline-dispatcher.sh +1 -1
- package/src/scripts/hooks/cursor-dispatcher.sh +11 -5
- package/src/scripts/hooks/dispatch_hook.ts +17 -22
- package/src/scripts/hooks/git_command_classifier.ts +156 -1
- package/src/scripts/hooks/host_lowering.ts +215 -0
- package/src/scripts/hooks/host_lowering.yaml +185 -0
- package/src/scripts/hooks/host_semantics.ts +105 -37
- package/src/scripts/hooks/journal_record_hook.ts +10 -0
- package/src/scripts/hooks/permission_gate.ts +117 -0
- package/src/scripts/hooks/session_eol_hook.ts +18 -7
- package/src/scripts/hooks_status.ts +12 -10
- package/src/scripts/install.ts +57 -86
- package/src/scripts/install_anthropic_key.sh +2 -2
- package/src/scripts/lint_agent_security.ts +316 -25
- package/src/scripts/lint_confusables.ts +42 -6
- package/src/scripts/lint_design_antipattern_parity.ts +80 -0
- package/src/scripts/lint_evidence_artifacts.ts +45 -1
- package/src/scripts/lint_handoffs.ts +0 -132
- package/src/scripts/lint_hidden_unicode.ts +49 -7
- package/src/scripts/lint_hook_manifest.ts +87 -3
- package/src/scripts/lint_instruction_smuggling.ts +42 -6
- package/src/scripts/lint_mcp_config_security.ts +42 -6
- package/src/scripts/lint_motion_authority_drift.ts +731 -0
- package/src/scripts/lint_readme_size.ts +158 -12
- package/src/scripts/lint_reasoning_fixtures.ts +216 -0
- package/src/scripts/lint_roadmap_later_disposition.ts +217 -27
- package/src/scripts/lint_skill_frontmatter_safety.ts +43 -7
- package/src/scripts/lint_skill_trigger_contradiction.ts +161 -0
- package/src/scripts/mcp_server/resources.ts +41 -0
- package/src/scripts/mcp_server/telemetry.ts +19 -4
- package/src/scripts/measure_sibling_naming.ts +150 -0
- package/src/scripts/orchestration_record.ts +12 -1
- package/src/scripts/redact_hook_capture.ts +1 -1
- package/src/scripts/release.ts +24 -24
- package/src/scripts/release_publication.ts +6 -2
- package/src/scripts/report_skill_activation.ts +319 -7
- package/src/scripts/schemas/review-findings.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +2 -2
- package/src/scripts/self_repair_cli.ts +31 -1
- package/src/scripts/session_canary_hook.ts +1 -1
- package/src/scripts/session_register_hook.ts +4 -3
- package/src/scripts/skill_scout.ts +69 -0
- package/src/scripts/trigger_eval_grandfather.json +5 -1
- package/src/scripts/validate_agent_settings.ts +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +0 -172
- package/dist/cli-delegate/chunk-LPPWO5CE.js +0 -161
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* permission_gate — whether a `pre_tool_use` call gets an explicit
|
|
3
|
+
* `permissionDecision`, and which one.
|
|
4
|
+
*
|
|
5
|
+
* Four independent conditions, each able to withhold an allow on its own: the
|
|
6
|
+
* host offers the field on `pre_tool_use` only; the dispatcher's reduced
|
|
7
|
+
* severity must already be `allow`; no concern may have voted `ask` or `deny`;
|
|
8
|
+
* and the call itself must be category A. An allow is emitted only when all
|
|
9
|
+
* four hold, so widening any one of them is a visible edit rather than an
|
|
10
|
+
* emergent effect.
|
|
11
|
+
*
|
|
12
|
+
* Separate from `dispatch_hook` because that file is against the per-file
|
|
13
|
+
* source-size budget, and because the seam is real: the dispatcher runs
|
|
14
|
+
* concerns and reduces exit codes, this module reads the result and decides
|
|
15
|
+
* what the host is told about permission.
|
|
16
|
+
*/
|
|
17
|
+
import { isCategoryA, type ToolInput } from "./category_a.js";
|
|
18
|
+
import {
|
|
19
|
+
composePermissionDecision,
|
|
20
|
+
type PermissionDecision,
|
|
21
|
+
type PermissionEmission,
|
|
22
|
+
} from "./host_semantics.js";
|
|
23
|
+
|
|
24
|
+
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
25
|
+
type JsonObject = { [k: string]: JsonValue };
|
|
26
|
+
|
|
27
|
+
function _isObject(v: unknown): v is JsonObject {
|
|
28
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Mirrors `dispatch_hook.EXIT_ALLOW` / `EXIT_BLOCK`; imported would be a cycle. */
|
|
32
|
+
const EXIT_ALLOW = 0;
|
|
33
|
+
const EXIT_BLOCK = 1;
|
|
34
|
+
|
|
35
|
+
/** The host's `tool_name`, or `""` when the event carries none. */
|
|
36
|
+
export function _payload_tool_name(envelope: JsonObject): string {
|
|
37
|
+
const payload = envelope["payload"];
|
|
38
|
+
if (!_isObject(payload)) return "";
|
|
39
|
+
const raw = payload["tool_name"];
|
|
40
|
+
return typeof raw === "string" ? raw : "";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The host's `tool_input` object, or `{}` when the event carries none. */
|
|
44
|
+
export function _payload_tool_input(envelope: JsonObject): ToolInput {
|
|
45
|
+
const payload = envelope["payload"];
|
|
46
|
+
if (!_isObject(payload)) return {};
|
|
47
|
+
const raw = payload["tool_input"];
|
|
48
|
+
return _isObject(raw) ? (raw as ToolInput) : {};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The root every category-A path argument must resolve inside.
|
|
53
|
+
*
|
|
54
|
+
* The host's own `cwd` wins over `workspace_root` because the latter is the
|
|
55
|
+
* dispatcher's process cwd, which in a worktree is the parent checkout rather
|
|
56
|
+
* than the tree the user is working in — confining against it would admit a
|
|
57
|
+
* path outside the tree the call actually runs in.
|
|
58
|
+
*/
|
|
59
|
+
export function _working_tree_root(envelope: JsonObject): string {
|
|
60
|
+
const payload = envelope["payload"];
|
|
61
|
+
if (_isObject(payload) && typeof payload["cwd"] === "string" && payload["cwd"].trim()) {
|
|
62
|
+
return payload["cwd"];
|
|
63
|
+
}
|
|
64
|
+
const workspace = envelope["workspace_root"];
|
|
65
|
+
return typeof workspace === "string" ? workspace : "";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* One concern's permission verdict.
|
|
70
|
+
*
|
|
71
|
+
* A block is a deny. A concern may also say `{"decision":"ask"}` on stdout —
|
|
72
|
+
* the field has been recorded in the feedback file since v1 and read by
|
|
73
|
+
* nothing, so an advisory concern that wanted a confirmation got silence.
|
|
74
|
+
* `ask` is honoured regardless of the exit code: an advisory concern cannot
|
|
75
|
+
* block and must not have to in order to be heard. Everything else abstains,
|
|
76
|
+
* which composes as `allow`.
|
|
77
|
+
*/
|
|
78
|
+
export function _concern_permission_verdict(
|
|
79
|
+
rc: number,
|
|
80
|
+
reply: JsonObject,
|
|
81
|
+
): PermissionDecision {
|
|
82
|
+
if (rc === EXIT_BLOCK) return "deny";
|
|
83
|
+
const stated = String(reply["decision"] ?? "").trim().toLowerCase();
|
|
84
|
+
if (stated === "ask") return "ask";
|
|
85
|
+
if (stated === "deny") return "deny";
|
|
86
|
+
return "allow";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The permission field to hand the host, or `null` to keep the legacy envelope.
|
|
91
|
+
*
|
|
92
|
+
* Four independent conditions, each able to withhold the allow on its own:
|
|
93
|
+
* the host offers the field on `pre_tool_use` only; the reduced severity must
|
|
94
|
+
* already be `allow`; no concern may have voted `ask` or `deny`; and the call
|
|
95
|
+
* itself must be category A. An allow is emitted only when all four hold, so
|
|
96
|
+
* widening any one of them is a visible edit rather than an emergent effect.
|
|
97
|
+
*/
|
|
98
|
+
export function _permission_for(
|
|
99
|
+
event: string,
|
|
100
|
+
envelope: JsonObject,
|
|
101
|
+
final_rc: number,
|
|
102
|
+
verdicts: readonly PermissionDecision[],
|
|
103
|
+
): PermissionEmission | null {
|
|
104
|
+
if (event !== "pre_tool_use") return null;
|
|
105
|
+
if (final_rc !== EXIT_ALLOW) return null;
|
|
106
|
+
if (composePermissionDecision(verdicts) !== "allow") return null;
|
|
107
|
+
const tool_name = _payload_tool_name(envelope);
|
|
108
|
+
if (!isCategoryA(tool_name, _payload_tool_input(envelope), _working_tree_root(envelope))) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
decision: "allow",
|
|
113
|
+
reason:
|
|
114
|
+
`agent-config: category-A ${tool_name} inside the working tree — ` +
|
|
115
|
+
`no concern gates it and none asked to.`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -45,7 +45,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
45
45
|
|
|
46
46
|
import recycleThresholdConfig from '../../config/recycle-threshold-budget.json';
|
|
47
47
|
|
|
48
|
-
import {
|
|
48
|
+
import { recycle_envelope_rel } from '../_lib/recycle_envelope_paths.js';
|
|
49
49
|
import {
|
|
50
50
|
emptyCounters,
|
|
51
51
|
eolSessionKey,
|
|
@@ -180,8 +180,16 @@ export function readState(file: string): SessionEolState {
|
|
|
180
180
|
* session's state — a wrong resume instead of an empty one. An envelope whose
|
|
181
181
|
* `written_at` predates the advisory is not this session's.
|
|
182
182
|
*/
|
|
183
|
-
export function envelopeExists(
|
|
184
|
-
|
|
183
|
+
export function envelopeExists(
|
|
184
|
+
workspaceRoot: string,
|
|
185
|
+
since: string | null = null,
|
|
186
|
+
sessionId: string | null = null,
|
|
187
|
+
): boolean {
|
|
188
|
+
// Phase 2.1: the record is keyed by session, so the counter-check must look
|
|
189
|
+
// at THIS session's path. Checking the shared name would read a peer's
|
|
190
|
+
// record as proof that this session wrote one — the same cross-session
|
|
191
|
+
// confusion the key exists to remove, re-created in the checker.
|
|
192
|
+
const target = path.join(workspaceRoot, recycle_envelope_rel(sessionId));
|
|
185
193
|
let raw: string;
|
|
186
194
|
try {
|
|
187
195
|
raw = fs.readFileSync(target, 'utf-8');
|
|
@@ -212,10 +220,10 @@ export function envelopeExists(workspaceRoot: string, since: string | null = nul
|
|
|
212
220
|
* the next action the advisory recommended is the one that destroys the
|
|
213
221
|
* session.
|
|
214
222
|
*/
|
|
215
|
-
export function buildMissingEnvelopeLine(workspaceRoot: string): string {
|
|
223
|
+
export function buildMissingEnvelopeLine(workspaceRoot: string, sessionId: string | null = null): string {
|
|
216
224
|
return (
|
|
217
225
|
`recycle advised earlier, but no envelope exists at ` +
|
|
218
|
-
`${path.join(workspaceRoot,
|
|
226
|
+
`${path.join(workspaceRoot, recycle_envelope_rel(sessionId))} — /clear now starts the successor ` +
|
|
219
227
|
`from nothing. Re-run \`agent-config session:recycle\` and check that it prints the ` +
|
|
220
228
|
`absolute path it wrote before clearing.`
|
|
221
229
|
);
|
|
@@ -334,11 +342,14 @@ export function main(): number {
|
|
|
334
342
|
// `AGENT_RECYCLE_THRESHOLD_TOKENS=0` is documented as the emergency switch
|
|
335
343
|
// for the whole advisory lane, and a lane that keeps one more warn after
|
|
336
344
|
// being switched off is not off.
|
|
345
|
+
// Raw id, not `sessionKey`: the record path is built from the id the host
|
|
346
|
+
// exported (`safe_stem`), never from the hashed state-file key.
|
|
347
|
+
const rawSessionId = payloadSessionId(payload, envelope) || null;
|
|
337
348
|
const shouldWarnMissing =
|
|
338
349
|
threshold !== null &&
|
|
339
350
|
state.advisory_fired_at !== null &&
|
|
340
351
|
(state.missing_envelope_warned_at ?? null) === null &&
|
|
341
|
-
!envelopeExists(workspaceRoot, state.advisory_fired_at);
|
|
352
|
+
!envelopeExists(workspaceRoot, state.advisory_fired_at, rawSessionId);
|
|
342
353
|
|
|
343
354
|
const nextState: SessionEolState = {
|
|
344
355
|
schema_version: 1,
|
|
@@ -415,7 +426,7 @@ export function main(): number {
|
|
|
415
426
|
`${JSON.stringify({
|
|
416
427
|
decision: 'warn',
|
|
417
428
|
reason: 'session-eol: recycle advised, no envelope written',
|
|
418
|
-
additional_context: buildMissingEnvelopeLine(workspaceRoot),
|
|
429
|
+
additional_context: buildMissingEnvelopeLine(workspaceRoot, rawSessionId),
|
|
419
430
|
})}\n`,
|
|
420
431
|
);
|
|
421
432
|
return EXIT_WARN;
|
|
@@ -45,7 +45,9 @@ const MANIFEST_PATH = path.join(
|
|
|
45
45
|
"hook_manifest.yaml",
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
// (
|
|
48
|
+
// (project-relative bridge path, one-line note shown when the bridge is not
|
|
49
|
+
// live). The note is printed verbatim, so a note that is not a command must
|
|
50
|
+
// not read as one.
|
|
49
51
|
// Path may be a directory (cline) — existence => any file inside.
|
|
50
52
|
//
|
|
51
53
|
// Cowork has no project-scope bridge path: the Claude desktop app's
|
|
@@ -58,17 +60,17 @@ const MANIFEST_PATH = path.join(
|
|
|
58
60
|
// Once upstream lands the fix and a stable settings location is
|
|
59
61
|
// documented, swap the empty path here for that location.
|
|
60
62
|
export const PLATFORM_BRIDGES: Record<string, [string, string]> = {
|
|
61
|
-
augment: [".augment/settings.json", "
|
|
62
|
-
claude: [".claude/settings.json", "
|
|
63
|
+
augment: [".augment/settings.json", "run `agent-config install`"],
|
|
64
|
+
claude: [".claude/settings.json", "run `agent-config install`"],
|
|
63
65
|
cowork: [
|
|
64
66
|
"",
|
|
65
67
|
"upstream-blocked: anthropics/claude-code#40495 + #27398 (settings.json ignored in Cowork sandbox)",
|
|
66
68
|
],
|
|
67
|
-
cursor: [".cursor/hooks.json", "
|
|
68
|
-
cline: [".clinerules/hooks", "
|
|
69
|
-
windsurf: [".windsurf/hooks.json", "
|
|
70
|
-
gemini: [".gemini/settings.json", "
|
|
71
|
-
copilot: ["", "rule-only fallback
|
|
69
|
+
cursor: [".cursor/hooks.json", "run `agent-config install`"],
|
|
70
|
+
cline: [".clinerules/hooks", "run `agent-config install`"],
|
|
71
|
+
windsurf: [".windsurf/hooks.json", "run `agent-config install`"],
|
|
72
|
+
gemini: [".gemini/settings.json", "run `agent-config install`"],
|
|
73
|
+
copilot: ["", "rule-only fallback — this package binds no hook here"],
|
|
72
74
|
};
|
|
73
75
|
|
|
74
76
|
export interface PlatformRow {
|
|
@@ -180,11 +182,11 @@ export function _render_table(matrix: StatusMatrix): string {
|
|
|
180
182
|
lines.push(` ${event.padEnd(22)} → ${concerns}`);
|
|
181
183
|
}
|
|
182
184
|
if (row.hint) {
|
|
183
|
-
lines.push(` hint:
|
|
185
|
+
lines.push(` hint: ${row.hint}`);
|
|
184
186
|
}
|
|
185
187
|
}
|
|
186
188
|
lines.push("");
|
|
187
|
-
lines.push("Source of truth: scripts/hook_manifest.yaml");
|
|
189
|
+
lines.push("Source of truth: src/scripts/hook_manifest.yaml");
|
|
188
190
|
lines.push("Contract: docs/contracts/hook-architecture-v1.md");
|
|
189
191
|
return lines.join("\n");
|
|
190
192
|
}
|
package/src/scripts/install.ts
CHANGED
|
@@ -75,6 +75,7 @@ import { build_merge_entries } from './_lib/json_pointers.js';
|
|
|
75
75
|
import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
|
|
76
76
|
import * as installed_lock from './_lib/installed_lock.js';
|
|
77
77
|
import * as mcp_bridge from './_lib/mcp_bridge.js';
|
|
78
|
+
import * as mcp_consent from './_lib/mcp_consent_residual.js';
|
|
78
79
|
import * as scoped_projection from './_lib/scoped_projection.js';
|
|
79
80
|
import * as surface_tiers from './_lib/surface_tiers.js';
|
|
80
81
|
import * as global_deploy_inventory from './_lib/global_deploy_inventory.js';
|
|
@@ -90,6 +91,7 @@ import * as catalogue from './_lib/skill_catalogue.js';
|
|
|
90
91
|
import { isInteractiveSession, type SessionProbe } from '../shared/interactiveContext.js';
|
|
91
92
|
import * as claude_desktop_bundler from './_lib/claude_desktop_bundler.js';
|
|
92
93
|
import * as claude_settings_hooks from './_lib/claude_settings_hooks.js';
|
|
94
|
+
import { hostBindings } from './hooks/host_lowering.js';
|
|
93
95
|
import { find_project_root_with_anchor, load_agent_settings } from './_lib/agent_settings.js';
|
|
94
96
|
import {
|
|
95
97
|
LEGACY_ALL,
|
|
@@ -417,7 +419,7 @@ function yamlSafeLoad(text: string): unknown {
|
|
|
417
419
|
}
|
|
418
420
|
|
|
419
421
|
// ---------------------------------------------------------------------------
|
|
420
|
-
// Module-level constants
|
|
422
|
+
// Module-level constants.
|
|
421
423
|
// ---------------------------------------------------------------------------
|
|
422
424
|
|
|
423
425
|
const DEFAULT_PROFILE = 'balanced';
|
|
@@ -1022,14 +1024,6 @@ const AUGMENT_LEGACY_TRAMPOLINES: readonly string[] = [
|
|
|
1022
1024
|
'augment-onboarding-gate.sh',
|
|
1023
1025
|
'augment-context-hygiene.sh',
|
|
1024
1026
|
];
|
|
1025
|
-
const AUGMENT_DISPATCHER_BINDINGS: ReadonlyArray<readonly [string, string]> = [
|
|
1026
|
-
['session_start', 'SessionStart'],
|
|
1027
|
-
['session_end', 'SessionEnd'],
|
|
1028
|
-
['stop', 'Stop'],
|
|
1029
|
-
['pre_tool_use', 'PreToolUse'],
|
|
1030
|
-
['post_tool_use', 'PostToolUse'],
|
|
1031
|
-
];
|
|
1032
|
-
|
|
1033
1027
|
function _deploy_augment_trampoline(package_root: string, name: string, force: boolean): string | null {
|
|
1034
1028
|
const src = path.join(package_root, 'scripts', 'hooks', name);
|
|
1035
1029
|
if (!pathExists(src)) {
|
|
@@ -1073,8 +1067,8 @@ function ensure_augment_user_hooks(package_root: string, force: boolean): Record
|
|
|
1073
1067
|
_remove_legacy_augment_trampolines();
|
|
1074
1068
|
|
|
1075
1069
|
const per_event: Record<string, unknown[]> = {};
|
|
1076
|
-
for (const
|
|
1077
|
-
const cmd = `${dst} ${
|
|
1070
|
+
for (const { slot, native } of hostBindings('augment')) {
|
|
1071
|
+
const cmd = `${dst} ${slot} ${native}`;
|
|
1078
1072
|
const entry = { hooks: [{ type: 'command', command: cmd }] };
|
|
1079
1073
|
(per_event[native] ??= []).push(entry);
|
|
1080
1074
|
}
|
|
@@ -1130,14 +1124,6 @@ const _prune_tier_b_modules = (
|
|
|
1130
1124
|
): [number, Record<string, DeployResult>] =>
|
|
1131
1125
|
_prune_modules_by(dr, mcp_bridge.tierBPrunePredicate(tier_b));
|
|
1132
1126
|
|
|
1133
|
-
const CURSOR_DISPATCHER_BINDINGS: ReadonlyArray<readonly [string, string]> = [
|
|
1134
|
-
['session_start', 'sessionStart'],
|
|
1135
|
-
['session_end', 'sessionEnd'],
|
|
1136
|
-
['stop', 'stop'],
|
|
1137
|
-
['user_prompt_submit', 'beforeSubmitPrompt'],
|
|
1138
|
-
['post_tool_use', 'postToolUse'],
|
|
1139
|
-
];
|
|
1140
|
-
|
|
1141
1127
|
function _cursor_dispatch_command(ac_event: string, native: string): string {
|
|
1142
1128
|
// Hook-resilience shim (P1.4): missing binary → silent exit 0; a
|
|
1143
1129
|
// present dispatcher's exit code propagates (fail_closed concerns
|
|
@@ -1152,8 +1138,8 @@ function _cursor_dispatch_command(ac_event: string, native: string): string {
|
|
|
1152
1138
|
|
|
1153
1139
|
function ensure_cursor_bridge(project_root: string, force: boolean): Record<string, unknown>[] {
|
|
1154
1140
|
const hooks: Record<string, unknown[]> = {};
|
|
1155
|
-
for (const
|
|
1156
|
-
(hooks[native] ??= []).push({ command: _cursor_dispatch_command(
|
|
1141
|
+
for (const { slot, native } of hostBindings('cursor')) {
|
|
1142
|
+
(hooks[native] ??= []).push({ command: _cursor_dispatch_command(slot, native) });
|
|
1157
1143
|
}
|
|
1158
1144
|
const bridge = { version: 1, hooks };
|
|
1159
1145
|
return merge_json_file(
|
|
@@ -1187,8 +1173,8 @@ function ensure_cursor_user_hooks(package_root: string, force: boolean): Record<
|
|
|
1187
1173
|
}
|
|
1188
1174
|
|
|
1189
1175
|
const hooks: Record<string, unknown[]> = {};
|
|
1190
|
-
for (const
|
|
1191
|
-
(hooks[native] ??= []).push({ command: `${dst} ${
|
|
1176
|
+
for (const { slot, native } of hostBindings('cursor')) {
|
|
1177
|
+
(hooks[native] ??= []).push({ command: `${dst} ${slot} ${native}` });
|
|
1192
1178
|
}
|
|
1193
1179
|
|
|
1194
1180
|
const settings_patch = { version: 1, hooks };
|
|
@@ -1200,15 +1186,6 @@ function ensure_cursor_user_hooks(package_root: string, force: boolean): Record<
|
|
|
1200
1186
|
);
|
|
1201
1187
|
}
|
|
1202
1188
|
|
|
1203
|
-
const CLINE_DISPATCHER_BINDINGS: ReadonlyArray<readonly [string, string]> = [
|
|
1204
|
-
['session_start', 'TaskStart'],
|
|
1205
|
-
['session_start', 'TaskResume'],
|
|
1206
|
-
['session_end', 'TaskComplete'],
|
|
1207
|
-
['stop', 'TaskCancel'],
|
|
1208
|
-
['user_prompt_submit', 'UserPromptSubmit'],
|
|
1209
|
-
['post_tool_use', 'PostToolUse'],
|
|
1210
|
-
];
|
|
1211
|
-
|
|
1212
1189
|
/** `shlex.quote` — POSIX shell single-quote escaping. */
|
|
1213
1190
|
function shlexQuote(s: string): string {
|
|
1214
1191
|
if (s === '') return "''";
|
|
@@ -1221,7 +1198,7 @@ function clineProjectHookBody(native_event: string, ac_event: string, workspace_
|
|
|
1221
1198
|
// template uses doubled braces ({{ }}) that .format() collapses to single.
|
|
1222
1199
|
return (
|
|
1223
1200
|
'#!/usr/bin/env bash\n' +
|
|
1224
|
-
'# Generated by event4u/agent-config
|
|
1201
|
+
'# Generated by event4u/agent-config — DO NOT EDIT.\n' +
|
|
1225
1202
|
`# Project-scope Cline hook for ${native_event} → agent-config ${ac_event}.\n` +
|
|
1226
1203
|
'# Phase 7.6 (docs/contracts/hook-architecture-v1.md).\n' +
|
|
1227
1204
|
'set -u\n' +
|
|
@@ -1249,14 +1226,14 @@ function ensure_cline_bridge(project_root: string, force: boolean): void {
|
|
|
1249
1226
|
|
|
1250
1227
|
const workspace_quoted = shlexQuote(resolvePath(project_root));
|
|
1251
1228
|
let written = 0;
|
|
1252
|
-
for (const
|
|
1253
|
-
const target = path.join(hooks_dir,
|
|
1254
|
-
const body = clineProjectHookBody(
|
|
1229
|
+
for (const { slot, native } of hostBindings('cline')) {
|
|
1230
|
+
const target = path.join(hooks_dir, native);
|
|
1231
|
+
const body = clineProjectHookBody(native, slot, workspace_quoted);
|
|
1255
1232
|
if (pathExists(target) && readText(target) === body && !force) {
|
|
1256
1233
|
continue;
|
|
1257
1234
|
}
|
|
1258
1235
|
if (pathExists(target) && !force) {
|
|
1259
|
-
skip(`.clinerules/hooks/${
|
|
1236
|
+
skip(`.clinerules/hooks/${native} exists, needs update (use --force)`);
|
|
1260
1237
|
continue;
|
|
1261
1238
|
}
|
|
1262
1239
|
writeText(target, body);
|
|
@@ -1292,13 +1269,13 @@ function ensure_cline_user_hooks(package_root: string, force: boolean): void {
|
|
|
1292
1269
|
}
|
|
1293
1270
|
|
|
1294
1271
|
const trampoline_quoted = shlexQuote(trampoline);
|
|
1295
|
-
for (const
|
|
1296
|
-
const wrapper = path.join(CLINE_USER_DIR,
|
|
1272
|
+
for (const { slot, native } of hostBindings('cline')) {
|
|
1273
|
+
const wrapper = path.join(CLINE_USER_DIR, native);
|
|
1297
1274
|
const body =
|
|
1298
1275
|
'#!/usr/bin/env bash\n' +
|
|
1299
|
-
'# Generated by event4u/agent-config
|
|
1300
|
-
`# User-scope Cline hook for ${
|
|
1301
|
-
`exec ${trampoline_quoted} ${
|
|
1276
|
+
'# Generated by event4u/agent-config — DO NOT EDIT.\n' +
|
|
1277
|
+
`# User-scope Cline hook for ${native} → agent-config ${slot}.\n` +
|
|
1278
|
+
`exec ${trampoline_quoted} ${slot} ${native}\n`;
|
|
1302
1279
|
if (pathExists(wrapper) && readText(wrapper) === body && !force) {
|
|
1303
1280
|
continue;
|
|
1304
1281
|
}
|
|
@@ -1307,12 +1284,6 @@ function ensure_cline_user_hooks(package_root: string, force: boolean): void {
|
|
|
1307
1284
|
}
|
|
1308
1285
|
}
|
|
1309
1286
|
|
|
1310
|
-
const WINDSURF_DISPATCHER_BINDINGS: ReadonlyArray<readonly [string, string]> = [
|
|
1311
|
-
['session_start', 'post_setup_worktree'],
|
|
1312
|
-
['user_prompt_submit', 'pre_user_prompt'],
|
|
1313
|
-
['stop', 'post_cascade_response'],
|
|
1314
|
-
];
|
|
1315
|
-
|
|
1316
1287
|
function _windsurf_dispatch_command(ac_event: string, native: string): string {
|
|
1317
1288
|
// Hook-resilience shim (P1.4): missing binary → silent exit 0; a
|
|
1318
1289
|
// present dispatcher's exit code propagates (fail_closed concerns
|
|
@@ -1327,9 +1298,9 @@ function _windsurf_dispatch_command(ac_event: string, native: string): string {
|
|
|
1327
1298
|
|
|
1328
1299
|
function ensure_windsurf_bridge(project_root: string, force: boolean): Record<string, unknown>[] {
|
|
1329
1300
|
const hooks: Record<string, unknown[]> = {};
|
|
1330
|
-
for (const
|
|
1301
|
+
for (const { slot, native } of hostBindings('windsurf')) {
|
|
1331
1302
|
(hooks[native] ??= []).push({
|
|
1332
|
-
command: _windsurf_dispatch_command(
|
|
1303
|
+
command: _windsurf_dispatch_command(slot, native),
|
|
1333
1304
|
show_output: false,
|
|
1334
1305
|
});
|
|
1335
1306
|
}
|
|
@@ -1365,9 +1336,9 @@ function ensure_windsurf_user_hooks(package_root: string, force: boolean): Recor
|
|
|
1365
1336
|
}
|
|
1366
1337
|
|
|
1367
1338
|
const hooks: Record<string, unknown[]> = {};
|
|
1368
|
-
for (const
|
|
1339
|
+
for (const { slot, native } of hostBindings('windsurf')) {
|
|
1369
1340
|
(hooks[native] ??= []).push({
|
|
1370
|
-
command: `${dst} ${
|
|
1341
|
+
command: `${dst} ${slot} ${native}`,
|
|
1371
1342
|
show_output: false,
|
|
1372
1343
|
});
|
|
1373
1344
|
}
|
|
@@ -1381,14 +1352,6 @@ function ensure_windsurf_user_hooks(package_root: string, force: boolean): Recor
|
|
|
1381
1352
|
);
|
|
1382
1353
|
}
|
|
1383
1354
|
|
|
1384
|
-
const GEMINI_DISPATCHER_BINDINGS: ReadonlyArray<readonly [string, string, string]> = [
|
|
1385
|
-
['session_start', 'SessionStart', ''],
|
|
1386
|
-
['session_end', 'SessionEnd', ''],
|
|
1387
|
-
['stop', 'AfterAgent', ''],
|
|
1388
|
-
['user_prompt_submit', 'BeforeAgent', ''],
|
|
1389
|
-
['post_tool_use', 'AfterTool', '.*'],
|
|
1390
|
-
];
|
|
1391
|
-
|
|
1392
1355
|
function _gemini_dispatch_command(ac_event: string, native: string): string {
|
|
1393
1356
|
// Hook-resilience shim (P1.4): missing binary → silent exit 0; a
|
|
1394
1357
|
// present dispatcher's exit code propagates (fail_closed concerns
|
|
@@ -1405,10 +1368,10 @@ function _gemini_hooks_dict(
|
|
|
1405
1368
|
command_factory: (ac_event: string, native: string) => string,
|
|
1406
1369
|
): Record<string, unknown[]> {
|
|
1407
1370
|
const out: Record<string, unknown[]> = {};
|
|
1408
|
-
for (const
|
|
1371
|
+
for (const { slot, native, matcher } of hostBindings('gemini')) {
|
|
1409
1372
|
(out[native] ??= []).push({
|
|
1410
1373
|
matcher,
|
|
1411
|
-
hooks: [{ type: 'command', command: command_factory(
|
|
1374
|
+
hooks: [{ type: 'command', command: command_factory(slot, native) }],
|
|
1412
1375
|
});
|
|
1413
1376
|
}
|
|
1414
1377
|
return out;
|
|
@@ -1724,15 +1687,37 @@ function ensure_kiro_bridge(project_root: string, force: boolean): void {
|
|
|
1724
1687
|
|
|
1725
1688
|
// --- Post-install smoke test ---
|
|
1726
1689
|
|
|
1727
|
-
|
|
1690
|
+
/**
|
|
1691
|
+
* Platforms whose bridge the smoke probe exercises, with the slot it probes.
|
|
1692
|
+
*
|
|
1693
|
+
* The NATIVE event is derived from `host_lowering.yaml`, never written here.
|
|
1694
|
+
* The hand-written list this replaced probed `['cursor', 'beforeShellExecution']`
|
|
1695
|
+
* — an event no cursor bridge has ever written — so the probe could not fail on
|
|
1696
|
+
* a real binding regression, which is the only thing it exists to catch. A
|
|
1697
|
+
* platform whose table row does not carry the probed slot is a hard error, not
|
|
1698
|
+
* a skip: a silent skip is how the previous list stayed wrong.
|
|
1699
|
+
*/
|
|
1700
|
+
const SMOKE_PROBE_SLOTS: ReadonlyArray<readonly [string, string]> = [
|
|
1728
1701
|
['augment', 'session_start'],
|
|
1729
|
-
['claude', '
|
|
1730
|
-
['cursor', '
|
|
1702
|
+
['claude', 'session_start'],
|
|
1703
|
+
['cursor', 'session_start'],
|
|
1731
1704
|
['cline', 'session_start'],
|
|
1732
|
-
['windsurf', '
|
|
1733
|
-
['gemini', '
|
|
1705
|
+
['windsurf', 'session_start'],
|
|
1706
|
+
['gemini', 'session_start'],
|
|
1734
1707
|
];
|
|
1735
1708
|
|
|
1709
|
+
export function smokeProbeEvents(): ReadonlyArray<readonly [string, string]> {
|
|
1710
|
+
return SMOKE_PROBE_SLOTS.map(([platform, slot]) => {
|
|
1711
|
+
const binding = hostBindings(platform).find((b) => b.slot === slot);
|
|
1712
|
+
if (binding === undefined) {
|
|
1713
|
+
throw new Error(
|
|
1714
|
+
`install smoke probe: host_lowering.yaml has no \`${slot}\` binding for \`${platform}\``,
|
|
1715
|
+
);
|
|
1716
|
+
}
|
|
1717
|
+
return [platform, binding.native] as const;
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1736
1721
|
const SMOKE_BRIDGE_PATHS: Record<string, string> = {
|
|
1737
1722
|
augment: '.augment/settings.json',
|
|
1738
1723
|
claude: '.claude/settings.json',
|
|
@@ -1787,7 +1772,7 @@ function _smoke_test_hooks(project_root: string, package_root: string): number {
|
|
|
1787
1772
|
const skipped: string[] = [];
|
|
1788
1773
|
const passed: string[] = [];
|
|
1789
1774
|
|
|
1790
|
-
for (const [platform, native] of
|
|
1775
|
+
for (const [platform, native] of smokeProbeEvents()) {
|
|
1791
1776
|
const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? '';
|
|
1792
1777
|
const bridge_path = rel_bridge ? path.join(project_root, rel_bridge) : null;
|
|
1793
1778
|
const bridge_present = Boolean(
|
|
@@ -2619,15 +2604,6 @@ function _is_agent_config_source_repo(project_root: string): [boolean, string] {
|
|
|
2619
2604
|
}
|
|
2620
2605
|
}
|
|
2621
2606
|
|
|
2622
|
-
const installer_self = path.join(project_root, 'scripts', 'install.py');
|
|
2623
|
-
try {
|
|
2624
|
-
if (isFile(installer_self) && resolvePath(installer_self) === resolvePath(_HERE)) {
|
|
2625
|
-
return [true, 'src/scripts/install.py (self)'];
|
|
2626
|
-
}
|
|
2627
|
-
} catch {
|
|
2628
|
-
/* OSError → pass */
|
|
2629
|
-
}
|
|
2630
|
-
|
|
2631
2607
|
return [false, ''];
|
|
2632
2608
|
}
|
|
2633
2609
|
|
|
@@ -4028,7 +4004,7 @@ function _merge_tools_aliases(tools: string | null, ai: string | null): string {
|
|
|
4028
4004
|
return items.length > 0 ? items.join(',') : 'all';
|
|
4029
4005
|
}
|
|
4030
4006
|
|
|
4031
|
-
const PROG = 'install
|
|
4007
|
+
const PROG = 'agent-config install';
|
|
4032
4008
|
// Verbatim argparse usage block at COLUMNS=80 (captured from the .py). The
|
|
4033
4009
|
// `--help` BODY (per-flag descriptions) is a documented divergence — argparse
|
|
4034
4010
|
// re-wraps it to the live terminal width, which is not worth reproducing; the
|
|
@@ -5146,11 +5122,9 @@ function _main_project_install(
|
|
|
5146
5122
|
...ensure_augment_bridge(project_root, opts.force),
|
|
5147
5123
|
];
|
|
5148
5124
|
if (_is_tool_enabled(tools, 'claude-code')) {
|
|
5149
|
-
merged_keys_by_tool['claude-code'] =
|
|
5150
|
-
...ensure_claude_bridge(project_root, opts.force),
|
|
5151
|
-
...ensure_mcp_bridge(project_root, opts.force),
|
|
5152
|
-
];
|
|
5125
|
+
merged_keys_by_tool['claude-code'] = ensure_claude_bridge(project_root, opts.force);
|
|
5153
5126
|
}
|
|
5127
|
+
mcp_bridge.registerMcpHosts(merge_json_file, project_root, opts.force, package_root, tools, merged_keys_by_tool);
|
|
5154
5128
|
if (_is_tool_enabled(tools, 'cursor')) {
|
|
5155
5129
|
merged_keys_by_tool['cursor'] = ensure_cursor_bridge(project_root, opts.force);
|
|
5156
5130
|
}
|
|
@@ -5251,6 +5225,7 @@ function _main_project_install(
|
|
|
5251
5225
|
);
|
|
5252
5226
|
process.stdout.write('\n');
|
|
5253
5227
|
}
|
|
5228
|
+
mcp_consent.printResiduals(tools, state.QUIET);
|
|
5254
5229
|
if (_is_tool_enabled(tools, 'claude-code')) {
|
|
5255
5230
|
const team_hint = _team_setup_hint_line(project_root);
|
|
5256
5231
|
if (team_hint !== null) {
|
|
@@ -5364,10 +5339,6 @@ export {
|
|
|
5364
5339
|
ROOCODE_MARKER,
|
|
5365
5340
|
ZED_MARKER,
|
|
5366
5341
|
// ADR-200 py2ts: re-exported for test_install_snapshot.ts twin
|
|
5367
|
-
CURSOR_DISPATCHER_BINDINGS,
|
|
5368
|
-
CLINE_DISPATCHER_BINDINGS,
|
|
5369
|
-
WINDSURF_DISPATCHER_BINDINGS,
|
|
5370
|
-
GEMINI_DISPATCHER_BINDINGS,
|
|
5371
5342
|
ensure_cursor_bridge,
|
|
5372
5343
|
ensure_cline_bridge,
|
|
5373
5344
|
ensure_mcp_bridge,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Interactive Anthropic-API-key installer for scripts/skill_trigger_eval.
|
|
2
|
+
# Interactive Anthropic-API-key installer for src/scripts/skill_trigger_eval.ts.
|
|
3
3
|
#
|
|
4
4
|
# Reads the key with `read -s` so it never echoes to the terminal and
|
|
5
5
|
# never lands in shell history or scrollback. Writes atomically to
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# ~/.config/agent-config/anthropic.key is read as a fallback by the
|
|
8
8
|
# loaders so pre-2.4 installs keep working until the namespace shim runs.
|
|
9
9
|
#
|
|
10
|
-
# Contract — companion to scripts/skill_trigger_eval.
|
|
10
|
+
# Contract — companion to src/scripts/skill_trigger_eval.ts:
|
|
11
11
|
# - File path: $HOME/.event4u/agent-config/anthropic.key
|
|
12
12
|
# - File mode: 0600 (owner read/write only)
|
|
13
13
|
# - Key format: must start with `sk-ant-`
|