@oneharness/sdk 0.15.1 → 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 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 `historyMigrate`. 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:
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
  };
@@ -56,6 +56,7 @@ export interface ConfigReport {
56
56
  history_labels: {
57
57
  [k: string]: Field3;
58
58
  };
59
+ history_pointer_file: Field3;
59
60
  hooks: Field10;
60
61
  max_parallel: Field8;
61
62
  mode: Field4;
@@ -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,2 @@
1
+ /* Generated from oneharness-core. Do not edit. */
2
+ export {};
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ /* Generated from oneharness-core. Do not edit. */
2
+ export {};
@@ -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": {
@@ -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",
@@ -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",
@@ -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
  }
@@ -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>;
@@ -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.15.1",
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.15.1",
22
+ "oneharness-cli": "0.16.0",
23
23
  "zod": "^4.4.3"
24
24
  }
25
25
  }