priiisk 0.1.6 → 0.1.8

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.
@@ -28,7 +28,7 @@ import {
28
28
  makePlatform,
29
29
  makeRunMain,
30
30
  stdin
31
- } from "./chunk-3NSS6BZD.js";
31
+ } from "./chunk-W2ZL6LWM.js";
32
32
  import {
33
33
  BaseProto,
34
34
  __export,
@@ -112,7 +112,7 @@ import {
112
112
  write,
113
113
  zip,
114
114
  zipRight
115
- } from "./chunk-KFSFN6L5.js";
115
+ } from "./chunk-TZBPOE6G.js";
116
116
 
117
117
  // node_modules/.pnpm/@effect+platform-node@0.107.0_@effect+cluster@0.59.0_@effect+platform@0.96.2_effect@3.2_9535e05eb804fa0fb275ce283b448483/node_modules/@effect/platform-node/dist/esm/NodeContext.js
118
118
  var NodeContext_exports = {};
@@ -37,6 +37,7 @@ import {
37
37
  campUiPendingAskBlockRenderer,
38
38
  campUiPendingAskTargets,
39
39
  campUiSubscriptionRetryDelay,
40
+ campUiToolResultCacheSize,
40
41
  campUiTranscriptBlockRenderer,
41
42
  compactNumber,
42
43
  composeCampUiDetailBlocks,
@@ -79,13 +80,14 @@ import {
79
80
  renderCampUiToolResult,
80
81
  renderCampUiWorkerState,
81
82
  renderSelectedCampUiRow,
83
+ resetCampUiToolResultCache,
82
84
  runCampUiPresentationClock,
83
85
  sameCampUiRuntimeHealth,
84
86
  selectCampRun,
85
87
  styleCampUiTone,
86
88
  uniqueCampUiNames
87
- } from "./chunk-32R4IEGS.js";
88
- import "./chunk-KFSFN6L5.js";
89
+ } from "./chunk-S7LCWMQY.js";
90
+ import "./chunk-TZBPOE6G.js";
89
91
  export {
90
92
  CAMP_UI_BASH_PREVIEW_LINES,
91
93
  CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
@@ -123,6 +125,7 @@ export {
123
125
  campUiPendingAskBlockRenderer,
124
126
  campUiPendingAskTargets,
125
127
  campUiSubscriptionRetryDelay,
128
+ campUiToolResultCacheSize,
126
129
  campUiTranscriptBlockRenderer,
127
130
  compactNumber,
128
131
  composeCampUiDetailBlocks,
@@ -165,6 +168,7 @@ export {
165
168
  renderCampUiToolResult,
166
169
  renderCampUiWorkerState,
167
170
  renderSelectedCampUiRow,
171
+ resetCampUiToolResultCache,
168
172
  runCampUiPresentationClock,
169
173
  sameCampUiRuntimeHealth,
170
174
  selectCampRun,
@@ -20,10 +20,11 @@ import {
20
20
  layerNet,
21
21
  makeCampSurfaceName,
22
22
  resolveProjectScopeSync
23
- } from "./chunk-3NSS6BZD.js";
23
+ } from "./chunk-W2ZL6LWM.js";
24
24
  import {
25
25
  Clock_exports,
26
26
  Config_exports,
27
+ Console_exports,
27
28
  Context_exports,
28
29
  Data_exports,
29
30
  Deferred_exports,
@@ -37,7 +38,7 @@ import {
37
38
  Schedule_exports,
38
39
  Schema_exports,
39
40
  Stream_exports
40
- } from "./chunk-KFSFN6L5.js";
41
+ } from "./chunk-TZBPOE6G.js";
41
42
 
42
43
  // packages/cli/src/doctor/doctorModel.ts
43
44
  var DOCTOR_REPORT_SCHEMA_VERSION = 1;
@@ -111,9 +112,12 @@ var CliSurfaceSelectionError = class extends Data_exports.TaggedError("CliSurfac
111
112
  import { randomUUID } from "node:crypto";
112
113
 
113
114
  // packages/cli/src/domain/cliVersion.ts
114
- var PRIIISK_CLI_VERSION = "0.1.6";
115
+ var PRIIISK_CLI_VERSION = "0.1.8";
115
116
 
116
117
  // packages/cli/src/client/campRpcConnection.ts
118
+ var reportRetry = (options, diagnostic) => options.onRetry === void 0 ? Console_exports.error(
119
+ `[retry] ${diagnostic.operation}: \u043F\u043E\u043F\u044B\u0442\u043A\u0430 ${String(diagnostic.attempt)}, \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0430\u044F \u0432 ${String(diagnostic.nextRetryAt)} \u2014 ${diagnostic.message}`
120
+ ).pipe(Effect_exports.ignore) : options.onRetry(diagnostic);
117
121
  var PRIIISK_CONTROLLER_ID_ENV = "PRIIISK_CONTROLLER_ID";
118
122
  var PRIIISK_CONSUMER_ID_ENV = "PRIIISK_CONSUMER_ID";
119
123
  var protocolRetrySchedule = Schedule_exports.exponential("50 millis").pipe(
@@ -151,12 +155,12 @@ var makeCampProtocolLayer = (socketPath, options) => Effect_exports.gen(function
151
155
  Effect_exports.flatMap(
152
156
  ({ attempt, cause }) => Clock_exports.currentTimeMillis.pipe(
153
157
  Effect_exports.flatMap(
154
- (now) => options.onRetry?.({
158
+ (now) => reportRetry(options, {
155
159
  operation: options.operation,
156
160
  attempt,
157
161
  nextRetryAt: now + 50 * 2 ** (attempt - 1),
158
162
  message: cause instanceof Error ? cause.message : String(cause)
159
- }) ?? Effect_exports.void
163
+ })
160
164
  )
161
165
  )
162
166
  )
@@ -3,7 +3,7 @@ const require = __priiiskCreateRequire(import.meta.url);
3
3
  import {
4
4
  FileSystem_exports,
5
5
  PRIIISK_PI_AGENT_DIR_ENV
6
- } from "./chunk-3NSS6BZD.js";
6
+ } from "./chunk-W2ZL6LWM.js";
7
7
  import {
8
8
  CampDeliveryPort,
9
9
  CampFailureCode,
@@ -30,7 +30,7 @@ import {
30
30
  __require,
31
31
  __toESM,
32
32
  campScopeClosedReason
33
- } from "./chunk-KFSFN6L5.js";
33
+ } from "./chunk-TZBPOE6G.js";
34
34
 
35
35
  // node_modules/.pnpm/undici@7.28.0/node_modules/undici/lib/core/symbols.js
36
36
  var require_symbols = __commonJS({
@@ -26557,14 +26557,30 @@ var makePiSessionRuntime = (options) => Effect_exports.gen(function* () {
26557
26557
  /*
26558
26558
  * Aborting ends the turn, not the session: the terminal signal stays
26559
26559
  * untouched, so the worker survives its interruption and the next
26560
- * message starts a new turn. Committing the cycle first keeps the late
26561
- * agent_end/agent_settled of the abandoned turn from settling it.
26560
+ * message starts a new turn. The cycle is committed first, because the
26561
+ * late agent_end/agent_settled of the abandoned turn must not settle it.
26562
+ *
26563
+ * An adapter that refuses the abort leaves the turn running, so the
26564
+ * commit is rolled back: otherwise the worker would keep working while
26565
+ * its own settled events were ignored as belonging to a finished cycle
26566
+ * (priiisk-nss.6.27).
26562
26567
  */
26563
26568
  abort: (sessionRef) => requireLive(sessionRef, PiSessionOperation.abort).pipe(
26564
26569
  Effect_exports.flatMap(
26565
- (live) => commitCurrentCycle(live).pipe(
26566
- Effect_exports.zipRight(
26567
- run(live, PiSessionOperation.abort, () => live.runtime.session.abort())
26570
+ (live) => Ref_exports.get(live.lifecycle).pipe(
26571
+ Effect_exports.flatMap(
26572
+ (before) => commitCurrentCycle(live).pipe(
26573
+ Effect_exports.zipRight(
26574
+ run(live, PiSessionOperation.abort, () => live.runtime.session.abort())
26575
+ ),
26576
+ Effect_exports.tapError(
26577
+ () => Ref_exports.update(live.lifecycle, (state) => ({
26578
+ cycle: state.cycle,
26579
+ providerAttempts: state.providerAttempts,
26580
+ ...before.committedCycle === void 0 ? {} : { committedCycle: before.committedCycle }
26581
+ }))
26582
+ )
26583
+ )
26568
26584
  )
26569
26585
  )
26570
26586
  )
@@ -12,7 +12,7 @@ import {
12
12
  Match_exports,
13
13
  Stream_exports,
14
14
  SubscriptionRef_exports
15
- } from "./chunk-KFSFN6L5.js";
15
+ } from "./chunk-TZBPOE6G.js";
16
16
 
17
17
  // packages/host-ui/src/backend/campUiBackend.ts
18
18
  var CampUiBackendError = class extends Data_exports.TaggedError("CampUiBackendError") {
@@ -1296,27 +1296,49 @@ var toolResultPlainText = (result) => [
1296
1296
  ...result.toolResultDetails === void 0 ? [] : [`Details
1297
1297
  ${jsonText(result.toolResultDetails)}`]
1298
1298
  ].filter((part) => part !== "").join("\n");
1299
+ var CAMP_UI_TOOL_RESULT_CACHE_LIMIT = 256;
1300
+ var renderedResults = /* @__PURE__ */ new Map();
1301
+ var cacheKey = (result, width, expanded, plainText) => result.toolCallId === void 0 ? void 0 : (
1302
+ // The tool name is part of the key because it chooses the preview budget.
1303
+ `${result.toolCallId}:${result.toolName ?? ""}:${String(width)}:${expanded ? "1" : "0"}:${String(plainText.length)}`
1304
+ );
1305
+ var remember = (key, lines) => {
1306
+ if (renderedResults.size >= CAMP_UI_TOOL_RESULT_CACHE_LIMIT) {
1307
+ const oldest = renderedResults.keys().next();
1308
+ if (!oldest.done) renderedResults.delete(oldest.value);
1309
+ }
1310
+ renderedResults.set(key, lines);
1311
+ return lines;
1312
+ };
1313
+ var resetCampUiToolResultCache = () => {
1314
+ renderedResults.clear();
1315
+ };
1316
+ var campUiToolResultCacheSize = () => renderedResults.size;
1299
1317
  var renderCampUiToolResult = (result, width, expanded) => {
1300
1318
  const boundedWidth = Math.max(1, width);
1301
1319
  const plainText = toolResultPlainText(result);
1320
+ const key = cacheKey(result, boundedWidth, expanded, plainText);
1321
+ const cached = key === void 0 ? void 0 : renderedResults.get(key);
1322
+ if (cached !== void 0) return cached;
1302
1323
  const preview = truncateToVisualLines(
1303
1324
  getSelectListTheme7().description(plainText),
1304
1325
  previewLinesByTool.get(result.toolName ?? "") ?? CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
1305
1326
  boundedWidth
1306
1327
  );
1328
+ const keep = (lines2) => key === void 0 ? lines2 : remember(key, lines2);
1307
1329
  if (!expanded) {
1308
- return [
1330
+ return keep([
1309
1331
  ...preview.visualLines,
1310
1332
  ...preview.skippedCount === 0 ? [] : [
1311
1333
  getSelectListTheme7().description(
1312
1334
  `... ${preview.skippedCount} more lines \xB7 enter expand`
1313
1335
  )
1314
1336
  ]
1315
- ];
1337
+ ]);
1316
1338
  }
1317
1339
  const content = toolResultContent(result, true);
1318
1340
  const lines = content === "" ? [] : new Markdown3(content, 0, 0, getMarkdownTheme6()).render(boundedWidth);
1319
- return [
1341
+ return keep([
1320
1342
  ...lines,
1321
1343
  ...result.errorMessage === void 0 ? [] : [getSelectListTheme7().noMatch(`Error: ${result.errorMessage}`)],
1322
1344
  ...result.toolResultDetails === void 0 ? [] : [
@@ -1326,7 +1348,7 @@ var renderCampUiToolResult = (result, width, expanded) => {
1326
1348
  )
1327
1349
  ],
1328
1350
  ...preview.skippedCount === 0 ? [] : [getSelectListTheme7().description("enter collapse")]
1329
- ];
1351
+ ]);
1330
1352
  };
1331
1353
 
1332
1354
  // packages/host-ui/src/pi/blocks/campUiTranscriptBlocks.ts
@@ -1535,8 +1557,10 @@ var makeCampUiDetailComponent = (context, registry = defaultCampUiDetailBlockRen
1535
1557
  if (worker.error !== void 0) {
1536
1558
  return [selectTheme.noMatch(`Snapshot error: ${worker.error}`)];
1537
1559
  }
1560
+ const clockShown = worker.asks.some((ask) => ask.state === "pending");
1561
+ const presentationNow = clockShown ? model.state.presentationNow : void 0;
1538
1562
  const cached = detailCache.get(workerId);
1539
- const detail = cached !== void 0 && cached.worker === worker && cached.width === viewport.width && cached.expandedDetailBlockIds === model.state.expandedDetailBlockIds && cached.presentationNow === model.state.presentationNow ? cached.detail : renderCampUiDetailBlockLayout(registry, {
1563
+ const detail = cached !== void 0 && cached.worker === worker && cached.width === viewport.width && cached.expandedDetailBlockIds === model.state.expandedDetailBlockIds && cached.presentationNow === presentationNow ? cached.detail : renderCampUiDetailBlockLayout(registry, {
1540
1564
  model,
1541
1565
  worker,
1542
1566
  width: viewport.width
@@ -1546,7 +1570,7 @@ var makeCampUiDetailComponent = (context, registry = defaultCampUiDetailBlockRen
1546
1570
  worker,
1547
1571
  width: viewport.width,
1548
1572
  expandedDetailBlockIds: model.state.expandedDetailBlockIds,
1549
- presentationNow: model.state.presentationNow,
1573
+ ...presentationNow === void 0 ? {} : { presentationNow },
1550
1574
  detail
1551
1575
  });
1552
1576
  }
@@ -2699,6 +2723,8 @@ export {
2699
2723
  renderCampUiExploredGroup,
2700
2724
  CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
2701
2725
  CAMP_UI_BASH_PREVIEW_LINES,
2726
+ resetCampUiToolResultCache,
2727
+ campUiToolResultCacheSize,
2702
2728
  renderCampUiToolResult,
2703
2729
  campUiTranscriptBlockRenderer,
2704
2730
  defaultCampUiDetailBlockRenderers,
@@ -8,13 +8,13 @@ import {
8
8
  makeDoctorReport,
9
9
  resolveCampSurface,
10
10
  withCampRpc
11
- } from "./chunk-UDDSOI3H.js";
11
+ } from "./chunk-FZQM7AKO.js";
12
12
  import {
13
13
  PI_RUNTIME_VERSION,
14
14
  PiModelCatalogIssueCode,
15
15
  inspectPiModelCatalog,
16
16
  makePiOperatorResources
17
- } from "./chunk-ZNRMKVX3.js";
17
+ } from "./chunk-OWFOOE7W.js";
18
18
  import {
19
19
  CampHealthComponentStatus,
20
20
  CampHealthOverallStatus,
@@ -48,13 +48,13 @@ import {
48
48
  resolveCredentialsPath,
49
49
  resolveProjectScope,
50
50
  resolveWorkerConfigPath
51
- } from "./chunk-3NSS6BZD.js";
51
+ } from "./chunk-W2ZL6LWM.js";
52
52
  import {
53
53
  Clock_exports,
54
54
  Effect_exports,
55
55
  Option_exports,
56
56
  Ref_exports
57
- } from "./chunk-KFSFN6L5.js";
57
+ } from "./chunk-TZBPOE6G.js";
58
58
 
59
59
  // packages/cli/src/doctor/environmentDoctor.ts
60
60
  import { dirname } from "node:path";
@@ -41892,6 +41892,15 @@ var CampWorkerInterrupted = class extends Data_exports.TaggedError("CampWorkerIn
41892
41892
  };
41893
41893
  var CampWorkerTerminated = class extends Data_exports.TaggedError("CampWorkerTerminated") {
41894
41894
  };
41895
+ var campTurnFailureReason = (outcome) => {
41896
+ if (outcome.stopReason !== CampTurnStopReason.error && outcome.failureCode === void 0) {
41897
+ return void 0;
41898
+ }
41899
+ return {
41900
+ code: outcome.failureCode === void 0 ? CampFailureCode.unknown : CampFailureCode.providerError,
41901
+ message: outcome.errorMessage ?? "turn ended with an error"
41902
+ };
41903
+ };
41895
41904
 
41896
41905
  // packages/kernel/src/domain/campTopology.ts
41897
41906
  var CampChildClosePolicy = { cascade: "cascade", detach: "detach" };
@@ -41918,11 +41927,30 @@ var lastTurnStart = (messages) => {
41918
41927
  }
41919
41928
  return 0;
41920
41929
  };
41930
+ var lastTurnWindowStart = (messages, limit, maxBytes) => {
41931
+ const turnStart = lastTurnStart(messages);
41932
+ let start3 = messages.length;
41933
+ let bytes = 0;
41934
+ let taken = 0;
41935
+ for (let index = messages.length - 1; index >= turnStart; index -= 1) {
41936
+ const message = messages[index];
41937
+ if (message === void 0) continue;
41938
+ const size19 = messageBytes(message);
41939
+ if (taken > 0 && (taken >= limit || bytes + size19 > maxBytes)) break;
41940
+ start3 = index;
41941
+ bytes += size19;
41942
+ taken += 1;
41943
+ }
41944
+ return Math.min(start3, messages.length);
41945
+ };
41921
41946
  var campTranscriptPage = (messages, origin, request2 = {}) => {
41922
41947
  const limit = Math.max(1, request2.limit ?? CAMP_TRANSCRIPT_DEFAULT_LIMIT);
41923
41948
  const maxBytes = Math.max(1, request2.maxBytes ?? CAMP_TRANSCRIPT_DEFAULT_MAX_BYTES);
41924
41949
  const start3 = Math.min(
41925
- Math.max(0, request2.cursor ?? (request2.lastTurn === true ? lastTurnStart(messages) : 0)),
41950
+ Math.max(
41951
+ 0,
41952
+ request2.cursor ?? (request2.lastTurn === true ? lastTurnWindowStart(messages, limit, maxBytes) : 0)
41953
+ ),
41926
41954
  messages.length
41927
41955
  );
41928
41956
  const page = [];
@@ -43377,9 +43405,11 @@ var handleSessionEvent = (runtime6, id3, event) => Effect_exports.gen(function*
43377
43405
  );
43378
43406
  return { kind: "retrying", worker: worker2, payload: event.payload };
43379
43407
  }
43408
+ const turnError = event.kind === CampSessionEventKind.turnCompleted ? campTurnFailureReason(event.payload.outcome) : void 0;
43380
43409
  const worker = yield* runtime6.registry.updateTimestamps(id3, {
43381
43410
  updatedAt,
43382
- lastActivityAt: updatedAt
43411
+ lastActivityAt: updatedAt,
43412
+ ...event.kind === CampSessionEventKind.turnCompleted ? { turnError: turnError ?? null } : {}
43383
43413
  });
43384
43414
  if (event.kind === CampSessionEventKind.activity) {
43385
43415
  return { kind: "activity", worker, payload: event.payload };
@@ -43891,13 +43921,15 @@ var makeRegistryLifecycleOperations = (stateRef) => ({
43891
43921
  if (isTerminalCampState(record4.state) || record4.state === CampWorkerState.interrupted) {
43892
43922
  return mutationFailure(registryInvalid("registry.updateTimestamps", { id: id3 }), state);
43893
43923
  }
43924
+ const carried = input.turnError === null ? Object.fromEntries(Object.entries(record4).filter(([key]) => key !== "error")) : record4;
43894
43925
  const next4 = {
43895
- ...record4,
43926
+ ...carried,
43896
43927
  updatedAt: input.updatedAt,
43897
43928
  version: record4.version + 1,
43898
43929
  ...input.admittedAt === void 0 ? {} : { admittedAt: input.admittedAt },
43899
43930
  ...input.startedAt === void 0 ? {} : { startedAt: input.startedAt },
43900
- ...input.lastActivityAt === void 0 ? {} : { lastActivityAt: input.lastActivityAt }
43931
+ ...input.lastActivityAt === void 0 ? {} : { lastActivityAt: input.lastActivityAt },
43932
+ ...input.turnError === void 0 || input.turnError === null ? {} : { error: input.turnError }
43901
43933
  };
43902
43934
  return mutationSuccess(next4, {
43903
43935
  ...state,
@@ -366,7 +366,7 @@ import {
366
366
  write,
367
367
  zipRight,
368
368
  zipRight2
369
- } from "./chunk-KFSFN6L5.js";
369
+ } from "./chunk-TZBPOE6G.js";
370
370
 
371
371
  // node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/process.js
372
372
  var require_process = __commonJS({
@@ -10678,7 +10678,7 @@ var describeDirectToolSandbox = (sandbox2) => sandbox2.kind === DirectToolSandbo
10678
10678
 
10679
10679
  // packages/protocol/src/domain/protocolVersion.ts
10680
10680
  var PRIIISK_PROTOCOL_VERSION = "11";
10681
- var PRIIISK_PROTOCOL_PACKAGE_VERSION = "0.1.6";
10681
+ var PRIIISK_PROTOCOL_PACKAGE_VERSION = "0.1.8";
10682
10682
  var ProtocolVersionSchema = Schema_exports.String.pipe(Schema_exports.minLength(1));
10683
10683
 
10684
10684
  // packages/protocol/src/domain/protocolIdentifiers.ts
@@ -13553,7 +13553,7 @@ var CampProtocol = class extends RpcGroup_exports.make(
13553
13553
  };
13554
13554
 
13555
13555
  // packages/camp-state/src/bootstrap/campHostVersion.ts
13556
- var PRIIISK_HOST_VERSION = "0.1.6";
13556
+ var PRIIISK_HOST_VERSION = "0.1.8";
13557
13557
 
13558
13558
  // packages/surface/src/domain/surfaceModel.ts
13559
13559
  var NonEmptyString7 = Schema_exports.String.pipe(Schema_exports.minLength(1));
@@ -14497,12 +14497,27 @@ var CampRunCatalogErrorCode = {
14497
14497
  notFound: "run_not_found",
14498
14498
  notResumable: "run_not_resumable",
14499
14499
  persistenceFailed: "persistence_failed",
14500
+ /**
14501
+ * Checkpoint написан другой версией схемы. Общий `persistence_failed` описывал
14502
+ * бы это как поломку хранилища, тогда как лечение другое и уже названо в
14503
+ * контракте recovery: свежий запуск либо обновление рантайма
14504
+ * (priiisk-nss.6.23).
14505
+ */
14506
+ checkpointUnsupported: "checkpoint_unsupported",
14500
14507
  scopeMismatch: "scope_mismatch"
14501
14508
  };
14502
14509
  var CampRunCatalogError = class extends Data_exports.TaggedError("CampRunCatalogError") {
14503
14510
  };
14504
14511
  var isCampRunResumable = (manifest) => manifest.workers.some((worker) => worker.session.lifecycle !== "pending");
14505
14512
 
14513
+ // packages/camp-state/src/history/campRunCatalogFailures.ts
14514
+ var manifestReadFailure = (operation, message, cause) => new CampRunCatalogError({
14515
+ operation,
14516
+ code: cause instanceof CampManifestVersionError ? CampRunCatalogErrorCode.checkpointUnsupported : CampRunCatalogErrorCode.persistenceFailed,
14517
+ message,
14518
+ ...cause === void 0 ? {} : { cause }
14519
+ });
14520
+
14506
14521
  // packages/camp-state/src/history/campRunCatalog.ts
14507
14522
  var catalogError = (operation, code, message, cause) => new CampRunCatalogError({
14508
14523
  operation,
@@ -14527,12 +14542,7 @@ var summary = (manifest, active) => ({
14527
14542
  });
14528
14543
  var loadRequired = (fs, path, operation) => loadCampManifest(fs, path).pipe(
14529
14544
  Effect_exports.mapError(
14530
- (cause) => catalogError(
14531
- operation,
14532
- CampRunCatalogErrorCode.persistenceFailed,
14533
- `\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C camp run: ${path}`,
14534
- cause
14535
- )
14545
+ (cause) => manifestReadFailure(operation, `\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C camp run: ${path}`, cause)
14536
14546
  ),
14537
14547
  Effect_exports.flatMap(
14538
14548
  Option_exports.match({
@@ -14556,12 +14566,7 @@ var pathExists = (fs, path, operation) => fs.exists(path).pipe(
14556
14566
  var listCampRuns = (fs, project, paths) => Effect_exports.gen(function* () {
14557
14567
  const active = yield* loadCampManifest(fs, paths.manifestPath).pipe(
14558
14568
  Effect_exports.mapError(
14559
- (cause) => catalogError(
14560
- "list",
14561
- CampRunCatalogErrorCode.persistenceFailed,
14562
- "\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C active camp run",
14563
- cause
14564
- )
14569
+ (cause) => manifestReadFailure("list", "\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C active camp run", cause)
14565
14570
  )
14566
14571
  );
14567
14572
  if (Option_exports.isSome(active)) yield* validateScope("list", project, active.value);
@@ -4,14 +4,14 @@ const require = __priiiskCreateRequire(import.meta.url);
4
4
  import {
5
5
  NodeContext_exports,
6
6
  NodeRuntime_exports
7
- } from "./chunk-JWVO4S72.js";
7
+ } from "./chunk-4V3HXXQ6.js";
8
8
  import {
9
9
  CampUiBackendError,
10
10
  CampUiHealthStatus,
11
11
  CampUiPlacement,
12
12
  CampUiRuntimeStatus,
13
13
  mountPiCampUi
14
- } from "./chunk-32R4IEGS.js";
14
+ } from "./chunk-S7LCWMQY.js";
15
15
  import {
16
16
  PiTransport,
17
17
  makePiOperatorResources,
@@ -19,7 +19,7 @@ import {
19
19
  makePiTransportLayer,
20
20
  requirePiModelCatalog,
21
21
  require_undici
22
- } from "./chunk-ZNRMKVX3.js";
22
+ } from "./chunk-OWFOOE7W.js";
23
23
  import {
24
24
  AgentRole,
25
25
  AgentRoleSchema,
@@ -100,7 +100,7 @@ import {
100
100
  runningCampManifest,
101
101
  saveCampHealth,
102
102
  saveCampManifest
103
- } from "./chunk-3NSS6BZD.js";
103
+ } from "./chunk-W2ZL6LWM.js";
104
104
  import {
105
105
  CampAskRouter,
106
106
  CampCancellationCode,
@@ -193,7 +193,7 @@ import {
193
193
  withFiberRuntime,
194
194
  workerAliasIdentity,
195
195
  workerIdIdentity
196
- } from "./chunk-KFSFN6L5.js";
196
+ } from "./chunk-TZBPOE6G.js";
197
197
 
198
198
  // node_modules/.pnpm/ws@8.21.1/node_modules/ws/lib/constants.js
199
199
  var require_constants = __commonJS({
@@ -12788,23 +12788,38 @@ var stableJson = (value) => {
12788
12788
  const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([left], [right]) => left.localeCompare(right));
12789
12789
  return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
12790
12790
  };
12791
+ var durableFailureSummary = (cause) => {
12792
+ const code = cause?.code;
12793
+ if (typeof code === "string" && code !== "") return code;
12794
+ const name = cause instanceof Error ? cause.name : void 0;
12795
+ return name === void 0 || name === "" ? "unknown" : name;
12796
+ };
12791
12797
  var receiptPersistenceFailure = (operation, cause) => new CampCommandFailure({
12792
12798
  operation,
12793
12799
  code: CampReceiptFailureCode.persistenceFailed,
12794
- message: `command receipt could not be made durable: ${String(cause)}`,
12795
- retryable: true
12800
+ message: `command receipt could not be made durable (${durableFailureSummary(cause)})`,
12801
+ retryable: true,
12802
+ recoveryAction: "manual_recovery"
12796
12803
  });
12797
12804
  var loadCampReceipts = (fs, path, runId) => fs.exists(path).pipe(
12798
12805
  Effect_exports.flatMap((exists) => exists ? fs.readFileString(path) : Effect_exports.succeed(void 0)),
12799
12806
  Effect_exports.flatMap(
12800
- (contents) => contents === void 0 ? Effect_exports.succeed([]) : Effect_exports.try(() => JSON.parse(contents)).pipe(
12807
+ (contents) => contents === void 0 ? Effect_exports.succeed({ receipts: [] }) : Effect_exports.try(() => JSON.parse(contents)).pipe(
12801
12808
  Effect_exports.flatMap(decodeState),
12802
12809
  Effect_exports.map(
12803
- (state) => state.schemaVersion === CAMP_RECEIPT_SCHEMA_VERSION && state.runId === runId ? state.receipts : []
12810
+ (state) => state.schemaVersion === CAMP_RECEIPT_SCHEMA_VERSION && state.runId === runId ? { receipts: state.receipts } : {
12811
+ receipts: [],
12812
+ unreadable: state.runId === runId ? "unsupported_schema_version" : "foreign_run"
12813
+ }
12814
+ ),
12815
+ Effect_exports.catchAll(
12816
+ () => Effect_exports.succeed({ receipts: [], unreadable: "corrupt" })
12804
12817
  )
12805
12818
  )
12806
12819
  ),
12807
- Effect_exports.catchAll(() => Effect_exports.succeed([]))
12820
+ Effect_exports.catchAll(
12821
+ () => Effect_exports.succeed({ receipts: [], unreadable: "unreadable" })
12822
+ )
12808
12823
  );
12809
12824
  var saveCampReceipts = (fs, path, runId, receipts) => {
12810
12825
  const temporaryPath = `${path}.${randomUUID2()}.tmp`;
@@ -12888,9 +12903,15 @@ var makeCampCommandReceiptStoreLayer = (options) => Layer_exports.scoped(
12888
12903
  const retentionMillis = (options.retentionSeconds ?? CAMP_RECEIPT_DEFAULT_RETENTION_SECONDS) * 1e3;
12889
12904
  const restoredAt = yield* Clock_exports.currentTimeMillis;
12890
12905
  const restored = yield* loadCampReceipts(fs, options.statePath, journal.runId);
12891
- const state = yield* Ref_exports.make(campReceiptStateFromRecords(restored, restoredAt));
12906
+ const state = yield* Ref_exports.make(campReceiptStateFromRecords(restored.receipts, restoredAt));
12892
12907
  const inFlight = yield* Ref_exports.make(/* @__PURE__ */ new Map());
12893
- const lastFailure = yield* Ref_exports.make(void 0);
12908
+ const lastFailure = yield* Ref_exports.make(
12909
+ restored.unreadable === void 0 ? void 0 : receiptFailure(
12910
+ "restore",
12911
+ CampReceiptFailureCode.unreadable,
12912
+ `durable command receipts were not restored (${restored.unreadable})`
12913
+ )
12914
+ );
12894
12915
  const changes = yield* PubSub_exports.sliding(1);
12895
12916
  const lane = yield* Effect_exports.makeSemaphore(1);
12896
12917
  const publish = PubSub_exports.publish(changes, void 0).pipe(Effect_exports.asVoid);
@@ -22416,7 +22437,7 @@ var Client = class extends Protocol {
22416
22437
  };
22417
22438
 
22418
22439
  // packages/mcp-backend/src/connections/clientIdentity.ts
22419
- var backendVersion = "0.1.6";
22440
+ var backendVersion = "0.1.8";
22420
22441
 
22421
22442
  // packages/mcp-backend/src/connections/mcpFailure.ts
22422
22443
  var McpFailure = class extends Data_exports.TaggedError("McpFailure") {
@@ -25399,6 +25420,7 @@ var readSegmentText = (fs, path) => fs.readFileString(path).pipe(
25399
25420
  var loadJournalSegment = (fs, path, expected) => readSegmentText(fs, path).pipe(
25400
25421
  Effect_exports.flatMap((text) => {
25401
25422
  const totalBytes = Buffer.byteLength(text, "utf8");
25423
+ const endsWithNewline = text.endsWith("\n");
25402
25424
  const lines = text.split("\n");
25403
25425
  if (lines[lines.length - 1] === "") lines.pop();
25404
25426
  const headerLine = lines[0];
@@ -25408,7 +25430,8 @@ var loadJournalSegment = (fs, path, expected) => readSegmentText(fs, path).pipe(
25408
25430
  firstCursor: expected.firstCursor,
25409
25431
  events: [],
25410
25432
  validBytes: 0,
25411
- totalBytes
25433
+ totalBytes,
25434
+ truncatedTail: false
25412
25435
  });
25413
25436
  }
25414
25437
  const headerJson = parseJson(headerLine);
@@ -25419,7 +25442,9 @@ var loadJournalSegment = (fs, path, expected) => readSegmentText(fs, path).pipe(
25419
25442
  firstCursor: expected.firstCursor,
25420
25443
  events: [],
25421
25444
  validBytes: 0,
25422
- totalBytes
25445
+ totalBytes,
25446
+ /* Заголовок целиком записан, но нечитаем: это повреждение, не обрыв. */
25447
+ truncatedTail: lines.length === 1 && !endsWithNewline
25423
25448
  });
25424
25449
  }
25425
25450
  if (header.right.schemaVersion > CAMP_JOURNAL_SCHEMA_VERSION) {
@@ -25454,12 +25479,19 @@ var loadJournalSegment = (fs, path, expected) => readSegmentText(fs, path).pipe(
25454
25479
  }
25455
25480
  const events = [];
25456
25481
  let validBytes = lineBytes(headerLine);
25482
+ let stoppedAt;
25457
25483
  for (let index = 1; index < lines.length; index += 1) {
25458
25484
  const line = lines[index] ?? "";
25459
25485
  const parsed = parseJson(line);
25460
25486
  const decoded = parsed === void 0 ? void 0 : decodeEvent(parsed);
25461
- if (decoded === void 0 || Either_exports.isLeft(decoded)) break;
25462
- if (decoded.right.cursor !== expected.firstCursor + events.length) break;
25487
+ if (decoded === void 0 || Either_exports.isLeft(decoded)) {
25488
+ stoppedAt = index;
25489
+ break;
25490
+ }
25491
+ if (decoded.right.cursor !== expected.firstCursor + events.length) {
25492
+ stoppedAt = index;
25493
+ break;
25494
+ }
25463
25495
  events.push(decoded.right);
25464
25496
  validBytes += lineBytes(line);
25465
25497
  }
@@ -25468,7 +25500,14 @@ var loadJournalSegment = (fs, path, expected) => readSegmentText(fs, path).pipe(
25468
25500
  firstCursor: expected.firstCursor,
25469
25501
  events,
25470
25502
  validBytes,
25471
- totalBytes
25503
+ totalBytes,
25504
+ /*
25505
+ * Обрезать можно только оборванную последнюю запись: она одна осталась
25506
+ * после валидного префикса и не завершена переводом строки. Если после
25507
+ * сбойной записи есть другие или сама она дописана до конца, это
25508
+ * повреждение внутри файла, и обрезка стерла бы durable историю.
25509
+ */
25510
+ truncatedTail: stoppedAt === lines.length - 1 && !endsWithNewline
25472
25511
  });
25473
25512
  })
25474
25513
  );
@@ -25552,6 +25591,16 @@ var restoreCampJournal = (fs, options) => Effect_exports.gen(function* () {
25552
25591
  )
25553
25592
  );
25554
25593
  }
25594
+ if (!loaded.truncatedTail) {
25595
+ return yield* Effect_exports.fail(
25596
+ campJournalError(
25597
+ "open",
25598
+ CampJournalErrorCode.corrupted,
25599
+ "journal segment is damaged inside its last segment",
25600
+ { path }
25601
+ )
25602
+ );
25603
+ }
25555
25604
  yield* truncateSegment(fs, path, loaded.validBytes);
25556
25605
  }
25557
25606
  if (loaded.validBytes === 0) {
@@ -25683,10 +25732,9 @@ var makeCampJournalWriter = (fs, options, restored) => Effect_exports.gen(functi
25683
25732
  const event = CampEventDtoSchema.make({ ...draft, cursor });
25684
25733
  yield* writeLine(active.segment, journalEventLine(event));
25685
25734
  yield* SubscriptionRef_exports.update(state, (latest) => {
25686
- const { lastFailure: _lastFailure, ...healthy } = latest;
25687
25735
  const records = (active.segments[active.segments.length - 1]?.records ?? 0) + 1;
25688
25736
  return {
25689
- ...healthy,
25737
+ ...latest,
25690
25738
  segments: withRecords(active.segments, records),
25691
25739
  latestCursor: cursor
25692
25740
  };
@@ -26259,13 +26307,26 @@ var CampRpcHandlersLive = CampProtocol.toLayer(
26259
26307
  )
26260
26308
  )
26261
26309
  ),
26310
+ /*
26311
+ * Interrupt is a mutating command like the rest, so it goes through the
26312
+ * receipt: a repeat of the same `commandId` answers with the recorded
26313
+ * result instead of aborting a turn twice, and a stale generation is
26314
+ * refused before the side effect (priiisk-nss.6.24).
26315
+ */
26262
26316
  Interrupt: (request) => validateReady(request).pipe(
26263
26317
  Effect_exports.zipRight(
26264
- operations.interrupt(commandContext(request), workerIdentityFromDto(request.worker))
26265
- ),
26266
- Effect_exports.as({ accepted: true }),
26267
- Effect_exports.mapError(
26268
- (error2) => error2 instanceof ProtocolVersionMismatch || error2 instanceof ProjectScopeMismatch ? error2 : failureFromKernel("interrupt", error2)
26318
+ receipts.run(
26319
+ {
26320
+ identity: commandIdentity(request),
26321
+ operation: "interrupt",
26322
+ payload: { worker: request.worker },
26323
+ schema: CampAckSchema
26324
+ },
26325
+ operations.interrupt(commandContext(request), workerIdentityFromDto(request.worker)).pipe(
26326
+ Effect_exports.as(CampAckSchema.make({ accepted: true })),
26327
+ Effect_exports.mapError((error2) => failureFromKernel("interrupt", error2))
26328
+ )
26329
+ )
26269
26330
  )
26270
26331
  ),
26271
26332
  OpenWorker: (request) => validateReady(request).pipe(
@@ -26721,6 +26782,26 @@ var acquireLiveCampHost = (options = {}) => Effect_exports.gen(function* () {
26721
26782
  piResources.modelRegistry,
26722
26783
  { authDiagnosticCodes: piResources.authDiagnosticCodes ?? [] }
26723
26784
  );
26785
+ const reportStartupJournalFailure = (cause) => cause instanceof CampJournalError ? Clock_exports.currentTimeMillis.pipe(
26786
+ Effect_exports.flatMap(
26787
+ (now) => saveCampHealth(fs, paths.healthPath, {
26788
+ ...initialCampHealthSnapshot(project.hash, "startup", now),
26789
+ overallStatus: CampHealthOverallStatus.failed,
26790
+ components: [
26791
+ {
26792
+ id: CAMP_JOURNAL_HEALTH_COMPONENT,
26793
+ category: CampHealthComponentCategory.controller,
26794
+ status: CampHealthComponentStatus.failed,
26795
+ code: cause.code,
26796
+ operation: "controller.journal.open",
26797
+ message: cause.message,
26798
+ updatedAt: now
26799
+ }
26800
+ ]
26801
+ })
26802
+ ),
26803
+ Effect_exports.ignore
26804
+ ) : Effect_exports.void;
26724
26805
  const context = yield* Layer_exports.build(
26725
26806
  makeLiveCampHostLayer({
26726
26807
  project,
@@ -26740,7 +26821,7 @@ var acquireLiveCampHost = (options = {}) => Effect_exports.gen(function* () {
26740
26821
  receiptsPath: campRunPaths(paths, options.manifestRunId).receiptsPath
26741
26822
  }
26742
26823
  })
26743
- );
26824
+ ).pipe(Effect_exports.tapError(reportStartupJournalFailure));
26744
26825
  const kernel = Context_exports.get(context, CampKernel);
26745
26826
  const asks = Context_exports.get(context, CampAskRouter);
26746
26827
  const health = Context_exports.get(context, CampHostHealth);
package/dist/priiisk.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  fromReadable,
6
6
  layer,
7
7
  runMain
8
- } from "./chunk-JWVO4S72.js";
8
+ } from "./chunk-4V3HXXQ6.js";
9
9
  import {
10
10
  CliCampLifecycleError,
11
11
  CliEquipmentConflict,
@@ -23,7 +23,7 @@ import {
23
23
  resolveCampSurface,
24
24
  withCampRpc,
25
25
  withCampRpcSession
26
- } from "./chunk-UDDSOI3H.js";
26
+ } from "./chunk-FZQM7AKO.js";
27
27
  import {
28
28
  CampCommandFailure,
29
29
  CampHostReadiness,
@@ -58,7 +58,7 @@ import {
58
58
  resolveProjectScopeSync,
59
59
  saveCampManifest,
60
60
  startingCampManifest
61
- } from "./chunk-3NSS6BZD.js";
61
+ } from "./chunk-W2ZL6LWM.js";
62
62
  import {
63
63
  Cause_exports,
64
64
  CommitPrototype,
@@ -239,7 +239,7 @@ import {
239
239
  zipLeft,
240
240
  zipRight,
241
241
  zipWith
242
- } from "./chunk-KFSFN6L5.js";
242
+ } from "./chunk-TZBPOE6G.js";
243
243
 
244
244
  // node_modules/.pnpm/ini@4.1.3/node_modules/ini/lib/ini.js
245
245
  var require_ini = __commonJS({
@@ -18637,9 +18637,11 @@ var equipmentLines = (equipment, revision) => [
18637
18637
  ` mcp: ${mcpGrants(equipment.mcp)}`,
18638
18638
  ` skills: ${names([...equipment.skillNames])}`
18639
18639
  ];
18640
+ var WORKER_ERROR_LIMIT = 160;
18640
18641
  var formatWorker = (worker) => {
18641
18642
  const alias = worker.alias === void 0 ? "" : ` (${worker.alias})`;
18642
- const headline = `${worker.workerId}${alias}: ${worker.state}, session ${worker.sessionState}`;
18643
+ const failure2 = worker.error === void 0 ? "" : ` \u2014 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u0445\u043E\u0434: ${worker.error.code}: ${worker.error.message.slice(0, WORKER_ERROR_LIMIT)}`;
18644
+ const headline = `${worker.workerId}${alias}: ${worker.state}, session ${worker.sessionState}${failure2}`;
18643
18645
  return worker.equipment === void 0 ? headline : [headline, ...equipmentLines(worker.equipment, worker.equipmentVersion)].join("\n");
18644
18646
  };
18645
18647
  var printWorkers = (json) => (effect) => effect.pipe(
@@ -18680,10 +18682,7 @@ var formatTranscriptPage = (page) => {
18680
18682
  var formatCampEvent = (event) => `${String(event.cursor)} ${event.kind} ${event.worker.alias ?? event.worker.workerId}`;
18681
18683
  var formatDeliveryOutcome = (outcome) => {
18682
18684
  if (outcome.settled === void 0) return "Message accepted";
18683
- return [
18684
- `Turn settled: ${outcome.settled.kind} at cursor ${String(outcome.settled.cursor)}`,
18685
- ...outcome.transcript === void 0 ? [] : [formatTranscriptPage(outcome.transcript)]
18686
- ].join("\n");
18685
+ return outcome.answer ?? `Turn settled: ${outcome.settled.kind}`;
18687
18686
  };
18688
18687
  var CAUSE_LIMIT = 400;
18689
18688
  var describeCause = (cause) => {
@@ -18997,6 +18996,60 @@ var runCampStdioSession = (runner, options3 = {}) => Effect_exports.gen(function
18997
18996
  );
18998
18997
  });
18999
18998
 
18999
+ // packages/cli/src/commands/commandOptions.ts
19000
+ var jsonOption = Options_exports.boolean("json");
19001
+ var workerArgument = Args_exports.text({ name: "worker" });
19002
+ var byIdOption = Options_exports.boolean("by-id");
19003
+ var workerSelector = (worker, byId) => byId ? { kind: "id", workerId: worker } : { kind: "alias", alias: worker };
19004
+
19005
+ // packages/cli/src/commands/answerCommand.ts
19006
+ var finalAnswerText = (page) => {
19007
+ for (let index = page.messages.length - 1; index >= 0; index -= 1) {
19008
+ const message = page.messages[index];
19009
+ if (message === void 0 || message.role !== "assistant") continue;
19010
+ for (let part = message.content.length - 1; part >= 0; part -= 1) {
19011
+ const content = message.content[part];
19012
+ if (content?.kind === "text" && content.text !== void 0 && content.text.trim() !== "") {
19013
+ return content.text;
19014
+ }
19015
+ }
19016
+ }
19017
+ return void 0;
19018
+ };
19019
+ var workingStates = /* @__PURE__ */ new Set(["running", "starting"]);
19020
+ var answerCommand = Command_exports.make(
19021
+ "answer",
19022
+ { worker: workerArgument, byId: byIdOption, json: jsonOption },
19023
+ ({ worker, byId, json }) => {
19024
+ const selector = workerSelector(worker, byId);
19025
+ return withCampRpc(
19026
+ ({ client, context }) => Effect_exports.all({
19027
+ status: client.WorkerStatus({ ...context, worker: selector }),
19028
+ page: client.WorkerTranscript({ ...context, worker: selector, lastTurn: true })
19029
+ }).pipe(
19030
+ Effect_exports.map(({ status, page }) => {
19031
+ const text11 = finalAnswerText(page);
19032
+ const working = workingStates.has(status.state);
19033
+ return text11 === void 0 || working ? {
19034
+ worker,
19035
+ answered: false,
19036
+ reason: working ? "turn_in_progress" : "no_answer_yet",
19037
+ state: status.state
19038
+ } : { worker, answered: true, text: text11, state: status.state };
19039
+ })
19040
+ ),
19041
+ { operation: "answer", timeoutMs: 3e4 }
19042
+ ).pipe(
19043
+ printValue(
19044
+ json,
19045
+ (answer) => answer.answered ? answer.text ?? "" : answer.reason === "turn_in_progress" ? `\u0412\u043E\u0440\u043A\u0435\u0440 ${answer.worker} \u0435\u0449\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043D\u0430\u0434 \u0445\u043E\u0434\u043E\u043C` : `\u0423 \u0432\u043E\u0440\u043A\u0435\u0440\u0430 ${answer.worker} \u043F\u043E\u043A\u0430 \u043D\u0435\u0442 \u043E\u0442\u0432\u0435\u0442\u0430`
19046
+ )
19047
+ );
19048
+ }
19049
+ ).pipe(
19050
+ Command_exports.withDescription("Prints the final answer of a worker, without the rest of the turn.")
19051
+ );
19052
+
19000
19053
  // packages/cli/src/input/messageSource.ts
19001
19054
  var fileOption = Options_exports.file("file", { exists: "either" }).pipe(
19002
19055
  Options_exports.withDescription("Reads the text from this file instead of the positional argument."),
@@ -19043,18 +19096,14 @@ var resolveMessageText = (operation, text11, file6) => {
19043
19096
  );
19044
19097
  }
19045
19098
  if (Option_exports.isSome(file6)) return readMessageFile(operation, file6.value);
19046
- if (Option_exports.isSome(text11)) return Effect_exports.succeed(text11.value);
19099
+ if (Option_exports.isSome(text11)) {
19100
+ return text11.value.trim().length === 0 ? Effect_exports.fail(failure(operation, "message_empty", "\u0422\u0435\u043A\u0441\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043F\u0443\u0441\u0442")) : Effect_exports.succeed(text11.value);
19101
+ }
19047
19102
  return Effect_exports.fail(
19048
19103
  failure(operation, "message_source_missing", "\u041D\u0443\u0436\u0435\u043D \u0442\u0435\u043A\u0441\u0442 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u043C \u043B\u0438\u0431\u043E --file <path>")
19049
19104
  );
19050
19105
  };
19051
19106
 
19052
- // packages/cli/src/commands/commandOptions.ts
19053
- var jsonOption = Options_exports.boolean("json");
19054
- var workerArgument = Args_exports.text({ name: "worker" });
19055
- var byIdOption = Options_exports.boolean("by-id");
19056
- var workerSelector = (worker, byId) => byId ? { kind: "id", workerId: worker } : { kind: "alias", alias: worker };
19057
-
19058
19107
  // packages/cli/src/commands/askCommands.ts
19059
19108
  var askIdArgument = Args_exports.text({ name: "ask-id" });
19060
19109
  var answerArgument = Args_exports.text({ name: "answer" }).pipe(Args_exports.optional);
@@ -19903,7 +19952,7 @@ var campResumeListCommand = Command_exports.make(
19903
19952
  )
19904
19953
  ).pipe(Command_exports.withDescription("Lists saved runs of this project that resume can restore."));
19905
19954
  var runIdArgument = Args_exports.text({ name: "runId" }).pipe(Args_exports.optional);
19906
- var selectCampRunOnDemand = (items) => Effect_exports.promise(() => import("./chunk-TOVFB7H6.js")).pipe(
19955
+ var selectCampRunOnDemand = (items) => Effect_exports.promise(() => import("./chunk-BXVX5A4M.js")).pipe(
19907
19956
  Effect_exports.flatMap((ui) => ui.selectCampRun({ items }))
19908
19957
  );
19909
19958
  var selectAndResume = (json) => {
@@ -19976,7 +20025,7 @@ var rootCommand = Command_exports.make(
19976
20025
  ).pipe(Command_exports.withDescription("Runs and observes a camp of collaborating workers."));
19977
20026
 
19978
20027
  // packages/cli/src/commands/doctorCommand.ts
19979
- var runDoctorOnDemand = Effect_exports.promise(() => import("./chunk-X4GVQOCR.js")).pipe(
20028
+ var runDoctorOnDemand = Effect_exports.promise(() => import("./chunk-TGTG65RZ.js")).pipe(
19980
20029
  Effect_exports.flatMap((doctor) => doctor.runDoctor)
19981
20030
  );
19982
20031
  var statusLabel = {
@@ -20314,7 +20363,19 @@ var eventsCommand = Command_exports.make(
20314
20363
  if (follow) {
20315
20364
  yield* stream.pipe(
20316
20365
  Stream_exports.runForEach(
20317
- (event) => Console_exports.log(json ? JSON.stringify(event) : formatCampEvent(event))
20366
+ (event) => Console_exports.log(json ? JSON.stringify(event) : formatCampEvent(event)).pipe(
20367
+ Effect_exports.zipRight(
20368
+ ack ? client.AckEvents({
20369
+ ...leaseRequest,
20370
+ generation: event.generation,
20371
+ cursor: event.cursor
20372
+ }).pipe(Effect_exports.asVoid) : Effect_exports.void
20373
+ )
20374
+ )
20375
+ )
20376
+ ).pipe(
20377
+ Effect_exports.ensuring(
20378
+ release ? client.ReleaseConsumer(context).pipe(Effect_exports.ignore) : Effect_exports.void
20318
20379
  )
20319
20380
  );
20320
20381
  return [];
@@ -20515,12 +20576,13 @@ var sendWaitCommand = Command_exports.make(
20515
20576
  cursor: before.latestCursor,
20516
20577
  timeoutMs
20517
20578
  });
20518
- const transcript = yield* session.client.WorkerTranscript({
20579
+ const page = yield* session.client.WorkerTranscript({
20519
20580
  ...session.context,
20520
20581
  worker: selector,
20521
20582
  lastTurn: true
20522
20583
  });
20523
- return { accepted: true, settled, transcript };
20584
+ const answer = finalAnswerText(page);
20585
+ return { accepted: true, settled, ...answer === void 0 ? {} : { answer } };
20524
20586
  }),
20525
20587
  {
20526
20588
  operation: "send",
@@ -20656,6 +20718,7 @@ var command = rootCommand.pipe(
20656
20718
  listCommand,
20657
20719
  statusCommand,
20658
20720
  transcriptCommand,
20721
+ answerCommand,
20659
20722
  hireCommand,
20660
20723
  equipCommand,
20661
20724
  interruptCommand,
@@ -20672,7 +20735,7 @@ var command = rootCommand.pipe(
20672
20735
  );
20673
20736
  var cli = Command_exports.run(command, {
20674
20737
  name: "priiisk camp control",
20675
- version: "0.1.6"
20738
+ version: "0.1.8"
20676
20739
  });
20677
20740
  var runCliCommand = (argumentsList) => cli(argumentsList).pipe(
20678
20741
  Effect_exports.matchEffect({
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "priiisk",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "CLI for running and observing a camp of collaborating agents",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "priiisk": "./dist/priiisk.js"
8
8
  },
9
9
  "files": [
10
- "dist/chunk-32R4IEGS.js",
11
- "dist/chunk-3NSS6BZD.js",
12
- "dist/chunk-3NSS6BZD.js.LEGAL.txt",
13
- "dist/chunk-JWVO4S72.js",
14
- "dist/chunk-KFSFN6L5.js",
15
- "dist/chunk-TOVFB7H6.js",
16
- "dist/chunk-UDDSOI3H.js",
17
- "dist/chunk-X4GVQOCR.js",
18
- "dist/chunk-ZNRMKVX3.js",
19
- "dist/chunk-ZNRMKVX3.js.LEGAL.txt",
10
+ "dist/chunk-4V3HXXQ6.js",
11
+ "dist/chunk-BXVX5A4M.js",
12
+ "dist/chunk-FZQM7AKO.js",
13
+ "dist/chunk-OWFOOE7W.js",
14
+ "dist/chunk-OWFOOE7W.js.LEGAL.txt",
15
+ "dist/chunk-S7LCWMQY.js",
16
+ "dist/chunk-TGTG65RZ.js",
17
+ "dist/chunk-TZBPOE6G.js",
18
+ "dist/chunk-W2ZL6LWM.js",
19
+ "dist/chunk-W2ZL6LWM.js.LEGAL.txt",
20
20
  "dist/priiisk-host.js",
21
21
  "dist/priiisk.js",
22
22
  "profiles",