patchwork-os 0.2.0-beta.13.canary.300 → 0.2.0-beta.13.canary.302
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/dist/index.js +71 -0
- package/dist/index.js.map +1 -1
- package/dist/recipeOrchestration.js +12 -0
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +7 -0
- package/dist/recipeRoutes.js +25 -0
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/server.d.ts +9 -0
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -1
- package/dist/workerGateDecisionLog.d.ts +34 -0
- package/dist/workerGateDecisionLog.js +85 -0
- package/dist/workerGateDecisionLog.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -161,6 +161,7 @@ const KNOWN_SUBCOMMANDS = [
|
|
|
161
161
|
"shadow-scan",
|
|
162
162
|
"workers",
|
|
163
163
|
"approvals",
|
|
164
|
+
"gate",
|
|
164
165
|
];
|
|
165
166
|
const __invokedSubcommand = (() => {
|
|
166
167
|
const sub = process.argv[2];
|
|
@@ -3937,6 +3938,76 @@ if (process.argv[2] === "approvals") {
|
|
|
3937
3938
|
}
|
|
3938
3939
|
})();
|
|
3939
3940
|
}
|
|
3941
|
+
// Handle gate subcommand — "why did the worker allow/gate THIS action" over
|
|
3942
|
+
// the local Decision Record (worker_gate_decisions.jsonl). Reads the log
|
|
3943
|
+
// directly (like `workers shadow` / `approvals`); no bridge round-trip needed
|
|
3944
|
+
// since the record is a local file, not live state.
|
|
3945
|
+
if (process.argv[2] === "gate") {
|
|
3946
|
+
const args = process.argv.slice(3);
|
|
3947
|
+
const sub = args[0];
|
|
3948
|
+
if (sub !== "explain" ||
|
|
3949
|
+
args.includes("--help") ||
|
|
3950
|
+
args.includes("-h") ||
|
|
3951
|
+
args.length < 3) {
|
|
3952
|
+
process.stdout.write("Usage: patchwork gate explain <workerId> <classKey> [--limit N] [--diff] [--json]\n\n" +
|
|
3953
|
+
"Explain the worker-autonomy gate's most recent decision(s) for a given\n" +
|
|
3954
|
+
"worker × action-class, from the local Decision Record\n" +
|
|
3955
|
+
"(~/.patchwork/worker_gate_decisions.jsonl) — no bridge required.\n\n" +
|
|
3956
|
+
' <classKey> e.g. "issue:compensable:high" (domain:reversibility:blastTier)\n' +
|
|
3957
|
+
" --limit N show the N most recent decisions (default 1, or 2 with --diff)\n" +
|
|
3958
|
+
" --diff compare the 2 most recent decisions and show what changed\n" +
|
|
3959
|
+
" --json emit raw JSON (for scripting)\n");
|
|
3960
|
+
process.exit(sub === "explain" ? 1 : 0);
|
|
3961
|
+
}
|
|
3962
|
+
(async () => {
|
|
3963
|
+
try {
|
|
3964
|
+
// Length checked above (args.length < 3 short-circuits to usage), so
|
|
3965
|
+
// args[1]/[2] are present here — noUncheckedIndexedAccess just can't see
|
|
3966
|
+
// across the `if` block above.
|
|
3967
|
+
const workerId = args[1];
|
|
3968
|
+
const classKey = args[2];
|
|
3969
|
+
const wantDiff = args.includes("--diff");
|
|
3970
|
+
const limitIdx = args.indexOf("--limit");
|
|
3971
|
+
const explicitLimit = limitIdx >= 0 && limitIdx + 1 < args.length
|
|
3972
|
+
? Number.parseInt(args[limitIdx + 1], 10)
|
|
3973
|
+
: undefined;
|
|
3974
|
+
const limit = explicitLimit ?? (wantDiff ? 2 : 1);
|
|
3975
|
+
if (!Number.isFinite(limit) || limit < 1) {
|
|
3976
|
+
process.stderr.write("Error: --limit must be a positive integer\n");
|
|
3977
|
+
process.exit(1);
|
|
3978
|
+
}
|
|
3979
|
+
const { WorkerGateDecisionLog, formatGateDecisionHistory, formatGateDecisionDiff, } = await import("./workerGateDecisionLog.js");
|
|
3980
|
+
const patchworkDir = process.env.PATCHWORK_HOME ?? path.join(os.homedir(), ".patchwork");
|
|
3981
|
+
const log = new WorkerGateDecisionLog({ dir: patchworkDir });
|
|
3982
|
+
const decisions = log.query({ workerId, classKey, limit });
|
|
3983
|
+
if (args.includes("--json")) {
|
|
3984
|
+
process.stdout.write(`${JSON.stringify(decisions, null, 2)}\n`);
|
|
3985
|
+
process.exit(0);
|
|
3986
|
+
}
|
|
3987
|
+
if (decisions.length === 0) {
|
|
3988
|
+
process.stdout.write(`No gate decisions found for worker "${workerId}" on class "${classKey}".\n` +
|
|
3989
|
+
"Either the worker hasn't acted on this class yet, or worker.autonomy is off.\n");
|
|
3990
|
+
process.exit(0);
|
|
3991
|
+
}
|
|
3992
|
+
if (wantDiff) {
|
|
3993
|
+
// query() sorts most-recent-first: newer is [0], older is [1].
|
|
3994
|
+
const [newer, older] = decisions;
|
|
3995
|
+
if (!newer || !older) {
|
|
3996
|
+
process.stdout.write(`Only one decision found for worker "${workerId}" on class "${classKey}" — nothing to diff against yet.\n`);
|
|
3997
|
+
process.exit(0);
|
|
3998
|
+
}
|
|
3999
|
+
process.stdout.write(`${formatGateDecisionDiff(newer, older)}\n`);
|
|
4000
|
+
process.exit(0);
|
|
4001
|
+
}
|
|
4002
|
+
process.stdout.write(`${formatGateDecisionHistory(decisions)}\n`);
|
|
4003
|
+
process.exit(0);
|
|
4004
|
+
}
|
|
4005
|
+
catch (err) {
|
|
4006
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
4007
|
+
process.exit(1);
|
|
4008
|
+
}
|
|
4009
|
+
})();
|
|
4010
|
+
}
|
|
3940
4011
|
// Handle launchd subcommand — install/uninstall macOS LaunchAgent for auto-start
|
|
3941
4012
|
if (process.argv[2] === "launchd") {
|
|
3942
4013
|
const sub = process.argv[3];
|