gcf-aif-ext 0.7.4 → 0.7.5
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 +1 -1
- package/extension.json +1 -1
- package/lib/board.js +27 -2
- package/lib/session-mark.js +8 -0
- package/lib/work-ops.js +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ On Windows, run `extension add` and `extension update` from PowerShell or cmd, n
|
|
|
52
52
|
|
|
53
53
|
### 0.7.1
|
|
54
54
|
|
|
55
|
-
- `gcf board --json`: a ready item's worktree with no run lock and no session mark is a run that stopped (a timeout, a stop, a crash), not a run: the item reads `running: false`, `resumable: true`, and keeps its moves; its next run resumes the worktree.
|
|
55
|
+
- `gcf board --json`: a ready item's worktree with no run lock and no session mark is a run that stopped (a timeout, a stop, a crash), not a run: the item reads `running: false`, `resumable: true`, and keeps its moves; its next run resumes the worktree. An agent session the harness kept (`.gcf-session/runs/<id>.agent.json`) makes a ready item `resumable` too, in either run mode, and shows as `resume: {ended, resets?}` (null without one).
|
|
56
56
|
|
|
57
57
|
### 0.7.0
|
|
58
58
|
|
package/extension.json
CHANGED
package/lib/board.js
CHANGED
|
@@ -120,6 +120,25 @@ function logOf(projectDir, id) {
|
|
|
120
120
|
return existsSync(path.join(projectDir, log)) ? log : null;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* How the agent session of the item's last run ended, when the harness kept it for a rerun to
|
|
125
|
+
* resume (`<id>.agent.json`): `{ended, resets?}`, or null. A file that is not a record is none.
|
|
126
|
+
*/
|
|
127
|
+
async function resumeOf(projectDir, id) {
|
|
128
|
+
try {
|
|
129
|
+
const file = path.join(projectDir, '.gcf-session', 'runs', `${id}.agent.json`);
|
|
130
|
+
const rec = JSON.parse(await readFile(file, 'utf8'));
|
|
131
|
+
if (typeof rec?.session_id !== 'string') return null;
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
ended: String(rec.ended ?? ''),
|
|
135
|
+
...(rec.resets ? { resets: String(rec.resets) } : {}),
|
|
136
|
+
};
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
123
142
|
// Fields of the item file a board shows as they are: null or [] when the file has none.
|
|
124
143
|
const SCALARS = [
|
|
125
144
|
'title',
|
|
@@ -163,10 +182,15 @@ async function itemOf(projectDir, c, verified) {
|
|
|
163
182
|
const ready = c.data.status === 'ready' && verified.has(id);
|
|
164
183
|
// `running` and `verify` are not stored (§4): a live harness run lock or a fresh session mark
|
|
165
184
|
// is a run; a trailer is a passed DoD. A worktree with neither is a run that stopped (a
|
|
166
|
-
// timeout, a stop, a crash): the item is ready, and its next run resumes that worktree.
|
|
185
|
+
// timeout, a stop, a crash): the item is ready, and its next run resumes that worktree. A
|
|
186
|
+
// session the harness kept (`resume`) is resumed by the next run in either mode.
|
|
167
187
|
const running = runHolder(projectDir, id) !== null || sessionActive(projectDir, id);
|
|
188
|
+
const resume = c.data.status === 'ready' ? await resumeOf(projectDir, id) : null;
|
|
168
189
|
const resumable =
|
|
169
|
-
!running &&
|
|
190
|
+
!running &&
|
|
191
|
+
c.data.status === 'ready' &&
|
|
192
|
+
!ready &&
|
|
193
|
+
(resume !== null || existsSync(worktreeOf(projectDir, id)));
|
|
170
194
|
|
|
171
195
|
return {
|
|
172
196
|
id,
|
|
@@ -179,6 +203,7 @@ async function itemOf(projectDir, c, verified) {
|
|
|
179
203
|
...(c.data.blocked ? { blocked: c.data.blocked } : {}),
|
|
180
204
|
running,
|
|
181
205
|
resumable,
|
|
206
|
+
resume,
|
|
182
207
|
verified: ready,
|
|
183
208
|
// What a board may offer (§4.1): nothing while a run drives the item.
|
|
184
209
|
moves: running ? [] : movesOf(c.data),
|
package/lib/session-mark.js
CHANGED
|
@@ -40,6 +40,14 @@ export function releaseSession(projectDir, id) {
|
|
|
40
40
|
rmSync(markOf(projectDir, id), { force: true });
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Forget the agent session the harness kept for a rerun of `id` (`<id>.agent.json`): a move,
|
|
45
|
+
* by hand or by an agent, ends the work it would resume.
|
|
46
|
+
*/
|
|
47
|
+
export function dropAgentSession(projectDir, id) {
|
|
48
|
+
rmSync(path.join(path.dirname(markOf(projectDir, id)), `${id}.agent.json`), { force: true });
|
|
49
|
+
}
|
|
50
|
+
|
|
43
51
|
/** Whether a session works the item now: a mark refreshed within SESSION_TTL_MS. */
|
|
44
52
|
export function sessionActive(projectDir, id) {
|
|
45
53
|
const file = markOf(projectDir, id);
|
package/lib/work-ops.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
import { dropInbox } from './inbox.js';
|
|
39
39
|
import { refuseByPhase } from './phase.js';
|
|
40
40
|
import { runHolder, withMainLock } from './main-lock.js';
|
|
41
|
-
import { releaseSession, sessionActive } from './session-mark.js';
|
|
41
|
+
import { dropAgentSession, releaseSession, sessionActive } from './session-mark.js';
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Options of a committed move; each move reads the ones it needs.
|
|
@@ -228,8 +228,10 @@ async function finish(m, move, tail, commit) {
|
|
|
228
228
|
commit,
|
|
229
229
|
inputs: [m.item.file],
|
|
230
230
|
});
|
|
231
|
-
// A move on the item ends the session that worked it: the board stops showing it running
|
|
231
|
+
// A move on the item ends the session that worked it: the board stops showing it running,
|
|
232
|
+
// and no rerun resumes it.
|
|
232
233
|
releaseSession(m.projectDir, String(m.item.data.id));
|
|
234
|
+
dropAgentSession(m.projectDir, String(m.item.data.id));
|
|
233
235
|
|
|
234
236
|
return hash;
|
|
235
237
|
}
|