@codeworksh/cli 0.3.0 → 0.4.0-canary.52.1.ge7df22a4

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 (66) hide show
  1. package/{acp-XRYX2dyw.mjs → acp-BPiMP9SV.mjs} +3 -3
  2. package/{acp-XRYX2dyw.mjs.map → acp-BPiMP9SV.mjs.map} +1 -1
  3. package/{add-Cih66f0Z.mjs → add-Dzsv-fKd.mjs} +3 -3
  4. package/{add-Cih66f0Z.mjs.map → add-Dzsv-fKd.mjs.map} +1 -1
  5. package/{check-CWXDjuC1.mjs → check-DhojkK_E.mjs} +3 -3
  6. package/{check-CWXDjuC1.mjs.map → check-DhojkK_E.mjs.map} +1 -1
  7. package/{entries-8LFGwy4n.mjs → entries-KpYvZdpi.mjs} +3 -3
  8. package/{entries-8LFGwy4n.mjs.map → entries-KpYvZdpi.mjs.map} +1 -1
  9. package/{error-CzUxh0Q9.mjs → error-BMI81XvR.mjs} +226 -7
  10. package/error-BMI81XvR.mjs.map +1 -0
  11. package/{identity-CSj_73kP.mjs → identity-Dl0hQHgK.mjs} +2 -2
  12. package/{identity-CSj_73kP.mjs.map → identity-Dl0hQHgK.mjs.map} +1 -1
  13. package/index.mjs +24 -24
  14. package/{install-CRGaL_bc.mjs → install-BLRDBzp1.mjs} +3 -3
  15. package/{install-CRGaL_bc.mjs.map → install-BLRDBzp1.mjs.map} +1 -1
  16. package/{link-BiwLQTXW.mjs → link--UnM2qnT.mjs} +2 -2
  17. package/{link-BiwLQTXW.mjs.map → link--UnM2qnT.mjs.map} +1 -1
  18. package/{list-BvBVZtHt.mjs → list-9fVqelid.mjs} +2 -2
  19. package/{list-BvBVZtHt.mjs.map → list-9fVqelid.mjs.map} +1 -1
  20. package/{list-Daq_zh4E.mjs → list-BE4xSEe3.mjs} +3 -3
  21. package/{list-Daq_zh4E.mjs.map → list-BE4xSEe3.mjs.map} +1 -1
  22. package/{login-lsagcqp6.mjs → login-CRwxi5WD.mjs} +3 -3
  23. package/{login-lsagcqp6.mjs.map → login-CRwxi5WD.mjs.map} +1 -1
  24. package/{logout-DdkYEWM6.mjs → logout-C89X0B9M.mjs} +3 -3
  25. package/{logout-DdkYEWM6.mjs.map → logout-C89X0B9M.mjs.map} +1 -1
  26. package/package-Biq8oAF2.mjs +6 -0
  27. package/package-Biq8oAF2.mjs.map +1 -0
  28. package/package.json +7 -6
  29. package/{providers-CZmPKpb_.mjs → providers-BrXJvY2P.mjs} +2 -2
  30. package/{providers-CZmPKpb_.mjs.map → providers-BrXJvY2P.mjs.map} +1 -1
  31. package/{refresh-BFxZjrH1.mjs → refresh--j0Pj4Cw.mjs} +2 -2
  32. package/{refresh-BFxZjrH1.mjs.map → refresh--j0Pj4Cw.mjs.map} +1 -1
  33. package/{refresh-Cbq-iY3f.mjs → refresh-D0wBP2Go.mjs} +3 -3
  34. package/{refresh-Cbq-iY3f.mjs.map → refresh-D0wBP2Go.mjs.map} +1 -1
  35. package/{reload-C6c48hBY.mjs → reload-DgPawyzr.mjs} +2 -2
  36. package/{reload-C6c48hBY.mjs.map → reload-DgPawyzr.mjs.map} +1 -1
  37. package/{remove-lig66J-D.mjs → remove-DfFme5w2.mjs} +3 -3
  38. package/{remove-lig66J-D.mjs.map → remove-DfFme5w2.mjs.map} +1 -1
  39. package/{restart-C0FtXDtK.mjs → restart-D3QLTXxy.mjs} +3 -3
  40. package/{restart-C0FtXDtK.mjs.map → restart-D3QLTXxy.mjs.map} +1 -1
  41. package/{run-DIFNYGN-.mjs → run-CVRkm_Iz.mjs} +3 -3
  42. package/{run-DIFNYGN-.mjs.map → run-CVRkm_Iz.mjs.map} +1 -1
  43. package/{serve-jhJP26fG.mjs → serve-D2BTAZpR.mjs} +108 -8
  44. package/serve-D2BTAZpR.mjs.map +1 -0
  45. package/{service-BP8Y1n1R.mjs → service-BI_FL26Q.mjs} +3 -3
  46. package/{service-BP8Y1n1R.mjs.map → service-BI_FL26Q.mjs.map} +1 -1
  47. package/{settings-BM_gw7Fm.mjs → settings-BfmoL27m.mjs} +2 -2
  48. package/{settings-BM_gw7Fm.mjs.map → settings-BfmoL27m.mjs.map} +1 -1
  49. package/{shared-wNZoC017.mjs → shared-CnuCjvcG.mjs} +2 -2
  50. package/{shared-wNZoC017.mjs.map → shared-CnuCjvcG.mjs.map} +1 -1
  51. package/{start-BBGmLmro.mjs → start-Bkk-Y6yE.mjs} +3 -3
  52. package/{start-BBGmLmro.mjs.map → start-Bkk-Y6yE.mjs.map} +1 -1
  53. package/{status-BmpmqhUX.mjs → status-BhkBSKLd.mjs} +3 -3
  54. package/{status-BmpmqhUX.mjs.map → status-BhkBSKLd.mjs.map} +1 -1
  55. package/{status-CQHqU7_7.mjs → status-DVzFDoek.mjs} +3 -3
  56. package/{status-CQHqU7_7.mjs.map → status-DVzFDoek.mjs.map} +1 -1
  57. package/{stop-DHzqbCeB.mjs → stop-COTZBIML.mjs} +3 -3
  58. package/{stop-DHzqbCeB.mjs.map → stop-COTZBIML.mjs.map} +1 -1
  59. package/{tui-BGZPK8sC.mjs → tui-Bk0VBJIB.mjs} +4 -4
  60. package/{tui-BGZPK8sC.mjs.map → tui-Bk0VBJIB.mjs.map} +1 -1
  61. package/{update-CfrkcWoW.mjs → update-D0XPVfJu.mjs} +3 -3
  62. package/{update-CfrkcWoW.mjs.map → update-D0XPVfJu.mjs.map} +1 -1
  63. package/error-CzUxh0Q9.mjs.map +0 -1
  64. package/package-DyEUYkEq.mjs +0 -6
  65. package/package-DyEUYkEq.mjs.map +0 -1
  66. package/serve-jhJP26fG.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { Deferred, Duration, Effect, Layer, Predicate, Schema, Stream } from "effect";
2
2
  import { Model } from "@codeworksh/aikit";
3
- import { Control, Event, EventList, EventSchema, Location, ModelCatalog, Plugin, PromptSchema, Runner, Sandbox, SandboxError, Session, SessionStore, Settings, optional } from "@codeworksh/harness/effect";
3
+ import { Control, Event, EventList, EventSchema, Location, ModelCatalog, Plugin, Project, PromptSchema, Runner, Sandbox, SandboxError, Session, SessionStore, Settings, optional } from "@codeworksh/harness/effect";
4
4
  import { SandboxProvider } from "@codeworksh/harness/sandbox";
5
5
  import { NodeSocket } from "@effect/platform-node";
6
6
  import { Rpc, RpcClient, RpcGroup, RpcSerialization } from "effect/rpc";
@@ -55,7 +55,7 @@ const encode = Effect.fn("Envelope.encode")(function* (payload, registry = Core)
55
55
  data
56
56
  };
57
57
  });
58
- const decode = Effect.fn("Envelope.decode")(function* (envelope, registry = Core) {
58
+ const decode$1 = Effect.fn("Envelope.decode")(function* (envelope, registry = Core) {
59
59
  const definition = registry(envelope.type);
60
60
  if (definition === void 0) return yield* new UnknownEventTypeError({ type: envelope.type });
61
61
  const data = yield* Schema.decodeEffect(definition.data)(envelope.data);
@@ -68,6 +68,58 @@ const decode = Effect.fn("Envelope.decode")(function* (envelope, registry = Core
68
68
  };
69
69
  });
70
70
  //#endregion
71
+ //#region src/server/part.ts
72
+ const TextContent = Schema.Struct({
73
+ type: Schema.Literal("text"),
74
+ text: Schema.String
75
+ });
76
+ const ImageContent = Schema.Struct({
77
+ type: Schema.Literal("image"),
78
+ data: Schema.String,
79
+ mimeType: Schema.String
80
+ });
81
+ const ThinkingContent = Schema.Struct({
82
+ type: Schema.Literal("thinking"),
83
+ thinking: Schema.String,
84
+ /** The provider withheld the reasoning; `thinking` is then empty. */
85
+ redacted: Schema.optionalKey(Schema.Boolean)
86
+ });
87
+ /** aikit's ToolStatusEnum. */
88
+ const ToolStatus = Schema.Literals([
89
+ "pending",
90
+ "running",
91
+ "completed",
92
+ "error",
93
+ "skipped",
94
+ "aborted"
95
+ ]);
96
+ const ToolResult = Schema.Struct({
97
+ content: Schema.Array(Schema.Union([TextContent, ImageContent])),
98
+ isError: Schema.Boolean
99
+ });
100
+ const ToolCall = Schema.Struct({
101
+ type: Schema.Literal("toolCall"),
102
+ callID: Schema.String,
103
+ name: Schema.String,
104
+ arguments: Schema.Record(Schema.String, Schema.Json),
105
+ status: ToolStatus,
106
+ /** Present once the call settled (completed, error, skipped, aborted). */
107
+ result: Schema.optionalKey(ToolResult),
108
+ /** Epoch milliseconds: started, and last lifecycle update. */
109
+ time: Schema.optionalKey(Schema.Struct({
110
+ start: Schema.Finite,
111
+ end: Schema.Finite
112
+ }))
113
+ });
114
+ const Part = Schema.Union([
115
+ TextContent,
116
+ ImageContent,
117
+ ThinkingContent,
118
+ ToolCall
119
+ ]);
120
+ /** A stored part row's JSON, or none when it is not a part a client renders. */
121
+ const decode = Schema.decodeUnknownOption(Schema.fromJsonString(Part));
122
+ //#endregion
71
123
  //#region src/server/contract.ts
72
124
  /** The HTTP path the RPC endpoint is served on; the version moves with breaking wire changes. */
73
125
  const path = "/rpc/v1";
@@ -89,7 +141,58 @@ const SessionInfo = Schema.Struct({
89
141
  directory: Session.AbsolutePath,
90
142
  /** The host directory this session is anchored to. Absent when it has none. */
91
143
  hostDir: optional(Session.AbsolutePath),
92
- sandbox: optional(SandboxInfo)
144
+ sandbox: optional(SandboxInfo),
145
+ /** The project the session's space belongs to. */
146
+ project: optional(Schema.Struct({
147
+ id: Schema.String,
148
+ name: Schema.String
149
+ })),
150
+ /** Last activity, epoch milliseconds. */
151
+ updatedAt: Schema.Finite,
152
+ /** The model chosen for this session; absent when settings decide. */
153
+ model: optional(Schema.Struct({
154
+ provider: Schema.String,
155
+ id: Schema.String
156
+ })),
157
+ /** The thinking level chosen for this session; absent when settings decide. */
158
+ thinkingLevel: optional(Schema.Enum(Model.ThinkingLevelEnum)),
159
+ /** Its unfinished run was cut off by restarts too often to resume on its own; the next prompt runs it. */
160
+ parked: optional(Schema.Boolean)
161
+ });
162
+ /** One message on a session's active branch, oldest first. */
163
+ const HistoryEntry = Schema.Struct({
164
+ /** The entry id: what live events and `session.message` refer to. */
165
+ id: Schema.String,
166
+ /** Its place in the session's durable log; live events continue from it. */
167
+ seq: Schema.Int,
168
+ role: Schema.Literals(["user", "assistant"]),
169
+ /** `draft` is a reply still streaming; `aborted` one that was interrupted. */
170
+ state: Schema.Literals([
171
+ "committed",
172
+ "draft",
173
+ "aborted"
174
+ ]),
175
+ /** Epoch milliseconds. */
176
+ createdAt: Schema.Finite,
177
+ /** Epoch milliseconds of the last change; for a reply, when it ended once it is no longer a draft. */
178
+ updatedAt: Schema.Finite,
179
+ parts: Schema.Array(Part)
180
+ });
181
+ /** A prompt admitted but not yet in the conversation: a steer waiting for the next model request, or a follow-up for the next turn. */
182
+ const QueuedPrompt = Schema.Struct({
183
+ /** The id of the user message it becomes once promoted. */
184
+ id: Schema.String,
185
+ delivery: PromptSchema.Delivery,
186
+ text: Schema.String,
187
+ /** Epoch milliseconds. */
188
+ createdAt: Schema.Finite
189
+ });
190
+ /** Ends `session.log`'s replay; `seq` is absent when the session has no durable events yet. */
191
+ const LogSynced = Schema.Struct({
192
+ type: Schema.Literal("log.synced"),
193
+ /** The session the log was read for. */
194
+ aggregateId: Schema.String,
195
+ seq: optional(Schema.Int)
93
196
  });
94
197
  const RuntimeConfig = Schema.Struct({
95
198
  model: optional(Schema.Struct({
@@ -99,6 +202,21 @@ const RuntimeConfig = Schema.Struct({
99
202
  thinkingLevel: optional(Schema.Enum(Model.ThinkingLevelEnum))
100
203
  });
101
204
  const SandboxRef = Sandbox.Selection;
205
+ /** A model to choose, by the catalog's id and display name, with the thinking levels it supports. */
206
+ const ModelOption = Schema.Struct({
207
+ id: Schema.String,
208
+ name: Schema.String,
209
+ /** In ascending order; `["off"]` for a model that does not reason. */
210
+ thinkingLevels: Schema.Array(Schema.Enum(Model.ThinkingLevelEnum))
211
+ });
212
+ /** A provider this server can call, with the models a session may use from it. */
213
+ const ModelProvider = Schema.Struct({
214
+ id: Schema.String,
215
+ name: Schema.String,
216
+ models: Schema.Array(ModelOption)
217
+ });
218
+ /** A project's name as a client sets it: trimmed, never empty. */
219
+ const ProjectName = Schema.Trimmed.check(Schema.isNonEmpty());
102
220
  var OAuthError$1 = class extends Schema.TaggedError()("Server.OAuthError", { message: Schema.String }) {};
103
221
  /** OAuth providers whose credentials this server stores. */
104
222
  const OAuthProvider = Schema.Literals(["openai-codex", "github-copilot"]);
@@ -200,7 +318,12 @@ const Api = RpcGroup.make(
200
318
  */
201
319
  hostDir: optional(Session.AbsolutePath),
202
320
  sandbox: optional(SandboxRef),
203
- runtime: optional(RuntimeConfig)
321
+ runtime: optional(RuntimeConfig),
322
+ /**
323
+ * Names the project when this session creates it, ahead of the repository's and the
324
+ * folder's name. A project that already exists keeps its name; `project.rename` changes it.
325
+ */
326
+ project: optional(Schema.Struct({ name: ProjectName }))
204
327
  },
205
328
  success: SessionInfo,
206
329
  error: Schema.Union([
@@ -209,10 +332,79 @@ const Api = RpcGroup.make(
209
332
  LocationErrors
210
333
  ])
211
334
  }),
335
+ Rpc.make("project.rename", {
336
+ payload: {
337
+ projectId: Schema.String,
338
+ name: ProjectName
339
+ },
340
+ success: Schema.Struct({
341
+ id: Schema.String,
342
+ name: Schema.String
343
+ }),
344
+ error: Project.ProjectNotFoundError
345
+ }),
346
+ /**
347
+ * The models a session anchored at `hostDir` can use: providers this server holds credentials
348
+ * for, in the catalog plus that project's settings, and the model settings pick when a session
349
+ * names none. Without `hostDir`, only the user's settings apply. Credentials are checked for
350
+ * presence, not validity.
351
+ */
352
+ Rpc.make("model.list", {
353
+ payload: { hostDir: optional(Session.AbsolutePath) },
354
+ success: Schema.Struct({
355
+ providers: Schema.Array(ModelProvider),
356
+ default: Schema.Struct({
357
+ provider: Schema.String,
358
+ id: Schema.String,
359
+ /** As settings name it; a run clamps it to what the model supports. */
360
+ thinkingLevel: Schema.Enum(Model.ThinkingLevelEnum),
361
+ /** Display names from the catalog, present even when its provider is not listed. */
362
+ name: optional(Schema.String),
363
+ providerName: optional(Schema.String)
364
+ })
365
+ }),
366
+ error: Schema.Union([Settings.SettingsError, Runner.ModelCatalogError])
367
+ }),
212
368
  Rpc.make("session.list", {
213
369
  payload: {},
214
370
  success: Schema.Array(SessionInfo)
215
371
  }),
372
+ /**
373
+ * The conversation on a session's active branch: user and assistant messages, oldest first.
374
+ * Other branches and the harness's own entries (compactions, summaries) are left out.
375
+ */
376
+ Rpc.make("session.history", {
377
+ payload: { sessionId: Session.SessionSchema.ID },
378
+ success: Schema.Struct({ entries: Schema.Array(HistoryEntry) }),
379
+ error: SessionStore.SessionNotFoundError
380
+ }),
381
+ /**
382
+ * Prompts admitted but not yet promoted, in admission order. Admission and promotion are
383
+ * durable events, so a client following `session.log` rereads this whenever the log moves.
384
+ */
385
+ Rpc.make("session.queue", {
386
+ payload: { sessionId: Session.SessionSchema.ID },
387
+ success: Schema.Struct({ entries: Schema.Array(QueuedPrompt) }),
388
+ error: SessionStore.SessionNotFoundError
389
+ }),
390
+ /**
391
+ * A session's durable events after `after` (exclusive; omitted reads from the start), then a
392
+ * `log.synced` marker at the head read when the call began. With `follow`, each event then
393
+ * streams as it commits; without it the stream ends at the marker.
394
+ * Ephemeral events (text and tool progress deltas) are never stored, so they are not here;
395
+ * `event.subscribe` carries them live. To resume, pass the higher of the last event's
396
+ * `durable.seq` and the last marker's `seq`: the marker can sit past the last event sent.
397
+ */
398
+ Rpc.make("session.log", {
399
+ payload: {
400
+ sessionId: Session.SessionSchema.ID,
401
+ after: optional(Schema.Int),
402
+ follow: optional(Schema.Boolean)
403
+ },
404
+ success: Schema.Union([EventEnvelope, LogSynced]),
405
+ error: Schema.Union([SessionStore.SessionNotFoundError, EncodingError]),
406
+ stream: true
407
+ }),
216
408
  Rpc.make("session.configure", {
217
409
  payload: {
218
410
  sessionId: Session.SessionSchema.ID,
@@ -265,6 +457,33 @@ const Api = RpcGroup.make(
265
457
  success: Schema.Void,
266
458
  error: Schema.Union([SessionStore.SessionNotFoundError, Control.PromptConflictError])
267
459
  }),
460
+ /**
461
+ * Withdraws a queued prompt before it joins the conversation. `cancelled` is false when it had
462
+ * already been promoted (it then stays in the conversation) or no pending prompt has that id.
463
+ */
464
+ Rpc.make("session.cancel", {
465
+ payload: {
466
+ sessionId: Session.SessionSchema.ID,
467
+ messageId: Session.SessionMessageSchema.ID
468
+ },
469
+ success: Schema.Struct({ cancelled: Schema.Boolean }),
470
+ error: SessionStore.SessionNotFoundError
471
+ }),
472
+ /**
473
+ * Moves a queued prompt to the other lane or rewrites it, keeping its place in the queue.
474
+ * `delivery: "steer"` also wakes the session, so a prompt left waiting after a stop runs now.
475
+ * `updated` is false when it had already been promoted or cancelled, or no pending prompt has that id.
476
+ */
477
+ Rpc.make("session.update", {
478
+ payload: {
479
+ sessionId: Session.SessionSchema.ID,
480
+ messageId: Session.SessionMessageSchema.ID,
481
+ delivery: optional(PromptSchema.Delivery),
482
+ text: optional(Schema.String)
483
+ },
484
+ success: Schema.Struct({ updated: Schema.Boolean }),
485
+ error: SessionStore.SessionNotFoundError
486
+ }),
268
487
  Rpc.make("session.interrupt", {
269
488
  payload: { sessionId: Session.SessionSchema.ID },
270
489
  success: Schema.Struct({ interrupted: Schema.Boolean })
@@ -384,7 +603,7 @@ const run = Effect.fn("Client.run")(function* (rpc, input, render) {
384
603
  });
385
604
  return;
386
605
  }
387
- const event = yield* decode(envelope).pipe(Effect.catchTag("UnknownEventTypeError", () => Effect.void));
606
+ const event = yield* decode$1(envelope).pipe(Effect.catchTag("UnknownEventTypeError", () => Effect.void));
388
607
  if (event === void 0 || !Predicate.hasProperty(event.data, "sessionId") || event.data.sessionId !== input.sessionId) return;
389
608
  if (Schema.is(EventList.PromptAdmitted)(event) && event.data.messageId === id) admitted = true;
390
609
  if (Schema.is(EventList.Prompted)(event) && event.data.messageId === id) {
@@ -625,6 +844,6 @@ const reportFailure = (error) => writeError(renderError(error)).pipe(Effect.andT
625
844
  process.exitCode = 1;
626
845
  })));
627
846
  //#endregion
628
- export { path as _, addUsage as a, encode as b, terminalColumns as c, writeOut as d, layer as f, OAuthError$1 as g, Api as h, reportFailure as i, usage as l, run as m, OAuthError as n, emptyUsage as o, make as p, renderError as r, header as s, InvalidInputError as t, writeError as u, Connected as v, Core as y };
847
+ export { path as _, addUsage as a, Core as b, terminalColumns as c, writeOut as d, layer as f, OAuthError$1 as g, Api as h, reportFailure as i, usage as l, run as m, OAuthError as n, emptyUsage as o, make as p, renderError as r, header as s, InvalidInputError as t, writeError as u, decode as v, encode as x, Connected as y };
629
848
 
630
- //# sourceMappingURL=error-CzUxh0Q9.mjs.map
849
+ //# sourceMappingURL=error-BMI81XvR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-BMI81XvR.mjs","names":["decode","OAuthError","Contract.Api","Envelope.decode","Client.ExecutionError"],"sources":["../../src/server/envelope.ts","../../src/server/part.ts","../../src/server/contract.ts","../../src/server/client.ts","../../src/cli/output.ts","../../src/cli/error.ts"],"sourcesContent":["import { EventList, EventSchema, optional } from \"@codeworksh/harness/effect\";\nimport { Effect, Schema } from \"effect\";\n\n/**\n * The wire form of an `EventSchema.Payload`. `data` is carried in its encoded\n * form — decoded payloads are not wire-safe (`Schema.Duration`, aikit class\n * transforms) — so clients decode it lazily through their own copy of the\n * registry and can skip types they do not know.\n */\nexport const EventEnvelope = Schema.Struct({\n\tid: EventSchema.ID,\n\ttype: Schema.String,\n\tdurable: optional(Schema.Struct({ aggregateId: Schema.String, seq: Schema.Int, version: Schema.Int })),\n\tmetadata: optional(Schema.Record(Schema.String, Schema.String)),\n\tdata: Schema.Unknown,\n});\nexport type EventEnvelope = typeof EventEnvelope.Type;\n\nexport class UnknownEventTypeError extends Schema.TaggedError<UnknownEventTypeError>()(\"UnknownEventTypeError\", {\n\ttype: Schema.String,\n}) {}\n\n/** The transport's own readiness frame; it has no meaning inside the harness. */\nexport const Connected = EventSchema.define({ type: \"server.connected\", schema: {} });\n\n/** Resolves a published type to the definition that encodes it. */\nexport type Registry = (type: string) => EventSchema.Definition | undefined;\n\n/**\n * What a stock client can decode: the harness's public events plus the frames\n * the transport adds itself. A server may know more than this -- plugins\n * register their own types -- which is exactly why `data` crosses the wire\n * encoded and is decoded lazily, so an unknown type is skipped, not fatal.\n */\nconst core = EventSchema.latest([...EventList.PublicDefinitions, Connected]);\nexport const Core: Registry = (type) => core.get(type);\n\nexport class EncodingError extends Schema.TaggedError<EncodingError>()(\"EventEncodingError\", {\n\ttype: Schema.String,\n\tcause: Schema.Defect(),\n}) {}\n\nexport const encode = Effect.fn(\"Envelope.encode\")(function* (payload: EventSchema.Payload, registry: Registry = Core) {\n\tconst definition = registry(payload.type);\n\tif (definition === undefined) return yield* new UnknownEventTypeError({ type: payload.type });\n\tconst data = yield* Schema.encodeEffect(definition.data)(payload.data).pipe(\n\t\tEffect.mapError((cause) => new EncodingError({ type: payload.type, cause })),\n\t);\n\treturn {\n\t\tid: payload.id,\n\t\ttype: payload.type,\n\t\t...(payload.durable === undefined ? {} : { durable: payload.durable }),\n\t\t...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),\n\t\tdata,\n\t};\n});\n\nexport const decode = Effect.fn(\"Envelope.decode\")(function* (envelope: EventEnvelope, registry: Registry = Core) {\n\tconst definition = registry(envelope.type);\n\tif (definition === undefined) {\n\t\treturn yield* new UnknownEventTypeError({ type: envelope.type });\n\t}\n\tconst data = yield* Schema.decodeEffect(definition.data)(envelope.data);\n\treturn {\n\t\tid: envelope.id,\n\t\ttype: envelope.type,\n\t\t...(envelope.durable === undefined ? {} : { durable: envelope.durable }),\n\t\t...(envelope.metadata === undefined ? {} : { metadata: envelope.metadata }),\n\t\tdata,\n\t} as EventSchema.Payload;\n});\n\nexport * as Envelope from \"./envelope.ts\";\n","import { Schema } from \"effect\";\n\n/*\n * A stored message part as clients see it: aikit's part JSON (persisted verbatim by the harness),\n * narrowed to what a client renders. Provider replay data (signatures, namespaces) and tool\n * `details` are left out, so decoding a stored part drops them.\n */\n\nexport const TextContent = Schema.Struct({ type: Schema.Literal(\"text\"), text: Schema.String });\nexport const ImageContent = Schema.Struct({\n\ttype: Schema.Literal(\"image\"),\n\tdata: Schema.String,\n\tmimeType: Schema.String,\n});\nexport const ThinkingContent = Schema.Struct({\n\ttype: Schema.Literal(\"thinking\"),\n\tthinking: Schema.String,\n\t/** The provider withheld the reasoning; `thinking` is then empty. */\n\tredacted: Schema.optionalKey(Schema.Boolean),\n});\n\n/** aikit's ToolStatusEnum. */\nexport const ToolStatus = Schema.Literals([\"pending\", \"running\", \"completed\", \"error\", \"skipped\", \"aborted\"]);\n\nexport const ToolResult = Schema.Struct({\n\tcontent: Schema.Array(Schema.Union([TextContent, ImageContent])),\n\tisError: Schema.Boolean,\n});\n\nexport const ToolCall = Schema.Struct({\n\ttype: Schema.Literal(\"toolCall\"),\n\tcallID: Schema.String,\n\tname: Schema.String,\n\targuments: Schema.Record(Schema.String, Schema.Json),\n\tstatus: ToolStatus,\n\t/** Present once the call settled (completed, error, skipped, aborted). */\n\tresult: Schema.optionalKey(ToolResult),\n\t/** Epoch milliseconds: started, and last lifecycle update. */\n\ttime: Schema.optionalKey(Schema.Struct({ start: Schema.Finite, end: Schema.Finite })),\n});\nexport type ToolCall = typeof ToolCall.Type;\n\nexport const Part = Schema.Union([TextContent, ImageContent, ThinkingContent, ToolCall]);\nexport type Part = typeof Part.Type;\n\n/** A stored part row's JSON, or none when it is not a part a client renders. */\nexport const decode = Schema.decodeUnknownOption(Schema.fromJsonString(Part));\n\nexport * as MessagePart from \"./part.ts\";\n","import { Model } from \"@codeworksh/aikit\";\nimport {\n\tControl,\n\tEvent,\n\tLocation,\n\toptional,\n\tProject,\n\tPromptSchema,\n\tRunner,\n\tSandbox,\n\tSandboxError,\n\tSession,\n\tSessionStore,\n\tSettings,\n} from \"@codeworksh/harness/effect\";\nimport { Schema } from \"effect\";\nimport { Rpc, RpcGroup } from \"effect/rpc\";\nimport { EncodingError, EventEnvelope } from \"./envelope.ts\";\nimport { Part } from \"./part.ts\";\n\n/** The HTTP path the RPC endpoint is served on; the version moves with breaking wire changes. */\nexport const path = \"/rpc/v1\";\n\nexport const SandboxInfo = Schema.Struct({\n\tid: Sandbox.SandboxInstance.ID,\n\tdriver: Schema.String,\n\tkind: Sandbox.SandboxInstance.Kind,\n\tproviderResourceId: Schema.OptionFromNullOr(Schema.String),\n\townership: Sandbox.SandboxInstance.Ownership,\n\tstatus: Sandbox.SandboxInstance.Status,\n\tusage: Sandbox.SandboxInstance.Usage,\n\trefCount: Schema.Int,\n\tcreatedAt: Schema.DateFromString,\n\tupdatedAt: Schema.DateFromString,\n});\nexport type SandboxInfo = typeof SandboxInfo.Type;\n\nexport const SessionInfo = Schema.Struct({\n\tid: Session.SessionSchema.ID,\n\ttitle: Schema.String,\n\tdirectory: Session.AbsolutePath,\n\t/** The host directory this session is anchored to. Absent when it has none. */\n\thostDir: optional(Session.AbsolutePath),\n\tsandbox: optional(SandboxInfo),\n\t/** The project the session's space belongs to. */\n\tproject: optional(Schema.Struct({ id: Schema.String, name: Schema.String })),\n\t/** Last activity, epoch milliseconds. */\n\tupdatedAt: Schema.Finite,\n\t/** The model chosen for this session; absent when settings decide. */\n\tmodel: optional(Schema.Struct({ provider: Schema.String, id: Schema.String })),\n\t/** The thinking level chosen for this session; absent when settings decide. */\n\tthinkingLevel: optional(Schema.Enum(Model.ThinkingLevelEnum)),\n\t/** Its unfinished run was cut off by restarts too often to resume on its own; the next prompt runs it. */\n\tparked: optional(Schema.Boolean),\n});\nexport type SessionInfo = typeof SessionInfo.Type;\n\n/** One message on a session's active branch, oldest first. */\nexport const HistoryEntry = Schema.Struct({\n\t/** The entry id: what live events and `session.message` refer to. */\n\tid: Schema.String,\n\t/** Its place in the session's durable log; live events continue from it. */\n\tseq: Schema.Int,\n\trole: Schema.Literals([\"user\", \"assistant\"]),\n\t/** `draft` is a reply still streaming; `aborted` one that was interrupted. */\n\tstate: Schema.Literals([\"committed\", \"draft\", \"aborted\"]),\n\t/** Epoch milliseconds. */\n\tcreatedAt: Schema.Finite,\n\t/** Epoch milliseconds of the last change; for a reply, when it ended once it is no longer a draft. */\n\tupdatedAt: Schema.Finite,\n\tparts: Schema.Array(Part),\n});\nexport type HistoryEntry = typeof HistoryEntry.Type;\n\n/** A prompt admitted but not yet in the conversation: a steer waiting for the next model request, or a follow-up for the next turn. */\nexport const QueuedPrompt = Schema.Struct({\n\t/** The id of the user message it becomes once promoted. */\n\tid: Schema.String,\n\tdelivery: PromptSchema.Delivery,\n\ttext: Schema.String,\n\t/** Epoch milliseconds. */\n\tcreatedAt: Schema.Finite,\n});\nexport type QueuedPrompt = typeof QueuedPrompt.Type;\n\n/** Ends `session.log`'s replay; `seq` is absent when the session has no durable events yet. */\nexport const LogSynced = Schema.Struct({\n\ttype: Schema.Literal(\"log.synced\"),\n\t/** The session the log was read for. */\n\taggregateId: Schema.String,\n\tseq: optional(Schema.Int),\n});\nexport type LogSynced = typeof LogSynced.Type;\n\nexport const RuntimeConfig = Schema.Struct({\n\tmodel: optional(Schema.Struct({ provider: Schema.String, id: Schema.String })),\n\tthinkingLevel: optional(Schema.Enum(Model.ThinkingLevelEnum)),\n});\nexport type RuntimeConfig = typeof RuntimeConfig.Type;\n\nexport const SandboxRef = Sandbox.Selection;\n\n/** A model to choose, by the catalog's id and display name, with the thinking levels it supports. */\nexport const ModelOption = Schema.Struct({\n\tid: Schema.String,\n\tname: Schema.String,\n\t/** In ascending order; `[\"off\"]` for a model that does not reason. */\n\tthinkingLevels: Schema.Array(Schema.Enum(Model.ThinkingLevelEnum)),\n});\n\n/** A provider this server can call, with the models a session may use from it. */\nexport const ModelProvider = Schema.Struct({\n\tid: Schema.String,\n\tname: Schema.String,\n\tmodels: Schema.Array(ModelOption),\n});\nexport type ModelProvider = typeof ModelProvider.Type;\n\n/** A project's name as a client sets it: trimmed, never empty. */\nexport const ProjectName = Schema.Trimmed.check(Schema.isNonEmpty());\n\nexport class OAuthError extends Schema.TaggedError<OAuthError>()(\"Server.OAuthError\", {\n\tmessage: Schema.String,\n}) {}\n\n/** OAuth providers whose credentials this server stores. */\nexport const OAuthProvider = Schema.Literals([\"openai-codex\", \"github-copilot\"]);\nexport type OAuthProvider = typeof OAuthProvider.Type;\n\n/**\n * Credentials as the provider's aikit module persists them. The union is\n * discriminated by `provider` so one set of RPCs serves every login.\n */\nexport const OAuthCredentials = Schema.Union([\n\tSchema.Struct({\n\t\tprovider: Schema.Literal(\"openai-codex\"),\n\t\taccess: Schema.String,\n\t\trefresh: Schema.String,\n\t\texpires: Schema.Finite,\n\t\taccountId: Schema.String,\n\t}),\n\tSchema.Struct({\n\t\tprovider: Schema.Literal(\"github-copilot\"),\n\t\taccess: Schema.String,\n\t\trefresh: Schema.String,\n\t\texpires: Schema.Finite,\n\t\tenterpriseUrl: optional(Schema.String),\n\t\tapiEndpoint: optional(Schema.String),\n\t\tavailableModelIds: optional(Schema.Array(Schema.String)),\n\t}),\n]);\nexport type OAuthCredentials = typeof OAuthCredentials.Type;\n\n/** What a login looks like from the outside: never the tokens themselves. */\nexport const OAuthInfo = Schema.Struct({\n\tprovider: OAuthProvider,\n\t/** Epoch millis, or 0 for a credential that does not expire. */\n\texpires: Schema.Finite,\n\taccountId: optional(Schema.String),\n\tapiEndpoint: optional(Schema.String),\n\tenterpriseUrl: optional(Schema.String),\n\tavailableModels: optional(Schema.Int),\n});\nexport type OAuthInfo = typeof OAuthInfo.Type;\n\nconst SessionErrors = Schema.Union([\n\tSessionStore.SessionNotFoundError,\n\tSessionStore.SessionLinkedSpaceNotFoundError,\n\tSessionStore.RelinkError,\n]);\n\n// Every lifecycle error the sandbox control plane can raise; narrowing per\n// endpoint would misreport what `withMount` and `stop` actually fail with.\nconst SandboxErrors = Schema.Union([\n\tSandboxError.SandboxNotFoundError,\n\tSandboxError.SandboxDriverNotRegisteredError,\n\tSandboxError.SandboxDriverRegistrationError,\n\tSandboxError.SandboxUnsupportedError,\n\tSandboxError.SandboxProviderError,\n\tSandboxError.SandboxUnavailError,\n\tSandboxError.SandboxRemovedError,\n\tSandboxError.SandboxTransitionConflictError,\n\tSandboxError.SandboxBusyError,\n]);\n\nconst LocationErrors = Schema.Union([Location.DirectoryNotFoundError, Location.NotDirectoryError]);\n\nexport const Api = RpcGroup.make(\n\t/**\n\t * The server's own identity: the process and build a client is talking to.\n\t *\n\t * The health probe: a discovery registration names a pid and version, and a\n\t * caller confirms the process answering is the one that registered before it\n\t * trusts the endpoint. Like every other capability it rides the RPC channel,\n\t * so there is no separate HTTP surface to keep in step.\n\t */\n\tRpc.make(\"server.info\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Struct({ pid: Schema.Int, version: Schema.String }),\n\t}),\n\tRpc.make(\"auth.save\", {\n\t\tpayload: { credentials: OAuthCredentials },\n\t\tsuccess: OAuthInfo,\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.status\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.NullOr(OAuthInfo),\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.refresh\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.NullOr(OAuthInfo),\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.logout\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.Void,\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"session.create\", {\n\t\tpayload: {\n\t\t\ttitle: optional(Schema.String),\n\t\t\tdirectory: optional(Schema.String),\n\t\t\t/**\n\t\t\t * The host directory this session is anchored to, usually the caller's project root.\n\t\t\t * Unrelated to `directory`, which names a place inside the session's space.\n\t\t\t *\n\t\t\t * It is an anchor and nothing more: whatever needs a host-side directory resolves from\n\t\t\t * here rather than from wherever the server happens to be running. What reads it is the\n\t\t\t * reader's business, not this field's.\n\t\t\t *\n\t\t\t * Optional and honoured as given. Omitting it is normal, not a failure.\n\t\t\t */\n\t\t\thostDir: optional(Session.AbsolutePath),\n\t\t\tsandbox: optional(SandboxRef),\n\t\t\truntime: optional(RuntimeConfig),\n\t\t\t/**\n\t\t\t * Names the project when this session creates it, ahead of the repository's and the\n\t\t\t * folder's name. A project that already exists keeps its name; `project.rename` changes it.\n\t\t\t */\n\t\t\tproject: optional(Schema.Struct({ name: ProjectName })),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: Schema.Union([SessionErrors, SandboxErrors, LocationErrors]),\n\t}),\n\tRpc.make(\"project.rename\", {\n\t\tpayload: { projectId: Schema.String, name: ProjectName },\n\t\tsuccess: Schema.Struct({ id: Schema.String, name: Schema.String }),\n\t\terror: Project.ProjectNotFoundError,\n\t}),\n\t/**\n\t * The models a session anchored at `hostDir` can use: providers this server holds credentials\n\t * for, in the catalog plus that project's settings, and the model settings pick when a session\n\t * names none. Without `hostDir`, only the user's settings apply. Credentials are checked for\n\t * presence, not validity.\n\t */\n\tRpc.make(\"model.list\", {\n\t\tpayload: { hostDir: optional(Session.AbsolutePath) },\n\t\tsuccess: Schema.Struct({\n\t\t\tproviders: Schema.Array(ModelProvider),\n\t\t\tdefault: Schema.Struct({\n\t\t\t\tprovider: Schema.String,\n\t\t\t\tid: Schema.String,\n\t\t\t\t/** As settings name it; a run clamps it to what the model supports. */\n\t\t\t\tthinkingLevel: Schema.Enum(Model.ThinkingLevelEnum),\n\t\t\t\t/** Display names from the catalog, present even when its provider is not listed. */\n\t\t\t\tname: optional(Schema.String),\n\t\t\t\tproviderName: optional(Schema.String),\n\t\t\t}),\n\t\t}),\n\t\terror: Schema.Union([Settings.SettingsError, Runner.ModelCatalogError]),\n\t}),\n\tRpc.make(\"session.list\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(SessionInfo),\n\t}),\n\t/**\n\t * The conversation on a session's active branch: user and assistant messages, oldest first.\n\t * Other branches and the harness's own entries (compactions, summaries) are left out.\n\t */\n\tRpc.make(\"session.history\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Struct({ entries: Schema.Array(HistoryEntry) }),\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Prompts admitted but not yet promoted, in admission order. Admission and promotion are\n\t * durable events, so a client following `session.log` rereads this whenever the log moves.\n\t */\n\tRpc.make(\"session.queue\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Struct({ entries: Schema.Array(QueuedPrompt) }),\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * A session's durable events after `after` (exclusive; omitted reads from the start), then a\n\t * `log.synced` marker at the head read when the call began. With `follow`, each event then\n\t * streams as it commits; without it the stream ends at the marker.\n\t * Ephemeral events (text and tool progress deltas) are never stored, so they are not here;\n\t * `event.subscribe` carries them live. To resume, pass the higher of the last event's\n\t * `durable.seq` and the last marker's `seq`: the marker can sit past the last event sent.\n\t */\n\tRpc.make(\"session.log\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, after: optional(Schema.Int), follow: optional(Schema.Boolean) },\n\t\tsuccess: Schema.Union([EventEnvelope, LogSynced]),\n\t\terror: Schema.Union([SessionStore.SessionNotFoundError, EncodingError]),\n\t\tstream: true,\n\t}),\n\tRpc.make(\"session.configure\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, runtime: RuntimeConfig },\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\tRpc.make(\"session.info\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Point an existing session at a host directory, or clear it with `null`.\n\t *\n\t * Not `session.relink`: that moves where the *work* happens, this changes which host directory\n\t * the session is *anchored to*. Conflating them would recreate exactly the `cwd`/`hostDir`\n\t * confusion the split exists to remove, which is why they sound alike and stay apart.\n\t */\n\tRpc.make(\"session.link\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\t/** Absent clears the anchor, leaving the session with no host directory. */\n\t\t\thostDir: optional(Session.AbsolutePath),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\tRpc.make(\"session.relink\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\tsandbox: optional(SandboxRef),\n\t\t\tdirectory: optional(Schema.String),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: Schema.Union([SessionErrors, SandboxErrors, LocationErrors]),\n\t}),\n\tRpc.make(\"session.prompt\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\ttext: Schema.String,\n\t\t\tdelivery: optional(PromptSchema.Delivery),\n\t\t\tid: optional(Session.SessionMessageSchema.ID),\n\t\t},\n\t\tsuccess: Schema.Void,\n\t\terror: Schema.Union([SessionStore.SessionNotFoundError, Control.PromptConflictError]),\n\t}),\n\t/**\n\t * Withdraws a queued prompt before it joins the conversation. `cancelled` is false when it had\n\t * already been promoted (it then stays in the conversation) or no pending prompt has that id.\n\t */\n\tRpc.make(\"session.cancel\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, messageId: Session.SessionMessageSchema.ID },\n\t\tsuccess: Schema.Struct({ cancelled: Schema.Boolean }),\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Moves a queued prompt to the other lane or rewrites it, keeping its place in the queue.\n\t * `delivery: \"steer\"` also wakes the session, so a prompt left waiting after a stop runs now.\n\t * `updated` is false when it had already been promoted or cancelled, or no pending prompt has that id.\n\t */\n\tRpc.make(\"session.update\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\tmessageId: Session.SessionMessageSchema.ID,\n\t\t\tdelivery: optional(PromptSchema.Delivery),\n\t\t\ttext: optional(Schema.String),\n\t\t},\n\t\tsuccess: Schema.Struct({ updated: Schema.Boolean }),\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\tRpc.make(\"session.interrupt\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Struct({ interrupted: Schema.Boolean }),\n\t}),\n\t/**\n\t * Whether a prompt materialized into the conversation. An admitted prompt\n\t * that is still queued has no entry yet, so this is the projection a client\n\t * reconciles against when the volatile stream left it unsure\n\t */\n\tRpc.make(\"session.message\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, messageId: Session.SessionMessageSchema.ID },\n\t\tsuccess: Schema.Struct({ found: Schema.Boolean }),\n\t}),\n\tRpc.make(\"session.wait\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Void,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Re-import every configured plugin, for the whole server.\n\t *\n\t * The one thing an exchange cannot notice on its own: a local plugin whose contents changed\n\t * while its path did not. A failure keeps the previous set and is reported here rather than\n\t * emptying a running server's tool registry.\n\t */\n\tRpc.make(\"plugin.reload\", {\n\t\tpayload: {},\n\t\t// No error channel: a reload that fails keeps the previous set and reports why, because a\n\t\t// server that empties its tool registry over a typo is worse than one that says so.\n\t\tsuccess: Schema.Struct({ plugins: Schema.Int, failure: optional(Schema.String) }),\n\t}),\n\tRpc.make(\"sandbox.drivers\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(Schema.Struct({ name: Schema.String, kind: Schema.String })),\n\t}),\n\tRpc.make(\"sandbox.list\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(SandboxInfo),\n\t}),\n\tRpc.make(\"sandbox.create\", {\n\t\tpayload: { driver: Schema.String },\n\t\tsuccess: SandboxInfo,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"sandbox.register\", {\n\t\tpayload: { driver: Schema.String, providerResourceId: Schema.String },\n\t\tsuccess: SandboxInfo,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"sandbox.stop\", {\n\t\tpayload: { sandboxId: Sandbox.SandboxInstance.ID },\n\t\tsuccess: Schema.Void,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"event.subscribe\", {\n\t\tpayload: {},\n\t\tsuccess: EventEnvelope,\n\t\terror: Schema.Union([Event.SubscriptionOverflowError, EncodingError]),\n\t\tstream: true,\n\t}),\n);\n\nexport * as Contract from \"./contract.ts\";\n","import { EventList, type EventSchema, optional, Session } from \"@codeworksh/harness/effect\";\nimport { NodeSocket } from \"@effect/platform-node\";\nimport { Deferred, Effect, Layer, Predicate, Schema, Stream } from \"effect\";\nimport { RpcClient, RpcSerialization } from \"effect/rpc\";\nimport { Contract } from \"./contract.ts\";\nimport { Envelope } from \"./envelope.ts\";\n\nexport const make = RpcClient.make(Contract.Api);\nexport type Client = Effect.Success<typeof make>;\n\nexport const layer = (url: string) =>\n\tRpcClient.layerProtocolSocket().pipe(\n\t\tLayer.provide(NodeSocket.layerWebSocket(url)),\n\t\tLayer.provide(RpcSerialization.layerNdjson),\n\t);\n\n/** A server-side failure as the client sees it: the category, not the cause. */\nexport class ExecutionError extends Schema.TaggedError<ExecutionError>()(\"Client.ExecutionError\", {\n\ttype: Schema.String,\n\tmessage: Schema.String,\n\tstatus: optional(Schema.Int),\n}) {}\n\n/**\n * Runs one prompt against a server and renders its output.\n *\n * Sessions are shared, so the stream carries other clients' work too and every\n * terminal event has to be attributed before it is believed. A terminal that\n * arrives before our own prompt is promoted belongs to somebody else's drain:\n * it is remembered rather than raised, and forgotten the moment our prompt is\n * promoted. It only becomes our outcome if the session reaches idle having\n * never promoted us -- at which point it is the best explanation available for\n * why our prompt never ran.\n */\nexport const run = Effect.fn(\"Client.run\")(function* <E, R>(\n\trpc: Client,\n\tinput: { sessionId: Session.SessionSchema.ID; text: string },\n\trender: (event: EventSchema.Payload) => Effect.Effect<void, E, R>,\n) {\n\tconst id = Session.SessionMessageSchema.ID.create();\n\tlet admitted = false;\n\tlet promoted = false;\n\tlet settled = false;\n\tlet unattributed: ExecutionError | undefined;\n\t// Raised once a busy period ends without our prompt in it: the session may be\n\t// about to go idle, and only idleness proves our prompt is never running.\n\tconst stalled = yield* Deferred.make<void>();\n\n\tconst terminal = (event: EventSchema.Payload): ExecutionError | undefined => {\n\t\tif (Schema.is(EventList.ExecutionInterrupted)(event))\n\t\t\treturn new ExecutionError({\n\t\t\t\ttype: \"aborted\",\n\t\t\t\tmessage: event.data.reason === \"shutdown\" ? \"Server stopped the session\" : \"Session interrupted\",\n\t\t\t});\n\t\tif (Schema.is(EventList.ExecutionFailed)(event))\n\t\t\treturn new ExecutionError({\n\t\t\t\ttype: event.data.error.type,\n\t\t\t\tmessage: event.data.error.message,\n\t\t\t\t...(event.data.error.status === undefined ? {} : { status: event.data.error.status }),\n\t\t\t});\n\t\treturn undefined;\n\t};\n\n\tconst consume = rpc[\"event.subscribe\"]({}).pipe(\n\t\tStream.mapEffect(\n\t\t\tEffect.fnUntraced(function* (envelope) {\n\t\t\t\tif (envelope.type === Envelope.Connected.type) {\n\t\t\t\t\tyield* rpc[\"session.prompt\"]({ ...input, id, delivery: \"followUp\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst event = yield* Envelope.decode(envelope).pipe(\n\t\t\t\t\tEffect.catchTag(\"UnknownEventTypeError\", () => Effect.void),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\tevent === undefined ||\n\t\t\t\t\t!Predicate.hasProperty(event.data, \"sessionId\") ||\n\t\t\t\t\tevent.data.sessionId !== input.sessionId\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\tif (Schema.is(EventList.PromptAdmitted)(event) && event.data.messageId === id) admitted = true;\n\t\t\t\tif (Schema.is(EventList.Prompted)(event) && event.data.messageId === id) {\n\t\t\t\t\tpromoted = true;\n\t\t\t\t\t// Our prompt is running after all; whatever ended before it was not ours.\n\t\t\t\t\tunattributed = undefined;\n\t\t\t\t}\n\t\t\t\tif (!admitted) return;\n\n\t\t\t\tconst ended = terminal(event);\n\t\t\t\tconst succeeded = Schema.is(EventList.ExecutionSucceeded)(event);\n\t\t\t\tif (!promoted) {\n\t\t\t\t\tif (ended !== undefined) unattributed = ended;\n\t\t\t\t\t// A busy period that ended without us: wait for idle to find out\n\t\t\t\t\t// whether a successor still picks our prompt up.\n\t\t\t\t\tif (ended !== undefined || succeeded) yield* Deferred.succeed(stalled, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (ended !== undefined) return yield* ended;\n\t\t\t\tif (succeeded) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield* render(event);\n\t\t\t}),\n\t\t),\n\t\tStream.takeUntil(() => settled),\n\t\tStream.runDrain,\n\t);\n\n\t// Idle is the cue to reconcile, not the verdict. `wait` follows successors, so\n\t// it resolves only once the session is quiet -- then the projection says\n\t// whether our prompt was ever part of it. A prompt that did run leaves its\n\t// terminal in flight on the same socket, so the consumer is left alone to\n\t// finish; only a prompt that never materialized ends the run early.\n\tlet abandoned = false;\n\tconst reconcile = Deferred.await(stalled).pipe(\n\t\tEffect.andThen(rpc[\"session.wait\"]({ sessionId: input.sessionId })),\n\t\tEffect.andThen(rpc[\"session.message\"]({ sessionId: input.sessionId, messageId: id })),\n\t\tEffect.andThen(({ found }) =>\n\t\t\tfound\n\t\t\t\t? Effect.never\n\t\t\t\t: Effect.sync(() => {\n\t\t\t\t\t\tabandoned = true;\n\t\t\t\t\t}),\n\t\t),\n\t);\n\n\tyield* Effect.raceFirst(consume, reconcile);\n\tif (settled) return;\n\tif (abandoned)\n\t\treturn yield* unattributed ?? new ExecutionError({ type: \"unknown\", message: \"Prompt was not promoted\" });\n\treturn yield* new ExecutionError({\n\t\ttype: \"transport.disconnected\",\n\t\tmessage: \"Event stream ended before the prompt finished; its output was not rendered\",\n\t});\n});\n\nexport * as Client from \"./client.ts\";\n","import type { Message } from \"@codeworksh/aikit\";\nimport { Effect } from \"effect\";\n\nexport interface UsageSummary {\n\treadonly turns: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly input: number;\n\treadonly output: number;\n\treadonly reasoning: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly totalTokens: number;\n\treadonly cost: number;\n}\n\nexport const emptyUsage: UsageSummary = {\n\tturns: 0,\n\tinput: 0,\n\toutput: 0,\n\treasoning: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: 0,\n};\n\nexport const addUsage = (summary: UsageSummary, message: Message.AssistantMessage): UsageSummary => ({\n\tturns: summary.turns + 1,\n\tprovider: message.provider.id,\n\tmodel: message.responseModel ?? message.model,\n\tinput: summary.input + message.usage.input,\n\toutput: summary.output + message.usage.output,\n\treasoning: summary.reasoning + (message.usage.reasoning ?? 0),\n\tcacheRead: summary.cacheRead + message.usage.cacheRead,\n\tcacheWrite: summary.cacheWrite + message.usage.cacheWrite,\n\ttotalTokens: summary.totalTokens + message.usage.totalTokens,\n\tcost: summary.cost + message.usage.cost.total,\n});\n\nconst number = new Intl.NumberFormat(\"en-US\");\nconst row = (label: string, value: string) => `${label.padEnd(9)}${value}\\n`;\n\nconst formatCost = (cost: number): string => `$${cost.toFixed(cost > 0 && cost < 0.01 ? 6 : 4)}`;\n\nexport const divider = (label: string, columns = 72): string => {\n\tconst width = Math.min(100, Math.max(32, columns));\n\tconst start = `── ${label} `;\n\treturn `${start}${\"─\".repeat(Math.max(2, width - start.length))}\\n`;\n};\n\nexport const header = (input: {\n\treadonly sessionId: string;\n\treadonly sandbox: string;\n\treadonly directory: string;\n\treadonly columns?: number;\n}): string =>\n\t`${row(\"session\", input.sessionId)}${row(\"sandbox\", `${input.sandbox} · ${input.directory}`)}\\n${divider(\n\t\t\"response\",\n\t\tinput.columns,\n\t)}`;\n\nexport const usage = (summary: UsageSummary, columns?: number): string => {\n\tconst turns = `${summary.turns} ${summary.turns === 1 ? \"turn\" : \"turns\"}`;\n\tconst model =\n\t\tsummary.provider === undefined || summary.model === undefined\n\t\t\t? \"unknown\"\n\t\t\t: `${summary.provider}/${summary.model}`;\n\tconst reasoning = summary.reasoning === 0 ? \"\" : ` · ${number.format(summary.reasoning)} reasoning`;\n\treturn `${divider(\"usage\", columns)}${row(\"model\", model)}${row(\n\t\t\"tokens\",\n\t\t`${number.format(summary.input)} input · ${number.format(summary.output)} output${reasoning} · ${number.format(\n\t\t\tsummary.totalTokens,\n\t\t)} total`,\n\t)}${row(\"cache\", `${number.format(summary.cacheRead)} read · ${number.format(summary.cacheWrite)} write`)}${row(\n\t\t\"cost\",\n\t\t`${formatCost(summary.cost)} · ${turns}`,\n\t)}`;\n};\n\nexport const writeOut = (value: string) => Effect.sync(() => void process.stdout.write(value));\nexport const writeError = (value: string) => Effect.sync(() => void process.stderr.write(value));\nexport const terminalColumns = () => (process.stderr.isTTY ? (process.stderr.columns ?? 72) : 72);\n","import { ModelCatalog, Plugin, Runner, SandboxError, SessionStore, Settings } from \"@codeworksh/harness/effect\";\nimport { SandboxProvider } from \"@codeworksh/harness/sandbox\";\nimport { Duration, Effect, Schema } from \"effect\";\nimport { Client } from \"../server/client.ts\";\nimport { writeError } from \"./output.ts\";\n\n/** Bad flag or argument combinations the parser cannot express on its own. */\nexport class InvalidInputError extends Schema.TaggedError<InvalidInputError>()(\"CLI.InvalidInputError\", {\n\tmessage: Schema.String,\n}) {}\n\nexport class OAuthError extends Schema.TaggedError<OAuthError>()(\"CLI.OAuthError\", {\n\tmessage: Schema.String,\n\tcause: Schema.optional(Schema.Defect()),\n}) {}\n\n/**\n * Every failure a command handler may surface to the runtime. Harness failures are\n * rendered inside the handler that owns them, so only the CLI's own errors reach\n * the top-level renderer.\n */\nexport type CommandError = InvalidInputError | OAuthError;\n\nconst isInvalidInputError = Schema.is(InvalidInputError);\nconst isOAuthError = Schema.is(OAuthError);\nconst isProviderError = Schema.is(Runner.ProviderError);\nconst isModelCatalogError = Schema.is(Runner.ModelCatalogError);\nconst isModelCatalogRefreshError = Schema.is(ModelCatalog.RefreshError);\nconst isModelNotFoundError = Schema.is(Runner.ModelNotFoundError);\nconst isLLMStreamError = Schema.is(Runner.LLMStreamError);\nconst isSandboxProviderError = Schema.is(SandboxProvider.SandboxProviderError);\nconst isPluginInstallError = Schema.is(Plugin.InstallError);\nconst isPluginSourceError = Schema.is(Plugin.SourceError);\nconst isPluginStoreError = Schema.is(Plugin.StoreError);\nconst isPluginLoadError = Schema.is(Plugin.LoadError);\nconst isSessionNotLinkedError = Schema.is(SessionStore.SessionNotLinkedError);\nconst isSettingsError = Schema.is(Settings.SettingsError);\nconst isSandboxDriverNotRegisteredError = Schema.is(SandboxError.SandboxDriverNotRegisteredError);\nconst isSandboxDriverRegistrationError = Schema.is(SandboxError.SandboxDriverRegistrationError);\nconst isExecutionError = Schema.is(Client.ExecutionError);\n\nconst credentialHint = (provider: string): string => {\n\tswitch (provider) {\n\t\tcase \"openrouter\":\n\t\t\treturn \"set OPENROUTER_API_KEY and retry\";\n\t\tcase \"openai\":\n\t\t\treturn \"set OPENAI_API_KEY and retry\";\n\t\tcase \"openai-codex\":\n\t\t\treturn \"run `codework auth login --openai-codex` and retry\";\n\t\tcase \"github-copilot\":\n\t\t\treturn \"run `codework auth login --github-copilot` and retry\";\n\t\tcase \"anthropic\":\n\t\t\treturn \"set ANTHROPIC_API_KEY and retry\";\n\t\tcase \"google\":\n\t\t\treturn \"set GOOGLE_GENERATIVE_AI_API_KEY and retry\";\n\t\tcase \"xai\":\n\t\t\treturn \"set XAI_API_KEY and retry\";\n\t\tdefault:\n\t\t\treturn `configure credentials for provider \"${provider}\" and retry`;\n\t}\n};\n\nconst providerHint = (error: Runner.ProviderError): string | undefined => {\n\tswitch (error.reason._tag) {\n\t\tcase \"Runner.ProviderAuthenticationError\":\n\t\t\treturn error.reason.authentication === \"missing\"\n\t\t\t\t? credentialHint(error.provider)\n\t\t\t\t: `check the credentials configured for provider \"${error.provider}\"`;\n\t\tcase \"Runner.ProviderAuthorizationError\":\n\t\t\treturn \"check that the credential can access this model and endpoint\";\n\t\tcase \"Runner.ProviderModelUnavailableError\":\n\t\t\treturn \"check the provider model ID and whether your account can access it\";\n\t\tcase \"Runner.ProviderRateLimitError\":\n\t\t\treturn error.reason.retryAfter === undefined\n\t\t\t\t? \"retry after the provider rate-limit window resets\"\n\t\t\t\t: `retry in about ${Math.ceil(Duration.toMillis(error.reason.retryAfter) / 1_000)} seconds`;\n\t\tcase \"Runner.ProviderQuotaError\":\n\t\t\treturn \"check the provider account quota or billing balance\";\n\t\tcase \"Runner.ProviderTimeoutError\":\n\t\tcase \"Runner.ProviderTransportError\":\n\t\tcase \"Runner.ProviderUnavailableError\":\n\t\t\treturn error.isRetryable ? \"this failure is retryable\" : undefined;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst unknownMessage = (error: unknown): string => {\n\tif (error instanceof Error && error.message.trim().length > 0) return error.message;\n\tif (typeof error === \"string\" && error.trim().length > 0) return error;\n\tif (typeof error === \"object\" && error !== null && \"_tag\" in error) {\n\t\t// A bare tag such as `ServeError` hides the reason; its cause carries it (`EADDRINUSE`).\n\t\tconst cause = \"cause\" in error ? error.cause : undefined;\n\t\treturn cause instanceof Error ? `${String(error._tag)}: ${cause.message}` : String(error._tag);\n\t}\n\treturn \"the command failed for an unknown reason\";\n};\n\n/**\n * What the reader can do about a reference that failed to prepare. A plugin list is\n * usually hand-written in a settings file, so the phase is worth translating.\n */\n/** One hint per reason. Lowercase, like everything else a plugin failure prints. */\nconst providerCategory = (reason: Runner.ProviderFailureReason): string => {\n\tswitch (reason._tag) {\n\t\tcase \"Runner.ProviderAuthenticationError\":\n\t\t\treturn \"provider-authentication-error\";\n\t\tcase \"Runner.ProviderConfigurationError\":\n\t\t\treturn \"provider-configuration-error\";\n\t\tcase \"Runner.ProviderAuthorizationError\":\n\t\t\treturn \"provider-authorization-error\";\n\t\tcase \"Runner.ProviderModelUnavailableError\":\n\t\t\treturn \"provider-model-unavailable-error\";\n\t\tcase \"Runner.ProviderRateLimitError\":\n\t\t\treturn \"provider-rate-limit-error\";\n\t\tcase \"Runner.ProviderQuotaError\":\n\t\t\treturn \"provider-quota-error\";\n\t\tcase \"Runner.ProviderInvalidRequestError\":\n\t\t\treturn \"provider-invalid-request-error\";\n\t\tcase \"Runner.ProviderContentPolicyError\":\n\t\t\treturn \"provider-content-filter-error\";\n\t\tcase \"Runner.ProviderTimeoutError\":\n\t\t\treturn \"provider-timeout-error\";\n\t\tcase \"Runner.ProviderTransportError\":\n\t\t\treturn \"provider-transport-error\";\n\t\tcase \"Runner.ProviderUnavailableError\":\n\t\t\treturn \"provider-unavailable-error\";\n\t\tcase \"Runner.ProviderInvalidResponseError\":\n\t\t\treturn \"provider-invalid-response-error\";\n\t\tcase \"Runner.ProviderUnknownError\":\n\t\t\treturn \"provider-unknown-error\";\n\t}\n};\n\nconst pluginReasonHint = (\n\treason:\n\t\t| Plugin.SourceError[\"reason\"]\n\t\t| Plugin.InstallError[\"reason\"]\n\t\t| Plugin.StoreError[\"reason\"]\n\t\t| Plugin.LoadError[\"reason\"],\n): string => {\n\tswitch (reason) {\n\t\tcase \"plugin-unsupported-source\":\n\t\t\treturn \"a path entry starts with `./`, `../`, `~/` or `/`; anything else is a package or a git spec, and a remote tarball is not supported\";\n\t\tcase \"plugin-not-found\":\n\t\t\treturn \"the path does not exist; check the spelling, remembering it anchors to the settings file that declares it\";\n\t\tcase \"plugin-escapes-root\":\n\t\t\treturn \"a plugin path must stay inside the project it is declared in\";\n\t\tcase \"plugin-resolve-failed\":\n\t\t\treturn \"check that the registry or git remote is reachable, and that your credentials are current\";\n\t\tcase \"plugin-fetch-failed\":\n\t\t\treturn \"check the package name and version, and that the registry is reachable\";\n\t\tcase \"plugin-no-commit\":\n\t\t\treturn \"the git source installed but no commit could be recovered; name a branch, tag or commit explicitly\";\n\t\tcase \"plugin-no-entrypoint\":\n\t\t\treturn \"the package installed but exports no module to import; check its `exports` and `main`\";\n\t\tcase \"plugin-not-installed\":\n\t\t\treturn \"run `codework plugin install` to fetch what the settings files name\";\n\t\tcase \"plugin-lock-timeout\":\n\t\t\treturn \"another install is holding this entry; wait for it to finish, or remove the stale `.lock` directory\";\n\t\tcase \"plugin-marker-invalid\":\n\t\tcase \"plugin-index-invalid\":\n\t\t\treturn \"the store entry is damaged; remove it and install again\";\n\t\tcase \"plugin-collect-failed\":\n\t\t\treturn \"the store could not be tidied; check the permissions on the plugin cache\";\n\t\tcase \"plugin-import-failed\":\n\t\t\treturn \"the module failed to load; import it directly to see its own error\";\n\t\tcase \"plugin-missing-dependency\":\n\t\t\treturn \"the plugin's own dependencies are missing; install them where the plugin lives\";\n\t\tcase \"plugin-not-compiled\":\n\t\t\treturn \"a plugin installed from git or npm must ship compiled javascript; build it and commit or publish the output\";\n\t\tcase \"plugin-invalid-definition\":\n\t\t\treturn \"a plugin module must default-export one object with a `setup` and a `vendor.domain.name` id\";\n\t}\n};\n\nconst settingsHint = (reason: Settings.SettingsError[\"reason\"]): string => {\n\tswitch (reason) {\n\t\tcase \"read\":\n\t\t\treturn \"the file exists but could not be read; check that it is a file and readable\";\n\t\tcase \"parse\":\n\t\t\treturn \"the file is not valid JSON; the location above is where parsing stopped\";\n\t\tcase \"decode\":\n\t\t\treturn \"the key above holds a value this setting does not accept\";\n\t}\n};\n\n/** Render typed SDK errors for humans without exposing Effect causes or provider payloads. */\nexport const renderError = (error: unknown): string => {\n\tif (isSandboxDriverNotRegisteredError(error)) {\n\t\treturn `error: sandbox driver \"${error.driver}\" is not registered (available: ${error.registered?.join(\", \") ?? \"none\"})\\n`;\n\t}\n\tif (isSandboxDriverRegistrationError(error)) {\n\t\treturn `error: ${error.reason}\\n`;\n\t}\n\tif (isInvalidInputError(error)) {\n\t\treturn `error: ${error.message}\\n`;\n\t}\n\tif (isOAuthError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[oauth-credential-error]: ${error.message}`,\n\t\t\t\t...(error.cause === undefined ? [] : [`detail: ${unknownMessage(error.cause)}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSandboxProviderError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error: SandboxProviderError - ${error.sanitized.message}`,\n\t\t\t\t`driver: ${error.driver}`,\n\t\t\t\t`operation: ${error.operation}`,\n\t\t\t\t...(error.sanitized.code === undefined ? [] : [`code: ${error.sanitized.code}`]),\n\t\t\t\t...(error.stack === undefined ? [] : [\"traceback:\", error.stack]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSessionNotLinkedError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${error.reason}]: ${error.message}`,\n\t\t\t\t`session: ${error.sessionId}`,\n\t\t\t\t\"hint: run `codework session link <session-id>` from the directory to anchor it to\",\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSettingsError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[settings-${error.reason}-failed]: ${error.path}`,\n\t\t\t\t`detail: ${error.detail}`,\n\t\t\t\t`hint: ${settingsHint(error.reason)}`,\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\t// One shape for all three plugin domains: the reason is the slug, the message is the sentence,\n\t// and the reference is the string the person recognises from their settings file.\n\tif (\n\t\tisPluginSourceError(error) ||\n\t\tisPluginInstallError(error) ||\n\t\tisPluginStoreError(error) ||\n\t\tisPluginLoadError(error)\n\t) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${error.reason}]: ${error.message}`,\n\t\t\t\t...(error.reference === \"\" ? [] : [`reference: ${error.reference}`]),\n\t\t\t\t...(error.file === undefined ? [] : [`declared in: ${error.file}`]),\n\t\t\t\t...(isPluginLoadError(error) && error.id !== undefined ? [`id: ${error.id}`] : []),\n\t\t\t\t`hint: ${pluginReasonHint(error.reason)}`,\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isProviderError(error)) {\n\t\tconst hint = providerHint(error);\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${providerCategory(error.reason)}]: ${error.message}`,\n\t\t\t\t`provider: ${error.provider}`,\n\t\t\t\t`model: ${error.model}`,\n\t\t\t\t...(error.reason.requestId === undefined ? [] : [`request: ${error.reason.requestId}`]),\n\t\t\t\t...(hint === undefined ? [] : [`hint: ${hint}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isModelCatalogError(error)) {\n\t\treturn (\n\t\t\t[`error[model-catalog-${error.reason}]: ${error.message}`, \"hint: run `codework models refresh`\"].join(\"\\n\") +\n\t\t\t\"\\n\"\n\t\t);\n\t}\n\tif (isModelCatalogRefreshError(error)) {\n\t\treturn (\n\t\t\t[`error[catalog-refresh-failed]: ${error.message}`, \"hint: check the network connection and retry\"].join(\n\t\t\t\t\"\\n\",\n\t\t\t) + \"\\n\"\n\t\t);\n\t}\n\tif (isModelNotFoundError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[model-not-found-error]: ${error.message}`,\n\t\t\t\t\"hint: check the provider/model IDs in models.gen.json or regenerate the catalog\",\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isLLMStreamError(error)) {\n\t\treturn `error[llm-stream-error]: ${error.message}\\n`;\n\t}\n\t// A remote run has only the category the server published; render it the same\n\t// way a local typed error is rendered, minus the detail that stayed server-side.\n\tif (isExecutionError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\terror.type === \"aborted\" ? `error: ${error.message}` : `error[${error.type}]: ${error.message}`,\n\t\t\t\t...(error.status === undefined ? [] : [`status: ${error.status}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\treturn `error: ${unknownMessage(error)}\\n`;\n};\n\nexport const reportFailure = (error: unknown) =>\n\twriteError(renderError(error)).pipe(\n\t\tEffect.andThen(\n\t\t\tEffect.sync(() => {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}),\n\t\t),\n\t);\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as version } from "./package-DyEUYkEq.mjs";
1
+ import { t as version } from "./package-Biq8oAF2.mjs";
2
2
  import { Context, Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from "effect";
3
3
  import { isSea } from "node:sea";
4
4
  //#region src/server/registration.ts
@@ -89,4 +89,4 @@ const layer = Layer.succeed(Service, Service.of(current));
89
89
  //#endregion
90
90
  export { file as a, register as c, command as i, current as n, infoJson as o, layer as r, log as s, Service as t };
91
91
 
92
- //# sourceMappingURL=identity-CSj_73kP.mjs.map
92
+ //# sourceMappingURL=identity-Dl0hQHgK.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity-CSj_73kP.mjs","names":["pkg.version"],"sources":["../../src/server/registration.ts","../../src/server/identity.ts"],"sourcesContent":["import { Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from \"effect\";\nimport { isSea } from \"node:sea\";\n\n/**\n * How a running server advertises itself so later invocations can find it\n * without scanning ports or the process table.\n *\n * The file is a discovery hint, never proof: a caller reads it for the endpoint,\n * then asks the endpoint `server.info` and believes the answer only when the\n * live pid and version match the ones on file. A crashed server leaves a\n * registration behind; the failed probe is what retires it.\n */\nexport const Info = Schema.Struct({\n\t/** Operating system process identifier of the server that wrote this. */\n\tpid: Schema.Int,\n\t/** The build serving this endpoint; a mismatch means a different binary. */\n\tversion: Schema.String,\n\t/** The `ws://host:port/rpc/v1` endpoint a client connects to. */\n\turl: Schema.String,\n\t/** The TCP port the server bound, for a caller that would rather reuse it than default. */\n\tport: Schema.Int,\n});\nexport type Info = typeof Info.Type;\n\nexport const infoJson = Schema.fromJsonString(Info);\n\n/** The registration file for a CodeWork home: `<home>/service.json`. */\nexport const file = (home: string) => `${home}/service.json`;\n\n/** Where a background (`serve --service`) server writes its log: `<log>/server.log`, truncated per start. */\nexport const log = (logDir: string) => `${logDir}/server.log`;\n\nconst decode = Schema.decodeUnknownEffect(infoJson);\n\nexport const write = Effect.fn(\"ServerRegistration.write\")(function* (path: string, info: Info) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst paths = yield* Path.Path;\n\tyield* fs.makeDirectory(paths.dirname(path), { recursive: true });\n\tconst encoded = yield* Schema.encodeEffect(infoJson)(info);\n\t// Write beside the target and rename, so a reader never sees a half-written\n\t// file. 0600 because a future registration may carry a credential.\n\tconst temp = `${path}.${info.pid}.tmp`;\n\tyield* fs.writeFileString(temp, encoded, { mode: 0o600 });\n\tyield* fs.rename(temp, path);\n});\n\n/**\n * Publishes a registration for as long as this server lives, removing it on the\n * way out if it is still the one on file. A file left by a crash is overwritten\n * by the next server to start, and retired by a probe that cannot confirm it.\n *\n * One home has one discoverable server. Every few seconds the file is checked:\n * a missing or unreadable file is written again, and a file naming another\n * server means this one lost discovery for good, so it shuts down rather than\n * run on where nothing can find or stop it.\n */\nexport const register = (options: { readonly home: string; readonly info: Info }) =>\n\tLayer.effectDiscard(\n\t\tEffect.gen(function* () {\n\t\t\tconst path = file(options.home);\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst current = fs.readFileString(path).pipe(Effect.flatMap(decode), Effect.option);\n\t\t\tconst owns = (found: Info) => found.pid === options.info.pid && found.url === options.info.url;\n\n\t\t\tyield* write(path, options.info);\n\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\tcurrent.pipe(\n\t\t\t\t\tEffect.flatMap((found) => (Option.isSome(found) && owns(found.value) ? fs.remove(path) : Effect.void)),\n\t\t\t\t\tEffect.ignore,\n\t\t\t\t),\n\t\t\t);\n\t\t\t// Forked after the finalizer, so shutdown stops the watch before the file is removed.\n\t\t\tyield* current.pipe(\n\t\t\t\tEffect.flatMap((found) =>\n\t\t\t\t\tOption.isNone(found)\n\t\t\t\t\t\t? write(path, options.info).pipe(Effect.ignore, Effect.as(true))\n\t\t\t\t\t\t: Effect.succeed(owns(found.value)),\n\t\t\t\t),\n\t\t\t\tEffect.repeat({ while: (ours) => ours, schedule: Schedule.spaced(\"5 seconds\") }),\n\t\t\t\tEffect.andThen(Effect.logWarning(`${path} names another server; shutting down`)),\n\t\t\t\t// The same graceful path `codework service stop` takes.\n\t\t\t\tEffect.andThen(Effect.sync(() => process.kill(process.pid, \"SIGTERM\"))),\n\t\t\t\tEffect.forkScoped,\n\t\t\t);\n\t\t}),\n\t);\n\n/**\n * The launcher command for a managed server: this same CLI, asked to serve.\n *\n * A packaged install runs `dist/pack/index.mjs`; under `--conditions=development`\n * the entry is TypeScript, and `process.execArgv` carries the conditions forward\n * so a managed server resolves workspace sources the same way this process did.\n * The standalone binary is its own entry.\n */\nexport const command = (): ReadonlyArray<string> => {\n\tif (isSea()) return [process.execPath];\n\tconst entry = process.argv[1];\n\tif (entry === undefined) return [process.execPath];\n\tconst runtime = import.meta.url.endsWith(\".ts\") ? process.execArgv : [];\n\treturn [process.execPath, ...runtime, entry];\n};\n\nexport * as Registration from \"./registration.ts\";\n","import { Context, Layer } from \"effect\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\n/**\n * What a running server is, as its clients need to know it.\n *\n * A discovery registration names the pid and version it wrote; `server.info`\n * answers with the live ones so a caller can tell the process it reached is the\n * one that registered rather than a different server that took the same port.\n */\nexport interface Interface {\n\treadonly pid: number;\n\treadonly version: string;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/identity/Service\") {}\n\n/** This process: a server answers with it, a client compares a server's version against it. */\nexport const current: Interface = { pid: process.pid, version: pkg.version };\n\nexport const layer = Layer.succeed(Service, Service.of(current));\n\nexport * as Identity from \"./identity.ts\";\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAa,OAAO,OAAO,OAAO;;CAEjC,KAAK,OAAO;;CAEZ,SAAS,OAAO;;CAEhB,KAAK,OAAO;;CAEZ,MAAM,OAAO;AACd,CAAC;AAGD,MAAa,WAAW,OAAO,eAAe,IAAI;;AAGlD,MAAa,QAAQ,SAAiB,GAAG,KAAK;;AAG9C,MAAa,OAAO,WAAmB,GAAG,OAAO;AAEjD,MAAM,SAAS,OAAO,oBAAoB,QAAQ;AAElD,MAAa,QAAQ,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAAW,MAAc,MAAY;CAC/F,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,QAAQ,OAAO,KAAK;CAC1B,OAAO,GAAG,cAAc,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAChE,MAAM,UAAU,OAAO,OAAO,aAAa,QAAQ,CAAC,CAAC,IAAI;CAGzD,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,IAAI;CACjC,OAAO,GAAG,gBAAgB,MAAM,SAAS,EAAE,MAAM,IAAM,CAAC;CACxD,OAAO,GAAG,OAAO,MAAM,IAAI;AAC5B,CAAC;;;;;;;;;;;AAYD,MAAa,YAAY,YACxB,MAAM,cACL,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,KAAK,QAAQ,IAAI;CAC9B,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,UAAU,GAAG,eAAe,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG,OAAO,MAAM;CAClF,MAAM,QAAQ,UAAgB,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM,QAAQ,QAAQ,KAAK;CAE3F,OAAO,MAAM,MAAM,QAAQ,IAAI;CAC/B,OAAO,OAAO,mBACb,QAAQ,KACP,OAAO,SAAS,UAAW,OAAO,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,IAAI,IAAI,OAAO,IAAK,GACrG,OAAO,MACR,CACD;CAEA,OAAO,QAAQ,KACd,OAAO,SAAS,UACf,OAAO,OAAO,KAAK,IAChB,MAAM,MAAM,QAAQ,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,GAAG,IAAI,CAAC,IAC7D,OAAO,QAAQ,KAAK,MAAM,KAAK,CAAC,CACpC,GACA,OAAO,OAAO;EAAE,QAAQ,SAAS;EAAM,UAAU,SAAS,OAAO,WAAW;CAAE,CAAC,GAC/E,OAAO,QAAQ,OAAO,WAAW,GAAG,KAAK,qCAAqC,CAAC,GAE/E,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK,QAAQ,KAAK,SAAS,CAAC,CAAC,GACtE,OAAO,UACR;AACD,CAAC,CACF;;;;;;;;;AAUD,MAAa,gBAAuC;CACnD,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,QAAQ;CACrC,MAAM,QAAQ,QAAQ,KAAK;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC,QAAQ,QAAQ;CACjD,MAAM,UAAU,YAAY,IAAI,SAAS,KAAK,IAAI,QAAQ,WAAW,CAAC;CACtE,OAAO;EAAC,QAAQ;EAAU,GAAG;EAAS;CAAK;AAC5C;;;ACtFA,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC;;AAG/G,MAAa,UAAqB;CAAE,KAAK,QAAQ;CAAcA;AAAY;AAE3E,MAAa,QAAQ,MAAM,QAAQ,SAAS,QAAQ,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"identity-Dl0hQHgK.mjs","names":["pkg.version"],"sources":["../../src/server/registration.ts","../../src/server/identity.ts"],"sourcesContent":["import { Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from \"effect\";\nimport { isSea } from \"node:sea\";\n\n/**\n * How a running server advertises itself so later invocations can find it\n * without scanning ports or the process table.\n *\n * The file is a discovery hint, never proof: a caller reads it for the endpoint,\n * then asks the endpoint `server.info` and believes the answer only when the\n * live pid and version match the ones on file. A crashed server leaves a\n * registration behind; the failed probe is what retires it.\n */\nexport const Info = Schema.Struct({\n\t/** Operating system process identifier of the server that wrote this. */\n\tpid: Schema.Int,\n\t/** The build serving this endpoint; a mismatch means a different binary. */\n\tversion: Schema.String,\n\t/** The `ws://host:port/rpc/v1` endpoint a client connects to. */\n\turl: Schema.String,\n\t/** The TCP port the server bound, for a caller that would rather reuse it than default. */\n\tport: Schema.Int,\n});\nexport type Info = typeof Info.Type;\n\nexport const infoJson = Schema.fromJsonString(Info);\n\n/** The registration file for a CodeWork home: `<home>/service.json`. */\nexport const file = (home: string) => `${home}/service.json`;\n\n/** Where a background (`serve --service`) server writes its log: `<log>/server.log`, truncated per start. */\nexport const log = (logDir: string) => `${logDir}/server.log`;\n\nconst decode = Schema.decodeUnknownEffect(infoJson);\n\nexport const write = Effect.fn(\"ServerRegistration.write\")(function* (path: string, info: Info) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst paths = yield* Path.Path;\n\tyield* fs.makeDirectory(paths.dirname(path), { recursive: true });\n\tconst encoded = yield* Schema.encodeEffect(infoJson)(info);\n\t// Write beside the target and rename, so a reader never sees a half-written\n\t// file. 0600 because a future registration may carry a credential.\n\tconst temp = `${path}.${info.pid}.tmp`;\n\tyield* fs.writeFileString(temp, encoded, { mode: 0o600 });\n\tyield* fs.rename(temp, path);\n});\n\n/**\n * Publishes a registration for as long as this server lives, removing it on the\n * way out if it is still the one on file. A file left by a crash is overwritten\n * by the next server to start, and retired by a probe that cannot confirm it.\n *\n * One home has one discoverable server. Every few seconds the file is checked:\n * a missing or unreadable file is written again, and a file naming another\n * server means this one lost discovery for good, so it shuts down rather than\n * run on where nothing can find or stop it.\n */\nexport const register = (options: { readonly home: string; readonly info: Info }) =>\n\tLayer.effectDiscard(\n\t\tEffect.gen(function* () {\n\t\t\tconst path = file(options.home);\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst current = fs.readFileString(path).pipe(Effect.flatMap(decode), Effect.option);\n\t\t\tconst owns = (found: Info) => found.pid === options.info.pid && found.url === options.info.url;\n\n\t\t\tyield* write(path, options.info);\n\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\tcurrent.pipe(\n\t\t\t\t\tEffect.flatMap((found) => (Option.isSome(found) && owns(found.value) ? fs.remove(path) : Effect.void)),\n\t\t\t\t\tEffect.ignore,\n\t\t\t\t),\n\t\t\t);\n\t\t\t// Forked after the finalizer, so shutdown stops the watch before the file is removed.\n\t\t\tyield* current.pipe(\n\t\t\t\tEffect.flatMap((found) =>\n\t\t\t\t\tOption.isNone(found)\n\t\t\t\t\t\t? write(path, options.info).pipe(Effect.ignore, Effect.as(true))\n\t\t\t\t\t\t: Effect.succeed(owns(found.value)),\n\t\t\t\t),\n\t\t\t\tEffect.repeat({ while: (ours) => ours, schedule: Schedule.spaced(\"5 seconds\") }),\n\t\t\t\tEffect.andThen(Effect.logWarning(`${path} names another server; shutting down`)),\n\t\t\t\t// The same graceful path `codework service stop` takes.\n\t\t\t\tEffect.andThen(Effect.sync(() => process.kill(process.pid, \"SIGTERM\"))),\n\t\t\t\tEffect.forkScoped,\n\t\t\t);\n\t\t}),\n\t);\n\n/**\n * The launcher command for a managed server: this same CLI, asked to serve.\n *\n * A packaged install runs `dist/pack/index.mjs`; under `--conditions=development`\n * the entry is TypeScript, and `process.execArgv` carries the conditions forward\n * so a managed server resolves workspace sources the same way this process did.\n * The standalone binary is its own entry.\n */\nexport const command = (): ReadonlyArray<string> => {\n\tif (isSea()) return [process.execPath];\n\tconst entry = process.argv[1];\n\tif (entry === undefined) return [process.execPath];\n\tconst runtime = import.meta.url.endsWith(\".ts\") ? process.execArgv : [];\n\treturn [process.execPath, ...runtime, entry];\n};\n\nexport * as Registration from \"./registration.ts\";\n","import { Context, Layer } from \"effect\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\n/**\n * What a running server is, as its clients need to know it.\n *\n * A discovery registration names the pid and version it wrote; `server.info`\n * answers with the live ones so a caller can tell the process it reached is the\n * one that registered rather than a different server that took the same port.\n */\nexport interface Interface {\n\treadonly pid: number;\n\treadonly version: string;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/identity/Service\") {}\n\n/** This process: a server answers with it, a client compares a server's version against it. */\nexport const current: Interface = { pid: process.pid, version: pkg.version };\n\nexport const layer = Layer.succeed(Service, Service.of(current));\n\nexport * as Identity from \"./identity.ts\";\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAa,OAAO,OAAO,OAAO;;CAEjC,KAAK,OAAO;;CAEZ,SAAS,OAAO;;CAEhB,KAAK,OAAO;;CAEZ,MAAM,OAAO;AACd,CAAC;AAGD,MAAa,WAAW,OAAO,eAAe,IAAI;;AAGlD,MAAa,QAAQ,SAAiB,GAAG,KAAK;;AAG9C,MAAa,OAAO,WAAmB,GAAG,OAAO;AAEjD,MAAM,SAAS,OAAO,oBAAoB,QAAQ;AAElD,MAAa,QAAQ,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAAW,MAAc,MAAY;CAC/F,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,QAAQ,OAAO,KAAK;CAC1B,OAAO,GAAG,cAAc,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAChE,MAAM,UAAU,OAAO,OAAO,aAAa,QAAQ,CAAC,CAAC,IAAI;CAGzD,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,IAAI;CACjC,OAAO,GAAG,gBAAgB,MAAM,SAAS,EAAE,MAAM,IAAM,CAAC;CACxD,OAAO,GAAG,OAAO,MAAM,IAAI;AAC5B,CAAC;;;;;;;;;;;AAYD,MAAa,YAAY,YACxB,MAAM,cACL,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,KAAK,QAAQ,IAAI;CAC9B,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,UAAU,GAAG,eAAe,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG,OAAO,MAAM;CAClF,MAAM,QAAQ,UAAgB,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM,QAAQ,QAAQ,KAAK;CAE3F,OAAO,MAAM,MAAM,QAAQ,IAAI;CAC/B,OAAO,OAAO,mBACb,QAAQ,KACP,OAAO,SAAS,UAAW,OAAO,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,IAAI,IAAI,OAAO,IAAK,GACrG,OAAO,MACR,CACD;CAEA,OAAO,QAAQ,KACd,OAAO,SAAS,UACf,OAAO,OAAO,KAAK,IAChB,MAAM,MAAM,QAAQ,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,GAAG,IAAI,CAAC,IAC7D,OAAO,QAAQ,KAAK,MAAM,KAAK,CAAC,CACpC,GACA,OAAO,OAAO;EAAE,QAAQ,SAAS;EAAM,UAAU,SAAS,OAAO,WAAW;CAAE,CAAC,GAC/E,OAAO,QAAQ,OAAO,WAAW,GAAG,KAAK,qCAAqC,CAAC,GAE/E,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK,QAAQ,KAAK,SAAS,CAAC,CAAC,GACtE,OAAO,UACR;AACD,CAAC,CACF;;;;;;;;;AAUD,MAAa,gBAAuC;CACnD,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,QAAQ;CACrC,MAAM,QAAQ,QAAQ,KAAK;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC,QAAQ,QAAQ;CACjD,MAAM,UAAU,YAAY,IAAI,SAAS,KAAK,IAAI,QAAQ,WAAW,CAAC;CACtE,OAAO;EAAC,QAAQ;EAAU,GAAG;EAAS;CAAK;AAC5C;;;ACtFA,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC;;AAG/G,MAAa,UAAqB;CAAE,KAAK,QAAQ;CAAcA;AAAY;AAE3E,MAAa,QAAQ,MAAM,QAAQ,SAAS,QAAQ,GAAG,OAAO,CAAC"}
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "./package-DyEUYkEq.mjs";
2
+ import { t as version } from "./package-Biq8oAF2.mjs";
3
3
  import { i as Cmd, n as handlers, r as run } from "./runtime-B43doHjV.mjs";
4
4
  import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
5
5
  import * as NodeServices from "@effect/platform-node/NodeServices";
@@ -7,35 +7,35 @@ import { Effect } from "effect";
7
7
  //#region src/index.ts
8
8
  const Handlers = handlers(Cmd, {
9
9
  auth: {
10
- login: () => import("./login-lsagcqp6.mjs"),
11
- status: () => import("./status-CQHqU7_7.mjs"),
12
- refresh: () => import("./refresh-Cbq-iY3f.mjs"),
13
- logout: () => import("./logout-DdkYEWM6.mjs")
10
+ login: () => import("./login-CRwxi5WD.mjs"),
11
+ status: () => import("./status-DVzFDoek.mjs"),
12
+ refresh: () => import("./refresh-D0wBP2Go.mjs"),
13
+ logout: () => import("./logout-C89X0B9M.mjs")
14
14
  },
15
- run: () => import("./run-DIFNYGN-.mjs"),
16
- tui: () => import("./tui-BGZPK8sC.mjs"),
17
- serve: () => import("./serve-jhJP26fG.mjs"),
15
+ run: () => import("./run-CVRkm_Iz.mjs"),
16
+ tui: () => import("./tui-Bk0VBJIB.mjs"),
17
+ serve: () => import("./serve-D2BTAZpR.mjs"),
18
18
  service: {
19
- start: () => import("./start-BBGmLmro.mjs"),
20
- restart: () => import("./restart-C0FtXDtK.mjs"),
21
- status: () => import("./status-BmpmqhUX.mjs"),
22
- stop: () => import("./stop-DHzqbCeB.mjs")
19
+ start: () => import("./start-Bkk-Y6yE.mjs"),
20
+ restart: () => import("./restart-D3QLTXxy.mjs"),
21
+ status: () => import("./status-BhkBSKLd.mjs"),
22
+ stop: () => import("./stop-COTZBIML.mjs")
23
23
  },
24
- session: { link: () => import("./link-BiwLQTXW.mjs") },
25
- acp: () => import("./acp-XRYX2dyw.mjs"),
24
+ session: { link: () => import("./link--UnM2qnT.mjs") },
25
+ acp: () => import("./acp-BPiMP9SV.mjs"),
26
26
  plugin: {
27
- add: () => import("./add-Cih66f0Z.mjs"),
28
- check: () => import("./check-CWXDjuC1.mjs"),
29
- install: () => import("./install-CRGaL_bc.mjs"),
30
- list: () => import("./list-Daq_zh4E.mjs"),
31
- reload: () => import("./reload-C6c48hBY.mjs"),
32
- remove: () => import("./remove-lig66J-D.mjs"),
33
- update: () => import("./update-CfrkcWoW.mjs")
27
+ add: () => import("./add-Dzsv-fKd.mjs"),
28
+ check: () => import("./check-DhojkK_E.mjs"),
29
+ install: () => import("./install-BLRDBzp1.mjs"),
30
+ list: () => import("./list-BE4xSEe3.mjs"),
31
+ reload: () => import("./reload-DgPawyzr.mjs"),
32
+ remove: () => import("./remove-DfFme5w2.mjs"),
33
+ update: () => import("./update-D0XPVfJu.mjs")
34
34
  },
35
35
  models: {
36
- $: () => import("./list-BvBVZtHt.mjs"),
37
- providers: () => import("./providers-CZmPKpb_.mjs"),
38
- refresh: () => import("./refresh-BFxZjrH1.mjs")
36
+ $: () => import("./list-9fVqelid.mjs"),
37
+ providers: () => import("./providers-BrXJvY2P.mjs"),
38
+ refresh: () => import("./refresh--j0Pj4Cw.mjs")
39
39
  }
40
40
  });
41
41
  const main = run(Cmd, Handlers, { version }).pipe(Effect.provide(NodeServices.layer));
@@ -1,6 +1,6 @@
1
1
  import { i as Cmd, t as handler } from "./runtime-B43doHjV.mjs";
2
- import { d as writeOut, i as reportFailure } from "./error-CzUxh0Q9.mjs";
3
- import { i as read, t as fetchable } from "./entries-8LFGwy4n.mjs";
2
+ import { d as writeOut, i as reportFailure } from "./error-BMI81XvR.mjs";
3
+ import { i as read, t as fetchable } from "./entries-KpYvZdpi.mjs";
4
4
  import { Effect } from "effect";
5
5
  import { Plugin } from "@codeworksh/harness/effect";
6
6
  //#region src/cli/cmd/handlers/plugin/install.ts
@@ -51,4 +51,4 @@ var install_default = handler(Cmd.commands.plugin.commands.install, Effect.fn("C
51
51
  //#endregion
52
52
  export { install_default as default };
53
53
 
54
- //# sourceMappingURL=install-CRGaL_bc.mjs.map
54
+ //# sourceMappingURL=install-BLRDBzp1.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"install-CRGaL_bc.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/plugin/install.ts"],"sourcesContent":["import { Plugin } from \"@codeworksh/harness/effect\";\nimport { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { fetchable, read } from \"./entries.ts\";\n\n/**\n * `plugin install`, with no argument: the answer to a fresh checkout.\n *\n * A committed `.codework/settings.jsonc` names plugins, the store on a colleague's machine is\n * empty, and something has to materialise them. This is `npm install` with no arguments -- it\n * writes no settings entry, because the entries already exist.\n *\n * It is also what lets **boot stay offline**. Without it the only path from an entry to bytes is a\n * boot that installs, which makes every fresh start a possible network wait; with it, boot\n * resolves or reports, and the error names this command as the remedy.\n */\nexport default Runtime.handler(\n\tCmd.commands.plugin.commands.install,\n\tEffect.fn(\"CLI.plugin.install\")(function* () {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst shared = yield* Cmd.spec;\n\t\t\tconst { entries, cache } = yield* read(shared);\n\n\t\t\tlet installed = 0;\n\t\t\tlet present = 0;\n\t\t\tlet local = 0;\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst target = fetchable(entry.target);\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\t// A local plugin is loaded where it lies and never copied into the store, so\n\t\t\t\t\t// there is nothing to install. An unparseable entry is `list`'s to report.\n\t\t\t\t\tlocal += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ((yield* Plugin.resolve(target, cache, entry.from)) !== undefined) {\n\t\t\t\t\tpresent += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// `inspect` installs, imports and validates, so a spec that turns out not to be a\n\t\t\t\t// plugin fails here rather than at the next run. The reported ID comes from the\n\t\t\t\t// module, never from the spec.\n\t\t\t\tconst plugin = yield* Plugin.inspect(entry.reference, { cache, hostDir: entry.from, file: entry.file });\n\t\t\t\tinstalled += 1;\n\t\t\t\tyield* writeOut(`Installed ${entry.reference} (${plugin.id})\\n`);\n\t\t\t}\n\n\t\t\tconst parts = [\n\t\t\t\t`${installed} installed`,\n\t\t\t\t...(present === 0 ? [] : [`${present} already present`]),\n\t\t\t\t...(local === 0 ? [] : [`${local} local`]),\n\t\t\t];\n\t\t\tyield* writeOut(`${parts.join(\", \")}\\n`);\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAA,kBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,SAC7B,OAAO,GAAG,oBAAoB,CAAC,CAAC,aAAa;CAoC5C,OAAO,OAnCS,OAAO,IAAI,aAAa;EACvC,MAAM,SAAS,OAAO,IAAI;EAC1B,MAAM,EAAE,SAAS,UAAU,OAAO,KAAK,MAAM;EAE7C,IAAI,YAAY;EAChB,IAAI,UAAU;EACd,IAAI,QAAQ;EACZ,KAAK,MAAM,SAAS,SAAS;GAC5B,MAAM,SAAS,UAAU,MAAM,MAAM;GACrC,IAAI,WAAW,KAAA,GAAW;IAGzB,SAAS;IACT;GACD;GACA,KAAK,OAAO,OAAO,QAAQ,QAAQ,OAAO,MAAM,IAAI,OAAO,KAAA,GAAW;IACrE,WAAW;IACX;GACD;GAIA,MAAM,SAAS,OAAO,OAAO,QAAQ,MAAM,WAAW;IAAE;IAAO,SAAS,MAAM;IAAM,MAAM,MAAM;GAAK,CAAC;GACtG,aAAa;GACb,OAAO,SAAS,aAAa,MAAM,UAAU,IAAI,OAAO,GAAG,IAAI;EAChE;EAEA,MAAM,QAAQ;GACb,GAAG,UAAU;GACb,GAAI,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,iBAAiB;GACtD,GAAI,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO;EACzC;EACA,OAAO,SAAS,GAAG,MAAM,KAAK,IAAI,EAAE,GAAG;CACxC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
1
+ {"version":3,"file":"install-BLRDBzp1.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/plugin/install.ts"],"sourcesContent":["import { Plugin } from \"@codeworksh/harness/effect\";\nimport { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { fetchable, read } from \"./entries.ts\";\n\n/**\n * `plugin install`, with no argument: the answer to a fresh checkout.\n *\n * A committed `.codework/settings.jsonc` names plugins, the store on a colleague's machine is\n * empty, and something has to materialise them. This is `npm install` with no arguments -- it\n * writes no settings entry, because the entries already exist.\n *\n * It is also what lets **boot stay offline**. Without it the only path from an entry to bytes is a\n * boot that installs, which makes every fresh start a possible network wait; with it, boot\n * resolves or reports, and the error names this command as the remedy.\n */\nexport default Runtime.handler(\n\tCmd.commands.plugin.commands.install,\n\tEffect.fn(\"CLI.plugin.install\")(function* () {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst shared = yield* Cmd.spec;\n\t\t\tconst { entries, cache } = yield* read(shared);\n\n\t\t\tlet installed = 0;\n\t\t\tlet present = 0;\n\t\t\tlet local = 0;\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst target = fetchable(entry.target);\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\t// A local plugin is loaded where it lies and never copied into the store, so\n\t\t\t\t\t// there is nothing to install. An unparseable entry is `list`'s to report.\n\t\t\t\t\tlocal += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ((yield* Plugin.resolve(target, cache, entry.from)) !== undefined) {\n\t\t\t\t\tpresent += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// `inspect` installs, imports and validates, so a spec that turns out not to be a\n\t\t\t\t// plugin fails here rather than at the next run. The reported ID comes from the\n\t\t\t\t// module, never from the spec.\n\t\t\t\tconst plugin = yield* Plugin.inspect(entry.reference, { cache, hostDir: entry.from, file: entry.file });\n\t\t\t\tinstalled += 1;\n\t\t\t\tyield* writeOut(`Installed ${entry.reference} (${plugin.id})\\n`);\n\t\t\t}\n\n\t\t\tconst parts = [\n\t\t\t\t`${installed} installed`,\n\t\t\t\t...(present === 0 ? [] : [`${present} already present`]),\n\t\t\t\t...(local === 0 ? [] : [`${local} local`]),\n\t\t\t];\n\t\t\tyield* writeOut(`${parts.join(\", \")}\\n`);\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAA,kBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,SAC7B,OAAO,GAAG,oBAAoB,CAAC,CAAC,aAAa;CAoC5C,OAAO,OAnCS,OAAO,IAAI,aAAa;EACvC,MAAM,SAAS,OAAO,IAAI;EAC1B,MAAM,EAAE,SAAS,UAAU,OAAO,KAAK,MAAM;EAE7C,IAAI,YAAY;EAChB,IAAI,UAAU;EACd,IAAI,QAAQ;EACZ,KAAK,MAAM,SAAS,SAAS;GAC5B,MAAM,SAAS,UAAU,MAAM,MAAM;GACrC,IAAI,WAAW,KAAA,GAAW;IAGzB,SAAS;IACT;GACD;GACA,KAAK,OAAO,OAAO,QAAQ,QAAQ,OAAO,MAAM,IAAI,OAAO,KAAA,GAAW;IACrE,WAAW;IACX;GACD;GAIA,MAAM,SAAS,OAAO,OAAO,QAAQ,MAAM,WAAW;IAAE;IAAO,SAAS,MAAM;IAAM,MAAM,MAAM;GAAK,CAAC;GACtG,aAAa;GACb,OAAO,SAAS,aAAa,MAAM,UAAU,IAAI,OAAO,GAAG,IAAI;EAChE;EAEA,MAAM,QAAQ;GACb,GAAG,UAAU;GACb,GAAI,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,iBAAiB;GACtD,GAAI,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO;EACzC;EACA,OAAO,SAAS,GAAG,MAAM,KAAK,IAAI,EAAE,GAAG;CACxC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
@@ -1,5 +1,5 @@
1
1
  import { i as Cmd, t as handler } from "./runtime-B43doHjV.mjs";
2
- import { d as writeOut, f as layer, i as reportFailure, p as make } from "./error-CzUxh0Q9.mjs";
2
+ import { d as writeOut, f as layer, i as reportFailure, p as make } from "./error-BMI81XvR.mjs";
3
3
  import { Effect, Option, Path } from "effect";
4
4
  import { Session } from "@codeworksh/harness/effect";
5
5
  //#region src/cli/cmd/handlers/session/link.ts
@@ -38,4 +38,4 @@ var link_default = handler(Cmd.commands.session.commands.link, Effect.fn("CLI.se
38
38
  //#endregion
39
39
  export { link_default as default };
40
40
 
41
- //# sourceMappingURL=link-BiwLQTXW.mjs.map
41
+ //# sourceMappingURL=link--UnM2qnT.mjs.map