@oneharness/sdk 0.8.0 → 0.10.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.
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { ConfigOptions } from "./config-options.js";
3
3
  import type { ConfigReport, Field, Field10, Field2, Field3, Field4, Field5, Field6, Field7, Field8, Field9, HarnessReport, HookEntry, VariantReport } from "./config-report.js";
4
- import type { ActionEvent, BatchReport, ControlEvent, ControlReason, ControlReport, ControlVerb, ExecutionTelemetry, FailureKind, FallThrough, FallbackReport, RunReport, RunResult, SessionReport, Status, TimingSource, ToolCallStatus, Usage, UtcInstant } from "./contracts.js";
4
+ import type { ActionEvent, BatchReport, ControlEvent, ControlReason, ControlReport, ControlVerb, ExecutionTelemetry, FailureKind, FallThrough, FallThroughReason, FallbackReport, RunReport, RunResult, SessionReport, Status, TimingSource, ToolCallStatus, Usage, UtcInstant } from "./contracts.js";
5
5
  import type { DetectOptions } from "./detect-options.js";
6
6
  import type { DetectInfo, DetectReport } from "./detection.js";
7
7
  import type { GateOptions } from "./gate-options.js";
@@ -53,6 +53,7 @@ export declare const DetectReportSchema: z.ZodType<DetectReport>;
53
53
  export declare const ExecutionTelemetrySchema: z.ZodType<ExecutionTelemetry>;
54
54
  export declare const FailureKindSchema: z.ZodType<FailureKind>;
55
55
  export declare const FallThroughSchema: z.ZodType<FallThrough>;
56
+ export declare const FallThroughReasonSchema: z.ZodType<FallThroughReason>;
56
57
  export declare const FallbackReportSchema: z.ZodType<FallbackReport>;
57
58
  export declare const FieldSchema: z.ZodType<Field>;
58
59
  export declare const Field10Schema: z.ZodType<Field10>;
@@ -169,11 +169,25 @@ export const FailureKindSchema = z.union([
169
169
  z.literal("quota"),
170
170
  z.literal("session_not_found"),
171
171
  z.literal("tool_deferred"),
172
+ z.literal("untrusted_directory"),
173
+ z.literal("input_too_large"),
172
174
  ]);
173
175
  export const FallThroughSchema = z.looseObject({
176
+ detail: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
174
177
  harness: z.string().refine((value) => value !== undefined, { message: "Required" }),
175
- reason: z.string().refine((value) => value !== undefined, { message: "Required" }),
178
+ reason: z.lazy(() => FallThroughReasonSchema).refine((value) => value !== undefined, { message: "Required" }),
176
179
  });
180
+ export const FallThroughReasonSchema = z.union([
181
+ z.literal("not-installed"),
182
+ z.literal("spawn-error"),
183
+ z.literal("auth"),
184
+ z.literal("quota"),
185
+ z.literal("session-not-found"),
186
+ z.literal("untrusted-directory"),
187
+ z.literal("input-too-large"),
188
+ z.literal("model-not-found"),
189
+ z.literal("rate-limit"),
190
+ ]);
177
191
  export const FallbackReportSchema = z.looseObject({
178
192
  fell_through: z
179
193
  .array(z.lazy(() => FallThroughSchema))
@@ -326,7 +340,7 @@ export const HistoryEventLineSchema = z.union([
326
340
  .refine((value) => [...value].length <= 36, { message: "Too long: expected at most 36 characters" })
327
341
  .refine((value) => value !== undefined, { message: "Required" }),
328
342
  schema_version: z
329
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
343
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
330
344
  .refine((value) => value !== undefined, { message: "Required" }),
331
345
  variant: z.union([z.string(), z.null()]).optional(),
332
346
  }),
@@ -376,7 +390,7 @@ export const HistoryLineSchema = z.union([
376
390
  .refine((value) => [...value].length <= 36, { message: "Too long: expected at most 36 characters" })
377
391
  .refine((value) => value !== undefined, { message: "Required" }),
378
392
  schema_version: z
379
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
393
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
380
394
  .refine((value) => value !== undefined, { message: "Required" }),
381
395
  type: z.literal("event").refine((value) => value !== undefined, { message: "Required" }),
382
396
  variant: z.union([z.string(), z.null()]).optional(),
@@ -453,6 +467,7 @@ export const HistoryLineSchema = z.union([
453
467
  z.literal("1.3"),
454
468
  z.literal("1.4"),
455
469
  z.literal("1.5"),
470
+ z.literal("1.6"),
456
471
  ])
457
472
  .refine((value) => value !== undefined, { message: "Required" }),
458
473
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -530,6 +545,7 @@ export const HistoryLineSchema = z.union([
530
545
  z.literal("1.3"),
531
546
  z.literal("1.4"),
532
547
  z.literal("1.5"),
548
+ z.literal("1.6"),
533
549
  ])
534
550
  .refine((value) => value !== undefined, { message: "Required" }),
535
551
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -604,7 +620,7 @@ export const HistoryLineSchema = z.union([
604
620
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
605
621
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
606
622
  schema_version: z
607
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
623
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
608
624
  .refine((value) => value !== undefined, { message: "Required" }),
609
625
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
610
626
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -667,6 +683,7 @@ export const HistoryLineSchema = z.union([
667
683
  z.literal("1.3"),
668
684
  z.literal("1.4"),
669
685
  z.literal("1.5"),
686
+ z.literal("1.6"),
670
687
  ])
671
688
  .refine((value) => value !== undefined, { message: "Required" }),
672
689
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -732,7 +749,7 @@ export const HistoryLineSchema = z.union([
732
749
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
733
750
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
734
751
  schema_version: z
735
- .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
752
+ .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
736
753
  .refine((value) => value !== undefined, { message: "Required" }),
737
754
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
738
755
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -806,6 +823,7 @@ export const HistoryLineSchema = z.union([
806
823
  z.literal("1.3"),
807
824
  z.literal("1.4"),
808
825
  z.literal("1.5"),
826
+ z.literal("1.6"),
809
827
  ])
810
828
  .refine((value) => value !== undefined, { message: "Required" }),
811
829
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
@@ -831,7 +849,9 @@ export const HistoryLineSchema = z.union([
831
849
  }),
832
850
  z.intersection(z.looseObject({
833
851
  error: z.string().refine((value) => value !== undefined, { message: "Required" }),
834
- schema_version: z.union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5")]).optional(),
852
+ schema_version: z
853
+ .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
854
+ .optional(),
835
855
  }), z.union([
836
856
  z.looseObject({
837
857
  status: z
@@ -864,9 +884,9 @@ export const HistoryLineSchema = z.union([
864
884
  .optional(),
865
885
  }),
866
886
  z.looseObject({
867
- schema_version: z.union([z.literal("1.4"), z.literal("1.5")]).optional(),
887
+ schema_version: z.union([z.literal("1.4"), z.literal("1.5"), z.literal("1.6")]).optional(),
868
888
  }),
869
- ])), z.union([
889
+ ])), z.intersection(z.union([
870
890
  z.looseObject({
871
891
  failure_kind: z
872
892
  .union([
@@ -875,14 +895,33 @@ export const HistoryLineSchema = z.union([
875
895
  z.literal("model_not_found"),
876
896
  z.literal("quota"),
877
897
  z.literal("tool_deferred"),
898
+ z.literal("untrusted_directory"),
899
+ z.literal("input_too_large"),
878
900
  z.literal(null),
879
901
  ])
880
902
  .optional(),
881
903
  }),
882
904
  z.looseObject({
883
- schema_version: z.literal("1.5").optional(),
905
+ schema_version: z.union([z.literal("1.5"), z.literal("1.6")]).optional(),
884
906
  }),
885
- ])),
907
+ ]), z.union([
908
+ z.looseObject({
909
+ failure_kind: z
910
+ .union([
911
+ z.literal("auth"),
912
+ z.literal("rate_limit"),
913
+ z.literal("model_not_found"),
914
+ z.literal("quota"),
915
+ z.literal("session_not_found"),
916
+ z.literal("tool_deferred"),
917
+ z.literal(null),
918
+ ])
919
+ .optional(),
920
+ }),
921
+ z.looseObject({
922
+ schema_version: z.literal("1.6").optional(),
923
+ }),
924
+ ]))),
886
925
  ]);
887
926
  export const HistoryListSchema = z.array(z.lazy(() => HistorySessionSummarySchema));
888
927
  export const HistoryListOptionsSchema = z.strictObject({
@@ -1032,7 +1071,7 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1032
1071
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
1033
1072
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
1034
1073
  schema_version: z
1035
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
1074
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1036
1075
  .refine((value) => value !== undefined, { message: "Required" }),
1037
1076
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
1038
1077
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -1236,7 +1275,7 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1236
1275
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
1237
1276
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
1238
1277
  schema_version: z
1239
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
1278
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1240
1279
  .refine((value) => value !== undefined, { message: "Required" }),
1241
1280
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
1242
1281
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -1298,7 +1337,7 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1298
1337
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
1299
1338
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
1300
1339
  schema_version: z
1301
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
1340
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1302
1341
  .refine((value) => value !== undefined, { message: "Required" }),
1303
1342
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
1304
1343
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -1354,7 +1393,7 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1354
1393
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
1355
1394
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
1356
1395
  schema_version: z
1357
- .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
1396
+ .union([z.literal("1.2"), z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1358
1397
  .refine((value) => value !== undefined, { message: "Required" }),
1359
1398
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
1360
1399
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -1419,7 +1458,7 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1419
1458
  project: z.string().refine((value) => value !== undefined, { message: "Required" }),
1420
1459
  prompt: z.string().refine((value) => value !== undefined, { message: "Required" }),
1421
1460
  schema_version: z
1422
- .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5")])
1461
+ .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1423
1462
  .refine((value) => value !== undefined, { message: "Required" }),
1424
1463
  session: z.string().refine((value) => value !== undefined, { message: "Required" }),
1425
1464
  session_id: z.union([z.string(), z.null()]).refine((value) => value !== undefined, { message: "Required" }),
@@ -1670,7 +1709,9 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1670
1709
  }),
1671
1710
  z.intersection(z.looseObject({
1672
1711
  error: z.string().refine((value) => value !== undefined, { message: "Required" }),
1673
- schema_version: z.union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5")]).optional(),
1712
+ schema_version: z
1713
+ .union([z.literal("1.3"), z.literal("1.4"), z.literal("1.5"), z.literal("1.6")])
1714
+ .optional(),
1674
1715
  }), z.union([
1675
1716
  z.looseObject({
1676
1717
  status: z
@@ -1701,9 +1742,9 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1701
1742
  .optional(),
1702
1743
  }),
1703
1744
  z.looseObject({
1704
- schema_version: z.union([z.literal("1.4"), z.literal("1.5")]).optional(),
1745
+ schema_version: z.union([z.literal("1.4"), z.literal("1.5"), z.literal("1.6")]).optional(),
1705
1746
  }),
1706
- ])), z.union([
1747
+ ])), z.intersection(z.union([
1707
1748
  z.looseObject({
1708
1749
  failure_kind: z
1709
1750
  .union([
@@ -1712,14 +1753,33 @@ export const HistoryRecordSchema = z.intersection(z.intersection(z.intersection(
1712
1753
  z.literal("model_not_found"),
1713
1754
  z.literal("quota"),
1714
1755
  z.literal("tool_deferred"),
1756
+ z.literal("untrusted_directory"),
1757
+ z.literal("input_too_large"),
1715
1758
  z.literal(null),
1716
1759
  ])
1717
1760
  .optional(),
1718
1761
  }),
1719
1762
  z.looseObject({
1720
- schema_version: z.literal("1.5").optional(),
1763
+ schema_version: z.union([z.literal("1.5"), z.literal("1.6")]).optional(),
1721
1764
  }),
1722
- ]));
1765
+ ]), z.union([
1766
+ z.looseObject({
1767
+ failure_kind: z
1768
+ .union([
1769
+ z.literal("auth"),
1770
+ z.literal("rate_limit"),
1771
+ z.literal("model_not_found"),
1772
+ z.literal("quota"),
1773
+ z.literal("session_not_found"),
1774
+ z.literal("tool_deferred"),
1775
+ z.literal(null),
1776
+ ])
1777
+ .optional(),
1778
+ }),
1779
+ z.looseObject({
1780
+ schema_version: z.literal("1.6").optional(),
1781
+ }),
1782
+ ])));
1723
1783
  export const HistoryRecordsSchema = z.array(z.lazy(() => HistoryRecordSchema));
1724
1784
  export const HistorySessionSummarySchema = z.looseObject({
1725
1785
  harnesses: z.array(z.string()).refine((value) => value !== undefined, { message: "Required" }),
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ import type { SyncOptions } from "./generated/sync-options.js";
25
25
  import type { SyncReport } from "./generated/sync-report.js";
26
26
  import type { UsageOptions } from "./generated/usage-options.js";
27
27
  import type { UsageReport } from "./generated/usage-report.js";
28
- export type { Capability, CapabilityMethod, FlagKind, OptionBinding, StdoutShape, } from "./generated/capabilities.js";
28
+ export type { Capability, CapabilityMethod, FlagKind, OptionBinding, StdoutShape, UnlessResolution, } from "./generated/capabilities.js";
29
29
  export { CAPABILITIES } from "./generated/capabilities.js";
30
30
  export type { ConfigOptions } from "./generated/config-options.js";
31
31
  export type { ConfigReport } from "./generated/config-report.js";
package/dist/index.js CHANGED
@@ -213,6 +213,23 @@ function rendersArgument(binding, value) {
213
213
  return true;
214
214
  }
215
215
  }
216
+ /**
217
+ * Does this value assert something, or merely occupy the key?
218
+ *
219
+ * Suppression asks whether a binding renders; refusing asks something narrower,
220
+ * because a contradiction takes two positive answers. An empty value is not one.
221
+ * `{system: ""}` does render `--system ""` — which is why it still suppresses the
222
+ * `--system-file` clap refuses beside it — but an empty system prompt asks for
223
+ * nothing, so a file beside it is a defaulted key next to a real choice rather
224
+ * than a caller asking for two different things.
225
+ */
226
+ function statesAChoice(binding, value) {
227
+ if (!rendersArgument(binding, value))
228
+ return false;
229
+ if (binding.kind === "value" || binding.kind === "positional")
230
+ return String(value) !== "";
231
+ return true;
232
+ }
216
233
  /**
217
234
  * Render one capability's argv from its declared bindings.
218
235
  *
@@ -239,8 +256,23 @@ function capabilityArguments(method, options) {
239
256
  // that an `unless` always resolves here, so a missing entry is unreachable
240
257
  // rather than a case to render through.
241
258
  const suppressor = binding.unless === null ? null : bound.get(binding.unless);
242
- if (suppressor && rendersArgument(suppressor, input[suppressor.option]))
259
+ if (suppressor && rendersArgument(suppressor, input[suppressor.option])) {
260
+ // What both halves asserting means is the manifest's question, not this
261
+ // client's: `prefer` is a request with one meaning (`{session, last:
262
+ // true}` is "the most recent"), `refuse` is a caller who asked for two
263
+ // different things. Editing the second one out picks an answer silently,
264
+ // which is how a turn gets billed to a harness nobody selected. So
265
+ // `prefer` is the only waiver, and everything else refuses: an absent
266
+ // annotation (a manifest older than the key) and a resolution added after
267
+ // this client shipped both read as the recoverable half, because a
268
+ // refusal the manifest meant to resolve is a message the caller can act
269
+ // on and the reverse is not.
270
+ if ((binding.unless_resolution ?? "refuse") !== "prefer" &&
271
+ statesAChoice(binding, input[binding.option]) &&
272
+ statesAChoice(suppressor, input[suppressor.option]))
273
+ throw new Error(`invalid oneharness ${capability.argv.join(" ")} options: \`${binding.option}\` and \`${suppressor.option}\` are mutually exclusive, and this call sets both to values the CLI would send. Pass only the one you mean — resolving it here would run the call as something you did not ask for.`);
243
274
  continue;
275
+ }
244
276
  const value = input[binding.option];
245
277
  if (value === undefined || value === null)
246
278
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneharness/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.10.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.8.0",
22
+ "oneharness-cli": "0.10.0",
23
23
  "zod": "^4.4.3"
24
24
  }
25
25
  }