@agent_forge/forge-dsh 1.61.3 → 1.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/lib/index.js +18 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,12 @@ the forge binary — the plugin itself has **zero runtime dependencies**.
|
|
|
11
11
|
|
|
12
12
|
## How it works
|
|
13
13
|
|
|
14
|
+
> The mapping table below and the fail-open contract at the end of this README
|
|
15
|
+
> are the **two-sided bridge contract**, mirrored machine-readably in
|
|
16
|
+
> [`contract.json`](./contract.json) and enforced by forge's compat snapshot
|
|
17
|
+
> (surface `bridges`). Change all three together: `contract.json`, this README,
|
|
18
|
+
> and the tests on both sides.
|
|
19
|
+
|
|
14
20
|
| DSH interception point | forge hook event | A forge block becomes |
|
|
15
21
|
|---|---|---|
|
|
16
22
|
| `tools/pre-execute` | `PreToolUse` | `{kind:'deny', reason}` |
|
package/lib/index.js
CHANGED
|
@@ -135,8 +135,8 @@ function apply(ctx, config = {}) {
|
|
|
135
135
|
return turnStoppingOutcome(outcome, agent);
|
|
136
136
|
}), "forge: turn-stopping");
|
|
137
137
|
|
|
138
|
-
// /forge-status — wired groups + recent runs (the only
|
|
139
|
-
// infrastructure errors surface without debug:true).
|
|
138
|
+
// /forge-status — wired groups + verdict summary + recent runs (the only
|
|
139
|
+
// place fail-open infrastructure errors surface without debug:true).
|
|
140
140
|
const commands = ctx.get("commands");
|
|
141
141
|
if (commands !== undefined) {
|
|
142
142
|
ctx.effect(() => commands.register({
|
|
@@ -146,6 +146,21 @@ function apply(ctx, config = {}) {
|
|
|
146
146
|
const groups = Object.entries(spec)
|
|
147
147
|
.map(([event, gs]) => ` ${event}: ${gs.flatMap((g) => g.hooks.map((h) => h.command.replace("forge hook ", ""))).join(", ")}`)
|
|
148
148
|
.join("\n");
|
|
149
|
+
// Verdict summary over the whole ring buffer (50 runs): the at-a-glance
|
|
150
|
+
// health line — how many runs forge blocked, and how many hook runs
|
|
151
|
+
// FAILED OPEN (infra errors, e.g. timeout) and thus lost that run's
|
|
152
|
+
// feedback. A rising fail-open count on a big project means timeoutMs
|
|
153
|
+
// needs raising.
|
|
154
|
+
const summary = recentRuns.reduce(
|
|
155
|
+
(acc, r) => {
|
|
156
|
+
acc.runs += 1;
|
|
157
|
+
if (r.blocked) acc.blocked += 1;
|
|
158
|
+
if (r.errors.length > 0) acc.failOpen += 1;
|
|
159
|
+
acc.contexts += r.contexts;
|
|
160
|
+
return acc;
|
|
161
|
+
},
|
|
162
|
+
{ runs: 0, blocked: 0, failOpen: 0, contexts: 0 },
|
|
163
|
+
);
|
|
149
164
|
const runs = recentRuns.length === 0
|
|
150
165
|
? " (no hook runs yet)"
|
|
151
166
|
: recentRuns.slice(-10).map((r) => {
|
|
@@ -157,7 +172,7 @@ function apply(ctx, config = {}) {
|
|
|
157
172
|
}).join("\n");
|
|
158
173
|
return {
|
|
159
174
|
kind: "success",
|
|
160
|
-
text: `# Forge quality gates\n\nforgeBin: ${opts.forgeBin} timeoutMs: ${opts.timeoutMs}\n\n## Wired groups\n${groups}\n\n## Recent runs (last 10)\n${runs}`,
|
|
175
|
+
text: `# Forge quality gates\n\nforgeBin: ${opts.forgeBin} timeoutMs: ${opts.timeoutMs}\n\n## Wired groups\n${groups}\n\n## Verdict summary (last ${recentRuns.length} runs)\n runs=${summary.runs} blocked=${summary.blocked} fail-open=${summary.failOpen} contexts=${summary.contexts}\n\n## Recent runs (last 10)\n${runs}`,
|
|
161
176
|
};
|
|
162
177
|
},
|
|
163
178
|
}), "forge: status command");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent_forge/forge-dsh",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.0",
|
|
4
4
|
"description": "Forge quality gates for DeepSeek Harness (dsh): task gates, read-before-edit, bash hazard interception and quality scoring, driven by the forge CLI through DSH's typed interception points.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|