opencode-swarm 7.139.4 → 7.139.6
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/.opencode/skills/brainstorm/SKILL.md +8 -101
- package/.opencode/skills/execute/SKILL.md +10 -9
- package/.opencode/skills/issue-ingest/SKILL.md +1 -1
- package/.opencode/skills/plan/SKILL.md +40 -97
- package/.opencode/skills/specify/SKILL.md +3 -89
- package/dist/agents/architect.d.ts +2 -3
- package/dist/cli/{config-doctor-whxr386t.js → config-doctor-7v9at76j.js} +3 -3
- package/dist/cli/{core-aj5g7an6.js → core-jtj9j6z5.js} +2 -2
- package/dist/cli/{curation-policy-anym2y3v.js → curation-policy-rbrx3kd2.js} +6 -6
- package/dist/cli/{curator-e8cvb55d.js → curator-bdc5hssa.js} +27 -27
- package/dist/cli/{curator-llm-factory-h9xbpgmw.js → curator-llm-factory-305cfcxz.js} +27 -27
- package/dist/cli/{evidence-summary-service-g82bsjqa.js → evidence-summary-service-nfdc1ht9.js} +9 -8
- package/dist/cli/{gate-evidence-72cgrvs2.js → gate-evidence-46qeyfc1.js} +4 -4
- package/dist/cli/{guardrail-explain-0be7msvq.js → guardrail-explain-w9rwgz4c.js} +28 -28
- package/dist/cli/{guardrail-log-9mm5443g.js → guardrail-log-4805jgj5.js} +4 -4
- package/dist/cli/{hive-promoter-nnzs5x1r.js → hive-promoter-jrd4pjb6.js} +27 -27
- package/dist/cli/{index-sd657fkp.js → index-1m1ksyqt.js} +1 -1
- package/dist/cli/{index-5azdnaty.js → index-1tw24kcp.js} +2 -2
- package/dist/cli/{index-pg84msyc.js → index-3fscvmfw.js} +3 -3
- package/dist/cli/{index-k41dn8me.js → index-68gh7p3t.js} +3 -3
- package/dist/cli/{index-e1k9vpqn.js → index-7qx874pn.js} +2 -2
- package/dist/cli/{index-jnfyxeap.js → index-8d2d7c6k.js} +4 -4
- package/dist/cli/{index-0e95eck5.js → index-a6v3kzyc.js} +5 -5
- package/dist/cli/{index-xmhhhjjw.js → index-adyxbmt5.js} +3 -3
- package/dist/cli/{index-xb1zq933.js → index-b6k9z88b.js} +1 -1
- package/dist/cli/{index-j77frjq8.js → index-b9rd29ge.js} +1 -1
- package/dist/cli/{index-6nzmp937.js → index-brh827g0.js} +442 -27
- package/dist/cli/{index-1kz6da87.js → index-d181x9zr.js} +2 -1
- package/dist/cli/{index-ejbcpbzp.js → index-ev72jrxc.js} +2 -2
- package/dist/cli/{index-s58vghgj.js → index-fjrt81db.js} +2 -2
- package/dist/cli/{index-6r522srn.js → index-h2waehqq.js} +1 -1
- package/dist/cli/{index-vyqd1hzm.js → index-h7ht03c4.js} +1529 -969
- package/dist/cli/{index-6z0a940s.js → index-hbnsmnb0.js} +2 -2
- package/dist/cli/{index-s0qc4gj6.js → index-hfvxhk4z.js} +1 -1
- package/dist/cli/{index-0xkjhgrf.js → index-jfjnn408.js} +1 -1
- package/dist/cli/{index-vfsqpcz6.js → index-k5z14rb1.js} +4 -4
- package/dist/cli/{index-6rxgb5r9.js → index-kbfsp07d.js} +16 -6
- package/dist/cli/{index-6vh6vrnk.js → index-m7xks4r4.js} +6 -6
- package/dist/cli/{index-5z2xps64.js → index-n0pja0qs.js} +2 -2
- package/dist/cli/{index-5s23pfsy.js → index-n3ppm2gt.js} +2 -2
- package/dist/cli/{index-4wjk296r.js → index-r4t92q32.js} +2 -2
- package/dist/cli/{index-33skgk1a.js → index-rs1f1bh0.js} +1 -1
- package/dist/cli/{index-rsrx77fg.js → index-ry0hgg3m.js} +3 -3
- package/dist/cli/{index-sa15nfgg.js → index-sfbwze80.js} +29 -29
- package/dist/cli/{index-gfmrw2f5.js → index-t94f72tb.js} +2 -2
- package/dist/cli/{index-9cdj4020.js → index-wv89xmbe.js} +2 -2
- package/dist/cli/{index-nrx08gcr.js → index-yyyk63kk.js} +2 -2
- package/dist/cli/index.js +27 -27
- package/dist/cli/{knowledge-escalator-a6z30y9p.js → knowledge-escalator-7z9vwqrk.js} +7 -7
- package/dist/cli/{knowledge-events-deq0ds8e.js → knowledge-events-vw2cdtnp.js} +5 -5
- package/dist/cli/{knowledge-link-bmbatt8s.js → knowledge-link-q46k9adx.js} +4 -4
- package/dist/cli/{knowledge-store-vdr19mnq.js → knowledge-store-ecv0qs7r.js} +5 -5
- package/dist/cli/{knowledge-validator-5hgacnrf.js → knowledge-validator-arppnzpb.js} +8 -8
- package/dist/cli/{pending-delegations-7ayryxbg.js → pending-delegations-qzrx38y9.js} +3 -3
- package/dist/cli/{pr-subscriptions-w5y08ebc.js → pr-subscriptions-5s59h4dd.js} +3 -3
- package/dist/cli/{runner-h7vmgkth.js → runner-y78d7ryb.js} +5 -5
- package/dist/cli/{scan-cursor-d6qcg9hr.js → scan-cursor-7740wg6r.js} +6 -6
- package/dist/cli/{schema-y1zekrag.js → schema-sajt4mcv.js} +2 -2
- package/dist/cli/{scope-persistence-tj6qway9.js → scope-persistence-dr1msqxw.js} +5 -5
- package/dist/cli/{skill-generator-bw8xhzzn.js → skill-generator-k8qz8ja5.js} +9 -9
- package/dist/cli/{telemetry-62cn5t24.js → telemetry-sc57xtb0.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-hs5c2qzp.js → worktree-collision-ownership-7a8e6gr9.js} +3 -3
- package/dist/config/plan-schema.d.ts +2 -0
- package/dist/db/index.d.ts +1 -1
- package/dist/db/qa-gate-profile.d.ts +86 -2
- package/dist/db/task-checkpoint-receipt.d.ts +27 -0
- package/dist/index.js +394 -309
- package/dist/plan/manager.d.ts +4 -0
- package/dist/qa-gate/recovery.d.ts +6 -0
- package/dist/services/export-service.d.ts +2 -6
- package/dist/services/handoff-service.d.ts +2 -6
- package/dist/tools/checkpoint.d.ts +17 -7
- package/dist/tools/get-approved-plan.d.ts +8 -6
- package/dist/tools/get-qa-gate-profile.d.ts +7 -3
- package/dist/tools/phase-complete/gates/gate-helpers.d.ts +1 -0
- package/dist/tools/qa-gate-plan-identity.d.ts +28 -0
- package/dist/tools/save-plan.d.ts +3 -14
- package/dist/tools/set-qa-gates.d.ts +13 -8
- package/dist/tools/write-drift-evidence.d.ts +2 -0
- package/package.json +1 -1
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
EvaluationRunV1Schema,
|
|
4
4
|
GateAuditResultV1Schema,
|
|
5
5
|
getProtectedEvaluationRunIds
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-yyyk63kk.js";
|
|
7
|
+
import {
|
|
8
|
+
loadDatabaseCtor
|
|
9
|
+
} from "./index-134d35c1.js";
|
|
7
10
|
import {
|
|
8
11
|
readEffectiveSpecSync
|
|
9
12
|
} from "./index-9ss2m4rs.js";
|
|
@@ -13,6 +16,7 @@ import {
|
|
|
13
16
|
computeCurrentPlanHash,
|
|
14
17
|
computePlanHash,
|
|
15
18
|
derivePlanId,
|
|
19
|
+
derivePlanIdentityHash,
|
|
16
20
|
getLatestLedgerSeq,
|
|
17
21
|
initLedger,
|
|
18
22
|
ledgerExists,
|
|
@@ -22,7 +26,7 @@ import {
|
|
|
22
26
|
replayFromLedgerWithStatus,
|
|
23
27
|
takeSnapshotEvent,
|
|
24
28
|
takeSnapshotWithRetry
|
|
25
|
-
} from "./index-
|
|
29
|
+
} from "./index-kbfsp07d.js";
|
|
26
30
|
import {
|
|
27
31
|
getWorktreeMergeFailure
|
|
28
32
|
} from "./index-b8zgtz81.js";
|
|
@@ -35,7 +39,7 @@ import {
|
|
|
35
39
|
readTaskEvidence,
|
|
36
40
|
readTaskEvidenceRaw,
|
|
37
41
|
sanitizeTaskId
|
|
38
|
-
} from "./index-
|
|
42
|
+
} from "./index-n0pja0qs.js";
|
|
39
43
|
import {
|
|
40
44
|
_internals,
|
|
41
45
|
buildDefaultPolicy,
|
|
@@ -49,8 +53,9 @@ import {
|
|
|
49
53
|
} from "./index-ed5ykebp.js";
|
|
50
54
|
import {
|
|
51
55
|
assertProjectRoot,
|
|
56
|
+
tryAcquireLock,
|
|
52
57
|
withEvidenceLock
|
|
53
|
-
} from "./index-
|
|
58
|
+
} from "./index-hfvxhk4z.js";
|
|
54
59
|
import {
|
|
55
60
|
bunHash,
|
|
56
61
|
bunWrite,
|
|
@@ -63,7 +68,7 @@ import {
|
|
|
63
68
|
} from "./index-gprxjmm7.js";
|
|
64
69
|
import {
|
|
65
70
|
PlanSchema
|
|
66
|
-
} from "./index-
|
|
71
|
+
} from "./index-d181x9zr.js";
|
|
67
72
|
import {
|
|
68
73
|
criticalWarn,
|
|
69
74
|
error,
|
|
@@ -72,7 +77,7 @@ import {
|
|
|
72
77
|
} from "./index-zgwm4ryv.js";
|
|
73
78
|
import {
|
|
74
79
|
emit
|
|
75
|
-
} from "./index-
|
|
80
|
+
} from "./index-ry0hgg3m.js";
|
|
76
81
|
import {
|
|
77
82
|
ZodError,
|
|
78
83
|
init_zod
|
|
@@ -972,9 +977,9 @@ var init_executor = __esm(() => {
|
|
|
972
977
|
import {
|
|
973
978
|
closeSync,
|
|
974
979
|
copyFileSync,
|
|
975
|
-
existsSync as
|
|
980
|
+
existsSync as existsSync4,
|
|
976
981
|
fsyncSync,
|
|
977
|
-
mkdirSync as
|
|
982
|
+
mkdirSync as mkdirSync4,
|
|
978
983
|
openSync,
|
|
979
984
|
readdirSync,
|
|
980
985
|
renameSync as renameSync2,
|
|
@@ -984,6 +989,342 @@ import {
|
|
|
984
989
|
import * as fsPromises from "fs/promises";
|
|
985
990
|
import * as path8 from "path";
|
|
986
991
|
|
|
992
|
+
// src/db/task-checkpoint-receipt.ts
|
|
993
|
+
import { createHash } from "crypto";
|
|
994
|
+
|
|
995
|
+
// src/db/project-db.ts
|
|
996
|
+
import { existsSync, mkdirSync } from "fs";
|
|
997
|
+
import { join, resolve } from "path";
|
|
998
|
+
var MIGRATIONS = [
|
|
999
|
+
{
|
|
1000
|
+
version: 1,
|
|
1001
|
+
name: "create_project_constraints",
|
|
1002
|
+
sql: `CREATE TABLE project_constraints (
|
|
1003
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1004
|
+
constraint_type TEXT NOT NULL,
|
|
1005
|
+
content TEXT NOT NULL,
|
|
1006
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
1007
|
+
)`
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
version: 2,
|
|
1011
|
+
name: "create_qa_gate_profile",
|
|
1012
|
+
sql: `CREATE TABLE qa_gate_profile (
|
|
1013
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1014
|
+
plan_id TEXT NOT NULL UNIQUE,
|
|
1015
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
1016
|
+
project_type TEXT,
|
|
1017
|
+
gates TEXT NOT NULL DEFAULT '{}',
|
|
1018
|
+
locked_at TEXT,
|
|
1019
|
+
locked_by_snapshot_seq INTEGER
|
|
1020
|
+
)`
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
version: 3,
|
|
1024
|
+
name: "create_qa_gate_profile_immutability_trigger",
|
|
1025
|
+
sql: `CREATE TRIGGER IF NOT EXISTS trg_qa_gate_profile_no_update_after_lock
|
|
1026
|
+
BEFORE UPDATE ON qa_gate_profile
|
|
1027
|
+
WHEN OLD.locked_at IS NOT NULL
|
|
1028
|
+
BEGIN
|
|
1029
|
+
SELECT RAISE(ABORT, 'qa_gate_profile row is locked and cannot be modified after critic approval');
|
|
1030
|
+
END`
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
version: 4,
|
|
1034
|
+
name: "add_qa_gate_profile_raw_swarm",
|
|
1035
|
+
sql: "ALTER TABLE qa_gate_profile ADD COLUMN raw_swarm TEXT"
|
|
1036
|
+
},
|
|
1037
|
+
{
|
|
1038
|
+
version: 5,
|
|
1039
|
+
name: "add_qa_gate_profile_raw_title",
|
|
1040
|
+
sql: "ALTER TABLE qa_gate_profile ADD COLUMN raw_title TEXT"
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
version: 6,
|
|
1044
|
+
name: "add_qa_gate_profile_identity_hash",
|
|
1045
|
+
sql: "ALTER TABLE qa_gate_profile ADD COLUMN identity_hash TEXT"
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
version: 7,
|
|
1049
|
+
name: "create_qa_gate_profile_identity_hash_index",
|
|
1050
|
+
sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_qa_gate_profile_identity_hash
|
|
1051
|
+
ON qa_gate_profile(identity_hash)
|
|
1052
|
+
WHERE identity_hash IS NOT NULL`
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
version: 8,
|
|
1056
|
+
name: "create_qa_gate_profile_identity",
|
|
1057
|
+
sql: `CREATE TABLE qa_gate_profile_identity (
|
|
1058
|
+
identity_hash TEXT PRIMARY KEY,
|
|
1059
|
+
profile_id INTEGER NOT NULL UNIQUE REFERENCES qa_gate_profile(id) ON DELETE CASCADE,
|
|
1060
|
+
raw_swarm TEXT NOT NULL,
|
|
1061
|
+
raw_title TEXT NOT NULL,
|
|
1062
|
+
readable_plan_id TEXT NOT NULL
|
|
1063
|
+
)`
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
version: 9,
|
|
1067
|
+
name: "create_qa_gate_profile_identity_readable_plan_index",
|
|
1068
|
+
sql: `CREATE INDEX idx_qa_gate_profile_identity_readable_plan_id
|
|
1069
|
+
ON qa_gate_profile_identity(readable_plan_id)`
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
version: 10,
|
|
1073
|
+
name: "backfill_qa_gate_profile_identity_from_legacy_columns",
|
|
1074
|
+
sql: `INSERT INTO qa_gate_profile_identity (
|
|
1075
|
+
identity_hash,
|
|
1076
|
+
profile_id,
|
|
1077
|
+
raw_swarm,
|
|
1078
|
+
raw_title,
|
|
1079
|
+
readable_plan_id
|
|
1080
|
+
)
|
|
1081
|
+
SELECT
|
|
1082
|
+
identity_hash,
|
|
1083
|
+
id,
|
|
1084
|
+
raw_swarm,
|
|
1085
|
+
raw_title,
|
|
1086
|
+
plan_id
|
|
1087
|
+
FROM qa_gate_profile
|
|
1088
|
+
WHERE identity_hash IS NOT NULL
|
|
1089
|
+
AND raw_swarm IS NOT NULL
|
|
1090
|
+
AND raw_title IS NOT NULL
|
|
1091
|
+
AND NOT EXISTS (
|
|
1092
|
+
SELECT 1
|
|
1093
|
+
FROM qa_gate_profile_identity AS qi
|
|
1094
|
+
WHERE qi.profile_id = qa_gate_profile.id
|
|
1095
|
+
)`
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
version: 11,
|
|
1099
|
+
name: "create_task_checkpoint_receipt",
|
|
1100
|
+
sql: `CREATE TABLE task_checkpoint_receipt (
|
|
1101
|
+
plan_identity_hash TEXT NOT NULL,
|
|
1102
|
+
task_id TEXT NOT NULL,
|
|
1103
|
+
label TEXT NOT NULL,
|
|
1104
|
+
state TEXT NOT NULL CHECK(state IN ('pending', 'committed', 'logged')),
|
|
1105
|
+
sha TEXT,
|
|
1106
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
1107
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
1108
|
+
PRIMARY KEY(plan_identity_hash, task_id)
|
|
1109
|
+
)`
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
version: 12,
|
|
1113
|
+
name: "add_task_checkpoint_receipt_completion_generation",
|
|
1114
|
+
sql: `ALTER TABLE task_checkpoint_receipt
|
|
1115
|
+
ADD COLUMN generation INTEGER NOT NULL DEFAULT 1;
|
|
1116
|
+
ALTER TABLE task_checkpoint_receipt
|
|
1117
|
+
ADD COLUMN completion_active INTEGER NOT NULL DEFAULT 1
|
|
1118
|
+
CHECK(completion_active IN (0, 1))`
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
version: 13,
|
|
1122
|
+
name: "bind_task_checkpoint_receipt_to_completion_ledger_seq",
|
|
1123
|
+
sql: `ALTER TABLE task_checkpoint_receipt
|
|
1124
|
+
ADD COLUMN completion_ledger_seq INTEGER
|
|
1125
|
+
CHECK(completion_ledger_seq IS NULL OR completion_ledger_seq >= 0)`
|
|
1126
|
+
}
|
|
1127
|
+
];
|
|
1128
|
+
var _projectDbs = new Map;
|
|
1129
|
+
function runProjectMigrations(db) {
|
|
1130
|
+
db.run(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
1131
|
+
version INTEGER PRIMARY KEY,
|
|
1132
|
+
name TEXT NOT NULL,
|
|
1133
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
1134
|
+
)`);
|
|
1135
|
+
const row = db.query("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
1136
|
+
const currentVersion = row?.version ?? 0;
|
|
1137
|
+
for (const migration of MIGRATIONS) {
|
|
1138
|
+
if (migration.version <= currentVersion)
|
|
1139
|
+
continue;
|
|
1140
|
+
const apply = db.transaction(() => {
|
|
1141
|
+
db.run(migration.sql);
|
|
1142
|
+
db.run("INSERT INTO schema_migrations (version, name) VALUES (?, ?)", [
|
|
1143
|
+
migration.version,
|
|
1144
|
+
migration.name
|
|
1145
|
+
]);
|
|
1146
|
+
});
|
|
1147
|
+
apply();
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
function projectDbPath(directory) {
|
|
1151
|
+
return join(resolve(directory), ".swarm", "swarm.db");
|
|
1152
|
+
}
|
|
1153
|
+
function projectDbExists(directory) {
|
|
1154
|
+
return existsSync(projectDbPath(directory));
|
|
1155
|
+
}
|
|
1156
|
+
function getProjectDb(directory) {
|
|
1157
|
+
const key = resolve(directory);
|
|
1158
|
+
const existing = _projectDbs.get(key);
|
|
1159
|
+
if (existing)
|
|
1160
|
+
return existing;
|
|
1161
|
+
const swarmDir = join(key, ".swarm");
|
|
1162
|
+
mkdirSync(swarmDir, { recursive: true });
|
|
1163
|
+
const Db = loadDatabaseCtor();
|
|
1164
|
+
const db = new Db(join(swarmDir, "swarm.db"));
|
|
1165
|
+
db.run("PRAGMA journal_mode = WAL;");
|
|
1166
|
+
db.run("PRAGMA synchronous = NORMAL;");
|
|
1167
|
+
db.run("PRAGMA busy_timeout = 5000;");
|
|
1168
|
+
db.run("PRAGMA foreign_keys = ON;");
|
|
1169
|
+
runProjectMigrations(db);
|
|
1170
|
+
_projectDbs.set(key, db);
|
|
1171
|
+
return db;
|
|
1172
|
+
}
|
|
1173
|
+
function closeProjectDb(directory) {
|
|
1174
|
+
const key = resolve(directory);
|
|
1175
|
+
const db = _projectDbs.get(key);
|
|
1176
|
+
if (db) {
|
|
1177
|
+
db.close();
|
|
1178
|
+
_projectDbs.delete(key);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/db/task-checkpoint-receipt.ts
|
|
1183
|
+
var TASK_COMPLETION_HASH_LENGTH = 16;
|
|
1184
|
+
function taskReceiptLabelSuffix(planIdentityHash, taskId, generation) {
|
|
1185
|
+
return createHash("sha256").update(JSON.stringify(generation === 1 ? [planIdentityHash, taskId] : [planIdentityHash, taskId, generation]), "utf8").digest("hex").slice(0, TASK_COMPLETION_HASH_LENGTH);
|
|
1186
|
+
}
|
|
1187
|
+
function scrubTaskIdForCheckpointLabel(taskId) {
|
|
1188
|
+
const scrubbed = taskId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
1189
|
+
return scrubbed.length > 32 ? scrubbed.slice(0, 32) : scrubbed;
|
|
1190
|
+
}
|
|
1191
|
+
function buildTaskCompletionDescriptor(planIdentityHash, taskId, generation) {
|
|
1192
|
+
if (!Number.isSafeInteger(generation) || generation < 1) {
|
|
1193
|
+
throw new Error(`Invalid task checkpoint generation: ${generation}`);
|
|
1194
|
+
}
|
|
1195
|
+
const suffix = taskReceiptLabelSuffix(planIdentityHash, taskId, generation);
|
|
1196
|
+
const safeTaskId = scrubTaskIdForCheckpointLabel(taskId) || "task";
|
|
1197
|
+
return {
|
|
1198
|
+
planIdentityHash,
|
|
1199
|
+
taskId,
|
|
1200
|
+
generation,
|
|
1201
|
+
label: `task-${safeTaskId}-complete-${suffix}`,
|
|
1202
|
+
subject: generation === 1 ? `checkpoint(task-complete ${suffix} plan ${planIdentityHash}): ${safeTaskId}` : `checkpoint(task-complete ${suffix} gen ${generation} plan ${planIdentityHash}): ${safeTaskId}`
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
function readTaskCheckpointReceipt(directory, planIdentityHash, taskId) {
|
|
1206
|
+
if (!projectDbExists(directory))
|
|
1207
|
+
return null;
|
|
1208
|
+
return getProjectDb(directory).query("SELECT * FROM task_checkpoint_receipt WHERE plan_identity_hash = ? AND task_id = ?").get(planIdentityHash, taskId) ?? null;
|
|
1209
|
+
}
|
|
1210
|
+
function ensureTaskCheckpointReceipt(directory, planIdentityHash, taskId, completionLedgerSeq) {
|
|
1211
|
+
if (!Number.isSafeInteger(completionLedgerSeq) || completionLedgerSeq < 0) {
|
|
1212
|
+
throw new Error(`Invalid task checkpoint completion ledger seq: ${completionLedgerSeq}`);
|
|
1213
|
+
}
|
|
1214
|
+
const db = getProjectDb(directory);
|
|
1215
|
+
const initial = buildTaskCompletionDescriptor(planIdentityHash, taskId, 1);
|
|
1216
|
+
db.transaction(() => {
|
|
1217
|
+
db.run(`INSERT OR IGNORE INTO task_checkpoint_receipt
|
|
1218
|
+
(plan_identity_hash, task_id, label, state, sha, generation,
|
|
1219
|
+
completion_active, completion_ledger_seq)
|
|
1220
|
+
VALUES (?, ?, ?, 'pending', NULL, 1, 1, ?)`, [planIdentityHash, taskId, initial.label, completionLedgerSeq]);
|
|
1221
|
+
const row2 = db.query("SELECT * FROM task_checkpoint_receipt WHERE plan_identity_hash = ? AND task_id = ?").get(planIdentityHash, taskId);
|
|
1222
|
+
if (!row2)
|
|
1223
|
+
return;
|
|
1224
|
+
if (row2.completion_ledger_seq === null) {
|
|
1225
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1226
|
+
SET completion_ledger_seq = ?, completion_active = 1,
|
|
1227
|
+
updated_at = datetime('now')
|
|
1228
|
+
WHERE plan_identity_hash = ? AND task_id = ?
|
|
1229
|
+
AND completion_ledger_seq IS NULL`, [completionLedgerSeq, planIdentityHash, taskId]);
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
if (row2.completion_ledger_seq !== completionLedgerSeq) {
|
|
1233
|
+
const nextGeneration = row2.generation + 1;
|
|
1234
|
+
const descriptor = buildTaskCompletionDescriptor(planIdentityHash, taskId, nextGeneration);
|
|
1235
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1236
|
+
SET label = ?, state = 'pending', sha = NULL, generation = ?,
|
|
1237
|
+
completion_active = 1, completion_ledger_seq = ?,
|
|
1238
|
+
updated_at = datetime('now')
|
|
1239
|
+
WHERE plan_identity_hash = ? AND task_id = ?
|
|
1240
|
+
AND completion_ledger_seq = ?`, [
|
|
1241
|
+
descriptor.label,
|
|
1242
|
+
nextGeneration,
|
|
1243
|
+
completionLedgerSeq,
|
|
1244
|
+
planIdentityHash,
|
|
1245
|
+
taskId,
|
|
1246
|
+
row2.completion_ledger_seq
|
|
1247
|
+
]);
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
if (row2.completion_active === 0) {
|
|
1251
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1252
|
+
SET completion_active = 1, updated_at = datetime('now')
|
|
1253
|
+
WHERE plan_identity_hash = ? AND task_id = ?
|
|
1254
|
+
AND completion_ledger_seq = ? AND completion_active = 0`, [planIdentityHash, taskId, completionLedgerSeq]);
|
|
1255
|
+
}
|
|
1256
|
+
})();
|
|
1257
|
+
const row = readTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1258
|
+
if (!row) {
|
|
1259
|
+
throw new Error(`Failed to create or read task checkpoint receipt for ${taskId}`);
|
|
1260
|
+
}
|
|
1261
|
+
return row;
|
|
1262
|
+
}
|
|
1263
|
+
function activateTaskCheckpointReceipt(directory, planIdentityHash, taskId) {
|
|
1264
|
+
if (!projectDbExists(directory))
|
|
1265
|
+
return null;
|
|
1266
|
+
const db = getProjectDb(directory);
|
|
1267
|
+
db.transaction(() => {
|
|
1268
|
+
const row = db.query("SELECT * FROM task_checkpoint_receipt WHERE plan_identity_hash = ? AND task_id = ?").get(planIdentityHash, taskId);
|
|
1269
|
+
if (!row || row.completion_active === 1)
|
|
1270
|
+
return;
|
|
1271
|
+
const descriptor = buildTaskCompletionDescriptor(planIdentityHash, taskId, row.generation);
|
|
1272
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1273
|
+
SET label = ?, state = 'pending', sha = NULL, completion_active = 1,
|
|
1274
|
+
updated_at = datetime('now')
|
|
1275
|
+
WHERE plan_identity_hash = ? AND task_id = ? AND completion_active = 0`, [descriptor.label, planIdentityHash, taskId]);
|
|
1276
|
+
})();
|
|
1277
|
+
return readTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1278
|
+
}
|
|
1279
|
+
function advanceTaskCheckpointReceiptGeneration(directory, planIdentityHash, taskId) {
|
|
1280
|
+
if (!projectDbExists(directory))
|
|
1281
|
+
return null;
|
|
1282
|
+
const db = getProjectDb(directory);
|
|
1283
|
+
db.transaction(() => {
|
|
1284
|
+
const row = db.query("SELECT * FROM task_checkpoint_receipt WHERE plan_identity_hash = ? AND task_id = ?").get(planIdentityHash, taskId);
|
|
1285
|
+
if (!row || row.completion_active === 0)
|
|
1286
|
+
return;
|
|
1287
|
+
const nextGeneration = row.generation + 1;
|
|
1288
|
+
const descriptor = buildTaskCompletionDescriptor(planIdentityHash, taskId, nextGeneration);
|
|
1289
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1290
|
+
SET label = ?, state = 'pending', sha = NULL, generation = ?,
|
|
1291
|
+
completion_active = 0, completion_ledger_seq = NULL,
|
|
1292
|
+
updated_at = datetime('now')
|
|
1293
|
+
WHERE plan_identity_hash = ? AND task_id = ? AND completion_active = 1`, [descriptor.label, nextGeneration, planIdentityHash, taskId]);
|
|
1294
|
+
})();
|
|
1295
|
+
return readTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1296
|
+
}
|
|
1297
|
+
function repairTaskCheckpointReceiptForCompletion(directory, planIdentityHash, taskId) {
|
|
1298
|
+
if (!projectDbExists(directory))
|
|
1299
|
+
return null;
|
|
1300
|
+
const current = readTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1301
|
+
if (!current)
|
|
1302
|
+
return null;
|
|
1303
|
+
if (current.completion_active === 0) {
|
|
1304
|
+
return activateTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1305
|
+
}
|
|
1306
|
+
advanceTaskCheckpointReceiptGeneration(directory, planIdentityHash, taskId);
|
|
1307
|
+
return activateTaskCheckpointReceipt(directory, planIdentityHash, taskId);
|
|
1308
|
+
}
|
|
1309
|
+
function updateTaskCheckpointReceipt(directory, descriptor, state, sha) {
|
|
1310
|
+
const db = getProjectDb(directory);
|
|
1311
|
+
db.run(`UPDATE task_checkpoint_receipt
|
|
1312
|
+
SET state = ?, sha = ?, updated_at = datetime('now')
|
|
1313
|
+
WHERE plan_identity_hash = ? AND task_id = ?
|
|
1314
|
+
AND generation = ? AND completion_active = 1`, [
|
|
1315
|
+
state,
|
|
1316
|
+
sha,
|
|
1317
|
+
descriptor.planIdentityHash,
|
|
1318
|
+
descriptor.taskId,
|
|
1319
|
+
descriptor.generation
|
|
1320
|
+
]);
|
|
1321
|
+
const row = readTaskCheckpointReceipt(directory, descriptor.planIdentityHash, descriptor.taskId);
|
|
1322
|
+
if (!row || row.generation !== descriptor.generation || row.completion_active !== 1) {
|
|
1323
|
+
throw new Error(`Task checkpoint receipt generation changed for ${descriptor.taskId}`);
|
|
1324
|
+
}
|
|
1325
|
+
return row;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
987
1328
|
// src/git/branch.ts
|
|
988
1329
|
init_executor();
|
|
989
1330
|
import * as child_process from "child_process";
|
|
@@ -1292,7 +1633,7 @@ async function resetToRemoteBranch(cwd, options) {
|
|
|
1292
1633
|
let lastError;
|
|
1293
1634
|
for (let retry = 0;retry < 4; retry++) {
|
|
1294
1635
|
if (retry > 0 && process.platform === "win32") {
|
|
1295
|
-
await new Promise((
|
|
1636
|
+
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
1296
1637
|
}
|
|
1297
1638
|
try {
|
|
1298
1639
|
gitExec(["reset", "--hard", targetBranch], cwd);
|
|
@@ -1502,7 +1843,7 @@ async function resetToMainAfterMerge(cwd, options) {
|
|
|
1502
1843
|
let discardSucceeded = false;
|
|
1503
1844
|
for (let retry = 0;retry < 4; retry++) {
|
|
1504
1845
|
if (retry > 0 && process.platform === "win32") {
|
|
1505
|
-
await new Promise((
|
|
1846
|
+
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
1506
1847
|
}
|
|
1507
1848
|
try {
|
|
1508
1849
|
_internals5.gitExec(["checkout", "--", "."], cwd);
|
|
@@ -2094,7 +2435,7 @@ var _internals7 = {
|
|
|
2094
2435
|
gitHeadSha: (cwd) => {
|
|
2095
2436
|
return _internals5.gitExec(["rev-parse", "HEAD"], cwd).trim();
|
|
2096
2437
|
},
|
|
2097
|
-
sleep: (ms) => new Promise((
|
|
2438
|
+
sleep: (ms) => new Promise((resolve4) => setTimeout(resolve4, ms)),
|
|
2098
2439
|
hasExistingTaskCommit: (cwd, taskId) => {
|
|
2099
2440
|
const safeId = scrubTaskIdForGitSubject(taskId);
|
|
2100
2441
|
const escaped = safeId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -2257,14 +2598,14 @@ function readTaskScopes(directory, taskId) {
|
|
|
2257
2598
|
}
|
|
2258
2599
|
|
|
2259
2600
|
// src/utils/spec-hash.ts
|
|
2260
|
-
import { createHash as
|
|
2601
|
+
import { createHash as createHash3 } from "crypto";
|
|
2261
2602
|
import * as fsSync2 from "fs";
|
|
2262
|
-
import { join as
|
|
2603
|
+
import { join as join7 } from "path";
|
|
2263
2604
|
async function computeSpecHash(directory) {
|
|
2264
2605
|
const spec = _internals8.readEffectiveSpecSync(directory);
|
|
2265
2606
|
if (!spec)
|
|
2266
2607
|
return null;
|
|
2267
|
-
return
|
|
2608
|
+
return createHash3("sha256").update(spec.content, "utf-8").digest("hex");
|
|
2268
2609
|
}
|
|
2269
2610
|
async function isSpecStale(directory, plan) {
|
|
2270
2611
|
const currentHash = await _internals8.computeSpecHash(directory);
|
|
@@ -2288,7 +2629,7 @@ async function isSpecStale(directory, plan) {
|
|
|
2288
2629
|
return { stale: false };
|
|
2289
2630
|
}
|
|
2290
2631
|
function isObligationPreserving(directory) {
|
|
2291
|
-
const snapshotPath =
|
|
2632
|
+
const snapshotPath = join7(directory, ".swarm", "spec-snapshot.md");
|
|
2292
2633
|
try {
|
|
2293
2634
|
let recordedContent;
|
|
2294
2635
|
try {
|
|
@@ -2334,7 +2675,7 @@ var _internals8 = {
|
|
|
2334
2675
|
readEffectiveSpecSync
|
|
2335
2676
|
};
|
|
2336
2677
|
function computeSpecDiff(directory) {
|
|
2337
|
-
const snapshotPath =
|
|
2678
|
+
const snapshotPath = join7(directory, ".swarm", "spec-snapshot.md");
|
|
2338
2679
|
let recordedContent;
|
|
2339
2680
|
try {
|
|
2340
2681
|
const snapshotSize = fsSync2.statSync(snapshotPath).size;
|
|
@@ -2538,7 +2879,7 @@ async function retryCasWithBackoff(directory, eventInput, options) {
|
|
|
2538
2879
|
expectedHashPrefix: currentExpected.slice(0, 8),
|
|
2539
2880
|
delayMs
|
|
2540
2881
|
});
|
|
2541
|
-
await new Promise((
|
|
2882
|
+
await new Promise((resolve5) => setTimeout(resolve5, delayMs));
|
|
2542
2883
|
if (options.verifyValid) {
|
|
2543
2884
|
const stillValid = await options.verifyValid();
|
|
2544
2885
|
if (!stillValid)
|
|
@@ -2616,6 +2957,14 @@ function computePlanContentHash(plan) {
|
|
|
2616
2957
|
swarm: plan.swarm,
|
|
2617
2958
|
current_phase: plan.current_phase,
|
|
2618
2959
|
migration_status: plan.migration_status,
|
|
2960
|
+
execution_profile: plan.execution_profile ? {
|
|
2961
|
+
parallelization_enabled: plan.execution_profile.parallelization_enabled,
|
|
2962
|
+
max_concurrent_tasks: plan.execution_profile.max_concurrent_tasks,
|
|
2963
|
+
council_parallel: plan.execution_profile.council_parallel,
|
|
2964
|
+
locked: plan.execution_profile.locked,
|
|
2965
|
+
auto_proceed: plan.execution_profile.auto_proceed,
|
|
2966
|
+
commit_after_each_completed_task: plan.execution_profile.commit_after_each_completed_task === true ? true : undefined
|
|
2967
|
+
} : undefined,
|
|
2619
2968
|
phases: plan.phases.map((phase) => ({
|
|
2620
2969
|
id: phase.id,
|
|
2621
2970
|
name: phase.name,
|
|
@@ -2947,6 +3296,23 @@ async function savePlan(directory, plan, options) {
|
|
|
2947
3296
|
throw new Error(`Invalid directory: directory must be a non-empty string`);
|
|
2948
3297
|
}
|
|
2949
3298
|
assertProjectRoot(directory);
|
|
3299
|
+
if (!options?.planLockAlreadyHeld) {
|
|
3300
|
+
const lockResult = await tryAcquireLock(directory, "plan.json", "plan-manager", `save-plan-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
3301
|
+
if (!lockResult.acquired) {
|
|
3302
|
+
throw new PlanConcurrentModificationError(`Plan write blocked: plan.json is locked by ${lockResult.existing?.agent ?? "another agent"} (task: ${lockResult.existing?.taskId ?? "unknown"})`);
|
|
3303
|
+
}
|
|
3304
|
+
try {
|
|
3305
|
+
await savePlan(directory, plan, {
|
|
3306
|
+
...options,
|
|
3307
|
+
planLockAlreadyHeld: true
|
|
3308
|
+
});
|
|
3309
|
+
return;
|
|
3310
|
+
} finally {
|
|
3311
|
+
if (lockResult.lock._release) {
|
|
3312
|
+
await lockResult.lock._release().catch(() => {});
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
2950
3316
|
const validated = PlanSchema.parse(plan);
|
|
2951
3317
|
if (options?.preserveCompletedStatuses !== false) {
|
|
2952
3318
|
try {
|
|
@@ -2991,7 +3357,7 @@ async function savePlan(directory, plan, options) {
|
|
|
2991
3357
|
const oldLedgerPath = path8.join(swarmDir2, "plan-ledger.jsonl");
|
|
2992
3358
|
const oldLedgerBackupPath = path8.join(swarmDir2, `plan-ledger.backup-${Date.now()}-${Math.floor(Math.random() * 1e9)}.jsonl`);
|
|
2993
3359
|
let backupExists = false;
|
|
2994
|
-
if (
|
|
3360
|
+
if (existsSync4(oldLedgerPath)) {
|
|
2995
3361
|
try {
|
|
2996
3362
|
renameSync2(oldLedgerPath, oldLedgerBackupPath);
|
|
2997
3363
|
backupExists = true;
|
|
@@ -3008,11 +3374,11 @@ async function savePlan(directory, plan, options) {
|
|
|
3008
3374
|
const errorMessage2 = String(initErr);
|
|
3009
3375
|
if (errorMessage2.includes("already initialized")) {
|
|
3010
3376
|
try {
|
|
3011
|
-
if (
|
|
3377
|
+
if (existsSync4(oldLedgerBackupPath))
|
|
3012
3378
|
unlinkSync2(oldLedgerBackupPath);
|
|
3013
3379
|
} catch {}
|
|
3014
3380
|
} else {
|
|
3015
|
-
if (
|
|
3381
|
+
if (existsSync4(oldLedgerBackupPath)) {
|
|
3016
3382
|
try {
|
|
3017
3383
|
renameSync2(oldLedgerBackupPath, oldLedgerPath);
|
|
3018
3384
|
} catch {
|
|
@@ -3034,13 +3400,13 @@ async function savePlan(directory, plan, options) {
|
|
|
3034
3400
|
} catch (renameErr) {
|
|
3035
3401
|
warn(`[savePlan] Could not archive old ledger (rename failed: ${renameErr instanceof Error ? renameErr.message : String(renameErr)}). Old ledger may still exist at ${oldLedgerBackupPath}.`);
|
|
3036
3402
|
try {
|
|
3037
|
-
if (
|
|
3403
|
+
if (existsSync4(oldLedgerBackupPath))
|
|
3038
3404
|
unlinkSync2(oldLedgerBackupPath);
|
|
3039
3405
|
} catch {}
|
|
3040
3406
|
}
|
|
3041
3407
|
} else if (!initSucceeded && backupExists) {
|
|
3042
3408
|
try {
|
|
3043
|
-
if (
|
|
3409
|
+
if (existsSync4(oldLedgerBackupPath))
|
|
3044
3410
|
unlinkSync2(oldLedgerBackupPath);
|
|
3045
3411
|
} catch {}
|
|
3046
3412
|
}
|
|
@@ -3257,6 +3623,37 @@ ${markdown}`;
|
|
|
3257
3623
|
});
|
|
3258
3624
|
await bunWrite(markerPath, marker);
|
|
3259
3625
|
} catch {}
|
|
3626
|
+
if (currentPlan) {
|
|
3627
|
+
try {
|
|
3628
|
+
const oldIdentityHash = derivePlanIdentityHash(currentPlan);
|
|
3629
|
+
const newIdentityHash = derivePlanIdentityHash(projectedPlan);
|
|
3630
|
+
if (oldIdentityHash === newIdentityHash) {
|
|
3631
|
+
const oldStatuses = new Map;
|
|
3632
|
+
for (const phase of currentPlan.phases) {
|
|
3633
|
+
for (const task of phase.tasks)
|
|
3634
|
+
oldStatuses.set(task.id, task.status);
|
|
3635
|
+
}
|
|
3636
|
+
const newStatuses = new Map;
|
|
3637
|
+
for (const phase of projectedPlan.phases) {
|
|
3638
|
+
for (const task of phase.tasks)
|
|
3639
|
+
newStatuses.set(task.id, task.status);
|
|
3640
|
+
}
|
|
3641
|
+
for (const [taskId, oldStatus] of oldStatuses) {
|
|
3642
|
+
const newStatus = newStatuses.get(taskId);
|
|
3643
|
+
if (oldStatus === "completed" && newStatus !== "completed") {
|
|
3644
|
+
advanceTaskCheckpointReceiptGeneration(directory, oldIdentityHash, taskId);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
for (const [taskId, newStatus] of newStatuses) {
|
|
3648
|
+
if (newStatus === "completed" && oldStatuses.get(taskId) !== "completed") {
|
|
3649
|
+
repairTaskCheckpointReceiptForCompletion(directory, newIdentityHash, taskId);
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
} catch (receiptError) {
|
|
3654
|
+
warn(`[savePlan] task checkpoint receipt lifecycle sync failed (plan remains authoritative): ${receiptError instanceof Error ? receiptError.message : String(receiptError)}`);
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3260
3657
|
}
|
|
3261
3658
|
async function rebuildPlan(directory, plan, options) {
|
|
3262
3659
|
assertProjectRoot(directory);
|
|
@@ -3266,7 +3663,7 @@ async function rebuildPlan(directory, plan, options) {
|
|
|
3266
3663
|
const swarmDir = path8.join(directory, ".swarm");
|
|
3267
3664
|
const planPath = path8.join(swarmDir, "plan.json");
|
|
3268
3665
|
const mdPath = path8.join(swarmDir, "plan.md");
|
|
3269
|
-
|
|
3666
|
+
mkdirSync4(swarmDir, { recursive: true });
|
|
3270
3667
|
const tempPlanPath = path8.join(swarmDir, `plan.json.rebuild.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
3271
3668
|
{
|
|
3272
3669
|
const fd = openSync(tempPlanPath, "w");
|
|
@@ -3423,6 +3820,24 @@ function derivePlanMarkdown(plan) {
|
|
|
3423
3820
|
Swarm: ${plan.swarm}
|
|
3424
3821
|
Phase: ${currentPhase} [${phaseStatus}] | Updated: ${now}
|
|
3425
3822
|
`;
|
|
3823
|
+
if (plan.execution_profile) {
|
|
3824
|
+
const profile = plan.execution_profile;
|
|
3825
|
+
markdown += `
|
|
3826
|
+
## Execution Profile
|
|
3827
|
+
`;
|
|
3828
|
+
markdown += `- Parallelization: ${profile.parallelization_enabled ? "enabled" : "disabled"}
|
|
3829
|
+
`;
|
|
3830
|
+
markdown += `- Max Concurrent Tasks: ${profile.max_concurrent_tasks}
|
|
3831
|
+
`;
|
|
3832
|
+
markdown += `- Council Parallel: ${profile.council_parallel ? "yes" : "no"}
|
|
3833
|
+
`;
|
|
3834
|
+
markdown += `- Locked: ${profile.locked ? "yes" : "no"}
|
|
3835
|
+
`;
|
|
3836
|
+
markdown += `- Auto Proceed: ${profile.auto_proceed ? "yes" : "no"}
|
|
3837
|
+
`;
|
|
3838
|
+
markdown += `- Commit After Each Completed Task: ${profile.commit_after_each_completed_task ? "yes" : "no"}
|
|
3839
|
+
`;
|
|
3840
|
+
}
|
|
3426
3841
|
const sortedPhases = [...plan.phases].sort((a, b) => a.id - b.id);
|
|
3427
3842
|
for (const phase of sortedPhases) {
|
|
3428
3843
|
const phaseStatusText = statusMap[phase.status] || "PENDING";
|
|
@@ -3683,7 +4098,7 @@ function migrateLegacyPlan(planContent, swarmId) {
|
|
|
3683
4098
|
// src/evidence/manager.ts
|
|
3684
4099
|
init_zod();
|
|
3685
4100
|
import {
|
|
3686
|
-
mkdirSync as
|
|
4101
|
+
mkdirSync as mkdirSync5,
|
|
3687
4102
|
readdirSync as readdirSync2,
|
|
3688
4103
|
realpathSync,
|
|
3689
4104
|
renameSync as renameSync3,
|
|
@@ -3880,7 +4295,7 @@ async function atomicRenameWithRetry(src, dst, renameFn = fsp.rename) {
|
|
|
3880
4295
|
throw err;
|
|
3881
4296
|
}
|
|
3882
4297
|
if (attempt < RENAME_MAX_ATTEMPTS - 1) {
|
|
3883
|
-
await new Promise((
|
|
4298
|
+
await new Promise((resolve5) => setTimeout(resolve5, RENAME_BACKOFF_MS));
|
|
3884
4299
|
}
|
|
3885
4300
|
}
|
|
3886
4301
|
}
|
|
@@ -4164,7 +4579,7 @@ async function saveEvidence(directory, taskId, evidence, abortSignal) {
|
|
|
4164
4579
|
if (bundleJson.length > EVIDENCE_MAX_JSON_BYTES) {
|
|
4165
4580
|
throw new Error(`Evidence bundle size (${bundleJson.length} bytes) exceeds maximum (${EVIDENCE_MAX_JSON_BYTES} bytes)`);
|
|
4166
4581
|
}
|
|
4167
|
-
|
|
4582
|
+
mkdirSync5(evidenceDir, { recursive: true });
|
|
4168
4583
|
const tempPath = path10.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
|
|
4169
4584
|
try {
|
|
4170
4585
|
await bunWrite(tempPath, bundleJson);
|
|
@@ -4552,4 +4967,4 @@ function mergeDurableGateEntriesFromEvidence(taskId, entries, evidence) {
|
|
|
4552
4967
|
return merged;
|
|
4553
4968
|
}
|
|
4554
4969
|
|
|
4555
|
-
export { getExecutor, init_executor, MAX_TRANSIENT_RETRIES, isTransientSpawnError, transientBackoff, getGitRepositoryStatus, isGitRepo, getDefaultBaseBranch, resetToRemoteBranch, resetToMainAfterMerge, containsPathTraversal, containsControlChars, isStateUnreadable, loadEpicSessionState, isEpicModeActive, enableEpicMode, disableEpicMode, normalizePath, pathsConflict, isGlobalFile, isProtectedPath, readTaskScopes, computeSpecHash, loadPlanJsonOnly, loadPlan, savePlan, closePlanTerminalState, derivePlanMarkdown, isValidEvidenceType, sanitizeTaskId2 as sanitizeTaskId, validateProjectRoot, saveEvidence, loadEvidence, listEvidenceTaskIds, checkRequirementCoverage, archiveEvidence, readDurableGateEvidence, getDurableGateEvidenceStatus, getDurableGateEvidenceStatusForTask, mergeDurableGateEntriesFromEvidence };
|
|
4970
|
+
export { projectDbExists, getProjectDb, closeProjectDb, buildTaskCompletionDescriptor, ensureTaskCheckpointReceipt, updateTaskCheckpointReceipt, getExecutor, init_executor, MAX_TRANSIENT_RETRIES, isTransientSpawnError, transientBackoff, getGitRepositoryStatus, isGitRepo, getDefaultBaseBranch, resetToRemoteBranch, resetToMainAfterMerge, containsPathTraversal, containsControlChars, isStateUnreadable, loadEpicSessionState, isEpicModeActive, enableEpicMode, disableEpicMode, normalizePath, pathsConflict, isGlobalFile, isProtectedPath, readTaskScopes, computeSpecHash, loadPlanJsonOnly, loadPlan, savePlan, closePlanTerminalState, derivePlanMarkdown, isValidEvidenceType, sanitizeTaskId2 as sanitizeTaskId, validateProjectRoot, saveEvidence, loadEvidence, listEvidenceTaskIds, checkRequirementCoverage, archiveEvidence, readDurableGateEvidence, getDurableGateEvidenceStatus, getDurableGateEvidenceStatusForTask, mergeDurableGateEntriesFromEvidence };
|
|
@@ -11,7 +11,8 @@ var ExecutionProfileSchema = exports_external.object({
|
|
|
11
11
|
max_concurrent_tasks: exports_external.number().int().min(1).max(64).default(10),
|
|
12
12
|
council_parallel: exports_external.boolean().default(true),
|
|
13
13
|
locked: exports_external.boolean().default(false),
|
|
14
|
-
auto_proceed: exports_external.boolean().default(false)
|
|
14
|
+
auto_proceed: exports_external.boolean().default(false),
|
|
15
|
+
commit_after_each_completed_task: exports_external.boolean().default(false)
|
|
15
16
|
});
|
|
16
17
|
var TaskStatusSchema = exports_external.enum([
|
|
17
18
|
"pending",
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
init_schema,
|
|
17
17
|
stripKnownSwarmPrefix
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-n3ppm2gt.js";
|
|
19
19
|
import {
|
|
20
20
|
init_constants
|
|
21
|
-
} from "./index-
|
|
21
|
+
} from "./index-r4t92q32.js";
|
|
22
22
|
import {
|
|
23
23
|
__commonJS,
|
|
24
24
|
__toESM
|