@magnusekdahl/parallix 1.2.1 → 1.3.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/index.js +190 -185
- package/lib/commands/active.js +502 -579
- package/lib/commands/active.ts +665 -0
- package/lib/commands/checkpoint.js +98 -74
- package/lib/commands/checkpoint.ts +79 -0
- package/lib/commands/config.js +61 -31
- package/lib/commands/config.ts +47 -0
- package/lib/commands/coverage-gate.js +271 -246
- package/lib/commands/coverage-gate.ts +362 -0
- package/lib/commands/diff.js +140 -119
- package/lib/commands/diff.ts +125 -0
- package/lib/commands/draft.js +770 -923
- package/lib/commands/draft.ts +1021 -0
- package/lib/commands/handoff.js +588 -608
- package/lib/commands/handoff.ts +694 -0
- package/lib/commands/integrate.js +1331 -1468
- package/lib/commands/integrate.ts +1688 -0
- package/lib/commands/mission-start.js +279 -237
- package/lib/commands/mission-start.ts +263 -0
- package/lib/commands/rebase.js +606 -582
- package/lib/commands/rebase.ts +635 -0
- package/lib/commands/repair-handoff.js +181 -179
- package/lib/commands/repair-handoff.ts +228 -0
- package/lib/commands/resolve-conflict.js +121 -102
- package/lib/commands/resolve-conflict.ts +112 -0
- package/lib/commands/review.js +3 -4
- package/lib/commands/review.ts +14 -0
- package/lib/commands/setup-review.js +4 -5
- package/lib/commands/setup-review.ts +14 -0
- package/lib/commands/setup.js +3 -3
- package/lib/commands/setup.ts +2 -0
- package/lib/commands/stats-backfill.js +394 -359
- package/lib/commands/stats-backfill.ts +418 -0
- package/lib/commands/stats.js +1424 -1665
- package/lib/commands/stats.ts +2186 -0
- package/lib/commands/status.js +219 -200
- package/lib/commands/status.ts +219 -0
- package/lib/commands/verify.js +3 -1
- package/lib/commands/verify.ts +2 -0
- package/lib/core/nels.js +112 -127
- package/lib/core/nels.ts +189 -0
- package/lib/core/subagent-limit.js +15 -16
- package/lib/core/subagent-limit.ts +25 -0
- package/lib/index.js +142 -59
- package/lib/index.ts +134 -0
- package/lib/review/rebase.js +142 -145
- package/lib/review/rebase.ts +188 -0
- package/lib/review/review-adapter.js +99 -87
- package/lib/review/review-adapter.ts +198 -0
- package/lib/review/review-artifacts.js +486 -629
- package/lib/review/review-artifacts.ts +622 -0
- package/lib/review/review-commands.js +1220 -1373
- package/lib/review/review-commands.ts +1579 -0
- package/lib/review/review-events.js +544 -886
- package/lib/review/review-events.ts +954 -0
- package/lib/review/review-loop.js +945 -1020
- package/lib/review/review-loop.ts +1174 -0
- package/lib/review/review-polling.js +86 -115
- package/lib/review/review-polling.ts +194 -0
- package/lib/review/review-prompts.js +154 -189
- package/lib/review/review-prompts.ts +182 -0
- package/lib/review/review-state.js +246 -225
- package/lib/review/review-state.ts +353 -0
- package/lib/review/review.js +63 -84
- package/lib/review/review.ts +138 -0
- package/lib/tools/backlog.js +694 -680
- package/lib/tools/backlog.ts +835 -0
- package/lib/tools/forgejo.js +1270 -1405
- package/lib/tools/forgejo.ts +1793 -0
- package/lib/tools/gatekeeper.js +106 -96
- package/lib/tools/gatekeeper.ts +124 -0
- package/lib/tools/redgreen.js +200 -181
- package/lib/tools/redgreen.ts +221 -0
- package/lib/tools/sessions.js +58 -52
- package/lib/tools/sessions.ts +81 -0
- package/lib/tools/setup-review.js +902 -975
- package/lib/tools/setup-review.ts +1152 -0
- package/package.json +4 -4
- package/px.js +226 -208
package/lib/tools/sessions.js
CHANGED
|
@@ -1,81 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.sessionsDir = sessionsDir;
|
|
7
|
+
exports.sessionFile = sessionFile;
|
|
8
|
+
exports.readSession = readSession;
|
|
9
|
+
exports.writeSession = writeSession;
|
|
10
|
+
exports.shouldResume = shouldResume;
|
|
11
|
+
exports.getSessionId = getSessionId;
|
|
12
|
+
exports.clearSession = clearSession;
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
4
15
|
// Per-worktree session markers used by startAgent to decide whether to launch
|
|
5
16
|
// an agent fresh or with its family-specific resume flag. Stored under
|
|
6
17
|
// .workflow/sessions/ which is already gitignored, so markers live with the
|
|
7
18
|
// mission worktree and survive harness restarts but never travel through git.
|
|
8
|
-
|
|
9
19
|
/** @param {string} worktree */
|
|
10
20
|
function sessionsDir(worktree) {
|
|
11
|
-
|
|
21
|
+
return path_1.default.join(worktree, '.workflow', 'sessions');
|
|
12
22
|
}
|
|
13
|
-
|
|
14
23
|
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
15
24
|
function sessionFile(worktree, slug, role) {
|
|
16
|
-
|
|
25
|
+
return path_1.default.join(sessionsDir(worktree), `${slug}-${role}.json`);
|
|
17
26
|
}
|
|
18
|
-
|
|
19
27
|
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
20
28
|
function readSession(worktree, slug, role) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
if (!worktree || !slug || !role) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const file = sessionFile(worktree, slug, role);
|
|
33
|
+
if (!fs_1.default.existsSync(file)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(fs_1.default.readFileSync(file, 'utf8'));
|
|
38
|
+
if (parsed && typeof parsed.agent === 'string') {
|
|
39
|
+
return parsed;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
catch (_) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
31
46
|
}
|
|
32
|
-
|
|
33
47
|
/** @param {string} worktree @param {string} slug @param {string} role @param {{agent: string, lastLaunched?: string, sessionId?: string|null}} payload */
|
|
34
48
|
function writeSession(worktree, slug, role, payload) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
if (!worktree || !slug || !role || !payload || typeof payload.agent !== 'string') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
fs_1.default.mkdirSync(sessionsDir(worktree), { recursive: true });
|
|
53
|
+
const body = {
|
|
54
|
+
agent: payload.agent,
|
|
55
|
+
lastLaunched: payload.lastLaunched || new Date().toISOString(),
|
|
56
|
+
sessionId: payload.sessionId || null
|
|
57
|
+
};
|
|
58
|
+
fs_1.default.writeFileSync(sessionFile(worktree, slug, role), JSON.stringify(body, null, 2) + '\n', 'utf8');
|
|
59
|
+
return true;
|
|
46
60
|
}
|
|
47
|
-
|
|
48
61
|
// Resume only when the previous launch in this (slug, role) used the same
|
|
49
62
|
// agent family. A fallback to a different family invalidates the marker —
|
|
50
63
|
// the new family has no prior session to continue.
|
|
51
64
|
/** @param {string} worktree @param {string} slug @param {string} role @param {string} agent */
|
|
52
65
|
function shouldResume(worktree, slug, role, agent) {
|
|
53
|
-
|
|
54
|
-
|
|
66
|
+
const prev = readSession(worktree, slug, role);
|
|
67
|
+
return Boolean(prev && prev.agent === agent);
|
|
55
68
|
}
|
|
56
|
-
|
|
57
69
|
// Return the session ID from the marker, if one was persisted.
|
|
58
70
|
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
59
71
|
function getSessionId(worktree, slug, role) {
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
const prev = readSession(worktree, slug, role);
|
|
73
|
+
return prev && prev.sessionId ? prev.sessionId : null;
|
|
62
74
|
}
|
|
63
|
-
|
|
64
75
|
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
65
76
|
function clearSession(worktree, slug, role) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
if (!worktree || !slug || !role) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const file = sessionFile(worktree, slug, role);
|
|
81
|
+
if (!fs_1.default.existsSync(file)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
fs_1.default.unlinkSync(file);
|
|
85
|
+
return true;
|
|
71
86
|
}
|
|
72
|
-
|
|
73
|
-
module.exports = {
|
|
74
|
-
sessionsDir,
|
|
75
|
-
sessionFile,
|
|
76
|
-
readSession,
|
|
77
|
-
writeSession,
|
|
78
|
-
shouldResume,
|
|
79
|
-
getSessionId,
|
|
80
|
-
clearSession
|
|
81
|
-
};
|
|
87
|
+
;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
// Per-worktree session markers used by startAgent to decide whether to launch
|
|
5
|
+
// an agent fresh or with its family-specific resume flag. Stored under
|
|
6
|
+
// .workflow/sessions/ which is already gitignored, so markers live with the
|
|
7
|
+
// mission worktree and survive harness restarts but never travel through git.
|
|
8
|
+
|
|
9
|
+
/** @param {string} worktree */
|
|
10
|
+
function sessionsDir(worktree: string) {
|
|
11
|
+
return path.join(worktree, '.workflow', 'sessions');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
15
|
+
function sessionFile(worktree: string, slug: string, role: string) {
|
|
16
|
+
return path.join(sessionsDir(worktree), `${slug}-${role}.json`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
20
|
+
function readSession(worktree: string, slug: string, role: string) {
|
|
21
|
+
if (!worktree || !slug || !role) {return null;}
|
|
22
|
+
const file = sessionFile(worktree, slug, role);
|
|
23
|
+
if (!fs.existsSync(file)) {return null;}
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
26
|
+
if (parsed && typeof parsed.agent === 'string') {return parsed;}
|
|
27
|
+
return null;
|
|
28
|
+
} catch (_) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @param {string} worktree @param {string} slug @param {string} role @param {{agent: string, lastLaunched?: string, sessionId?: string|null}} payload */
|
|
34
|
+
function writeSession(worktree: string, slug: string, role: string, payload: {agent: string, lastLaunched?: string, sessionId?: string | null}) {
|
|
35
|
+
if (!worktree || !slug || !role || !payload || typeof payload.agent !== 'string') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
fs.mkdirSync(sessionsDir(worktree), { recursive: true });
|
|
39
|
+
const body = {
|
|
40
|
+
agent: payload.agent,
|
|
41
|
+
lastLaunched: payload.lastLaunched || new Date().toISOString(),
|
|
42
|
+
sessionId: payload.sessionId || null
|
|
43
|
+
};
|
|
44
|
+
fs.writeFileSync(sessionFile(worktree, slug, role), JSON.stringify(body, null, 2) + '\n', 'utf8');
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Resume only when the previous launch in this (slug, role) used the same
|
|
49
|
+
// agent family. A fallback to a different family invalidates the marker —
|
|
50
|
+
// the new family has no prior session to continue.
|
|
51
|
+
/** @param {string} worktree @param {string} slug @param {string} role @param {string} agent */
|
|
52
|
+
function shouldResume(worktree: string, slug: string, role: string, agent: string) {
|
|
53
|
+
const prev = readSession(worktree, slug, role);
|
|
54
|
+
return Boolean(prev && prev.agent === agent);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Return the session ID from the marker, if one was persisted.
|
|
58
|
+
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
59
|
+
function getSessionId(worktree: string, slug: string, role: string) {
|
|
60
|
+
const prev = readSession(worktree, slug, role);
|
|
61
|
+
return prev && prev.sessionId ? prev.sessionId : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @param {string} worktree @param {string} slug @param {string} role */
|
|
65
|
+
function clearSession(worktree: string, slug: string, role: string) {
|
|
66
|
+
if (!worktree || !slug || !role) {return false;}
|
|
67
|
+
const file = sessionFile(worktree, slug, role);
|
|
68
|
+
if (!fs.existsSync(file)) {return false;}
|
|
69
|
+
fs.unlinkSync(file);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
export { sessionsDir };
|
|
75
|
+
export { sessionFile };
|
|
76
|
+
export { readSession };
|
|
77
|
+
export { writeSession };
|
|
78
|
+
export { shouldResume };
|
|
79
|
+
export { getSessionId };
|
|
80
|
+
export { clearSession };
|
|
81
|
+
;
|