@jitsusama/agentic-harness.core 0.6.2 → 0.6.4
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/command/tokenize.js +51 -5
- package/dist/internal/file-lock.d.ts +30 -0
- package/dist/internal/file-lock.js +183 -0
- package/dist/internal/quest/bash-effects.d.ts +26 -0
- package/dist/internal/quest/bash-effects.js +477 -0
- package/dist/internal/quest/bash-write.d.ts +37 -0
- package/dist/internal/quest/bash-write.js +311 -37
- package/dist/internal/quest/io.js +47 -22
- package/dist/internal/quest/record-audit.d.ts +43 -0
- package/dist/internal/quest/record-audit.js +126 -0
- package/dist/internal/quest/record-gate.d.ts +36 -0
- package/dist/internal/quest/record-gate.js +101 -0
- package/dist/internal/quest/record.d.ts +112 -0
- package/dist/internal/quest/record.js +284 -0
- package/dist/internal/quest/workspace.d.ts +32 -0
- package/dist/internal/quest/workspace.js +51 -0
- package/dist/review/ask/store.js +37 -19
- package/package.json +7 -1
package/dist/review/ask/store.js
CHANGED
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
* council needs that council still to be there, or nothing can say
|
|
12
12
|
* what it consolidated.
|
|
13
13
|
*/
|
|
14
|
+
import { randomUUID } from "node:crypto";
|
|
14
15
|
import { mkdir, readdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
15
16
|
import { join } from "node:path";
|
|
17
|
+
import { withFileLock } from "../../internal/file-lock.js";
|
|
16
18
|
import { changeKey } from "../keys.js";
|
|
17
19
|
/** Runs on disk, one file per change. */
|
|
18
20
|
export function createRunStore(root) {
|
|
@@ -71,15 +73,29 @@ export function createRunStore(root) {
|
|
|
71
73
|
// whose whole premise is that the session may not survive it,
|
|
72
74
|
// so the window stopped being theoretical. A rename within one
|
|
73
75
|
// directory is atomic: a reader sees the old ledger or the new
|
|
74
|
-
// one.
|
|
75
|
-
|
|
76
|
+
// one. Named per write, not per process: two writes in one
|
|
77
|
+
// process sharing a name tore the file, the shorter write landing
|
|
78
|
+
// over the start of the longer.
|
|
79
|
+
const pending = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
76
80
|
await writeFile(pending, JSON.stringify(ledger, null, 2), "utf8");
|
|
77
81
|
await rename(pending, path);
|
|
78
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Read, change and write one change's ledger as a single step. Every
|
|
85
|
+
* write is a whole ledger built from the one read before it, so two
|
|
86
|
+
* of these at once, from parallel tool calls or two sessions on one
|
|
87
|
+
* change, would each lay its version over the other's and drop a
|
|
88
|
+
* round without an error.
|
|
89
|
+
*/
|
|
90
|
+
async function mutate(change, next) {
|
|
91
|
+
await mkdir(root, { recursive: true });
|
|
92
|
+
await withFileLock(join(root, fileFor(change)), async () => {
|
|
93
|
+
await write(change, next(await read(change)));
|
|
94
|
+
});
|
|
95
|
+
}
|
|
79
96
|
return {
|
|
80
97
|
async record(change, run) {
|
|
81
|
-
|
|
82
|
-
await write(change, { runs: [...ledger.runs, run] });
|
|
98
|
+
await mutate(change, (ledger) => ({ runs: [...ledger.runs, run] }));
|
|
83
99
|
},
|
|
84
100
|
async list(change) {
|
|
85
101
|
return (await read(change)).runs;
|
|
@@ -176,24 +192,26 @@ export function createRunStore(root) {
|
|
|
176
192
|
return (await read(change)).runs.find((r) => r.id === runId);
|
|
177
193
|
},
|
|
178
194
|
async keep(change, run) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
195
|
+
await mutate(change, (ledger) => {
|
|
196
|
+
const at = ledger.runs.findIndex((held) => held.id === run.id);
|
|
197
|
+
return {
|
|
198
|
+
runs: at === -1
|
|
199
|
+
? [...ledger.runs, run]
|
|
200
|
+
: ledger.runs.map((held, index) => (index === at ? run : held)),
|
|
201
|
+
};
|
|
185
202
|
});
|
|
186
203
|
},
|
|
187
204
|
async replace(change, run) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
205
|
+
await mutate(change, (ledger) => {
|
|
206
|
+
const at = ledger.runs.findIndex((held) => held.id === run.id);
|
|
207
|
+
if (at === -1) {
|
|
208
|
+
// Adding it silently would make a retry look like it
|
|
209
|
+
// patched something when it invented a round instead.
|
|
210
|
+
throw new Error(`No run "${run.id}" is held against this change, so there is nothing to replace. Record it first, or check the id.`);
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
runs: ledger.runs.map((held, index) => (index === at ? run : held)),
|
|
214
|
+
};
|
|
197
215
|
});
|
|
198
216
|
},
|
|
199
217
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jitsusama/agentic-harness.core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Pi-agnostic business logic for agentic-harness: state machines, guardian decisions, quest/TDD domain model.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,6 +45,12 @@
|
|
|
45
45
|
"./quest/verbs/queries": "./dist/quest/verbs/queries.js",
|
|
46
46
|
"./quest/verbs/lifecycle": "./dist/quest/verbs/lifecycle.js",
|
|
47
47
|
"./quest/verbs/tree-ops": "./dist/quest/verbs/tree-ops.js",
|
|
48
|
+
"./quest/bash-write": "./dist/internal/quest/bash-write.js",
|
|
49
|
+
"./quest/write-classifier": "./dist/internal/quest/write-classifier.js",
|
|
50
|
+
"./quest/record": "./dist/internal/quest/record.js",
|
|
51
|
+
"./quest/workspace": "./dist/internal/quest/workspace.js",
|
|
52
|
+
"./quest/record-gate": "./dist/internal/quest/record-gate.js",
|
|
53
|
+
"./quest/record-audit": "./dist/internal/quest/record-audit.js",
|
|
48
54
|
"./tree": "./dist/tree/index.js",
|
|
49
55
|
"./lsp": "./dist/lsp/index.js",
|
|
50
56
|
"./result": "./dist/result/index.js",
|