priiisk 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1185 @@
1
+ import { createRequire as __priiiskCreateRequire } from "node:module";
2
+ const require = __priiiskCreateRequire(import.meta.url);
3
+ import {
4
+ CampProtocol,
5
+ CampSurface,
6
+ CommandExecutor_exports,
7
+ Command_exports,
8
+ PRIIISK_PROTOCOL_VERSION,
9
+ ProtocolClientKind,
10
+ RpcClient_exports,
11
+ RpcSerialization_exports,
12
+ SurfaceActivity,
13
+ SurfaceError,
14
+ SurfaceErrorCode,
15
+ SurfaceOwnership,
16
+ SurfacePresence,
17
+ campProjectPaths,
18
+ ensureSurfaceHandleClosable,
19
+ ensureSurfaceHandleProvider,
20
+ layerNet,
21
+ makeCampSurfaceName,
22
+ resolveProjectScopeSync
23
+ } from "./chunk-RJO6Z3SQ.js";
24
+ import {
25
+ Clock_exports,
26
+ Config_exports,
27
+ Context_exports,
28
+ Data_exports,
29
+ Deferred_exports,
30
+ Duration_exports,
31
+ Effect_exports,
32
+ Either_exports,
33
+ FiberRef_exports,
34
+ Layer_exports,
35
+ Option_exports,
36
+ Ref_exports,
37
+ Schedule_exports,
38
+ Schema_exports,
39
+ Stream_exports
40
+ } from "./chunk-KFSFN6L5.js";
41
+
42
+ // packages/cli/src/doctor/doctorModel.ts
43
+ var DOCTOR_REPORT_SCHEMA_VERSION = 1;
44
+ var DoctorCheckStatus = {
45
+ pass: "pass",
46
+ warning: "warning",
47
+ failure: "failure",
48
+ skipped: "skipped"
49
+ };
50
+ var DoctorOverallStatus = {
51
+ healthy: "healthy",
52
+ degraded: "degraded",
53
+ failed: "failed"
54
+ };
55
+ var DoctorCheckSchema = Schema_exports.Struct({
56
+ id: Schema_exports.String.pipe(Schema_exports.minLength(1)),
57
+ status: Schema_exports.Literal(...Object.values(DoctorCheckStatus)),
58
+ summary: Schema_exports.String.pipe(Schema_exports.minLength(1)),
59
+ details: Schema_exports.optional(Schema_exports.Record({ key: Schema_exports.String, value: Schema_exports.Unknown }))
60
+ });
61
+ var DoctorReportSchema = Schema_exports.Struct({
62
+ schemaVersion: Schema_exports.Literal(DOCTOR_REPORT_SCHEMA_VERSION),
63
+ overallStatus: Schema_exports.Literal(...Object.values(DoctorOverallStatus)),
64
+ checkedAt: Schema_exports.Number.pipe(Schema_exports.int(), Schema_exports.nonNegative()),
65
+ projectHash: Schema_exports.optional(Schema_exports.String.pipe(Schema_exports.minLength(1))),
66
+ checks: Schema_exports.Array(DoctorCheckSchema)
67
+ });
68
+ var doctorCheck = (id, status, summary, details) => ({
69
+ id,
70
+ status,
71
+ summary,
72
+ ...details === void 0 ? {} : { details }
73
+ });
74
+ var makeDoctorReport = (checks, checkedAt, projectHash) => ({
75
+ schemaVersion: DOCTOR_REPORT_SCHEMA_VERSION,
76
+ overallStatus: checks.some((check) => check.status === DoctorCheckStatus.failure) ? DoctorOverallStatus.failed : checks.some((check) => check.status === DoctorCheckStatus.warning) ? DoctorOverallStatus.degraded : DoctorOverallStatus.healthy,
77
+ checkedAt,
78
+ ...projectHash === void 0 ? {} : { projectHash },
79
+ checks
80
+ });
81
+ var doctorErrorMessage = (cause) => (cause instanceof Error ? cause.message : String(cause)).slice(-2048);
82
+
83
+ // packages/cli/src/client/campRpcRuntime.ts
84
+ import { existsSync } from "node:fs";
85
+
86
+ // packages/cli/src/domain/cliErrors.ts
87
+ var CliRpcTimeout = class extends Data_exports.TaggedError("CliRpcTimeout") {
88
+ };
89
+ var CliCampNotRunning = class extends Data_exports.TaggedError("CliCampNotRunning") {
90
+ };
91
+ var CliTurnWaitTimeout = class extends Data_exports.TaggedError("CliTurnWaitTimeout") {
92
+ };
93
+ var CliMessageSourceError = class extends Data_exports.TaggedError("CliMessageSourceError") {
94
+ };
95
+ var CliEquipmentConflict = class extends Data_exports.TaggedError("CliEquipmentConflict") {
96
+ };
97
+ var CliCampLifecycleError = class extends Data_exports.TaggedError("CliCampLifecycleError") {
98
+ };
99
+ var CliGenerationChanged = class extends Data_exports.TaggedError("CliGenerationChanged") {
100
+ };
101
+ var CliStdioRequestInvalid = class extends Data_exports.TaggedError("CliStdioRequestInvalid") {
102
+ };
103
+ var CliStdioCommandCancelled = class extends Data_exports.TaggedError("CliStdioCommandCancelled") {
104
+ };
105
+ var CliStdioStreamFailure = class extends Data_exports.TaggedError("CliStdioStreamFailure") {
106
+ };
107
+ var CliSurfaceSelectionError = class extends Data_exports.TaggedError("CliSurfaceSelectionError") {
108
+ };
109
+
110
+ // packages/cli/src/client/campRpcConnection.ts
111
+ import { randomUUID } from "node:crypto";
112
+
113
+ // packages/cli/src/domain/cliVersion.ts
114
+ var PRIIISK_CLI_VERSION = "0.1.1";
115
+
116
+ // packages/cli/src/client/campRpcConnection.ts
117
+ var PRIIISK_CONTROLLER_ID_ENV = "PRIIISK_CONTROLLER_ID";
118
+ var PRIIISK_CONSUMER_ID_ENV = "PRIIISK_CONSUMER_ID";
119
+ var protocolRetrySchedule = Schedule_exports.exponential("50 millis").pipe(
120
+ Schedule_exports.intersect(Schedule_exports.recurs(5))
121
+ );
122
+ var trimmedEnvironment = (name) => {
123
+ const value = process.env[name]?.trim();
124
+ return value === void 0 || value === "" ? void 0 : value;
125
+ };
126
+ var makeClientContext = (projectHash, consumerId) => {
127
+ const configured = trimmedEnvironment(PRIIISK_CONTROLLER_ID_ENV);
128
+ const configuredConsumer = consumerId?.trim();
129
+ return {
130
+ protocolVersion: PRIIISK_PROTOCOL_VERSION,
131
+ clientVersion: PRIIISK_CLI_VERSION,
132
+ projectHash,
133
+ controllerId: configured ?? `orchestrator-${projectHash}`,
134
+ consumerId: configuredConsumer === void 0 || configuredConsumer === "" ? trimmedEnvironment(PRIIISK_CONSUMER_ID_ENV) ?? `cli-${randomUUID()}` : configuredConsumer,
135
+ clientKind: ProtocolClientKind.orchestrator
136
+ };
137
+ };
138
+ var makeCampProtocolLayer = (socketPath, options) => Effect_exports.gen(function* () {
139
+ const retryState = yield* Ref_exports.make({
140
+ attempt: 0
141
+ });
142
+ const retrySchedule = protocolRetrySchedule.pipe(
143
+ Schedule_exports.tapInput(
144
+ (cause) => Ref_exports.update(retryState, (current) => ({ ...current, cause }))
145
+ ),
146
+ Schedule_exports.onDecision(
147
+ (_output, decision) => decision._tag === "Done" ? Effect_exports.void : Ref_exports.modify(retryState, (current) => {
148
+ const next = { attempt: current.attempt + 1, cause: current.cause };
149
+ return [next, next];
150
+ }).pipe(
151
+ Effect_exports.flatMap(
152
+ ({ attempt, cause }) => Clock_exports.currentTimeMillis.pipe(
153
+ Effect_exports.flatMap(
154
+ (now) => options.onRetry?.({
155
+ operation: options.operation,
156
+ attempt,
157
+ nextRetryAt: now + 50 * 2 ** (attempt - 1),
158
+ message: cause instanceof Error ? cause.message : String(cause)
159
+ }) ?? Effect_exports.void
160
+ )
161
+ )
162
+ )
163
+ )
164
+ )
165
+ );
166
+ return RpcClient_exports.layerProtocolSocket({
167
+ retryTransientErrors: options.retryTransientErrors ?? false,
168
+ retrySchedule
169
+ }).pipe(
170
+ Layer_exports.provide(RpcSerialization_exports.layerNdjson),
171
+ Layer_exports.provide(layerNet({ path: socketPath }))
172
+ );
173
+ });
174
+ var makeCampProtocolContext = (socketPath, options) => makeCampProtocolLayer(socketPath, options).pipe(Effect_exports.flatMap(Layer_exports.build));
175
+ var makeCommandFactory = (client, context, operation, acceptedGeneration) => (
176
+ /*
177
+ * A one-shot command adopts whatever generation the handshake reports. A
178
+ * session command must not: the host may have restarted since the client
179
+ * reconciled, and applying the command under the new epoch would hide it.
180
+ */
181
+ (commandId = randomUUID()) => client.Handshake(context).pipe(
182
+ Effect_exports.flatMap((handshake) => {
183
+ const bound = { ...context, generation: handshake.generation, commandId };
184
+ if (acceptedGeneration === void 0) return Effect_exports.succeed(bound);
185
+ return Ref_exports.get(acceptedGeneration).pipe(
186
+ Effect_exports.flatMap(
187
+ (accepted) => accepted === void 0 || accepted === handshake.generation ? Effect_exports.succeed(bound) : Effect_exports.fail(
188
+ new CliGenerationChanged({
189
+ operation,
190
+ code: "session_generation_changed",
191
+ recoveryAction: "reconcile_snapshot",
192
+ acceptedGeneration: accepted,
193
+ currentGeneration: handshake.generation,
194
+ message: `host generation changed from ${accepted} to ${handshake.generation}; reconcile before sending commands`
195
+ })
196
+ )
197
+ )
198
+ );
199
+ })
200
+ )
201
+ );
202
+
203
+ // packages/cli/src/client/campRpcRuntime.ts
204
+ var isTransportFailure = (error) => {
205
+ if (typeof error !== "object" || error === null) return false;
206
+ const tag = error._tag;
207
+ return tag === "RpcClientError" || tag === "SocketError" || tag === "SocketGenericError";
208
+ };
209
+ var activeCampRpc = FiberRef_exports.unsafeMake(void 0);
210
+ var SESSION_CONNECT_TIMEOUT_MS = 3e4;
211
+ var releaseCampRpcConnection = FiberRef_exports.get(activeCampRpc).pipe(
212
+ Effect_exports.flatMap((active) => active?.release ?? Effect_exports.void)
213
+ );
214
+ var withCampRpc = (use, options) => {
215
+ const scope = resolveProjectScopeSync();
216
+ const { socketPath } = campProjectPaths(scope);
217
+ const timeoutMs = options.timeoutMs ?? 5e3;
218
+ const bounded = (effect) => timeoutMs === "none" ? effect : effect.pipe(
219
+ Effect_exports.timeoutFail({
220
+ duration: timeoutMs,
221
+ onTimeout: () => new CliRpcTimeout({ operation: options.operation, timeoutMs })
222
+ })
223
+ );
224
+ const run = Effect_exports.gen(function* () {
225
+ if (options.expectRunning !== false && !existsSync(socketPath)) {
226
+ yield* releaseCampRpcConnection;
227
+ return yield* Effect_exports.fail(
228
+ new CliCampNotRunning({
229
+ operation: options.operation,
230
+ projectHash: scope.hash,
231
+ code: "camp_not_running",
232
+ message: "camp \u043D\u0435 \u0437\u0430\u043F\u0443\u0449\u0435\u043D \u0432 \u044D\u0442\u043E\u043C project scope",
233
+ recoveryAction: "camp_up"
234
+ })
235
+ );
236
+ }
237
+ const active = yield* FiberRef_exports.get(activeCampRpc);
238
+ if (active !== void 0) {
239
+ const connection = yield* active.connect;
240
+ const context = makeClientContext(
241
+ active.projectHash,
242
+ options.consumerId ?? active.consumerId
243
+ );
244
+ return yield* bounded(
245
+ use({
246
+ client: connection.client,
247
+ context,
248
+ command: makeCommandFactory(
249
+ connection.client,
250
+ context,
251
+ options.operation,
252
+ active.acceptedGeneration
253
+ ),
254
+ socketPath: connection.socketPath
255
+ }).pipe(
256
+ Effect_exports.provide(connection.protocol),
257
+ Effect_exports.tapError(
258
+ (error) => isTransportFailure(error) ? active.invalidate(connection) : Effect_exports.void
259
+ )
260
+ )
261
+ );
262
+ }
263
+ const protocolLayer = yield* makeCampProtocolLayer(socketPath, options);
264
+ return yield* bounded(
265
+ Effect_exports.scoped(
266
+ RpcClient_exports.make(CampProtocol).pipe(
267
+ Effect_exports.flatMap((client) => {
268
+ const context = makeClientContext(scope.hash, options.consumerId);
269
+ return use({
270
+ client,
271
+ context,
272
+ command: makeCommandFactory(client, context, options.operation),
273
+ socketPath
274
+ });
275
+ }),
276
+ Effect_exports.provide(protocolLayer)
277
+ )
278
+ )
279
+ );
280
+ });
281
+ return run;
282
+ };
283
+ var withCampRpcSession = (use, options) => Effect_exports.scoped(
284
+ Effect_exports.gen(function* () {
285
+ const sessionScope = yield* Effect_exports.scope;
286
+ const project = resolveProjectScopeSync();
287
+ const { socketPath } = campProjectPaths(project);
288
+ const context = makeClientContext(project.hash, options.consumerId);
289
+ const acceptedGeneration = yield* Ref_exports.make(void 0);
290
+ const connectionRef = yield* Ref_exports.make(void 0);
291
+ const gate = yield* Effect_exports.makeSemaphore(1);
292
+ const open = Effect_exports.gen(function* () {
293
+ const ready = yield* Deferred_exports.make();
294
+ const held = yield* Deferred_exports.make();
295
+ const holder = Effect_exports.gen(function* () {
296
+ const protocol = yield* makeCampProtocolContext(socketPath, options);
297
+ const client = yield* RpcClient_exports.make(CampProtocol).pipe(Effect_exports.provide(protocol));
298
+ const handshake = yield* client.Handshake(context).pipe(Effect_exports.provide(protocol));
299
+ const connection = {
300
+ client,
301
+ socketPath,
302
+ protocol,
303
+ release: Deferred_exports.succeed(held, void 0).pipe(Effect_exports.asVoid)
304
+ };
305
+ yield* Ref_exports.update(acceptedGeneration, (current) => current ?? handshake.generation);
306
+ yield* Ref_exports.set(connectionRef, connection);
307
+ yield* options.onConnect?.(handshake) ?? Effect_exports.void;
308
+ yield* Deferred_exports.succeed(ready, connection);
309
+ yield* Deferred_exports.await(held);
310
+ });
311
+ yield* Effect_exports.forkIn(
312
+ Effect_exports.scoped(holder).pipe(
313
+ Effect_exports.onError(
314
+ (cause) => Ref_exports.set(connectionRef, void 0).pipe(
315
+ Effect_exports.zipRight(Deferred_exports.failCause(ready, cause)),
316
+ Effect_exports.asVoid
317
+ )
318
+ )
319
+ ),
320
+ sessionScope
321
+ );
322
+ return yield* Deferred_exports.await(ready);
323
+ });
324
+ const invalidate = (connection) => gate.withPermits(1)(
325
+ Ref_exports.get(connectionRef).pipe(
326
+ Effect_exports.flatMap(
327
+ (current) => current === connection ? Ref_exports.set(connectionRef, void 0).pipe(Effect_exports.zipRight(connection.release)) : Effect_exports.void
328
+ )
329
+ )
330
+ );
331
+ const connect = gate.withPermits(1)(
332
+ Ref_exports.get(connectionRef).pipe(
333
+ Effect_exports.flatMap((current) => current === void 0 ? open : Effect_exports.succeed(current))
334
+ )
335
+ ).pipe(
336
+ Effect_exports.timeoutFail({
337
+ duration: SESSION_CONNECT_TIMEOUT_MS,
338
+ onTimeout: () => new CliRpcTimeout({
339
+ operation: `${options.operation}.connect`,
340
+ timeoutMs: SESSION_CONNECT_TIMEOUT_MS
341
+ })
342
+ })
343
+ );
344
+ const release = gate.withPermits(1)(
345
+ Ref_exports.get(connectionRef).pipe(
346
+ Effect_exports.flatMap(
347
+ (current) => current === void 0 ? Effect_exports.void : Ref_exports.set(connectionRef, void 0).pipe(Effect_exports.zipRight(current.release))
348
+ )
349
+ )
350
+ );
351
+ return yield* Effect_exports.locally(activeCampRpc, {
352
+ projectHash: project.hash,
353
+ consumerId: context.consumerId,
354
+ acceptedGeneration,
355
+ connect,
356
+ invalidate,
357
+ release
358
+ })(use({ projectHash: project.hash, socketPath }));
359
+ })
360
+ );
361
+ var acceptCampGeneration = (generation) => FiberRef_exports.get(activeCampRpc).pipe(
362
+ Effect_exports.flatMap(
363
+ (active) => active === void 0 ? Effect_exports.void : Ref_exports.set(active.acceptedGeneration, generation)
364
+ )
365
+ );
366
+
367
+ // packages/surface-herdr/src/domain/herdrErrors.ts
368
+ var HerdrUnavailableError = class extends Data_exports.TaggedError("HerdrUnavailableError") {
369
+ };
370
+ var HerdrTimeoutError = class extends Data_exports.TaggedError("HerdrTimeoutError") {
371
+ };
372
+ var HerdrCommandError = class extends Data_exports.TaggedError("HerdrCommandError") {
373
+ };
374
+ var HerdrApiError = class extends Data_exports.TaggedError("HerdrApiError") {
375
+ };
376
+ var HerdrEnvelopeError = class extends Data_exports.TaggedError("HerdrEnvelopeError") {
377
+ };
378
+ var HerdrRollbackError = class extends Data_exports.TaggedError("HerdrRollbackError") {
379
+ };
380
+
381
+ // packages/surface-herdr/src/commands/herdrOutput.ts
382
+ var ApiErrorEnvelopeSchema = Schema_exports.Struct({
383
+ error: Schema_exports.Struct({ code: Schema_exports.String, message: Schema_exports.String })
384
+ });
385
+ var isApiErrorEnvelope = Schema_exports.is(ApiErrorEnvelopeSchema);
386
+ var emptyOutputTail = () => ({
387
+ bytes: new Uint8Array(),
388
+ truncated: false
389
+ });
390
+ var appendOutputTail = (current, chunk, limit) => {
391
+ const combined = Buffer.concat([Buffer.from(current.bytes), Buffer.from(chunk)]);
392
+ const overflowed = combined.length > limit;
393
+ return {
394
+ bytes: overflowed ? combined.subarray(combined.length - limit) : combined,
395
+ truncated: current.truncated || overflowed
396
+ };
397
+ };
398
+ var redactHerdrOutput = (text, values) => [...new Set(values.filter((value) => value !== ""))].sort((left, right) => right.length - left.length).reduce((current, value) => current.replaceAll(value, "<redacted>"), text);
399
+ var renderOutputTail = (output, redactions) => redactHerdrOutput(Buffer.from(output.bytes).toString("utf8"), redactions);
400
+ var parseJson = (text) => {
401
+ const trimmed = text.trim();
402
+ if (trimmed === "") return {};
403
+ try {
404
+ return { value: JSON.parse(trimmed) };
405
+ } catch (cause) {
406
+ return { cause };
407
+ }
408
+ };
409
+ var HerdrResponseMode = {
410
+ emptyOk: "empty-ok",
411
+ json: "json",
412
+ raw: "raw"
413
+ };
414
+ var isHerdrRawOutput = (value) => typeof value === "object" && value !== null && "text" in value && typeof value.text === "string" && "truncated" in value && typeof value.truncated === "boolean";
415
+ var decodeHerdrOutput = (captured, responseMode) => {
416
+ const stdout = parseJson(captured.stdoutTail);
417
+ const stderr = parseJson(captured.stderrTail);
418
+ const apiError = isApiErrorEnvelope(stdout.value) ? stdout.value : isApiErrorEnvelope(stderr.value) ? stderr.value : void 0;
419
+ if (apiError !== void 0) {
420
+ return Effect_exports.fail(
421
+ new HerdrApiError({
422
+ args: captured.args,
423
+ code: apiError.error.code,
424
+ message: apiError.error.message
425
+ })
426
+ );
427
+ }
428
+ if (responseMode === HerdrResponseMode.raw && captured.exitCode === 0) {
429
+ return Effect_exports.succeed({
430
+ text: captured.stdoutTail,
431
+ truncated: captured.stdoutTruncated
432
+ });
433
+ }
434
+ if (responseMode === HerdrResponseMode.emptyOk && captured.exitCode === 0 && stdout.cause === void 0 && stdout.value === void 0) {
435
+ return Effect_exports.succeed(void 0);
436
+ }
437
+ if (captured.exitCode !== 0 || stdout.cause !== void 0 || stdout.value === void 0) {
438
+ return Effect_exports.fail(
439
+ new HerdrCommandError({
440
+ ...captured,
441
+ cause: stdout.cause
442
+ })
443
+ );
444
+ }
445
+ return Effect_exports.succeed(stdout.value);
446
+ };
447
+
448
+ // packages/surface-herdr/src/commands/herdrCli.ts
449
+ var DEFAULT_TIMEOUT_MS = 5e3;
450
+ var DEFAULT_OUTPUT_TAIL_BYTES = 16 * 1024;
451
+ var SPAWN_RETRY = Schedule_exports.exponential(Duration_exports.millis(50)).pipe(
452
+ Schedule_exports.intersect(Schedule_exports.recurs(2))
453
+ );
454
+ var HerdrCli = class extends Context_exports.Tag("priiisk/SurfaceHerdr/HerdrCli")() {
455
+ };
456
+ var resolveCommandPrefix = (options) => options.commandPrefix === void 0 ? Config_exports.string("PRIIISK_HERDR_BIN").pipe(
457
+ Config_exports.withDefault("herdr"),
458
+ Effect_exports.map((executable) => [executable]),
459
+ Effect_exports.orDie
460
+ ) : Effect_exports.succeed(options.commandPrefix);
461
+ var makeHerdrCli = (options = {}) => Effect_exports.gen(function* () {
462
+ const executor = yield* CommandExecutor_exports.CommandExecutor;
463
+ const commandPrefix = yield* resolveCommandPrefix(options);
464
+ const [executable, ...prefixArgs] = commandPrefix;
465
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
466
+ const outputLimit = options.outputTailBytes ?? DEFAULT_OUTPUT_TAIL_BYTES;
467
+ const attempt = (args, runOptions) => Effect_exports.gen(function* () {
468
+ const displayArgs = runOptions.displayArgs ?? args;
469
+ const redactions = runOptions.redactValues ?? [];
470
+ const stdoutRef = yield* Ref_exports.make(emptyOutputTail());
471
+ const stderrRef = yield* Ref_exports.make(emptyOutputTail());
472
+ const command = Command_exports.make(executable, ...prefixArgs, ...args);
473
+ const execute = Effect_exports.scoped(
474
+ Effect_exports.gen(function* () {
475
+ const running = yield* executor.start(command).pipe(Effect_exports.mapError((cause) => new HerdrUnavailableError({ executable, cause })));
476
+ const drain = (stream, ref) => Stream_exports.runForEach(
477
+ stream,
478
+ (chunk) => Ref_exports.update(ref, (current) => appendOutputTail(current, chunk, outputLimit))
479
+ );
480
+ const [, , exitCode2] = yield* Effect_exports.all(
481
+ [
482
+ drain(running.stdout, stdoutRef),
483
+ drain(running.stderr, stderrRef),
484
+ running.exitCode.pipe(
485
+ Effect_exports.map(Number),
486
+ Effect_exports.orElseSucceed(() => null)
487
+ )
488
+ ],
489
+ { concurrency: "unbounded" }
490
+ ).pipe(
491
+ Effect_exports.catchAll(
492
+ (cause) => Effect_exports.all([Ref_exports.get(stdoutRef), Ref_exports.get(stderrRef)]).pipe(
493
+ Effect_exports.flatMap(
494
+ ([stdout2, stderr2]) => Effect_exports.fail(
495
+ new HerdrCommandError({
496
+ args: displayArgs,
497
+ exitCode: null,
498
+ stdoutTail: renderOutputTail(stdout2, redactions),
499
+ stderrTail: renderOutputTail(stderr2, redactions),
500
+ stdoutTruncated: stdout2.truncated,
501
+ stderrTruncated: stderr2.truncated,
502
+ cause
503
+ })
504
+ )
505
+ )
506
+ )
507
+ )
508
+ );
509
+ return { exitCode: exitCode2 };
510
+ })
511
+ ).pipe(
512
+ Effect_exports.timeoutFail({
513
+ duration: Duration_exports.millis(timeoutMs),
514
+ onTimeout: () => new HerdrTimeoutError({
515
+ args: displayArgs,
516
+ timeoutMs,
517
+ stdoutTail: "",
518
+ stderrTail: "",
519
+ stdoutTruncated: false,
520
+ stderrTruncated: false
521
+ })
522
+ })
523
+ );
524
+ const { exitCode } = yield* execute.pipe(
525
+ Effect_exports.catchTag(
526
+ "HerdrTimeoutError",
527
+ (error) => Effect_exports.all([Ref_exports.get(stdoutRef), Ref_exports.get(stderrRef)]).pipe(
528
+ Effect_exports.flatMap(
529
+ ([stdout2, stderr2]) => Effect_exports.fail(
530
+ new HerdrTimeoutError({
531
+ ...error,
532
+ stdoutTail: renderOutputTail(stdout2, redactions),
533
+ stderrTail: renderOutputTail(stderr2, redactions),
534
+ stdoutTruncated: stdout2.truncated,
535
+ stderrTruncated: stderr2.truncated
536
+ })
537
+ )
538
+ )
539
+ )
540
+ )
541
+ );
542
+ const stdout = yield* Ref_exports.get(stdoutRef);
543
+ const stderr = yield* Ref_exports.get(stderrRef);
544
+ const stdoutTail = renderOutputTail(stdout, redactions);
545
+ const stderrTail = renderOutputTail(stderr, redactions);
546
+ return yield* decodeHerdrOutput(
547
+ {
548
+ args: displayArgs,
549
+ exitCode,
550
+ stdoutTail,
551
+ stderrTail,
552
+ stdoutTruncated: stdout.truncated,
553
+ stderrTruncated: stderr.truncated
554
+ },
555
+ runOptions.responseMode ?? HerdrResponseMode.json
556
+ );
557
+ });
558
+ return {
559
+ run: (args, runOptions = {}) => attempt(args, runOptions).pipe(
560
+ Effect_exports.retry({
561
+ schedule: SPAWN_RETRY,
562
+ while: (error) => error._tag === "HerdrUnavailableError"
563
+ })
564
+ )
565
+ };
566
+ });
567
+ var makeHerdrCliLayer = (options = {}) => Layer_exports.effect(HerdrCli, makeHerdrCli(options));
568
+ var HerdrCliLive = makeHerdrCliLayer();
569
+
570
+ // packages/surface-herdr/src/commands/herdrCommand.ts
571
+ var HerdrCommand = {
572
+ paneGet: ["pane", "get"],
573
+ paneRead: ["pane", "read"],
574
+ paneReportAgent: ["pane", "report-agent"],
575
+ paneRun: ["pane", "run"],
576
+ tabClose: ["tab", "close"],
577
+ tabCreate: ["tab", "create"],
578
+ tabFocus: ["tab", "focus"],
579
+ tabGet: ["tab", "get"],
580
+ tabList: ["tab", "list"]
581
+ };
582
+ var HerdrFlag = {
583
+ agent: "--agent",
584
+ customStatus: "--custom-status",
585
+ cwd: "--cwd",
586
+ env: "--env",
587
+ format: "--format",
588
+ label: "--label",
589
+ lines: "--lines",
590
+ noFocus: "--no-focus",
591
+ seq: "--seq",
592
+ source: "--source",
593
+ state: "--state",
594
+ workspace: "--workspace"
595
+ };
596
+ var HerdrReadSource = {
597
+ visible: "visible"
598
+ };
599
+ var HerdrOutputFormat = {
600
+ text: "text"
601
+ };
602
+ var HerdrApiErrorCode = {
603
+ paneNotFound: "pane_not_found",
604
+ tabNotFound: "tab_not_found",
605
+ workspaceNotFound: "workspace_not_found"
606
+ };
607
+
608
+ // packages/surface-herdr/src/protocol/herdrEnvelopes.ts
609
+ var HerdrWireField = {
610
+ result: "result",
611
+ resultKind: "type"
612
+ };
613
+ var TabSchema = Schema_exports.Struct({
614
+ tab_id: Schema_exports.String,
615
+ workspace_id: Schema_exports.String,
616
+ focused: Schema_exports.Boolean,
617
+ label: Schema_exports.String
618
+ });
619
+ var PaneSchema = Schema_exports.Struct({
620
+ pane_id: Schema_exports.String,
621
+ tab_id: Schema_exports.String,
622
+ workspace_id: Schema_exports.String
623
+ });
624
+ var TabCreatedEnvelopeSchema = Schema_exports.Struct({
625
+ result: Schema_exports.Struct({
626
+ tab: TabSchema,
627
+ root_pane: PaneSchema
628
+ })
629
+ });
630
+ var TabInfoEnvelopeSchema = Schema_exports.Struct({
631
+ result: Schema_exports.Struct({ tab: TabSchema })
632
+ });
633
+ var TabListEnvelopeSchema = Schema_exports.Struct({
634
+ result: Schema_exports.Struct({ tabs: Schema_exports.Array(TabSchema) })
635
+ });
636
+ var PaneInfoEnvelopeSchema = Schema_exports.Struct({
637
+ result: Schema_exports.Struct({ pane: PaneSchema })
638
+ });
639
+ var decoders = {
640
+ paneInfo: Schema_exports.decodeUnknown(PaneInfoEnvelopeSchema),
641
+ tabCreated: Schema_exports.decodeUnknown(TabCreatedEnvelopeSchema),
642
+ tabInfo: Schema_exports.decodeUnknown(TabInfoEnvelopeSchema),
643
+ tabList: Schema_exports.decodeUnknown(TabListEnvelopeSchema)
644
+ };
645
+ var isRecord = (value) => typeof value === "object" && value !== null;
646
+ var readResultKind = (value) => {
647
+ if (!isRecord(value)) return void 0;
648
+ const result = value[HerdrWireField.result];
649
+ if (!isRecord(result)) return void 0;
650
+ const kind = result[HerdrWireField.resultKind];
651
+ return typeof kind === "string" ? kind : void 0;
652
+ };
653
+ var ensureResultKind = (value, expectedKind, operation) => readResultKind(value) === expectedKind ? Effect_exports.void : Effect_exports.fail(
654
+ new HerdrEnvelopeError({
655
+ operation,
656
+ expectedKind,
657
+ cause: `received ${String(readResultKind(value))}`
658
+ })
659
+ );
660
+ var mapDecodeError = (operation, expectedKind) => (cause) => new HerdrEnvelopeError({ operation, expectedKind, cause });
661
+ var parseTabCreated = (value) => ensureResultKind(value, "tab_created", "herdr.tab.create").pipe(
662
+ Effect_exports.zipRight(
663
+ decoders.tabCreated(value).pipe(Effect_exports.mapError(mapDecodeError("herdr.tab.create", "tab_created")))
664
+ ),
665
+ Effect_exports.map(({ result }) => ({
666
+ workspaceId: result.tab.workspace_id,
667
+ tabId: result.tab.tab_id,
668
+ paneId: result.root_pane.pane_id
669
+ }))
670
+ );
671
+ var parseTabInfoFor = (value, operation) => ensureResultKind(value, "tab_info", operation).pipe(
672
+ Effect_exports.zipRight(
673
+ decoders.tabInfo(value).pipe(Effect_exports.mapError(mapDecodeError(operation, "tab_info")))
674
+ ),
675
+ Effect_exports.map(({ result }) => ({
676
+ workspaceId: result.tab.workspace_id,
677
+ tabId: result.tab.tab_id,
678
+ focused: result.tab.focused,
679
+ label: result.tab.label
680
+ }))
681
+ );
682
+ var parseTabInfo = (value) => parseTabInfoFor(value, "herdr.tab.get");
683
+ var parseFocusedTab = (value) => parseTabInfoFor(value, "herdr.tab.focus");
684
+ var parseTabList = (value) => ensureResultKind(value, "tab_list", "herdr.tab.list").pipe(
685
+ Effect_exports.zipRight(
686
+ decoders.tabList(value).pipe(Effect_exports.mapError(mapDecodeError("herdr.tab.list", "tab_list")))
687
+ ),
688
+ Effect_exports.map(
689
+ ({ result }) => result.tabs.map((tab) => ({
690
+ workspaceId: tab.workspace_id,
691
+ tabId: tab.tab_id,
692
+ focused: tab.focused,
693
+ label: tab.label
694
+ }))
695
+ )
696
+ );
697
+ var parsePaneInfo = (value) => ensureResultKind(value, "pane_info", "herdr.pane.get").pipe(
698
+ Effect_exports.zipRight(
699
+ decoders.paneInfo(value).pipe(Effect_exports.mapError(mapDecodeError("herdr.pane.get", "pane_info")))
700
+ ),
701
+ Effect_exports.map(({ result }) => ({
702
+ workspaceId: result.pane.workspace_id,
703
+ tabId: result.pane.tab_id,
704
+ paneId: result.pane.pane_id
705
+ }))
706
+ );
707
+ var parseOk = (value, operation) => ensureResultKind(value, "ok", operation);
708
+
709
+ // packages/surface-herdr/src/runtime/herdrFailureMapping.ts
710
+ var surfaceCodeByFailure = {
711
+ HerdrApiError: SurfaceErrorCode.commandFailed,
712
+ HerdrCommandError: SurfaceErrorCode.commandFailed,
713
+ HerdrEnvelopeError: SurfaceErrorCode.responseInvalid,
714
+ HerdrRollbackError: SurfaceErrorCode.adapterFailure,
715
+ HerdrTimeoutError: SurfaceErrorCode.timeout,
716
+ HerdrUnavailableError: SurfaceErrorCode.contextUnavailable
717
+ };
718
+ var diagnosticsByFailure = {
719
+ HerdrApiError: (error) => ({ args: error.args, apiCode: error.code, message: error.message }),
720
+ HerdrCommandError: (error) => ({
721
+ args: error.args,
722
+ exitCode: error.exitCode,
723
+ stdoutTail: error.stdoutTail,
724
+ stderrTail: error.stderrTail,
725
+ stdoutTruncated: error.stdoutTruncated,
726
+ stderrTruncated: error.stderrTruncated
727
+ }),
728
+ HerdrEnvelopeError: (error) => ({ expectedKind: error.expectedKind }),
729
+ HerdrRollbackError: (error) => ({
730
+ primary: error.primary._tag,
731
+ rollback: error.rollback._tag
732
+ }),
733
+ HerdrTimeoutError: (error) => ({
734
+ args: error.args,
735
+ timeoutMs: error.timeoutMs,
736
+ stdoutTail: error.stdoutTail,
737
+ stderrTail: error.stderrTail,
738
+ stdoutTruncated: error.stdoutTruncated,
739
+ stderrTruncated: error.stderrTruncated
740
+ }),
741
+ HerdrUnavailableError: (error) => ({ executable: error.executable })
742
+ };
743
+ var mapHerdrFailure = (operation, error) => {
744
+ const diagnostics = diagnosticsByFailure[error._tag];
745
+ return new SurfaceError({
746
+ operation,
747
+ code: surfaceCodeByFailure[error._tag],
748
+ details: diagnostics(error),
749
+ cause: error
750
+ });
751
+ };
752
+
753
+ // packages/surface-herdr/src/runtime/herdrContext.ts
754
+ var HerdrEnvironment = {
755
+ paneId: "HERDR_PANE_ID",
756
+ tabId: "HERDR_TAB_ID",
757
+ workspaceId: "HERDR_WORKSPACE_ID"
758
+ };
759
+ var readOptional = (name) => Config_exports.option(Config_exports.string(name));
760
+ var readContextEnvironment = Effect_exports.all({
761
+ containerRef: readOptional(HerdrEnvironment.workspaceId),
762
+ viewRef: readOptional(HerdrEnvironment.tabId),
763
+ executionRef: readOptional(HerdrEnvironment.paneId)
764
+ });
765
+ var detectHerdrContext = (cli) => Effect_exports.gen(function* () {
766
+ const configured = yield* readContextEnvironment.pipe(
767
+ Effect_exports.map((values) => ({
768
+ containerRef: Option_exports.getOrUndefined(values.containerRef),
769
+ viewRef: Option_exports.getOrUndefined(values.viewRef),
770
+ executionRef: Option_exports.getOrUndefined(values.executionRef)
771
+ })),
772
+ Effect_exports.mapError(
773
+ (cause) => new SurfaceError({
774
+ operation: "surface.detectContext",
775
+ code: SurfaceErrorCode.contextUnavailable,
776
+ details: { reason: "config_error" },
777
+ cause
778
+ })
779
+ )
780
+ );
781
+ const { containerRef, viewRef, executionRef } = configured;
782
+ if (containerRef === void 0 || viewRef === void 0 || executionRef === void 0) {
783
+ return yield* Effect_exports.fail(
784
+ new SurfaceError({
785
+ operation: "surface.detectContext",
786
+ code: SurfaceErrorCode.contextUnavailable,
787
+ details: {
788
+ missing: Object.entries(configured).filter(([, value]) => value === void 0).map(([name]) => name)
789
+ }
790
+ })
791
+ );
792
+ }
793
+ const tab = yield* cli.run([...HerdrCommand.tabGet, viewRef]).pipe(
794
+ Effect_exports.flatMap(parseTabInfo),
795
+ Effect_exports.mapError((error) => mapHerdrFailure("surface.detectContext", error))
796
+ );
797
+ const pane = yield* cli.run([...HerdrCommand.paneGet, executionRef]).pipe(
798
+ Effect_exports.flatMap(parsePaneInfo),
799
+ Effect_exports.mapError((error) => mapHerdrFailure("surface.detectContext", error))
800
+ );
801
+ if (tab.workspaceId !== containerRef || pane.workspaceId !== containerRef || pane.tabId !== viewRef) {
802
+ return yield* Effect_exports.fail(
803
+ new SurfaceError({
804
+ operation: "surface.detectContext",
805
+ code: SurfaceErrorCode.contextUnavailable,
806
+ details: { reason: "context_mismatch" }
807
+ })
808
+ );
809
+ }
810
+ return { providerAlias: "herdr", containerRef, viewRef, executionRef };
811
+ });
812
+
813
+ // packages/surface-herdr/src/runtime/shellQuote.ts
814
+ var ENVIRONMENT_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
815
+ var quoteShellWord = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
816
+ var parseHerdrEnvironment = (environment) => {
817
+ const entries = Object.entries(environment ?? {});
818
+ const invalidName = entries.find(([name]) => !ENVIRONMENT_NAME.test(name));
819
+ return invalidName === void 0 ? Effect_exports.succeed(entries) : Effect_exports.fail(
820
+ new SurfaceError({
821
+ operation: "surface.launch",
822
+ code: SurfaceErrorCode.invalidRequest,
823
+ details: { field: "command.environment", name: invalidName[0] }
824
+ })
825
+ );
826
+ };
827
+ var buildHerdrCommandLine = (command) => {
828
+ if (command.executable === "") {
829
+ return Effect_exports.fail(
830
+ new SurfaceError({
831
+ operation: "surface.launch",
832
+ code: SurfaceErrorCode.invalidRequest,
833
+ details: { field: "command.executable" }
834
+ })
835
+ );
836
+ }
837
+ return Effect_exports.succeed(
838
+ [command.executable, ...command.arguments ?? []].map(quoteShellWord).join(" ")
839
+ );
840
+ };
841
+
842
+ // packages/surface-herdr/src/runtime/herdrLaunch.ts
843
+ var HERDR_SURFACE_ALIAS = "herdr";
844
+ var rollbackExact = (operations, tabId, primary) => operations.closeTab(tabId).pipe(
845
+ Effect_exports.matchEffect({
846
+ onFailure: (rollback) => Effect_exports.fail(new HerdrRollbackError({ operation: "surface.launch", primary, rollback })),
847
+ onSuccess: () => Effect_exports.fail(primary)
848
+ })
849
+ );
850
+ var rollbackUnknown = (operations, containerRef, previousIds, label, primary) => operations.listTabs(containerRef).pipe(
851
+ Effect_exports.flatMap((tabs) => {
852
+ const candidates = tabs.filter((tab) => !previousIds.has(tab.tabId) && tab.label === label);
853
+ if (candidates.length === 0) return Effect_exports.fail(primary);
854
+ if (candidates.length === 1) {
855
+ const candidate = candidates[0];
856
+ return candidate === void 0 ? Effect_exports.fail(primary) : rollbackExact(operations, candidate.tabId, primary);
857
+ }
858
+ return Effect_exports.fail(
859
+ new HerdrRollbackError({
860
+ operation: "surface.launch.reconcile",
861
+ primary,
862
+ rollback: new HerdrEnvelopeError({
863
+ operation: "herdr.tab.list",
864
+ expectedKind: "single_new_tab",
865
+ cause: { candidateIds: candidates.map((tab) => tab.tabId) }
866
+ })
867
+ })
868
+ );
869
+ }),
870
+ Effect_exports.catchAll(
871
+ (rollback) => rollback === primary ? Effect_exports.fail(primary) : Effect_exports.fail(
872
+ rollback._tag === "HerdrRollbackError" ? rollback : new HerdrRollbackError({ operation: "surface.launch", primary, rollback })
873
+ )
874
+ )
875
+ );
876
+ var launchHerdrSurface = (cli, operations, request) => Effect_exports.gen(function* () {
877
+ const context = yield* detectHerdrContext(cli);
878
+ const commandLine = yield* buildHerdrCommandLine(request.command);
879
+ const environment = yield* parseHerdrEnvironment(request.command.environment);
880
+ const surfaceName = makeCampSurfaceName(request.project);
881
+ const mapFailure = (error) => mapHerdrFailure("surface.launch", error);
882
+ const before = yield* operations.listTabs(context.containerRef).pipe(Effect_exports.mapError(mapFailure));
883
+ const previousIds = new Set(before.map((tab) => tab.tabId));
884
+ const created = yield* operations.createTab(context, request.project.cwd, surfaceName, environment).pipe(
885
+ Effect_exports.catchAll(
886
+ (primary) => rollbackUnknown(operations, context.containerRef, previousIds, surfaceName, primary)
887
+ ),
888
+ Effect_exports.mapError(mapFailure)
889
+ );
890
+ if (created.workspaceId !== context.containerRef || created.tabId === context.viewRef || created.paneId === context.executionRef) {
891
+ const primary = new HerdrEnvelopeError({
892
+ operation: "herdr.tab.create",
893
+ expectedKind: "sibling_tab"
894
+ });
895
+ return yield* rollbackExact(operations, created.tabId, primary).pipe(
896
+ Effect_exports.mapError(mapFailure)
897
+ );
898
+ }
899
+ yield* operations.runPane(created.paneId, commandLine, Object.values(request.command.environment ?? {})).pipe(
900
+ Effect_exports.catchAll((primary) => rollbackExact(operations, created.tabId, primary)),
901
+ Effect_exports.mapError(mapFailure)
902
+ );
903
+ return {
904
+ providerAlias: HERDR_SURFACE_ALIAS,
905
+ containerRef: created.workspaceId,
906
+ viewRef: created.tabId,
907
+ executionRef: created.paneId,
908
+ originViewRef: context.viewRef,
909
+ ownership: SurfaceOwnership.created
910
+ };
911
+ });
912
+
913
+ // packages/surface-herdr/src/runtime/herdrOperations.ts
914
+ var statusByActivity = {
915
+ [SurfaceActivity.blocked]: "blocked",
916
+ [SurfaceActivity.idle]: "idle",
917
+ [SurfaceActivity.unknown]: "unknown",
918
+ [SurfaceActivity.working]: "working"
919
+ };
920
+ var readLines = (options) => Math.max(1, Math.min(options?.maxLines ?? 200, 1e4));
921
+ var makeHerdrOperations = (cli) => {
922
+ const getTab = (tabId) => cli.run([...HerdrCommand.tabGet, tabId]).pipe(
923
+ Effect_exports.flatMap(parseTabInfo),
924
+ Effect_exports.map(Option_exports.some),
925
+ Effect_exports.catchTag(
926
+ "HerdrApiError",
927
+ (error) => error.code === HerdrApiErrorCode.tabNotFound ? Effect_exports.succeed(Option_exports.none()) : Effect_exports.fail(error)
928
+ )
929
+ );
930
+ const getPane = (paneId) => cli.run([...HerdrCommand.paneGet, paneId]).pipe(
931
+ Effect_exports.flatMap(parsePaneInfo),
932
+ Effect_exports.map(Option_exports.some),
933
+ Effect_exports.catchTag(
934
+ "HerdrApiError",
935
+ (error) => error.code === HerdrApiErrorCode.paneNotFound ? Effect_exports.succeed(Option_exports.none()) : Effect_exports.fail(error)
936
+ )
937
+ );
938
+ const listTabs = (workspaceId) => cli.run([...HerdrCommand.tabList, HerdrFlag.workspace, workspaceId]).pipe(Effect_exports.flatMap(parseTabList));
939
+ const createTab = (context, cwd, label, environment) => cli.run(
940
+ [
941
+ ...HerdrCommand.tabCreate,
942
+ HerdrFlag.workspace,
943
+ context.containerRef,
944
+ HerdrFlag.cwd,
945
+ cwd,
946
+ HerdrFlag.label,
947
+ label,
948
+ ...environment.flatMap(([name, value]) => [HerdrFlag.env, `${name}=${value}`]),
949
+ HerdrFlag.noFocus
950
+ ],
951
+ {
952
+ displayArgs: [
953
+ ...HerdrCommand.tabCreate,
954
+ HerdrFlag.workspace,
955
+ context.containerRef,
956
+ HerdrFlag.cwd,
957
+ cwd,
958
+ HerdrFlag.label,
959
+ label,
960
+ ...environment.flatMap(([name]) => [HerdrFlag.env, `${name}=<redacted>`]),
961
+ HerdrFlag.noFocus
962
+ ],
963
+ redactValues: environment.map(([, value]) => value)
964
+ }
965
+ ).pipe(Effect_exports.flatMap(parseTabCreated));
966
+ const runPane = (paneId, commandLine, secretValues) => cli.run([...HerdrCommand.paneRun, paneId, commandLine], {
967
+ displayArgs: [...HerdrCommand.paneRun, paneId, "<redacted-command>"],
968
+ redactValues: secretValues,
969
+ responseMode: HerdrResponseMode.emptyOk
970
+ }).pipe(Effect_exports.asVoid);
971
+ const focusTab = (tabId) => cli.run([...HerdrCommand.tabFocus, tabId]).pipe(
972
+ Effect_exports.flatMap(parseFocusedTab),
973
+ Effect_exports.filterOrFail(
974
+ (tab) => tab.tabId === tabId && tab.focused,
975
+ (tab) => new HerdrEnvelopeError({
976
+ operation: "herdr.tab.focus",
977
+ expectedKind: "focused_tab_info",
978
+ cause: `received tab ${tab.tabId}, focused=${String(tab.focused)}`
979
+ })
980
+ ),
981
+ Effect_exports.asVoid
982
+ );
983
+ const readPane = (paneId, options) => cli.run(
984
+ [
985
+ ...HerdrCommand.paneRead,
986
+ paneId,
987
+ HerdrFlag.source,
988
+ HerdrReadSource.visible,
989
+ HerdrFlag.lines,
990
+ String(readLines(options)),
991
+ HerdrFlag.format,
992
+ HerdrOutputFormat.text
993
+ ],
994
+ { responseMode: HerdrResponseMode.raw }
995
+ ).pipe(
996
+ Effect_exports.flatMap(
997
+ (value) => isHerdrRawOutput(value) ? Effect_exports.succeed(value) : Effect_exports.fail(
998
+ new HerdrEnvelopeError({
999
+ operation: "herdr.pane.read",
1000
+ expectedKind: "raw_text"
1001
+ })
1002
+ )
1003
+ )
1004
+ );
1005
+ const reportPane = (paneId, report) => {
1006
+ const args = [
1007
+ ...HerdrCommand.paneReportAgent,
1008
+ paneId,
1009
+ HerdrFlag.source,
1010
+ "priiisk-surface",
1011
+ HerdrFlag.agent,
1012
+ "camp",
1013
+ HerdrFlag.state,
1014
+ statusByActivity[report.activity],
1015
+ ...report.message === void 0 ? [] : [HerdrFlag.customStatus, report.message.slice(0, 240)],
1016
+ ...report.sequence === void 0 ? [] : [HerdrFlag.seq, String(report.sequence)]
1017
+ ];
1018
+ return cli.run(args, { responseMode: HerdrResponseMode.emptyOk }).pipe(Effect_exports.asVoid);
1019
+ };
1020
+ const closeTab = (tabId) => cli.run([...HerdrCommand.tabClose, tabId]).pipe(
1021
+ Effect_exports.flatMap((value) => parseOk(value, "herdr.tab.close")),
1022
+ Effect_exports.catchTag(
1023
+ "HerdrApiError",
1024
+ (error) => error.code === HerdrApiErrorCode.tabNotFound ? Effect_exports.void : Effect_exports.fail(error)
1025
+ )
1026
+ );
1027
+ return {
1028
+ closeTab,
1029
+ createTab,
1030
+ focusTab,
1031
+ getPane,
1032
+ getTab,
1033
+ listTabs,
1034
+ readPane,
1035
+ reportPane,
1036
+ runPane
1037
+ };
1038
+ };
1039
+
1040
+ // packages/surface-herdr/src/runtime/herdrCampSurface.ts
1041
+ var invalidHandle = (reason) => new SurfaceError({
1042
+ operation: "surface.handle",
1043
+ code: SurfaceErrorCode.invalidHandle,
1044
+ details: { reason }
1045
+ });
1046
+ var makeHerdrCampSurface = (cli) => {
1047
+ const operations = makeHerdrOperations(cli);
1048
+ const mapFailure = (operation) => (error) => mapHerdrFailure(operation, error);
1049
+ const validateProvider = (handle, operation) => ensureSurfaceHandleProvider(handle, HERDR_SURFACE_ALIAS, operation);
1050
+ const verifyLive = (handle, operation) => validateProvider(handle, operation).pipe(
1051
+ Effect_exports.zipRight(
1052
+ Effect_exports.all({
1053
+ tab: operations.getTab(handle.viewRef),
1054
+ pane: operations.getPane(handle.executionRef)
1055
+ }).pipe(Effect_exports.mapError(mapFailure(operation)))
1056
+ ),
1057
+ Effect_exports.flatMap(({ tab, pane }) => {
1058
+ if (Option_exports.isNone(tab) || Option_exports.isNone(pane)) return Effect_exports.succeed(Option_exports.none());
1059
+ if (tab.value.workspaceId !== handle.containerRef || pane.value.workspaceId !== handle.containerRef || pane.value.tabId !== handle.viewRef) {
1060
+ return Effect_exports.fail(invalidHandle("provider_refs_mismatch"));
1061
+ }
1062
+ return Effect_exports.succeed(Option_exports.some({ tab: tab.value, pane: pane.value }));
1063
+ })
1064
+ );
1065
+ return {
1066
+ detectContext: () => detectHerdrContext(cli),
1067
+ attachCurrent: () => detectHerdrContext(cli).pipe(
1068
+ Effect_exports.map((context) => ({
1069
+ ...context,
1070
+ originViewRef: context.viewRef,
1071
+ ownership: SurfaceOwnership.attached
1072
+ }))
1073
+ ),
1074
+ launch: (request) => launchHerdrSurface(cli, operations, request),
1075
+ inspect: (handle) => verifyLive(handle, "surface.inspect").pipe(
1076
+ Effect_exports.map(
1077
+ (live) => Option_exports.isNone(live) ? { presence: SurfacePresence.missing } : { presence: SurfacePresence.present, focused: live.value.tab.focused }
1078
+ )
1079
+ ),
1080
+ focus: (handle) => verifyLive(handle, "surface.focus").pipe(
1081
+ Effect_exports.filterOrFail(Option_exports.isSome, () => invalidHandle("view_missing")),
1082
+ Effect_exports.zipRight(
1083
+ operations.focusTab(handle.viewRef).pipe(Effect_exports.mapError(mapFailure("surface.focus")))
1084
+ ),
1085
+ Effect_exports.asVoid
1086
+ ),
1087
+ read: (handle, options) => verifyLive(handle, "surface.read").pipe(
1088
+ Effect_exports.filterOrFail(Option_exports.isSome, () => invalidHandle("view_missing")),
1089
+ Effect_exports.zipRight(
1090
+ operations.readPane(handle.executionRef, options).pipe(Effect_exports.mapError(mapFailure("surface.read")))
1091
+ ),
1092
+ Effect_exports.map((read) => ({ text: read.text, truncated: read.truncated }))
1093
+ ),
1094
+ reportStatus: (handle, report) => verifyLive(handle, "surface.reportStatus").pipe(
1095
+ Effect_exports.filterOrFail(Option_exports.isSome, () => invalidHandle("view_missing")),
1096
+ Effect_exports.zipRight(
1097
+ operations.reportPane(handle.executionRef, report).pipe(Effect_exports.mapError(mapFailure("surface.reportStatus")))
1098
+ ),
1099
+ Effect_exports.asVoid
1100
+ ),
1101
+ close: (handle) => validateProvider(handle, "surface.close").pipe(
1102
+ Effect_exports.zipRight(ensureSurfaceHandleClosable(handle)),
1103
+ Effect_exports.zipRight(verifyLive(handle, "surface.close")),
1104
+ Effect_exports.flatMap(
1105
+ (live) => Option_exports.isNone(live) ? Effect_exports.void : operations.closeTab(handle.viewRef).pipe(Effect_exports.mapError(mapFailure("surface.close")))
1106
+ )
1107
+ )
1108
+ };
1109
+ };
1110
+ var HerdrCampSurfaceLive = Layer_exports.effect(
1111
+ CampSurface,
1112
+ Effect_exports.map(HerdrCli, makeHerdrCampSurface)
1113
+ );
1114
+
1115
+ // packages/cli/src/surface/surfaceRegistry.ts
1116
+ var registrations = [
1117
+ {
1118
+ providerAlias: HERDR_SURFACE_ALIAS,
1119
+ make: makeHerdrCli().pipe(Effect_exports.map(makeHerdrCampSurface))
1120
+ }
1121
+ ];
1122
+ var resolveCampSurface = (providerAlias) => {
1123
+ const registration = registrations.find((candidate) => candidate.providerAlias === providerAlias);
1124
+ return registration === void 0 ? Effect_exports.fail(
1125
+ new CliSurfaceSelectionError({
1126
+ operation: "resolve",
1127
+ providerAlias,
1128
+ message: `surface adapter \u043D\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D: ${providerAlias}`
1129
+ })
1130
+ ) : registration.make;
1131
+ };
1132
+ var detectCampSurface = () => Effect_exports.forEach(
1133
+ registrations,
1134
+ (registration) => registration.make.pipe(
1135
+ Effect_exports.flatMap(
1136
+ (surface) => surface.detectContext().pipe(Effect_exports.as({ registration, surface }))
1137
+ ),
1138
+ Effect_exports.either
1139
+ )
1140
+ ).pipe(
1141
+ Effect_exports.flatMap((attempts) => {
1142
+ const matches = attempts.filter(Either_exports.isRight).map((attempt) => attempt.right);
1143
+ if (matches.length === 1) {
1144
+ const match = matches[0];
1145
+ return match === void 0 ? Effect_exports.die("surface registry lost its only match") : Effect_exports.succeed(match.surface);
1146
+ }
1147
+ if (matches.length > 1) {
1148
+ return Effect_exports.fail(
1149
+ new CliSurfaceSelectionError({
1150
+ operation: "detect",
1151
+ message: `\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E surface contexts: ${matches.map(({ registration }) => registration.providerAlias).join(", ")}`
1152
+ })
1153
+ );
1154
+ }
1155
+ return Effect_exports.fail(
1156
+ new CliSurfaceSelectionError({
1157
+ operation: "detect",
1158
+ message: "\u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 surface context",
1159
+ cause: attempts.filter(Either_exports.isLeft).map((attempt) => attempt.left)
1160
+ })
1161
+ );
1162
+ })
1163
+ );
1164
+
1165
+ export {
1166
+ CliTurnWaitTimeout,
1167
+ CliMessageSourceError,
1168
+ CliEquipmentConflict,
1169
+ CliCampLifecycleError,
1170
+ CliStdioRequestInvalid,
1171
+ CliStdioCommandCancelled,
1172
+ CliStdioStreamFailure,
1173
+ PRIIISK_CLI_VERSION,
1174
+ releaseCampRpcConnection,
1175
+ withCampRpc,
1176
+ withCampRpcSession,
1177
+ acceptCampGeneration,
1178
+ resolveCampSurface,
1179
+ detectCampSurface,
1180
+ DoctorCheckStatus,
1181
+ DoctorOverallStatus,
1182
+ doctorCheck,
1183
+ makeDoctorReport,
1184
+ doctorErrorMessage
1185
+ };