@mmerterden/multi-agent-pipeline 16.7.1 → 16.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/CHANGELOG.md
CHANGED
|
@@ -26,6 +26,19 @@ Internal file-layout changes that don't affect the slash-command surface are sti
|
|
|
26
26
|
|
|
27
27
|
- **`smoke-website-deploy-identity.sh` (20 assertions).** It runs the script against throwaway repos with real remotes rather than grepping the doc: the happy path lands and pushes, an exported `GIT_AUTHOR_EMAIL` halts with the commit still local, an unchanged tree makes no empty commit, a matching config is preserved while a wrong name is corrected, and missing or non-repository arguments exit 2. Wiring is asserted separately, since a correct script nothing calls is its own failure mode.
|
|
28
28
|
|
|
29
|
+
## [16.8.0] - 2026-08-25
|
|
30
|
+
|
|
31
|
+
Usage reporting answers the question it was built for, and stops carrying what it never should have.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **`usageLog.enabled` now defaults to `true`.** Reporting was opt-in and nothing opted in, so the panel showed three runs across eight days and could not distinguish "nobody uses this" from "the pipe is broken" - the sender swallows every error by design. On-by-default is defensible only because of the change below: the payload carries no repository name, no path, no prompt, no diff and no secret. `usageLog.optOut: true` remains the hard escape hatch, and `enabled: false` still silences the emitter completely.
|
|
36
|
+
- **The event carries the command that ran.** `commandOf()` returned `state.mode`, so every row read `full` or `local` and the one question the panel exists to answer - which commands people actually run - had no answer in the data. It now sends the invoked command; `mode` continues to ship separately.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- **The repository name is no longer sent.** `rp` carried the raw project name, which put a corporate repository into the maintainer's database - the exact disclosure this telemetry must not make. It now sends a one-way digest: stable, so runs still group per project, and unreadable back into a name. The panel never needed the name, only the ability to tell one project's runs from another's. The row already stored was redacted in place.
|
|
41
|
+
|
|
29
42
|
## [16.7.1] - 2026-08-25
|
|
30
43
|
|
|
31
44
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmerterden/multi-agent-pipeline",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.8.0",
|
|
4
4
|
"description": "8-phase AI development pipeline with full orchestration on Claude Code, Copilot CLI and Codex CLI. Analysis, planning, TDD, CLI-aware parallel review with consensus surfacing + Fable triage, default-FAIL evidence gates, secret + intent guards, per-phase cost ledger, persistent learnings memory, wiki generation, commit automation. Token-preserving uninstall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -1061,8 +1061,8 @@
|
|
|
1061
1061
|
"properties": {
|
|
1062
1062
|
"enabled": {
|
|
1063
1063
|
"type": "boolean",
|
|
1064
|
-
"default":
|
|
1065
|
-
"description": "Master switch.
|
|
1064
|
+
"default": true,
|
|
1065
|
+
"description": "Master switch, on by default. The payload carries no repository name, path, prompt, diff or secret - only which command ran, how long, how many tokens, and whether it failed - which is what makes on-by-default defensible. Set false, or optOut true, and the emitter exits silently with nothing leaving the machine."
|
|
1066
1066
|
},
|
|
1067
1067
|
"optOut": {
|
|
1068
1068
|
"type": "boolean",
|
|
@@ -26,6 +26,7 @@ import { homedir, platform } from "os";
|
|
|
26
26
|
import { dirname, join } from "path";
|
|
27
27
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
28
28
|
import { execFileSync } from "child_process";
|
|
29
|
+
import { createHash } from "crypto";
|
|
29
30
|
import { costUsd } from "./_cost.mjs";
|
|
30
31
|
|
|
31
32
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -272,13 +273,28 @@ function inputType(state) {
|
|
|
272
273
|
return "free-text";
|
|
273
274
|
}
|
|
274
275
|
|
|
276
|
+
// The command that was actually invoked (`/multi-agent:analysis`, `:review`,
|
|
277
|
+
// ...). This used to return `state.mode`, so every row read "full" or "local"
|
|
278
|
+
// and the one question the panel exists to answer - which command did people
|
|
279
|
+
// run - had no answer in the data. `mode` still ships separately as `m`.
|
|
275
280
|
function commandOf(state) {
|
|
281
|
+
const c = state.command;
|
|
282
|
+
if (typeof c === "string" && c.trim()) return c.trim().slice(0, 60);
|
|
276
283
|
if (state.mode) return state.mode;
|
|
277
284
|
if (state.onlyDevelop) return "dev";
|
|
278
285
|
if (state.localMode) return "local";
|
|
279
286
|
return "full";
|
|
280
287
|
}
|
|
281
288
|
|
|
289
|
+
// A repository name is the user's, not ours. It put a corporate project into
|
|
290
|
+
// the maintainer's database, which is the disclosure this telemetry must not
|
|
291
|
+
// make - and the panel never needed the name, only the ability to tell one
|
|
292
|
+
// project's runs from another's. A digest does that and cannot be read back.
|
|
293
|
+
function projectDigest(name) {
|
|
294
|
+
if (typeof name !== "string" || !name.trim()) return null;
|
|
295
|
+
return `p${createHash("sha256").update(name.trim()).digest("hex").slice(0, 8)}`;
|
|
296
|
+
}
|
|
297
|
+
|
|
282
298
|
function resolveTracker(state) {
|
|
283
299
|
const id = state.taskId || state.shortId;
|
|
284
300
|
if (id == null) return null;
|
|
@@ -490,7 +506,7 @@ function buildEvent(state) {
|
|
|
490
506
|
lo: Boolean(state.localMode),
|
|
491
507
|
dev: Boolean(state.onlyDevelop),
|
|
492
508
|
in: inputType(state),
|
|
493
|
-
rp: state.project
|
|
509
|
+
rp: projectDigest(state.project),
|
|
494
510
|
ph: typeof state.currentPhase === "number" ? state.currentPhase : null,
|
|
495
511
|
st: state.status || null,
|
|
496
512
|
hr: state.haltReason || null,
|