@zhivex-ai/harness 1.2.0 → 1.3.0-rc.3

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +7 -8
  3. package/contracts/engine-api.json +2587 -0
  4. package/dist/acp-cli.js +95 -14996
  5. package/dist/cli/cli-options.d.ts +2 -41
  6. package/dist/cli/cli-stream.d.ts +2 -167
  7. package/dist/cli/run-document.d.ts +2 -91
  8. package/dist/cli/terminal/terminal-continuation.d.ts +2 -3
  9. package/dist/{cli-entry-427869g9.js → cli-entry-0mmeag20.js} +49 -1
  10. package/dist/{cli-entry-b1mfvmxe.js → cli-entry-7h9savv5.js} +1 -2
  11. package/dist/{cli-entry-c2f58zj2.js → cli-entry-xmf48p6a.js} +27 -18
  12. package/dist/{cli-3jmy4h5h.js → cli-qgwvtk0w.js} +5 -6
  13. package/dist/cli.js +2 -2
  14. package/dist/client/continuation.d.ts +3 -0
  15. package/dist/client/run-document.d.ts +91 -0
  16. package/dist/client/stream.d.ts +167 -0
  17. package/dist/compat/cli-options.d.ts +41 -0
  18. package/dist/compat/code-support.d.ts +22 -0
  19. package/dist/compat/code-support.js +138 -0
  20. package/dist/config-6gtpxvjv.js +59 -0
  21. package/dist/{config-1k9t4jhh.js → config-q32jm1e6.js} +1 -1
  22. package/dist/engine/acp.d.ts +4 -0
  23. package/dist/engine/acp.js +9 -0
  24. package/dist/engine/client.d.ts +6 -0
  25. package/dist/engine/client.js +21 -0
  26. package/dist/engine/index.d.ts +61 -0
  27. package/dist/engine/index.js +477 -0
  28. package/dist/engine/protocol.d.ts +6 -0
  29. package/dist/engine/protocol.js +158 -0
  30. package/dist/engine/service.d.ts +5 -0
  31. package/dist/engine/service.js +21 -0
  32. package/dist/hostile-repository-demo.js +59 -1
  33. package/dist/index-1bx83sw4.js +4 -0
  34. package/dist/index-2aymdsqc.js +150 -0
  35. package/dist/index-41fkzt91.js +293 -0
  36. package/dist/index-5wjwe91x.js +9434 -0
  37. package/dist/index-77h9qr5h.js +326 -0
  38. package/dist/index-d0wrghff.js +3271 -0
  39. package/dist/index-f4sb0e2q.js +318 -0
  40. package/dist/index-fvca1xea.js +2069 -0
  41. package/dist/index-kfgt9yqq.js +526 -0
  42. package/dist/index-pgqz45fj.js +2449 -0
  43. package/dist/index.js +238 -18649
  44. package/dist/service-cli.js +10 -14502
  45. package/dist/{service-client-cli-yx56n0hc.js → service-client-cli-gs78wrxe.js} +2 -2
  46. package/dist/verify-historical-migrations.js +59 -1
  47. package/dist/zhx.js +2 -2
  48. package/docs/CODE_RELEASE.md +93 -0
  49. package/docs/ENGINE_API.md +111 -0
  50. package/docs/FIRST_USE.md +6 -6
  51. package/docs/README.md +5 -0
  52. package/docs/STABILITY.md +6 -0
  53. package/evaluations/representative-assembly-matrix.json +28 -1
  54. package/examples/README.md +1 -1
  55. package/package.json +35 -4
@@ -0,0 +1,158 @@
1
+ // src/client/protocol.ts
2
+ import { z } from "zod";
3
+ var HARNESS_CLIENT_PROTOCOL_VERSION = 1;
4
+ var id = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/);
5
+ var revision = z.number().int().nonnegative().safe();
6
+ var scoped = { projectId: id };
7
+ var session = { ...scoped, sessionId: id };
8
+ var run = { ...session, runId: id };
9
+ var mutation = { idempotencyKey: id };
10
+ var harnessClientCommandSchema = z.discriminatedUnion("method", [
11
+ z.object({ method: z.literal("project.get"), ...scoped }).strict(),
12
+ z.object({ method: z.literal("session.list"), ...scoped, search: z.string().max(256).optional() }).strict(),
13
+ z.object({ method: z.literal("session.create"), ...scoped, ...mutation, title: z.string().max(256).optional() }).strict(),
14
+ z.object({ method: z.literal("session.get"), ...session }).strict(),
15
+ z.object({ method: z.literal("session.rename"), ...session, ...mutation, expectedRevision: revision, title: z.string().max(256) }).strict(),
16
+ z.object({ method: z.literal("run.start"), ...session, ...mutation, expectedRevision: revision, prompt: z.string().min(1).max(64 * 1024) }).strict(),
17
+ z.object({ method: z.literal("run.get"), ...run, includeReview: z.boolean().optional(), includeDiff: z.boolean().optional(), decisionOffset: z.number().int().min(0).max(512).optional() }).strict(),
18
+ z.object({
19
+ method: z.literal("approval.resolve"),
20
+ ...run,
21
+ ...mutation,
22
+ expectedRevision: revision,
23
+ decisions: z.array(z.object({ approvalId: z.string().min(1).max(256), digest: z.string().regex(/^[a-f0-9]{64}$/), approve: z.boolean() }).strict()).min(1).max(64)
24
+ }).strict(),
25
+ z.object({ method: z.literal("run.cancel"), ...run, ...mutation, expectedRevision: revision }).strict()
26
+ ]);
27
+ var harnessClientRequestSchema = z.object({
28
+ protocolVersion: z.literal(HARNESS_CLIENT_PROTOCOL_VERSION),
29
+ requestId: id,
30
+ connectionId: id,
31
+ command: harnessClientCommandSchema
32
+ }).strict();
33
+ // src/client/stream.ts
34
+ var CLI_JSON_SCHEMA_VERSION = 1;
35
+ var CLI_EVENT_SCHEMA_VERSION = 1;
36
+ var streamEventDocument = (event, sequence = 0) => {
37
+ if (!Number.isSafeInteger(sequence) || sequence < 0) {
38
+ throw new Error("JSONL event sequence must be a non-negative integer.");
39
+ }
40
+ const base = {
41
+ schemaVersion: CLI_EVENT_SCHEMA_VERSION,
42
+ kind: "run-event",
43
+ sequence,
44
+ type: event.type
45
+ };
46
+ switch (event.type) {
47
+ case "text-delta":
48
+ return { ...base, textDelta: event.textDelta };
49
+ case "tool-call":
50
+ return { ...base, toolCallId: event.toolCall.id, toolName: event.toolCall.name };
51
+ case "tool-result":
52
+ return {
53
+ ...base,
54
+ toolCallId: event.toolResult.toolCallId,
55
+ toolName: event.toolResult.toolName,
56
+ isError: event.toolResult.isError
57
+ };
58
+ case "tool-approval-request":
59
+ case "agent-approval-request":
60
+ return {
61
+ ...base,
62
+ approvalRequestId: event.approval.id,
63
+ approvalKind: event.approval.kind ?? "provider",
64
+ toolName: event.approval.name
65
+ };
66
+ case "agent-approval-resolved":
67
+ return {
68
+ ...base,
69
+ approvalRequestId: event.approval.approvalRequestId,
70
+ approved: event.approval.approve
71
+ };
72
+ case "provider-data":
73
+ return { ...base, provider: event.provider };
74
+ case "image-generation":
75
+ return {
76
+ ...base,
77
+ provider: event.provider,
78
+ partial: event.partial,
79
+ ...event.id ? { id: event.id } : {},
80
+ ...event.index !== undefined ? { index: event.index } : {}
81
+ };
82
+ case "finish":
83
+ return {
84
+ ...base,
85
+ ...event.finishReason ? { finishReason: event.finishReason } : {},
86
+ ...event.usage ? { usage: event.usage } : {}
87
+ };
88
+ case "error":
89
+ return { ...base, error: "Provider stream failed." };
90
+ case "agent-run-start":
91
+ return { ...base, currentStep: event.currentStep, maxSteps: event.maxSteps };
92
+ case "agent-step-start":
93
+ return { ...base, stepIndex: event.stepIndex };
94
+ case "agent-step-finish":
95
+ return {
96
+ ...base,
97
+ stepIndex: event.step.index,
98
+ status: event.step.status,
99
+ toolCalls: event.step.toolResults.length
100
+ };
101
+ case "agent-compaction":
102
+ return {
103
+ ...base,
104
+ compactionId: event.compaction.id,
105
+ reasons: event.compaction.reasons,
106
+ messageCountBefore: event.compaction.messageCountBefore,
107
+ messageCountAfter: event.compaction.messageCountAfter
108
+ };
109
+ case "agent-run-finish":
110
+ return {
111
+ ...base,
112
+ runId: event.state.runId,
113
+ status: event.status,
114
+ provider: event.state.provider,
115
+ model: event.state.modelId
116
+ };
117
+ }
118
+ };
119
+ var serializeStreamEvent = (event, sequence = 0) => JSON.stringify(streamEventDocument(event, sequence));
120
+ var streamResultDocument = (result, sequence = 0) => {
121
+ if (!Number.isSafeInteger(sequence) || sequence < 0) {
122
+ throw new Error("JSONL result sequence must be a non-negative integer.");
123
+ }
124
+ return {
125
+ schemaVersion: CLI_EVENT_SCHEMA_VERSION,
126
+ kind: "run-stream-result",
127
+ sequence,
128
+ runId: result.runId,
129
+ status: result.status,
130
+ provider: result.provider,
131
+ model: result.model,
132
+ steps: result.steps,
133
+ toolCalls: result.toolCalls,
134
+ pendingApprovals: (result.pendingApprovals ?? []).map((approval) => ({
135
+ id: approval.id,
136
+ kind: approval.kind,
137
+ name: approval.name,
138
+ ...approval.childRunId ? { childRunId: approval.childRunId } : {},
139
+ ...approval.childAgentId ? { childAgentId: approval.childAgentId } : {}
140
+ })),
141
+ children: (result.children ?? []).map((child) => ({
142
+ runId: child.runId,
143
+ status: child.status
144
+ }))
145
+ };
146
+ };
147
+ var serializeStreamResult = (result, sequence = 0) => JSON.stringify(streamResultDocument(result, sequence));
148
+ export {
149
+ CLI_EVENT_SCHEMA_VERSION,
150
+ CLI_JSON_SCHEMA_VERSION,
151
+ HARNESS_CLIENT_PROTOCOL_VERSION,
152
+ harnessClientCommandSchema,
153
+ harnessClientRequestSchema,
154
+ serializeStreamEvent,
155
+ serializeStreamResult,
156
+ streamEventDocument,
157
+ streamResultDocument
158
+ };
@@ -0,0 +1,5 @@
1
+ /** Explicit Harness integration surface. See contracts/engine-api.json for stability tiers. */
2
+ export { harnessLocalCredentialsSchema, startHarnessLocalService, readHarnessLocalCredentials, requestHarnessLocalService, recoverHarnessLocalService } from "../client/local-service.js";
3
+ export type { HarnessLocalService, HarnessLocalServiceOptions, HarnessLocalCredentials } from "../client/local-service.js";
4
+ export { openHarnessActivityStore } from "../client/service-events.js";
5
+ export type { HarnessActivityEvent, HarnessActivityRun, HarnessActivitySnapshot, HarnessActivityPage, HarnessActivityStore, HarnessActivityOptions } from "../client/service-events.js";
@@ -0,0 +1,21 @@
1
+ import {
2
+ harnessLocalCredentialsSchema,
3
+ openHarnessActivityStore,
4
+ readHarnessLocalCredentials,
5
+ recoverHarnessLocalService,
6
+ requestHarnessLocalService,
7
+ startHarnessLocalService
8
+ } from "../index-kfgt9yqq.js";
9
+ import"../index-5wjwe91x.js";
10
+ import"../index-pgqz45fj.js";
11
+ import"../index-fvca1xea.js";
12
+ import"../index-2aymdsqc.js";
13
+ import"../index-1bx83sw4.js";
14
+ export {
15
+ harnessLocalCredentialsSchema,
16
+ openHarnessActivityStore,
17
+ readHarnessLocalCredentials,
18
+ recoverHarnessLocalService,
19
+ requestHarnessLocalService,
20
+ startHarnessLocalService
21
+ };
@@ -108,6 +108,7 @@ var createMetaContinuationFetch = (fetcher = fetch, backoff = [1000, 2000]) => {
108
108
 
109
109
  // src/providers/meta-replay.ts
110
110
  import { wrapLanguageModel as wrapLanguageModel2 } from "@zhivex-ai/core";
111
+ import { withTimeoutSignal } from "@zhivex-ai/core/provider";
111
112
  import { createMeta } from "@zhivex-ai/meta";
112
113
  var replayPlan = (messages) => {
113
114
  let offset = 0;
@@ -181,7 +182,54 @@ var createMetaReplayModel = (options, modelId) => {
181
182
  },
182
183
  async wrapStream({ input }) {
183
184
  const prepared = prepare(input);
184
- return prepared.model.stream(prepared.input);
185
+ const lifetime = withTimeoutSignal(prepared.input);
186
+ const { timeoutMs: _timeout, ...request } = prepared.input;
187
+ try {
188
+ const stream = await prepared.model.stream({ ...request, abortSignal: lifetime.signal });
189
+ const iterator = stream[Symbol.asyncIterator]();
190
+ const owned = {
191
+ [Symbol.asyncIterator]() {
192
+ return owned;
193
+ },
194
+ async next() {
195
+ try {
196
+ const result = await iterator.next();
197
+ if (result.done)
198
+ lifetime.cleanup();
199
+ return result;
200
+ } catch (error) {
201
+ lifetime.cleanup();
202
+ throw error;
203
+ }
204
+ },
205
+ async return() {
206
+ try {
207
+ return await iterator.return?.() ?? { done: true, value: undefined };
208
+ } finally {
209
+ lifetime.cleanup();
210
+ }
211
+ },
212
+ async throw(error) {
213
+ try {
214
+ if (iterator.throw) {
215
+ const result = await iterator.throw(error);
216
+ if (result.done)
217
+ lifetime.cleanup();
218
+ return result;
219
+ }
220
+ await iterator.return?.();
221
+ throw error;
222
+ } catch (failure) {
223
+ lifetime.cleanup();
224
+ throw failure;
225
+ }
226
+ }
227
+ };
228
+ return owned;
229
+ } catch (error) {
230
+ lifetime.cleanup();
231
+ throw error;
232
+ }
185
233
  }
186
234
  }]);
187
235
  };
@@ -2447,6 +2495,16 @@ var editProposalSchema = z3.strictObject({
2447
2495
  var applyEditProposalInputSchema = z3.strictObject({
2448
2496
  proposalId: fileDigestSchema,
2449
2497
  changes: editChangesSchema
2498
+ }).superRefine((input, context) => {
2499
+ if (!editProposalInputSchema.safeParse({ changes: input.changes }).success)
2500
+ return;
2501
+ if (createEditProposal({ changes: input.changes }).proposalId !== input.proposalId) {
2502
+ context.addIssue({
2503
+ code: "custom",
2504
+ path: ["proposalId"],
2505
+ message: "proposalId does not match the supplied paths, preconditions, and content. Read proposalId from the matching propose_edits result; do not invent it."
2506
+ });
2507
+ }
2450
2508
  });
2451
2509
  var moveFileInputSchema = z3.strictObject({
2452
2510
  source: workspaceFilePathSchema,
@@ -0,0 +1,4 @@
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
+
4
+ export { __require };
@@ -0,0 +1,150 @@
1
+ // src/client/stream.ts
2
+ var CLI_JSON_SCHEMA_VERSION = 1;
3
+ var CLI_EVENT_SCHEMA_VERSION = 1;
4
+ var streamEventDocument = (event, sequence = 0) => {
5
+ if (!Number.isSafeInteger(sequence) || sequence < 0) {
6
+ throw new Error("JSONL event sequence must be a non-negative integer.");
7
+ }
8
+ const base = {
9
+ schemaVersion: CLI_EVENT_SCHEMA_VERSION,
10
+ kind: "run-event",
11
+ sequence,
12
+ type: event.type
13
+ };
14
+ switch (event.type) {
15
+ case "text-delta":
16
+ return { ...base, textDelta: event.textDelta };
17
+ case "tool-call":
18
+ return { ...base, toolCallId: event.toolCall.id, toolName: event.toolCall.name };
19
+ case "tool-result":
20
+ return {
21
+ ...base,
22
+ toolCallId: event.toolResult.toolCallId,
23
+ toolName: event.toolResult.toolName,
24
+ isError: event.toolResult.isError
25
+ };
26
+ case "tool-approval-request":
27
+ case "agent-approval-request":
28
+ return {
29
+ ...base,
30
+ approvalRequestId: event.approval.id,
31
+ approvalKind: event.approval.kind ?? "provider",
32
+ toolName: event.approval.name
33
+ };
34
+ case "agent-approval-resolved":
35
+ return {
36
+ ...base,
37
+ approvalRequestId: event.approval.approvalRequestId,
38
+ approved: event.approval.approve
39
+ };
40
+ case "provider-data":
41
+ return { ...base, provider: event.provider };
42
+ case "image-generation":
43
+ return {
44
+ ...base,
45
+ provider: event.provider,
46
+ partial: event.partial,
47
+ ...event.id ? { id: event.id } : {},
48
+ ...event.index !== undefined ? { index: event.index } : {}
49
+ };
50
+ case "finish":
51
+ return {
52
+ ...base,
53
+ ...event.finishReason ? { finishReason: event.finishReason } : {},
54
+ ...event.usage ? { usage: event.usage } : {}
55
+ };
56
+ case "error":
57
+ return { ...base, error: "Provider stream failed." };
58
+ case "agent-run-start":
59
+ return { ...base, currentStep: event.currentStep, maxSteps: event.maxSteps };
60
+ case "agent-step-start":
61
+ return { ...base, stepIndex: event.stepIndex };
62
+ case "agent-step-finish":
63
+ return {
64
+ ...base,
65
+ stepIndex: event.step.index,
66
+ status: event.step.status,
67
+ toolCalls: event.step.toolResults.length
68
+ };
69
+ case "agent-compaction":
70
+ return {
71
+ ...base,
72
+ compactionId: event.compaction.id,
73
+ reasons: event.compaction.reasons,
74
+ messageCountBefore: event.compaction.messageCountBefore,
75
+ messageCountAfter: event.compaction.messageCountAfter
76
+ };
77
+ case "agent-run-finish":
78
+ return {
79
+ ...base,
80
+ runId: event.state.runId,
81
+ status: event.status,
82
+ provider: event.state.provider,
83
+ model: event.state.modelId
84
+ };
85
+ }
86
+ };
87
+ var serializeStreamEvent = (event, sequence = 0) => JSON.stringify(streamEventDocument(event, sequence));
88
+ var streamResultDocument = (result, sequence = 0) => {
89
+ if (!Number.isSafeInteger(sequence) || sequence < 0) {
90
+ throw new Error("JSONL result sequence must be a non-negative integer.");
91
+ }
92
+ return {
93
+ schemaVersion: CLI_EVENT_SCHEMA_VERSION,
94
+ kind: "run-stream-result",
95
+ sequence,
96
+ runId: result.runId,
97
+ status: result.status,
98
+ provider: result.provider,
99
+ model: result.model,
100
+ steps: result.steps,
101
+ toolCalls: result.toolCalls,
102
+ pendingApprovals: (result.pendingApprovals ?? []).map((approval) => ({
103
+ id: approval.id,
104
+ kind: approval.kind,
105
+ name: approval.name,
106
+ ...approval.childRunId ? { childRunId: approval.childRunId } : {},
107
+ ...approval.childAgentId ? { childAgentId: approval.childAgentId } : {}
108
+ })),
109
+ children: (result.children ?? []).map((child) => ({
110
+ runId: child.runId,
111
+ status: child.status
112
+ }))
113
+ };
114
+ };
115
+ var serializeStreamResult = (result, sequence = 0) => JSON.stringify(streamResultDocument(result, sequence));
116
+
117
+ // src/client/protocol.ts
118
+ import { z } from "zod";
119
+ var HARNESS_CLIENT_PROTOCOL_VERSION = 1;
120
+ var id = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/);
121
+ var revision = z.number().int().nonnegative().safe();
122
+ var scoped = { projectId: id };
123
+ var session = { ...scoped, sessionId: id };
124
+ var run = { ...session, runId: id };
125
+ var mutation = { idempotencyKey: id };
126
+ var harnessClientCommandSchema = z.discriminatedUnion("method", [
127
+ z.object({ method: z.literal("project.get"), ...scoped }).strict(),
128
+ z.object({ method: z.literal("session.list"), ...scoped, search: z.string().max(256).optional() }).strict(),
129
+ z.object({ method: z.literal("session.create"), ...scoped, ...mutation, title: z.string().max(256).optional() }).strict(),
130
+ z.object({ method: z.literal("session.get"), ...session }).strict(),
131
+ z.object({ method: z.literal("session.rename"), ...session, ...mutation, expectedRevision: revision, title: z.string().max(256) }).strict(),
132
+ z.object({ method: z.literal("run.start"), ...session, ...mutation, expectedRevision: revision, prompt: z.string().min(1).max(64 * 1024) }).strict(),
133
+ z.object({ method: z.literal("run.get"), ...run, includeReview: z.boolean().optional(), includeDiff: z.boolean().optional(), decisionOffset: z.number().int().min(0).max(512).optional() }).strict(),
134
+ z.object({
135
+ method: z.literal("approval.resolve"),
136
+ ...run,
137
+ ...mutation,
138
+ expectedRevision: revision,
139
+ decisions: z.array(z.object({ approvalId: z.string().min(1).max(256), digest: z.string().regex(/^[a-f0-9]{64}$/), approve: z.boolean() }).strict()).min(1).max(64)
140
+ }).strict(),
141
+ z.object({ method: z.literal("run.cancel"), ...run, ...mutation, expectedRevision: revision }).strict()
142
+ ]);
143
+ var harnessClientRequestSchema = z.object({
144
+ protocolVersion: z.literal(HARNESS_CLIENT_PROTOCOL_VERSION),
145
+ requestId: id,
146
+ connectionId: id,
147
+ command: harnessClientCommandSchema
148
+ }).strict();
149
+
150
+ export { CLI_JSON_SCHEMA_VERSION, CLI_EVENT_SCHEMA_VERSION, streamEventDocument, serializeStreamEvent, streamResultDocument, serializeStreamResult, HARNESS_CLIENT_PROTOCOL_VERSION, harnessClientCommandSchema, harnessClientRequestSchema };