@oneharness/sdk 0.19.1 → 0.21.1

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.
@@ -1139,6 +1139,7 @@ export const HistoryListOptionsSchema = z.strictObject({
1139
1139
  noConfig: z.boolean().optional(),
1140
1140
  project: z.string().optional(),
1141
1141
  variant: z.string().optional(),
1142
+ window: z.union([z.lazy(() => HistoryWindowSchema), z.null()]).optional(),
1142
1143
  });
1143
1144
  export const HistoryLookupSchema = z.union([
1144
1145
  z.lazy(() => HistoryLookupByLastSchema),
@@ -1153,6 +1154,7 @@ export const HistoryLookupByLastSchema = z.strictObject({
1153
1154
  noConfig: z.boolean().optional(),
1154
1155
  project: z.string().optional(),
1155
1156
  session: z.string().optional(),
1157
+ window: z.union([z.lazy(() => HistoryWindowSchema), z.null()]).optional(),
1156
1158
  });
1157
1159
  export const HistoryLookupBySessionSchema = z.strictObject({
1158
1160
  all: z.boolean().optional(),
@@ -1166,6 +1168,7 @@ export const HistoryLookupBySessionSchema = z.strictObject({
1166
1168
  .string()
1167
1169
  .min(1)
1168
1170
  .refine((value) => value !== undefined, { message: "Required" }),
1171
+ window: z.union([z.lazy(() => HistoryWindowSchema), z.null()]).optional(),
1169
1172
  });
1170
1173
  export const HistoryMigrateOptionsSchema = z.strictObject({
1171
1174
  config: z.array(z.string()).optional(),
@@ -2235,7 +2238,27 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
2235
2238
  schema_version: z.literal("1.9").optional(),
2236
2239
  }),
2237
2240
  ])));
2238
- export const HistoryRecordsSchema = z.array(z.lazy(() => HistoryRecordSchema));
2241
+ export const HistoryReindexOptionsSchema = z.strictObject({
2242
+ config: z.array(z.string()).optional(),
2243
+ historyDir: z.string().optional(),
2244
+ noConfig: z.boolean().optional(),
2245
+ });
2246
+ export const HistoryReindexReportSchema = z.looseObject({
2247
+ entries_added: z
2248
+ .int()
2249
+ .gte(0)
2250
+ .refine((value) => value !== undefined, { message: "Required" }),
2251
+ files_read: z
2252
+ .int()
2253
+ .gte(0)
2254
+ .refine((value) => value !== undefined, { message: "Required" }),
2255
+ segments: z
2256
+ .array(z.lazy(() => SegmentReindexSummarySchema))
2257
+ .refine((value) => value !== undefined, { message: "Required" }),
2258
+ unreadable: z
2259
+ .array(z.lazy(() => UnreadableSessionFileSchema))
2260
+ .refine((value) => value !== undefined, { message: "Required" }),
2261
+ });
2239
2262
  export const HistorySessionSummarySchema = z.looseObject({
2240
2263
  harnesses: z.array(z.string()).refine((value) => value !== undefined, { message: "Required" }),
2241
2264
  id: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -2250,6 +2273,11 @@ export const HistorySessionSummarySchema = z.looseObject({
2250
2273
  running: z.boolean().optional(),
2251
2274
  started: z.string().refine((value) => value !== undefined, { message: "Required" }),
2252
2275
  });
2276
+ export const HistoryShowEntriesSchema = z.array(z.lazy(() => HistoryShowEntrySchema));
2277
+ export const HistoryShowEntrySchema = z.union([
2278
+ z.lazy(() => HistoryRecordSchema),
2279
+ z.lazy(() => IncompleteHistoryRunSchema),
2280
+ ]);
2253
2281
  export const HistoryStreamEnvelopeSchema = z.union([
2254
2282
  z.looseObject({
2255
2283
  record: z.lazy(() => HistoryRecordSchema).refine((value) => value !== undefined, { message: "Required" }),
@@ -2287,7 +2315,29 @@ export const HistoryWatchOptionsSchema = z.strictObject({
2287
2315
  ])
2288
2316
  .optional(),
2289
2317
  variant: z.string().optional(),
2318
+ window: z.union([z.lazy(() => HistoryWindowSchema), z.null()]).optional(),
2290
2319
  });
2320
+ export const HistoryWindowSchema = z.union([
2321
+ z.strictObject({
2322
+ recent: z
2323
+ .strictObject({
2324
+ days: z
2325
+ .int()
2326
+ .gte(1)
2327
+ .refine((value) => value !== undefined, { message: "Required" }),
2328
+ })
2329
+ .refine((value) => value !== undefined, { message: "Required" }),
2330
+ }),
2331
+ z.strictObject({
2332
+ since: z
2333
+ .string()
2334
+ .min(10)
2335
+ .regex(new RegExp("^(?:[1-9][0-9]{3}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12][0-9]|3[01])|(?:0[469]|11)-(?:0[1-9]|[12][0-9]|30)|02-(?:0[1-9]|1[0-9]|2[0-8]))|(?:[1-9][0-9](?:0[48]|[2468][048]|[13579][26])|(?:1[26]|2[048]|3[26]|4[048]|5[26]|6[048]|7[26]|8[048]|9[26])00)-02-29)$", "u"))
2336
+ .refine((value) => [...value].length <= 10, { message: "Too long: expected at most 10 characters" })
2337
+ .refine((value) => value !== undefined, { message: "Required" }),
2338
+ }),
2339
+ z.literal("allTime"),
2340
+ ]);
2291
2341
  export const HookEntrySchema = z.strictObject({
2292
2342
  command: z.string().refine((value) => value !== undefined, { message: "Required" }),
2293
2343
  harnesses: z.union([z.array(z.string()), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -2313,6 +2363,21 @@ export const IdentitySelectorSchema = z.union([
2313
2363
  kind: z.literal("ambient").refine((value) => value !== undefined, { message: "Required" }),
2314
2364
  }),
2315
2365
  ]);
2366
+ export const IncompleteHistoryRunSchema = z.looseObject({
2367
+ events: z
2368
+ .array(z.lazy(() => ActionEventSchema))
2369
+ .min(1)
2370
+ .refine((value) => value !== undefined, { message: "Required" }),
2371
+ harness: z.string().refine((value) => value !== undefined, { message: "Required" }),
2372
+ run_id: z
2373
+ .string()
2374
+ .min(36)
2375
+ .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"))
2376
+ .refine((value) => [...value].length <= 36, { message: "Too long: expected at most 36 characters" })
2377
+ .refine((value) => value !== undefined, { message: "Required" }),
2378
+ type: z.lazy(() => IncompleteRunTypeSchema).refine((value) => value !== undefined, { message: "Required" }),
2379
+ });
2380
+ export const IncompleteRunTypeSchema = z.literal("incomplete");
2316
2381
  export const InitOptionsSchema = z.strictObject({
2317
2382
  force: z.boolean().optional(),
2318
2383
  path: z.string().optional(),
@@ -2540,6 +2605,14 @@ export const RunStreamEnvelopeSchema = z.union([
2540
2605
  }),
2541
2606
  ]);
2542
2607
  export const RunWorkSchema = z.union([z.literal("done"), z.literal("none")]);
2608
+ export const SegmentReindexSummarySchema = z.looseObject({
2609
+ added: z
2610
+ .int()
2611
+ .gte(0)
2612
+ .refine((value) => value !== undefined, { message: "Required" }),
2613
+ path: z.string().refine((value) => value !== undefined, { message: "Required" }),
2614
+ segment: z.string().refine((value) => value !== undefined, { message: "Required" }),
2615
+ });
2543
2616
  export const SessionPhaseSchema = z.union([z.literal("create"), z.literal("continue")]);
2544
2617
  export const SessionReportSchema = z.looseObject({
2545
2618
  name: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -2623,6 +2696,10 @@ export const UnmappedRuleSchema = z.looseObject({
2623
2696
  reason: z.string().refine((value) => value !== undefined, { message: "Required" }),
2624
2697
  rule: z.string().refine((value) => value !== undefined, { message: "Required" }),
2625
2698
  });
2699
+ export const UnreadableSessionFileSchema = z.looseObject({
2700
+ error: z.string().refine((value) => value !== undefined, { message: "Required" }),
2701
+ path: z.string().refine((value) => value !== undefined, { message: "Required" }),
2702
+ });
2626
2703
  export const UsageSchema = z.looseObject({
2627
2704
  cache_read_tokens: z
2628
2705
  .union([z.int().gte(0), z.null()])
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ZodType } from "zod";
1
2
  import type { ConfigOptions } from "./generated/config-options.js";
2
3
  import type { ConfigReport } from "./generated/config-report.js";
3
4
  import type { RunReport } from "./generated/contracts.js";
@@ -14,6 +15,9 @@ import type { HistoryMigrateOptions } from "./generated/history-migrate-options.
14
15
  import type { HistoryMigrateReport } from "./generated/history-migrate-report.js";
15
16
  import type { HistoryPointers } from "./generated/history-pointers.js";
16
17
  import type { HistoryPointersOptions } from "./generated/history-pointers-options.js";
18
+ import type { HistoryReindexOptions } from "./generated/history-reindex-options.js";
19
+ import type { HistoryReindexReport } from "./generated/history-reindex-report.js";
20
+ import type { HistoryShowEntries, HistoryShowEntry, IncompleteHistoryRun } from "./generated/history-show-entries.js";
17
21
  import type { HistoryStreamEnvelope } from "./generated/history-stream-envelope.js";
18
22
  import type { HistoryWatchOptions } from "./generated/history-watch-options.js";
19
23
  import type { InitOptions } from "./generated/init-options.js";
@@ -40,13 +44,15 @@ export type { HistoryClearOptions } from "./generated/history-clear-options.js";
40
44
  export type { HistoryClearDryRun, HistoryClearRemoved, HistoryClearReport, } from "./generated/history-clear-report.js";
41
45
  export type { HistoryLine } from "./generated/history-line.js";
42
46
  export type { HistoryList, HistorySessionSummary, } from "./generated/history-list.js";
43
- export type { HistoryListOptions } from "./generated/history-list-options.js";
47
+ export type { HistoryListOptions, HistoryWindow, } from "./generated/history-list-options.js";
44
48
  export type { HistoryLookup, HistoryLookupByLast, HistoryLookupBySession, } from "./generated/history-lookup.js";
45
49
  export type { HistoryMigrateOptions } from "./generated/history-migrate-options.js";
46
50
  export type { HistoryMigrateReport } from "./generated/history-migrate-report.js";
47
51
  export type { HistoryPointer, HistoryPointers, } from "./generated/history-pointers.js";
48
52
  export type { HistoryPointersOptions } from "./generated/history-pointers-options.js";
49
- export type { HistoryRecords } from "./generated/history-records.js";
53
+ export type { HistoryReindexOptions } from "./generated/history-reindex-options.js";
54
+ export type { HistoryReindexReport, SegmentReindexSummary, UnreadableSessionFile, } from "./generated/history-reindex-report.js";
55
+ export type { HistoryShowEntries, HistoryShowEntry, IncompleteHistoryRun, } from "./generated/history-show-entries.js";
50
56
  export type { HistoryStreamEnvelope } from "./generated/history-stream-envelope.js";
51
57
  export type { HistoryWatchOptions } from "./generated/history-watch-options.js";
52
58
  export type { InitOptions } from "./generated/init-options.js";
@@ -62,6 +68,20 @@ export type { UsageReport } from "./generated/usage-report.js";
62
68
  export type Detection = DetectInfo;
63
69
  export type { HarnessInfo, ListReport, ModeInfo, } from "./generated/registry.js";
64
70
  export * from "./generated/zod.js";
71
+ /**
72
+ * Finished runs' records only.
73
+ *
74
+ * @deprecated `history show` also answers an in-flight run, so its output is
75
+ * `HistoryShowEntries`; this names only the finished records it can carry.
76
+ */
77
+ export type HistoryRecords = HistoryRecord[];
78
+ /**
79
+ * Validates finished runs' records only; an in-flight entry fails it.
80
+ *
81
+ * @deprecated `history show`'s output is validated by
82
+ * `HistoryShowEntriesSchema`, which also accepts an in-flight run.
83
+ */
84
+ export declare const HistoryRecordsSchema: ZodType<HistoryRecords>;
65
85
  export type OneHarnessOptions = {
66
86
  executable?: string;
67
87
  executableArgs?: readonly string[];
@@ -74,6 +94,11 @@ export type MockHarnessScript = {
74
94
  exitCode?: number;
75
95
  latencyMs?: number;
76
96
  };
97
+ /**
98
+ * Whether a `history()` entry is a run still in flight rather than a finished
99
+ * run's record. Records carry no `type`; an in-flight entry's is `incomplete`.
100
+ */
101
+ export declare function isIncompleteHistoryRun(entry: HistoryShowEntry): entry is IncompleteHistoryRun;
77
102
  /** A non-zero exit from the oneharness subprocess. */
78
103
  export declare class OneHarnessProcessError extends Error {
79
104
  readonly exitCode: number | null;
@@ -138,7 +163,14 @@ export declare class OneHarness {
138
163
  * on. So a non-zero exit still yields the frame.
139
164
  */
140
165
  interrupt(options: InterruptOptions): Promise<InterruptResponse>;
141
- history(lookup: HistoryLookup): Promise<HistoryRecord[]>;
166
+ /**
167
+ * Resolve one history record or session.
168
+ *
169
+ * A run still in flight has no record yet: it is an `IncompleteHistoryRun`
170
+ * entry (`type: "incomplete"`) carrying its `run_id`, `harness` and the
171
+ * `events` so far.
172
+ */
173
+ history(lookup: HistoryLookup): Promise<HistoryShowEntries>;
142
174
  historyList(options?: HistoryListOptions): Promise<HistorySessionSummary[]>;
143
175
  /**
144
176
  * Remove history sessions.
@@ -150,6 +182,15 @@ export declare class OneHarness {
150
182
  historyClear(options?: HistoryClearOptions): Promise<HistoryClearReport>;
151
183
  /** Rewrite legacy session files to the current record version. */
152
184
  historyMigrate(options?: HistoryMigrateOptions): Promise<HistoryMigrateReport>;
185
+ /**
186
+ * Index every session line the dated history index lacks: append one entry
187
+ * per run or event line its date's segment does not hold yet.
188
+ *
189
+ * Idempotent and append-only, and the only verb that reads every session
190
+ * file to build the index. The report names what was added per segment and
191
+ * every file that could not be read.
192
+ */
193
+ historyReindex(options?: HistoryReindexOptions): Promise<HistoryReindexReport>;
153
194
  /**
154
195
  * Read a run's pointer file (`historyPointerFile` on `run()`): one line per
155
196
  * harness run begun with history on, naming where its session went.
package/dist/index.js CHANGED
@@ -2,9 +2,23 @@ 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, HistoryPointersOptionsSchema, HistoryPointersSchema, 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, HistoryRecordSchema, HistoryReindexOptionsSchema, HistoryReindexReportSchema, HistoryShowEntriesSchema, 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
+ /**
9
+ * Validates finished runs' records only; an in-flight entry fails it.
10
+ *
11
+ * @deprecated `history show`'s output is validated by
12
+ * `HistoryShowEntriesSchema`, which also accepts an in-flight run.
13
+ */
14
+ export const HistoryRecordsSchema = HistoryRecordSchema.array();
15
+ /**
16
+ * Whether a `history()` entry is a run still in flight rather than a finished
17
+ * run's record. Records carry no `type`; an in-flight entry's is `incomplete`.
18
+ */
19
+ export function isIncompleteHistoryRun(entry) {
20
+ return entry.type === "incomplete";
21
+ }
8
22
  /** A non-zero exit from the oneharness subprocess. */
9
23
  export class OneHarnessProcessError extends Error {
10
24
  exitCode;
@@ -230,6 +244,23 @@ function statesAChoice(binding, value) {
230
244
  return String(value) !== "";
231
245
  return true;
232
246
  }
247
+ /**
248
+ * The one flag a history window renders: `--days N`, `--since D`, or
249
+ * `--all-time`. The window is a single validated value, so exactly one of the
250
+ * three is ever sent.
251
+ */
252
+ function windowArguments(binding, window) {
253
+ // `FlagKind::Window` serializes its spellings beside the binding, so a
254
+ // window binding without them is a manifest this client cannot render.
255
+ const flags = binding.window;
256
+ if (flags === undefined)
257
+ throw new Error(`the capability manifest's \`${binding.option}\` window binding names no flags`);
258
+ if (window === "allTime")
259
+ return [flags.allTime];
260
+ if ("since" in window)
261
+ return [flags.since, window.since];
262
+ return [flags.days, String(window.recent.days)];
263
+ }
233
264
  /**
234
265
  * Render one capability's argv from its declared bindings.
235
266
  *
@@ -297,6 +328,12 @@ function capabilityArguments(method, options) {
297
328
  case "trailing":
298
329
  trailing.push(...value.map(String));
299
330
  break;
331
+ case "window":
332
+ // A `window` binding only ever names an option the contract types as
333
+ // `HistoryWindow`, and Zod validated this value against that contract
334
+ // before it reached here, so the assertion restates a checked shape.
335
+ args.push(...windowArguments(binding, value));
336
+ break;
300
337
  }
301
338
  }
302
339
  args.push(...positional);
@@ -450,13 +487,20 @@ export class OneHarness {
450
487
  async interrupt(options) {
451
488
  return await this.call("interrupt", options, InterruptOptionsSchema, InterruptResponseSchema, { acceptJsonOnNonzero: true });
452
489
  }
490
+ /**
491
+ * Resolve one history record or session.
492
+ *
493
+ * A run still in flight has no record yet: it is an `IncompleteHistoryRun`
494
+ * entry (`type: "incomplete"`) carrying its `run_id`, `harness` and the
495
+ * `events` so far.
496
+ */
453
497
  async history(lookup) {
454
498
  // The `--last`-suppresses-a-name rule is declared, not re-derived here:
455
499
  // the union deliberately accepts `{session, last: true}` and resolves it
456
500
  // to "the most recent", and the manifest binds `session` with
457
501
  // `unless: "last"` so the builder renders only `--last`. Rust, the
458
502
  // generated Zod, and this call therefore agree by construction.
459
- return await this.call("history", lookup, HistoryLookupSchema, HistoryRecordsSchema, {
503
+ return await this.call("history", lookup, HistoryLookupSchema, HistoryShowEntriesSchema, {
460
504
  history: true,
461
505
  optionsLabel: "invalid oneharness history options",
462
506
  contractLabel: "invalid history contract",
@@ -482,6 +526,17 @@ export class OneHarness {
482
526
  async historyMigrate(options = {}) {
483
527
  return await this.call("historyMigrate", options, HistoryMigrateOptionsSchema, HistoryMigrateReportSchema);
484
528
  }
529
+ /**
530
+ * Index every session line the dated history index lacks: append one entry
531
+ * per run or event line its date's segment does not hold yet.
532
+ *
533
+ * Idempotent and append-only, and the only verb that reads every session
534
+ * file to build the index. The report names what was added per segment and
535
+ * every file that could not be read.
536
+ */
537
+ async historyReindex(options = {}) {
538
+ return await this.call("historyReindex", options, HistoryReindexOptionsSchema, HistoryReindexReportSchema);
539
+ }
485
540
  /**
486
541
  * Read a run's pointer file (`historyPointerFile` on `run()`): one line per
487
542
  * harness run begun with history on, naming where its session went.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneharness/sdk",
3
- "version": "0.19.1",
3
+ "version": "0.21.1",
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.19.1",
22
+ "oneharness-cli": "0.21.1",
23
23
  "zod": "^4.4.3"
24
24
  }
25
25
  }