@oneharness/sdk 0.15.0 → 0.16.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/README.md +1 -1
- package/dist/generated/capabilities.d.ts +27 -0
- package/dist/generated/capabilities.js +31 -0
- package/dist/generated/config-report.d.ts +1 -0
- package/dist/generated/contracts.d.ts +1 -1
- package/dist/generated/history-pointers-options.d.ts +10 -0
- package/dist/generated/history-pointers-options.js +2 -0
- package/dist/generated/history-pointers.d.ts +100 -0
- package/dist/generated/history-pointers.js +2 -0
- package/dist/generated/options.d.ts +8 -0
- package/dist/generated/run-stream-envelope.d.ts +1 -1
- package/dist/generated/schemas.json +201 -10
- package/dist/generated/usage-report.d.ts +3 -3
- package/dist/generated/zod.d.ts +5 -0
- package/dist/generated/zod.js +35 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ const checked: RunReport = RunReportSchema.parse(report);
|
|
|
11
11
|
console.log(checked.results[0]?.text, checked.results[0]?.usage.input_tokens);
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
The client covers every verb the CLI exposes, so nothing needs a hand-built command line: `run`, `runMock`, `runStream`, `list`, `detect`, `config`, `sync`, `init`, `usage`, `gate`, `mock`, `interrupt`, `history`, `historyList`, `historyWatch`, `historyClear`, and `
|
|
14
|
+
The client covers every verb the CLI exposes, so nothing needs a hand-built command line: `run`, `runMock`, `runStream`, `list`, `detect`, `config`, `sync`, `init`, `usage`, `gate`, `mock`, `interrupt`, `history`, `historyList`, `historyWatch`, `historyClear`, `historyMigrate`, and `historyPointers`. That coverage is gated, not asserted here. `runMock` uses the deterministic responder shipped in the CLI; see [Testing patterns](../../docs/testing-patterns.md). Both streaming methods return async iterators:
|
|
15
15
|
|
|
16
16
|
```ts
|
|
17
17
|
for await (const envelope of oneharness.runStream({
|
|
@@ -250,6 +250,11 @@ export declare const CAPABILITIES: {
|
|
|
250
250
|
readonly flag: "--history-dir";
|
|
251
251
|
readonly kind: "value";
|
|
252
252
|
readonly unless: null;
|
|
253
|
+
}, {
|
|
254
|
+
readonly option: "historyPointerFile";
|
|
255
|
+
readonly flag: "--history-pointer-file";
|
|
256
|
+
readonly kind: "value";
|
|
257
|
+
readonly unless: null;
|
|
253
258
|
}, {
|
|
254
259
|
readonly option: "historyName";
|
|
255
260
|
readonly flag: "--history-name";
|
|
@@ -490,6 +495,11 @@ export declare const CAPABILITIES: {
|
|
|
490
495
|
readonly flag: "--history-dir";
|
|
491
496
|
readonly kind: "value";
|
|
492
497
|
readonly unless: null;
|
|
498
|
+
}, {
|
|
499
|
+
readonly option: "historyPointerFile";
|
|
500
|
+
readonly flag: "--history-pointer-file";
|
|
501
|
+
readonly kind: "value";
|
|
502
|
+
readonly unless: null;
|
|
493
503
|
}, {
|
|
494
504
|
readonly option: "historyName";
|
|
495
505
|
readonly flag: "--history-name";
|
|
@@ -1044,5 +1054,22 @@ export declare const CAPABILITIES: {
|
|
|
1044
1054
|
}];
|
|
1045
1055
|
readonly uncovered: readonly [];
|
|
1046
1056
|
};
|
|
1057
|
+
readonly historyPointers: {
|
|
1058
|
+
readonly method: "historyPointers";
|
|
1059
|
+
readonly argv: readonly ["history", "pointers"];
|
|
1060
|
+
readonly options: "history_pointers_options";
|
|
1061
|
+
readonly output: "history_pointers";
|
|
1062
|
+
readonly stdout: "json";
|
|
1063
|
+
readonly stdin: false;
|
|
1064
|
+
readonly rust: "oneharness_core::io::history::read_pointers";
|
|
1065
|
+
readonly always: readonly ["--compact", "--format", "json"];
|
|
1066
|
+
readonly bindings: readonly [{
|
|
1067
|
+
readonly option: "file";
|
|
1068
|
+
readonly flag: "";
|
|
1069
|
+
readonly kind: "positional";
|
|
1070
|
+
readonly unless: null;
|
|
1071
|
+
}];
|
|
1072
|
+
readonly uncovered: readonly [];
|
|
1073
|
+
};
|
|
1047
1074
|
};
|
|
1048
1075
|
export type CapabilityMethod = keyof typeof CAPABILITIES;
|
|
@@ -253,6 +253,12 @@ export const CAPABILITIES = {
|
|
|
253
253
|
kind: "value",
|
|
254
254
|
unless: null,
|
|
255
255
|
},
|
|
256
|
+
{
|
|
257
|
+
option: "historyPointerFile",
|
|
258
|
+
flag: "--history-pointer-file",
|
|
259
|
+
kind: "value",
|
|
260
|
+
unless: null,
|
|
261
|
+
},
|
|
256
262
|
{
|
|
257
263
|
option: "historyName",
|
|
258
264
|
flag: "--history-name",
|
|
@@ -541,6 +547,12 @@ export const CAPABILITIES = {
|
|
|
541
547
|
kind: "value",
|
|
542
548
|
unless: null,
|
|
543
549
|
},
|
|
550
|
+
{
|
|
551
|
+
option: "historyPointerFile",
|
|
552
|
+
flag: "--history-pointer-file",
|
|
553
|
+
kind: "value",
|
|
554
|
+
unless: null,
|
|
555
|
+
},
|
|
544
556
|
{
|
|
545
557
|
option: "historyName",
|
|
546
558
|
flag: "--history-name",
|
|
@@ -1184,4 +1196,23 @@ export const CAPABILITIES = {
|
|
|
1184
1196
|
],
|
|
1185
1197
|
uncovered: [],
|
|
1186
1198
|
},
|
|
1199
|
+
historyPointers: {
|
|
1200
|
+
method: "historyPointers",
|
|
1201
|
+
argv: ["history", "pointers"],
|
|
1202
|
+
options: "history_pointers_options",
|
|
1203
|
+
output: "history_pointers",
|
|
1204
|
+
stdout: "json",
|
|
1205
|
+
stdin: false,
|
|
1206
|
+
rust: "oneharness_core::io::history::read_pointers",
|
|
1207
|
+
always: ["--compact", "--format", "json"],
|
|
1208
|
+
bindings: [
|
|
1209
|
+
{
|
|
1210
|
+
option: "file",
|
|
1211
|
+
flag: "",
|
|
1212
|
+
kind: "positional",
|
|
1213
|
+
unless: null,
|
|
1214
|
+
},
|
|
1215
|
+
],
|
|
1216
|
+
uncovered: [],
|
|
1217
|
+
},
|
|
1187
1218
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options accepted by the language SDKs' `historyPointers()`: the pointer
|
|
3
|
+
* file a run was given as `historyPointerFile`.
|
|
4
|
+
*/
|
|
5
|
+
export interface HistoryPointersOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The pointer file to read. A file that does not exist reads as empty.
|
|
8
|
+
*/
|
|
9
|
+
file: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What [`read_pointers`] read: every well-formed [`HistoryPointer`] line in
|
|
3
|
+
* file order, and how many lines were not one.
|
|
4
|
+
*/
|
|
5
|
+
export interface HistoryPointers {
|
|
6
|
+
/**
|
|
7
|
+
* The pointer lines, in the order they were appended.
|
|
8
|
+
*/
|
|
9
|
+
pointers: HistoryPointer[];
|
|
10
|
+
/**
|
|
11
|
+
* Lines that were not one complete pointer object — a torn tail left by
|
|
12
|
+
* an interrupted writer, or a foreign line — counted rather than failing
|
|
13
|
+
* the read.
|
|
14
|
+
*/
|
|
15
|
+
skipped: number;
|
|
16
|
+
[k: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* One line of a run's **pointer file**: where one harness run's history went.
|
|
20
|
+
*
|
|
21
|
+
* A consumer that starts many `oneharness` processes (or in-process runs) names
|
|
22
|
+
* one file, and every run with history on appends one of these per harness run
|
|
23
|
+
* it begins — so "which sessions did this run launch, and where are they" is a
|
|
24
|
+
* read of that one small file rather than a scan of the whole store, wherever
|
|
25
|
+
* the store lives. `history_dir` / `history_project` / `history_session` are
|
|
26
|
+
* spelled as the `oneharness-session` artifact `oneagentgraph` publishes, so a
|
|
27
|
+
* reader already resolving that through `io::history::find_session_path`
|
|
28
|
+
* resolves these unchanged.
|
|
29
|
+
*
|
|
30
|
+
* Built only through [`HistoryPointer::new`] over a [`PointerSession`], and
|
|
31
|
+
* read back only through a deserialization that re-checks every invariant
|
|
32
|
+
* `new` establishes — the four session spellings compose into one file, the
|
|
33
|
+
* two identity spellings are the parsed [`HarnessIdentity`]'s own, the version
|
|
34
|
+
* is one this reader knows — so a line that parses IS a pointer, and a foreign
|
|
35
|
+
* object that happens to carry these keys is counted as skipped rather than
|
|
36
|
+
* read as one.
|
|
37
|
+
* The fields are read through accessors for the same reason: a Rust caller
|
|
38
|
+
* gets a line from one of those two doors, never assembles or edits one.
|
|
39
|
+
*/
|
|
40
|
+
export interface HistoryPointer {
|
|
41
|
+
/**
|
|
42
|
+
* The harness id's base, e.g. `claude-code`.
|
|
43
|
+
*/
|
|
44
|
+
harness: string;
|
|
45
|
+
/**
|
|
46
|
+
* The whole configured id, e.g. `claude-code:primary` — always `harness`
|
|
47
|
+
* with `:variant` when there is one.
|
|
48
|
+
*/
|
|
49
|
+
harness_id: string;
|
|
50
|
+
/**
|
|
51
|
+
* The store the session is under, absolute.
|
|
52
|
+
*/
|
|
53
|
+
history_dir: string;
|
|
54
|
+
/**
|
|
55
|
+
* The session file, absolute; the same path the run report echoes, and
|
|
56
|
+
* always `<history_dir>/<history_project>/<history_session>.jsonl`.
|
|
57
|
+
*/
|
|
58
|
+
history_file: string;
|
|
59
|
+
/**
|
|
60
|
+
* The history id of the record this harness run will close with — the
|
|
61
|
+
* exact id `history show <history-id>` resolves.
|
|
62
|
+
*/
|
|
63
|
+
history_id: string;
|
|
64
|
+
/**
|
|
65
|
+
* The project slug — the session file's parent directory name.
|
|
66
|
+
*/
|
|
67
|
+
history_project: string;
|
|
68
|
+
/**
|
|
69
|
+
* The session id — the session file's stem.
|
|
70
|
+
*/
|
|
71
|
+
history_session: string;
|
|
72
|
+
labels?: HistoryLabels | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The session's human-meaningful name (see [`session_name`]).
|
|
75
|
+
*/
|
|
76
|
+
name: string;
|
|
77
|
+
/**
|
|
78
|
+
* The project directory the run operates in, canonical.
|
|
79
|
+
*/
|
|
80
|
+
project: string;
|
|
81
|
+
/**
|
|
82
|
+
* [`POINTER_SCHEMA_VERSION`]; a reader accepts any `1.<minor>`.
|
|
83
|
+
*/
|
|
84
|
+
schema_version: string;
|
|
85
|
+
/**
|
|
86
|
+
* RFC 3339 UTC, when this harness run began.
|
|
87
|
+
*/
|
|
88
|
+
started: string;
|
|
89
|
+
/**
|
|
90
|
+
* The variant, omitted for a bare harness.
|
|
91
|
+
*/
|
|
92
|
+
variant?: string | null | undefined;
|
|
93
|
+
[k: string]: unknown;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The session's validated labels, omitted when empty.
|
|
97
|
+
*/
|
|
98
|
+
export interface HistoryLabels {
|
|
99
|
+
[k: string]: string;
|
|
100
|
+
}
|
|
@@ -69,6 +69,14 @@ export interface RunOptions {
|
|
|
69
69
|
historyDir?: string | undefined;
|
|
70
70
|
historyLabels?: HistoryLabels | undefined;
|
|
71
71
|
historyName?: string | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* The run's pointer file: with history on, every harness run this run
|
|
74
|
+
* begins appends one `HistoryPointer` line here saying where its session
|
|
75
|
+
* went (see `historyPointers()`), the store itself staying where
|
|
76
|
+
* `historyDir` puts it. An empty path is refused rather than read as
|
|
77
|
+
* unset — leave the option out to name no file.
|
|
78
|
+
*/
|
|
79
|
+
historyPointerFile?: string | undefined;
|
|
72
80
|
/**
|
|
73
81
|
* Maximum harnesses (or, in a batch, prompts) to run concurrently.
|
|
74
82
|
*/
|
|
@@ -261,6 +261,12 @@
|
|
|
261
261
|
"kind": "value",
|
|
262
262
|
"unless": null
|
|
263
263
|
},
|
|
264
|
+
{
|
|
265
|
+
"option": "historyPointerFile",
|
|
266
|
+
"flag": "--history-pointer-file",
|
|
267
|
+
"kind": "value",
|
|
268
|
+
"unless": null
|
|
269
|
+
},
|
|
264
270
|
{
|
|
265
271
|
"option": "historyName",
|
|
266
272
|
"flag": "--history-name",
|
|
@@ -554,6 +560,12 @@
|
|
|
554
560
|
"kind": "value",
|
|
555
561
|
"unless": null
|
|
556
562
|
},
|
|
563
|
+
{
|
|
564
|
+
"option": "historyPointerFile",
|
|
565
|
+
"flag": "--history-pointer-file",
|
|
566
|
+
"kind": "value",
|
|
567
|
+
"unless": null
|
|
568
|
+
},
|
|
557
569
|
{
|
|
558
570
|
"option": "historyName",
|
|
559
571
|
"flag": "--history-name",
|
|
@@ -1272,6 +1284,32 @@
|
|
|
1272
1284
|
}
|
|
1273
1285
|
],
|
|
1274
1286
|
"uncovered": []
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
"method": "historyPointers",
|
|
1290
|
+
"argv": [
|
|
1291
|
+
"history",
|
|
1292
|
+
"pointers"
|
|
1293
|
+
],
|
|
1294
|
+
"options": "history_pointers_options",
|
|
1295
|
+
"output": "history_pointers",
|
|
1296
|
+
"stdout": "json",
|
|
1297
|
+
"stdin": false,
|
|
1298
|
+
"rust": "oneharness_core::io::history::read_pointers",
|
|
1299
|
+
"always": [
|
|
1300
|
+
"--compact",
|
|
1301
|
+
"--format",
|
|
1302
|
+
"json"
|
|
1303
|
+
],
|
|
1304
|
+
"bindings": [
|
|
1305
|
+
{
|
|
1306
|
+
"option": "file",
|
|
1307
|
+
"flag": "",
|
|
1308
|
+
"kind": "positional",
|
|
1309
|
+
"unless": null
|
|
1310
|
+
}
|
|
1311
|
+
],
|
|
1312
|
+
"uncovered": []
|
|
1275
1313
|
}
|
|
1276
1314
|
],
|
|
1277
1315
|
"run_report": {
|
|
@@ -1842,7 +1880,7 @@
|
|
|
1842
1880
|
"const": "quota"
|
|
1843
1881
|
},
|
|
1844
1882
|
{
|
|
1845
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
1883
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
1846
1884
|
"type": "string",
|
|
1847
1885
|
"const": "session_not_found"
|
|
1848
1886
|
},
|
|
@@ -2057,7 +2095,7 @@
|
|
|
2057
2095
|
"type": "string"
|
|
2058
2096
|
},
|
|
2059
2097
|
"command": {
|
|
2060
|
-
"description": "The exact argv oneharness built
|
|
2098
|
+
"description": "The exact argv oneharness built; its first element is the binary.",
|
|
2061
2099
|
"type": "array",
|
|
2062
2100
|
"items": {
|
|
2063
2101
|
"type": "string"
|
|
@@ -2923,7 +2961,7 @@
|
|
|
2923
2961
|
"const": "quota"
|
|
2924
2962
|
},
|
|
2925
2963
|
{
|
|
2926
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
2964
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
2927
2965
|
"type": "string",
|
|
2928
2966
|
"const": "session_not_found"
|
|
2929
2967
|
},
|
|
@@ -3302,7 +3340,7 @@
|
|
|
3302
3340
|
"type": "string"
|
|
3303
3341
|
},
|
|
3304
3342
|
"command": {
|
|
3305
|
-
"description": "The exact argv oneharness built
|
|
3343
|
+
"description": "The exact argv oneharness built; its first element is the binary.",
|
|
3306
3344
|
"type": "array",
|
|
3307
3345
|
"items": {
|
|
3308
3346
|
"type": "string"
|
|
@@ -3798,6 +3836,11 @@
|
|
|
3798
3836
|
"historyName": {
|
|
3799
3837
|
"type": "string"
|
|
3800
3838
|
},
|
|
3839
|
+
"historyPointerFile": {
|
|
3840
|
+
"description": "The run's pointer file: with history on, every harness run this run\nbegins appends one `HistoryPointer` line here saying where its session\nwent (see `historyPointers()`), the store itself staying where\n`historyDir` puts it. An empty path is refused rather than read as\nunset — leave the option out to name no file.",
|
|
3841
|
+
"type": "string",
|
|
3842
|
+
"minLength": 1
|
|
3843
|
+
},
|
|
3801
3844
|
"maxParallel": {
|
|
3802
3845
|
"description": "Maximum harnesses (or, in a batch, prompts) to run concurrently.",
|
|
3803
3846
|
"type": "integer",
|
|
@@ -5974,7 +6017,7 @@
|
|
|
5974
6017
|
"const": "quota"
|
|
5975
6018
|
},
|
|
5976
6019
|
{
|
|
5977
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
6020
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
5978
6021
|
"type": "string",
|
|
5979
6022
|
"const": "session_not_found"
|
|
5980
6023
|
},
|
|
@@ -8976,7 +9019,7 @@
|
|
|
8976
9019
|
"const": "quota"
|
|
8977
9020
|
},
|
|
8978
9021
|
{
|
|
8979
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
9022
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
8980
9023
|
"type": "string",
|
|
8981
9024
|
"const": "session_not_found"
|
|
8982
9025
|
},
|
|
@@ -9360,7 +9403,7 @@
|
|
|
9360
9403
|
"const": "quota"
|
|
9361
9404
|
},
|
|
9362
9405
|
{
|
|
9363
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
9406
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
9364
9407
|
"type": "string",
|
|
9365
9408
|
"const": "session_not_found"
|
|
9366
9409
|
},
|
|
@@ -12482,7 +12525,7 @@
|
|
|
12482
12525
|
"const": "quota"
|
|
12483
12526
|
},
|
|
12484
12527
|
{
|
|
12485
|
-
"description": "The session this run asked to continue does not exist for the identity
|
|
12528
|
+
"description": "The session this run asked to continue does not exist for the identity\nit ran as, so the harness refused before doing any work (see the private\n`unknown_session_rejection` rule). Distinct from every other kind\nbecause the task itself is fine: another identity — or a fresh session\non this one — can still run it.",
|
|
12486
12529
|
"type": "string",
|
|
12487
12530
|
"const": "session_not_found"
|
|
12488
12531
|
},
|
|
@@ -15958,6 +16001,9 @@
|
|
|
15958
16001
|
"$ref": "#/$defs/Field3"
|
|
15959
16002
|
}
|
|
15960
16003
|
},
|
|
16004
|
+
"history_pointer_file": {
|
|
16005
|
+
"$ref": "#/$defs/Field3"
|
|
16006
|
+
},
|
|
15961
16007
|
"hooks": {
|
|
15962
16008
|
"$ref": "#/$defs/Field10"
|
|
15963
16009
|
},
|
|
@@ -16035,6 +16081,7 @@
|
|
|
16035
16081
|
"require_available",
|
|
16036
16082
|
"history",
|
|
16037
16083
|
"history_dir",
|
|
16084
|
+
"history_pointer_file",
|
|
16038
16085
|
"history_labels",
|
|
16039
16086
|
"allowed_tools",
|
|
16040
16087
|
"denied_tools",
|
|
@@ -16760,7 +16807,7 @@
|
|
|
16760
16807
|
"usage_report": {
|
|
16761
16808
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
16762
16809
|
"title": "UsageReport",
|
|
16763
|
-
"description": "One usage report: every probed identity, stamped with a single observation\ntime supplied by the caller (this module reads no clock).\n\nDeserializing is a consumer boundary — `oneharness-core` is published for\nsibling tools — so the envelope is validated on the way in rather than\ntrusted: see
|
|
16810
|
+
"description": "One usage report: every probed identity, stamped with a single observation\ntime supplied by the caller (this module reads no clock).\n\nDeserializing is a consumer boundary — `oneharness-core` is published for\nsibling tools — so the envelope is validated on the way in rather than\ntrusted: see the private `UsageReportWire` shape.",
|
|
16764
16811
|
"type": "object",
|
|
16765
16812
|
"properties": {
|
|
16766
16813
|
"identities": {
|
|
@@ -17057,7 +17104,7 @@
|
|
|
17057
17104
|
]
|
|
17058
17105
|
},
|
|
17059
17106
|
"UsageIdentity": {
|
|
17060
|
-
"description": "One harness identity's headroom.\n\nDeserializing is a consumer boundary like the envelope's, so every string an\nidentity carries is flattened through
|
|
17107
|
+
"description": "One harness identity's headroom.\n\nDeserializing is a consumer boundary like the envelope's, so every string an\nidentity carries is flattened through the private `without_control_chars`\nfilter on the way in — see the private `UsageIdentityWire` shape.",
|
|
17061
17108
|
"type": "object",
|
|
17062
17109
|
"properties": {
|
|
17063
17110
|
"auth_mode": {
|
|
@@ -17634,5 +17681,149 @@
|
|
|
17634
17681
|
]
|
|
17635
17682
|
}
|
|
17636
17683
|
}
|
|
17684
|
+
},
|
|
17685
|
+
"history_pointers_options": {
|
|
17686
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
17687
|
+
"title": "HistoryPointersOptions",
|
|
17688
|
+
"description": "Options accepted by the language SDKs' `historyPointers()`: the pointer\nfile a run was given as `historyPointerFile`.",
|
|
17689
|
+
"type": "object",
|
|
17690
|
+
"properties": {
|
|
17691
|
+
"file": {
|
|
17692
|
+
"description": "The pointer file to read. A file that does not exist reads as empty.",
|
|
17693
|
+
"type": "string",
|
|
17694
|
+
"minLength": 1
|
|
17695
|
+
}
|
|
17696
|
+
},
|
|
17697
|
+
"additionalProperties": false,
|
|
17698
|
+
"required": [
|
|
17699
|
+
"file"
|
|
17700
|
+
]
|
|
17701
|
+
},
|
|
17702
|
+
"history_pointers": {
|
|
17703
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
17704
|
+
"title": "HistoryPointers",
|
|
17705
|
+
"description": "What [`read_pointers`] read: every well-formed [`HistoryPointer`] line in\nfile order, and how many lines were not one.",
|
|
17706
|
+
"type": "object",
|
|
17707
|
+
"properties": {
|
|
17708
|
+
"pointers": {
|
|
17709
|
+
"description": "The pointer lines, in the order they were appended.",
|
|
17710
|
+
"type": "array",
|
|
17711
|
+
"items": {
|
|
17712
|
+
"$ref": "#/$defs/HistoryPointer"
|
|
17713
|
+
}
|
|
17714
|
+
},
|
|
17715
|
+
"skipped": {
|
|
17716
|
+
"description": "Lines that were not one complete pointer object — a torn tail left by\nan interrupted writer, or a foreign line — counted rather than failing\nthe read.",
|
|
17717
|
+
"type": "integer",
|
|
17718
|
+
"format": "uint",
|
|
17719
|
+
"minimum": 0
|
|
17720
|
+
}
|
|
17721
|
+
},
|
|
17722
|
+
"required": [
|
|
17723
|
+
"pointers",
|
|
17724
|
+
"skipped"
|
|
17725
|
+
],
|
|
17726
|
+
"$defs": {
|
|
17727
|
+
"HistoryLabels": {
|
|
17728
|
+
"type": "object",
|
|
17729
|
+
"additionalProperties": {
|
|
17730
|
+
"type": "string",
|
|
17731
|
+
"maxLength": 256,
|
|
17732
|
+
"minLength": 1,
|
|
17733
|
+
"not": {
|
|
17734
|
+
"pattern": "[\\u0000-\\u001f\\u007f-\\u009f]"
|
|
17735
|
+
}
|
|
17736
|
+
},
|
|
17737
|
+
"propertyNames": {
|
|
17738
|
+
"type": "string",
|
|
17739
|
+
"maxLength": 64,
|
|
17740
|
+
"not": {
|
|
17741
|
+
"pattern": "[^A-Za-z0-9._-]"
|
|
17742
|
+
},
|
|
17743
|
+
"pattern": "^[A-Za-z0-9]"
|
|
17744
|
+
}
|
|
17745
|
+
},
|
|
17746
|
+
"HistoryPointer": {
|
|
17747
|
+
"description": "One line of a run's **pointer file**: where one harness run's history went.\n\nA consumer that starts many `oneharness` processes (or in-process runs) names\none file, and every run with history on appends one of these per harness run\nit begins — so \"which sessions did this run launch, and where are they\" is a\nread of that one small file rather than a scan of the whole store, wherever\nthe store lives. `history_dir` / `history_project` / `history_session` are\nspelled as the `oneharness-session` artifact `oneagentgraph` publishes, so a\nreader already resolving that through `io::history::find_session_path`\nresolves these unchanged.\n\nBuilt only through [`HistoryPointer::new`] over a [`PointerSession`], and\nread back only through a deserialization that re-checks every invariant\n`new` establishes — the four session spellings compose into one file, the\ntwo identity spellings are the parsed [`HarnessIdentity`]'s own, the version\nis one this reader knows — so a line that parses IS a pointer, and a foreign\nobject that happens to carry these keys is counted as skipped rather than\nread as one.\nThe fields are read through accessors for the same reason: a Rust caller\ngets a line from one of those two doors, never assembles or edits one.",
|
|
17748
|
+
"type": "object",
|
|
17749
|
+
"properties": {
|
|
17750
|
+
"harness": {
|
|
17751
|
+
"description": "The harness id's base, e.g. `claude-code`.",
|
|
17752
|
+
"type": "string"
|
|
17753
|
+
},
|
|
17754
|
+
"harness_id": {
|
|
17755
|
+
"description": "The whole configured id, e.g. `claude-code:primary` — always `harness`\nwith `:variant` when there is one.",
|
|
17756
|
+
"type": "string"
|
|
17757
|
+
},
|
|
17758
|
+
"history_dir": {
|
|
17759
|
+
"description": "The store the session is under, absolute.",
|
|
17760
|
+
"type": "string"
|
|
17761
|
+
},
|
|
17762
|
+
"history_file": {
|
|
17763
|
+
"description": "The session file, absolute; the same path the run report echoes, and\nalways `<history_dir>/<history_project>/<history_session>.jsonl`.",
|
|
17764
|
+
"type": "string"
|
|
17765
|
+
},
|
|
17766
|
+
"history_id": {
|
|
17767
|
+
"description": "The history id of the record this harness run will close with — the\nexact id `history show <history-id>` resolves.",
|
|
17768
|
+
"type": "string",
|
|
17769
|
+
"maxLength": 36,
|
|
17770
|
+
"minLength": 36,
|
|
17771
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
|
|
17772
|
+
},
|
|
17773
|
+
"history_project": {
|
|
17774
|
+
"description": "The project slug — the session file's parent directory name.",
|
|
17775
|
+
"type": "string"
|
|
17776
|
+
},
|
|
17777
|
+
"history_session": {
|
|
17778
|
+
"description": "The session id — the session file's stem.",
|
|
17779
|
+
"type": "string"
|
|
17780
|
+
},
|
|
17781
|
+
"labels": {
|
|
17782
|
+
"description": "The session's validated labels, omitted when empty.",
|
|
17783
|
+
"$ref": "#/$defs/HistoryLabels"
|
|
17784
|
+
},
|
|
17785
|
+
"name": {
|
|
17786
|
+
"description": "The session's human-meaningful name (see [`session_name`]).",
|
|
17787
|
+
"type": "string"
|
|
17788
|
+
},
|
|
17789
|
+
"project": {
|
|
17790
|
+
"description": "The project directory the run operates in, canonical.",
|
|
17791
|
+
"type": "string"
|
|
17792
|
+
},
|
|
17793
|
+
"schema_version": {
|
|
17794
|
+
"description": "[`POINTER_SCHEMA_VERSION`]; a reader accepts any `1.<minor>`.",
|
|
17795
|
+
"type": "string"
|
|
17796
|
+
},
|
|
17797
|
+
"started": {
|
|
17798
|
+
"description": "RFC 3339 UTC, when this harness run began.",
|
|
17799
|
+
"$ref": "#/$defs/UtcInstant"
|
|
17800
|
+
},
|
|
17801
|
+
"variant": {
|
|
17802
|
+
"description": "The variant, omitted for a bare harness.",
|
|
17803
|
+
"type": [
|
|
17804
|
+
"string",
|
|
17805
|
+
"null"
|
|
17806
|
+
]
|
|
17807
|
+
}
|
|
17808
|
+
},
|
|
17809
|
+
"required": [
|
|
17810
|
+
"schema_version",
|
|
17811
|
+
"history_id",
|
|
17812
|
+
"history_dir",
|
|
17813
|
+
"history_project",
|
|
17814
|
+
"history_session",
|
|
17815
|
+
"history_file",
|
|
17816
|
+
"name",
|
|
17817
|
+
"project",
|
|
17818
|
+
"harness",
|
|
17819
|
+
"harness_id",
|
|
17820
|
+
"started"
|
|
17821
|
+
]
|
|
17822
|
+
},
|
|
17823
|
+
"UtcInstant": {
|
|
17824
|
+
"description": "An RFC 3339 timestamp in UTC (`Z`), in oneharness's canonical spelling.",
|
|
17825
|
+
"type": "string"
|
|
17826
|
+
}
|
|
17827
|
+
}
|
|
17637
17828
|
}
|
|
17638
17829
|
}
|
|
@@ -145,7 +145,7 @@ export type UnknownReason = {
|
|
|
145
145
|
*
|
|
146
146
|
* Deserializing is a consumer boundary — `oneharness-core` is published for
|
|
147
147
|
* sibling tools — so the envelope is validated on the way in rather than
|
|
148
|
-
* trusted: see
|
|
148
|
+
* trusted: see the private `UsageReportWire` shape.
|
|
149
149
|
*/
|
|
150
150
|
export interface UsageReport {
|
|
151
151
|
identities: UsageIdentity[];
|
|
@@ -163,8 +163,8 @@ export interface UsageReport {
|
|
|
163
163
|
* One harness identity's headroom.
|
|
164
164
|
*
|
|
165
165
|
* Deserializing is a consumer boundary like the envelope's, so every string an
|
|
166
|
-
* identity carries is flattened through
|
|
167
|
-
* — see
|
|
166
|
+
* identity carries is flattened through the private `without_control_chars`
|
|
167
|
+
* filter on the way in — see the private `UsageIdentityWire` shape.
|
|
168
168
|
*/
|
|
169
169
|
export interface UsageIdentity {
|
|
170
170
|
auth_mode: AuthMode;
|
package/dist/generated/zod.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ import type { HistoryListOptions } from "./history-list-options.js";
|
|
|
14
14
|
import type { HistoryLookup, HistoryLookupByLast, HistoryLookupBySession } from "./history-lookup.js";
|
|
15
15
|
import type { HistoryMigrateOptions } from "./history-migrate-options.js";
|
|
16
16
|
import type { HistoryMigrateReport, MigrationSummary } from "./history-migrate-report.js";
|
|
17
|
+
import type { HistoryPointer, HistoryPointers } from "./history-pointers.js";
|
|
18
|
+
import type { HistoryPointersOptions } from "./history-pointers-options.js";
|
|
17
19
|
import type { HistoryRecords } from "./history-records.js";
|
|
18
20
|
import type { HistoryEventLine, HistoryStreamEnvelope } from "./history-stream-envelope.js";
|
|
19
21
|
import type { HistoryWatchOptions } from "./history-watch-options.js";
|
|
@@ -83,6 +85,9 @@ export declare const HistoryLookupByLastSchema: z.ZodType<HistoryLookupByLast>;
|
|
|
83
85
|
export declare const HistoryLookupBySessionSchema: z.ZodType<HistoryLookupBySession>;
|
|
84
86
|
export declare const HistoryMigrateOptionsSchema: z.ZodType<HistoryMigrateOptions>;
|
|
85
87
|
export declare const HistoryMigrateReportSchema: z.ZodType<HistoryMigrateReport>;
|
|
88
|
+
export declare const HistoryPointerSchema: z.ZodType<HistoryPointer>;
|
|
89
|
+
export declare const HistoryPointersSchema: z.ZodType<HistoryPointers>;
|
|
90
|
+
export declare const HistoryPointersOptionsSchema: z.ZodType<HistoryPointersOptions>;
|
|
86
91
|
export declare const HistoryRecordSchema: z.ZodType<HistoryRecord>;
|
|
87
92
|
export declare const HistoryRecordsSchema: z.ZodType<HistoryRecords>;
|
|
88
93
|
export declare const HistorySessionSummarySchema: z.ZodType<HistorySessionSummary>;
|
package/dist/generated/zod.js
CHANGED
|
@@ -57,6 +57,7 @@ export const ConfigReportSchema = z.looseObject({
|
|
|
57
57
|
history_labels: z
|
|
58
58
|
.record(z.string(), z.lazy(() => Field3Schema))
|
|
59
59
|
.refine((value) => value !== undefined, { message: "Required" }),
|
|
60
|
+
history_pointer_file: z.lazy(() => Field3Schema).refine((value) => value !== undefined, { message: "Required" }),
|
|
60
61
|
hooks: z.lazy(() => Field10Schema).refine((value) => value !== undefined, { message: "Required" }),
|
|
61
62
|
max_parallel: z.lazy(() => Field8Schema).refine((value) => value !== undefined, { message: "Required" }),
|
|
62
63
|
mode: z.lazy(() => Field4Schema).refine((value) => value !== undefined, { message: "Required" }),
|
|
@@ -1134,6 +1135,39 @@ export const HistoryMigrateReportSchema = z.looseObject({
|
|
|
1134
1135
|
.gte(0)
|
|
1135
1136
|
.refine((value) => value !== undefined, { message: "Required" }),
|
|
1136
1137
|
});
|
|
1138
|
+
export const HistoryPointerSchema = z.looseObject({
|
|
1139
|
+
harness: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1140
|
+
harness_id: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1141
|
+
history_dir: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1142
|
+
history_file: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1143
|
+
history_id: z
|
|
1144
|
+
.string()
|
|
1145
|
+
.min(36)
|
|
1146
|
+
.regex(new RegExp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$", "u"))
|
|
1147
|
+
.refine((value) => [...value].length <= 36, { message: "Too long: expected at most 36 characters" })
|
|
1148
|
+
.refine((value) => value !== undefined, { message: "Required" }),
|
|
1149
|
+
history_project: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1150
|
+
history_session: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1151
|
+
labels: z.lazy(() => HistoryLabelsSchema).optional(),
|
|
1152
|
+
name: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1153
|
+
project: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1154
|
+
schema_version: z.string().refine((value) => value !== undefined, { message: "Required" }),
|
|
1155
|
+
started: z.lazy(() => UtcInstantSchema).refine((value) => value !== undefined, { message: "Required" }),
|
|
1156
|
+
variant: z.union([z.string(), z.null()]).optional(),
|
|
1157
|
+
});
|
|
1158
|
+
export const HistoryPointersSchema = z.looseObject({
|
|
1159
|
+
pointers: z.array(z.lazy(() => HistoryPointerSchema)).refine((value) => value !== undefined, { message: "Required" }),
|
|
1160
|
+
skipped: z
|
|
1161
|
+
.int()
|
|
1162
|
+
.gte(0)
|
|
1163
|
+
.refine((value) => value !== undefined, { message: "Required" }),
|
|
1164
|
+
});
|
|
1165
|
+
export const HistoryPointersOptionsSchema = z.strictObject({
|
|
1166
|
+
file: z
|
|
1167
|
+
.string()
|
|
1168
|
+
.min(1)
|
|
1169
|
+
.refine((value) => value !== undefined, { message: "Required" }),
|
|
1170
|
+
});
|
|
1137
1171
|
export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(z.intersection(z.intersection(z.union([
|
|
1138
1172
|
z.looseObject({
|
|
1139
1173
|
duration_ms: z
|
|
@@ -2321,6 +2355,7 @@ export const RunOptionsSchema = z.strictObject({
|
|
|
2321
2355
|
historyDir: z.string().optional(),
|
|
2322
2356
|
historyLabels: z.lazy(() => HistoryLabelsSchema).optional(),
|
|
2323
2357
|
historyName: z.string().optional(),
|
|
2358
|
+
historyPointerFile: z.string().min(1).optional(),
|
|
2324
2359
|
maxParallel: z.int().gte(0).optional(),
|
|
2325
2360
|
mockHarnesses: z.array(z.string()).optional(),
|
|
2326
2361
|
mockRules: z.string().optional(),
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ import type { HistoryListOptions } from "./generated/history-list-options.js";
|
|
|
12
12
|
import type { HistoryLookup } from "./generated/history-lookup.js";
|
|
13
13
|
import type { HistoryMigrateOptions } from "./generated/history-migrate-options.js";
|
|
14
14
|
import type { HistoryMigrateReport } from "./generated/history-migrate-report.js";
|
|
15
|
+
import type { HistoryPointers } from "./generated/history-pointers.js";
|
|
16
|
+
import type { HistoryPointersOptions } from "./generated/history-pointers-options.js";
|
|
15
17
|
import type { HistoryStreamEnvelope } from "./generated/history-stream-envelope.js";
|
|
16
18
|
import type { HistoryWatchOptions } from "./generated/history-watch-options.js";
|
|
17
19
|
import type { InitOptions } from "./generated/init-options.js";
|
|
@@ -42,6 +44,8 @@ export type { HistoryListOptions } from "./generated/history-list-options.js";
|
|
|
42
44
|
export type { HistoryLookup, HistoryLookupByLast, HistoryLookupBySession, } from "./generated/history-lookup.js";
|
|
43
45
|
export type { HistoryMigrateOptions } from "./generated/history-migrate-options.js";
|
|
44
46
|
export type { HistoryMigrateReport } from "./generated/history-migrate-report.js";
|
|
47
|
+
export type { HistoryPointer, HistoryPointers, } from "./generated/history-pointers.js";
|
|
48
|
+
export type { HistoryPointersOptions } from "./generated/history-pointers-options.js";
|
|
45
49
|
export type { HistoryRecords } from "./generated/history-records.js";
|
|
46
50
|
export type { HistoryStreamEnvelope } from "./generated/history-stream-envelope.js";
|
|
47
51
|
export type { HistoryWatchOptions } from "./generated/history-watch-options.js";
|
|
@@ -146,5 +150,13 @@ export declare class OneHarness {
|
|
|
146
150
|
historyClear(options?: HistoryClearOptions): Promise<HistoryClearReport>;
|
|
147
151
|
/** Rewrite legacy session files to the current record version. */
|
|
148
152
|
historyMigrate(options?: HistoryMigrateOptions): Promise<HistoryMigrateReport>;
|
|
153
|
+
/**
|
|
154
|
+
* Read a run's pointer file (`historyPointerFile` on `run()`): one line per
|
|
155
|
+
* harness run begun with history on, naming where its session went.
|
|
156
|
+
*
|
|
157
|
+
* A missing file reads as empty; a torn or foreign line is counted in
|
|
158
|
+
* `skipped` rather than failing the read.
|
|
159
|
+
*/
|
|
160
|
+
historyPointers(options: HistoryPointersOptions): Promise<HistoryPointers>;
|
|
149
161
|
historyWatch(options?: HistoryWatchOptions): AsyncGenerator<HistoryStreamEnvelope>;
|
|
150
162
|
}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
4
|
import { CAPABILITIES, } from "./generated/capabilities.js";
|
|
5
|
-
import { ConfigOptionsSchema, ConfigReportSchema, DetectOptionsSchema, DetectReportSchema, GateOptionsSchema, HistoryClearOptionsSchema, HistoryClearReportSchema, HistoryListOptionsSchema, HistoryListSchema, HistoryLookupSchema, HistoryMigrateOptionsSchema, HistoryMigrateReportSchema, HistoryRecordsSchema, HistoryStreamEnvelopeSchema, HistoryWatchOptionsSchema, InitOptionsSchema, InterruptOptionsSchema, InterruptResponseSchema, ListReportSchema, MockOptionsSchema, RunOptionsSchema, RunReportSchema, RunStreamEnvelopeSchema, SyncOptionsSchema, SyncReportSchema, UsageOptionsSchema, UsageReportSchema, } from "./generated/zod.js";
|
|
5
|
+
import { ConfigOptionsSchema, ConfigReportSchema, DetectOptionsSchema, DetectReportSchema, GateOptionsSchema, HistoryClearOptionsSchema, HistoryClearReportSchema, HistoryListOptionsSchema, HistoryListSchema, HistoryLookupSchema, HistoryMigrateOptionsSchema, HistoryMigrateReportSchema, HistoryPointersOptionsSchema, HistoryPointersSchema, HistoryRecordsSchema, HistoryStreamEnvelopeSchema, HistoryWatchOptionsSchema, InitOptionsSchema, InterruptOptionsSchema, InterruptResponseSchema, ListReportSchema, MockOptionsSchema, RunOptionsSchema, RunReportSchema, RunStreamEnvelopeSchema, SyncOptionsSchema, SyncReportSchema, UsageOptionsSchema, UsageReportSchema, } from "./generated/zod.js";
|
|
6
6
|
export { CAPABILITIES } from "./generated/capabilities.js";
|
|
7
7
|
export * from "./generated/zod.js";
|
|
8
8
|
/** A non-zero exit from the oneharness subprocess. */
|
|
@@ -482,6 +482,16 @@ export class OneHarness {
|
|
|
482
482
|
async historyMigrate(options = {}) {
|
|
483
483
|
return await this.call("historyMigrate", options, HistoryMigrateOptionsSchema, HistoryMigrateReportSchema);
|
|
484
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* Read a run's pointer file (`historyPointerFile` on `run()`): one line per
|
|
487
|
+
* harness run begun with history on, naming where its session went.
|
|
488
|
+
*
|
|
489
|
+
* A missing file reads as empty; a torn or foreign line is counted in
|
|
490
|
+
* `skipped` rather than failing the read.
|
|
491
|
+
*/
|
|
492
|
+
async historyPointers(options) {
|
|
493
|
+
return await this.call("historyPointers", options, HistoryPointersOptionsSchema, HistoryPointersSchema);
|
|
494
|
+
}
|
|
485
495
|
historyWatch(options = {}) {
|
|
486
496
|
const input = parseContract(HistoryWatchOptionsSchema, options, "invalid oneharness history watch options");
|
|
487
497
|
return invokeStreamWith(this.options, capabilityArguments("historyWatch", input), HistoryStreamEnvelopeSchema, "invalid oneharness history watch contract", undefined, true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneharness/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Typed Node.js SDK for oneharness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"node": ">=20"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"oneharness-cli": "0.
|
|
22
|
+
"oneharness-cli": "0.16.0",
|
|
23
23
|
"zod": "^4.4.3"
|
|
24
24
|
}
|
|
25
25
|
}
|