priiisk 0.1.2 → 0.1.4

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.
@@ -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-EBRDSFGF.js";
6
+ } from "./chunk-QX5EESCS.js";
7
7
  import {
8
8
  CampDeliveryPort,
9
9
  CampFailureCode,
@@ -1067,7 +1067,7 @@ var makeCampUiComposerComponent = (context, tui) => {
1067
1067
  };
1068
1068
 
1069
1069
  // packages/host-ui/src/pi/blocks/campUiDetail.ts
1070
- import { getSelectListTheme as getSelectListTheme7 } from "@earendil-works/pi-coding-agent";
1070
+ import { getSelectListTheme as getSelectListTheme8 } from "@earendil-works/pi-coding-agent";
1071
1071
  import { Key as Key2, matchesKey as matchesKey2 } from "@earendil-works/pi-tui";
1072
1072
 
1073
1073
  // packages/host-ui/src/pi/blocks/campUiEquipmentBlock.ts
@@ -1134,10 +1134,129 @@ var renderCampUiPanel = (label, body, width) => {
1134
1134
  ];
1135
1135
  };
1136
1136
 
1137
+ // packages/host-ui/src/pi/blocks/campUiExploredBlock.ts
1138
+ import { getSelectListTheme as getSelectListTheme6 } from "@earendil-works/pi-coding-agent";
1139
+ var CAMP_UI_EXPLORED_TOOL_NAMES = ["read"];
1140
+ var CAMP_UI_EXPLORED_COLLAPSED_PATHS = 8;
1141
+ var CampUiExploredStatus = {
1142
+ running: "running",
1143
+ completed: "completed",
1144
+ failed: "failed"
1145
+ };
1146
+ var isCampUiExploredTool = (toolName) => CAMP_UI_EXPLORED_TOOL_NAMES.includes(toolName);
1147
+ var stringArgument = (parameters, name) => {
1148
+ const value = parameters[name];
1149
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
1150
+ };
1151
+ var numberArgument = (parameters, name) => {
1152
+ const value = parameters[name];
1153
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1154
+ };
1155
+ var campUiExploredReadPath = (parameters) => stringArgument(parameters, "path") ?? stringArgument(parameters, "file_path");
1156
+ var campUiExploredReadRange = (parameters) => {
1157
+ const offset = numberArgument(parameters, "offset");
1158
+ const limit = numberArgument(parameters, "limit");
1159
+ if (offset === void 0 && limit === void 0) return void 0;
1160
+ const start = offset ?? 1;
1161
+ return limit === void 0 ? `from line ${String(start)}` : `lines ${String(start)}-${String(start + limit - 1)}`;
1162
+ };
1163
+ var statusRank = {
1164
+ completed: 0,
1165
+ running: 1,
1166
+ failed: 2
1167
+ };
1168
+ var splitPath = (path) => {
1169
+ const separator = path.lastIndexOf("/");
1170
+ if (separator < 0) return { directory: ".", name: path };
1171
+ if (separator === 0) return { directory: "/", name: path.slice(1) };
1172
+ return { directory: path.slice(0, separator), name: path.slice(separator + 1) };
1173
+ };
1174
+ var collectNodes = (reads) => {
1175
+ const byPath = /* @__PURE__ */ new Map();
1176
+ for (const read of reads) {
1177
+ const existing = byPath.get(read.path);
1178
+ const node = existing ?? (() => {
1179
+ const { directory, name } = splitPath(read.path);
1180
+ const created = {
1181
+ path: read.path,
1182
+ directory,
1183
+ name,
1184
+ reads: 0,
1185
+ status: CampUiExploredStatus.completed,
1186
+ ranges: [],
1187
+ errorMessage: void 0
1188
+ };
1189
+ byPath.set(read.path, created);
1190
+ return created;
1191
+ })();
1192
+ node.reads += 1;
1193
+ if (statusRank[read.status] > statusRank[node.status]) node.status = read.status;
1194
+ if (read.range !== void 0 && !node.ranges.includes(read.range)) node.ranges.push(read.range);
1195
+ if (read.errorMessage !== void 0 && node.errorMessage === void 0) {
1196
+ node.errorMessage = read.errorMessage;
1197
+ }
1198
+ }
1199
+ return [...byPath.values()];
1200
+ };
1201
+ var toneByStatus = {
1202
+ completed: CampUiTone.success,
1203
+ running: CampUiTone.active,
1204
+ failed: CampUiTone.error
1205
+ };
1206
+ var firstLine = (message) => message.split("\n")[0] ?? message;
1207
+ var nodeLine = (node, expanded) => {
1208
+ const theme = getSelectListTheme6();
1209
+ const repeats = node.reads > 1 ? theme.description(` \xD7${String(node.reads)}`) : "";
1210
+ const ranges = expanded && node.ranges.length > 0 ? theme.description(` \xB7 ${node.ranges.join(", ")}`) : "";
1211
+ const error = node.errorMessage === void 0 ? "" : theme.noMatch(` \u2014 ${firstLine(node.errorMessage)}`);
1212
+ return ` ${renderCampUiStatus(node.name, toneByStatus[node.status])}${repeats}${ranges}${error}`;
1213
+ };
1214
+ var selectVisibleNodes = (nodes, budget) => {
1215
+ if (nodes.length <= budget) return nodes;
1216
+ const attention = nodes.filter((node) => node.status !== CampUiExploredStatus.completed);
1217
+ const remaining = Math.max(0, budget - attention.length);
1218
+ const completed = nodes.filter((node) => node.status === CampUiExploredStatus.completed).slice(0, remaining);
1219
+ const keep = /* @__PURE__ */ new Set([...attention, ...completed]);
1220
+ return nodes.filter((node) => keep.has(node));
1221
+ };
1222
+ var renderCampUiExploredGroup = (reads, width, expanded) => {
1223
+ const theme = getSelectListTheme6();
1224
+ const nodes = collectNodes(reads);
1225
+ const visible = expanded ? nodes : selectVisibleNodes(nodes, CAMP_UI_EXPLORED_COLLAPSED_PATHS);
1226
+ const hidden = nodes.length - visible.length;
1227
+ const running = nodes.filter((node) => node.status === CampUiExploredStatus.running).length;
1228
+ const failed = nodes.filter((node) => node.status === CampUiExploredStatus.failed).length;
1229
+ const label = [
1230
+ `explored \xB7 ${String(nodes.length)} ${nodes.length === 1 ? "file" : "files"}`,
1231
+ ...running === 0 ? [] : [`${String(running)} running`],
1232
+ ...failed === 0 ? [] : [`${String(failed)} failed`]
1233
+ ].join(" \xB7 ");
1234
+ const innerWidth = Math.max(1, width - 2);
1235
+ const body = [];
1236
+ let directory;
1237
+ for (const node of visible) {
1238
+ if (node.directory !== directory) {
1239
+ directory = node.directory;
1240
+ body.push(theme.description(directory));
1241
+ }
1242
+ body.push(nodeLine(node, expanded));
1243
+ }
1244
+ body.push(
1245
+ theme.description(
1246
+ hidden > 0 ? `... ${String(hidden)} more paths \xB7 enter expand` : expanded ? "enter collapse" : "enter expand"
1247
+ )
1248
+ );
1249
+ return renderCampUiPanel(
1250
+ label,
1251
+ body.map((line) => fitCampUiLine(line, innerWidth)),
1252
+ width
1253
+ );
1254
+ };
1255
+
1137
1256
  // packages/host-ui/src/pi/blocks/campUiToolResult.ts
1138
1257
  import {
1139
1258
  getMarkdownTheme as getMarkdownTheme6,
1140
- getSelectListTheme as getSelectListTheme6,
1259
+ getSelectListTheme as getSelectListTheme7,
1141
1260
  truncateToVisualLines
1142
1261
  } from "@earendil-works/pi-coding-agent";
1143
1262
  import { Markdown as Markdown3 } from "@earendil-works/pi-tui";
@@ -1174,7 +1293,7 @@ var renderCampUiToolResult = (result, width, expanded) => {
1174
1293
  const boundedWidth = Math.max(1, width);
1175
1294
  const plainText = toolResultPlainText(result);
1176
1295
  const preview = truncateToVisualLines(
1177
- getSelectListTheme6().description(plainText),
1296
+ getSelectListTheme7().description(plainText),
1178
1297
  previewLinesByTool.get(result.toolName ?? "") ?? CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
1179
1298
  boundedWidth
1180
1299
  );
@@ -1182,7 +1301,7 @@ var renderCampUiToolResult = (result, width, expanded) => {
1182
1301
  return [
1183
1302
  ...preview.visualLines,
1184
1303
  ...preview.skippedCount === 0 ? [] : [
1185
- getSelectListTheme6().description(
1304
+ getSelectListTheme7().description(
1186
1305
  `... ${preview.skippedCount} more lines \xB7 enter expand`
1187
1306
  )
1188
1307
  ]
@@ -1192,18 +1311,24 @@ var renderCampUiToolResult = (result, width, expanded) => {
1192
1311
  const lines = content === "" ? [] : new Markdown3(content, 0, 0, getMarkdownTheme6()).render(boundedWidth);
1193
1312
  return [
1194
1313
  ...lines,
1195
- ...result.errorMessage === void 0 ? [] : [getSelectListTheme6().noMatch(`Error: ${result.errorMessage}`)],
1314
+ ...result.errorMessage === void 0 ? [] : [getSelectListTheme7().noMatch(`Error: ${result.errorMessage}`)],
1196
1315
  ...result.toolResultDetails === void 0 ? [] : [
1197
- getSelectListTheme6().description("Details"),
1316
+ getSelectListTheme7().description("Details"),
1198
1317
  ...new Markdown3(jsonText(result.toolResultDetails), 0, 0, getMarkdownTheme6()).render(
1199
1318
  boundedWidth
1200
1319
  )
1201
1320
  ],
1202
- ...preview.skippedCount === 0 ? [] : [getSelectListTheme6().description("enter collapse")]
1321
+ ...preview.skippedCount === 0 ? [] : [getSelectListTheme7().description("enter collapse")]
1203
1322
  ];
1204
1323
  };
1205
1324
 
1206
1325
  // packages/host-ui/src/pi/blocks/campUiTranscriptBlocks.ts
1326
+ var toolResultErrorText = (result) => {
1327
+ for (const content of result.content) {
1328
+ if (content.kind === "text" && content.text.trim() !== "") return content.text;
1329
+ }
1330
+ return void 0;
1331
+ };
1207
1332
  var contentMarkdown = (message, includeToolCalls) => message.content.flatMap((content) => {
1208
1333
  if (content.kind === "text") return [content.text];
1209
1334
  if (content.kind === "thinking") {
@@ -1290,6 +1415,17 @@ var renderUnmatchedToolResult = (message, width, expanded) => {
1290
1415
  width
1291
1416
  );
1292
1417
  };
1418
+ var exploredRead = (toolCall, path, result) => {
1419
+ const range = campUiExploredReadRange(toolCall.arguments);
1420
+ const errorMessage = result?.isError === true ? result.errorMessage ?? toolResultErrorText(result) ?? "read failed" : void 0;
1421
+ return {
1422
+ toolCallId: toolCall.toolCallId,
1423
+ path,
1424
+ status: result === void 0 ? CampUiExploredStatus.running : result.isError === true ? CampUiExploredStatus.failed : CampUiExploredStatus.completed,
1425
+ ...range === void 0 ? {} : { range },
1426
+ ...errorMessage === void 0 ? {} : { errorMessage }
1427
+ };
1428
+ };
1293
1429
  var renderTranscript = (transcript, width, expandedDetailBlockIds) => {
1294
1430
  const results = /* @__PURE__ */ new Map();
1295
1431
  const callIds = /* @__PURE__ */ new Set();
@@ -1301,23 +1437,45 @@ var renderTranscript = (transcript, width, expandedDetailBlockIds) => {
1301
1437
  if (content.kind === "tool-call") callIds.add(content.toolCallId);
1302
1438
  }
1303
1439
  }
1304
- return transcript.flatMap((message, index) => {
1440
+ const blocks = [];
1441
+ let group = [];
1442
+ const closeGroup = () => {
1443
+ const first = group[0];
1444
+ if (first === void 0) return;
1445
+ const blockId = `explored:${first.toolCallId}`;
1446
+ blocks.push({
1447
+ id: blockId,
1448
+ lines: renderCampUiExploredGroup(group, width, expandedDetailBlockIds.has(blockId)),
1449
+ toggleable: true
1450
+ });
1451
+ group = [];
1452
+ };
1453
+ transcript.forEach((message, index) => {
1305
1454
  const messageId = message.id ?? String(index);
1306
1455
  if (message.role === "toolResult") {
1456
+ if (message.toolCallId !== void 0 && callIds.has(message.toolCallId)) return;
1457
+ closeGroup();
1307
1458
  const blockId = `tool-result:${messageId}`;
1308
- return message.toolCallId !== void 0 && callIds.has(message.toolCallId) ? [] : [
1309
- {
1310
- id: blockId,
1311
- lines: renderUnmatchedToolResult(message, width, expandedDetailBlockIds.has(blockId)),
1312
- toggleable: true
1313
- }
1314
- ];
1459
+ blocks.push({
1460
+ id: blockId,
1461
+ lines: renderUnmatchedToolResult(message, width, expandedDetailBlockIds.has(blockId)),
1462
+ toggleable: true
1463
+ });
1464
+ return;
1315
1465
  }
1316
- const blocks = [];
1317
1466
  const messageLines = renderMessage(message, width);
1318
- if (messageLines.length > 0) blocks.push({ id: `message:${messageId}`, lines: messageLines });
1467
+ if (messageLines.length > 0) {
1468
+ closeGroup();
1469
+ blocks.push({ id: `message:${messageId}`, lines: messageLines });
1470
+ }
1319
1471
  for (const content of message.content) {
1320
1472
  if (content.kind !== "tool-call") continue;
1473
+ const path = isCampUiExploredTool(content.toolName) ? campUiExploredReadPath(content.arguments) : void 0;
1474
+ if (path !== void 0) {
1475
+ group.push(exploredRead(content, path, results.get(content.toolCallId)));
1476
+ continue;
1477
+ }
1478
+ closeGroup();
1321
1479
  const blockId = `tool-call:${content.toolCallId}`;
1322
1480
  blocks.push({
1323
1481
  id: blockId,
@@ -1330,8 +1488,9 @@ var renderTranscript = (transcript, width, expandedDetailBlockIds) => {
1330
1488
  toggleable: results.has(content.toolCallId)
1331
1489
  });
1332
1490
  }
1333
- return blocks;
1334
1491
  });
1492
+ closeGroup();
1493
+ return blocks;
1335
1494
  };
1336
1495
  var campUiTranscriptBlockRenderer = {
1337
1496
  id: "transcript",
@@ -1361,7 +1520,7 @@ var makeCampUiDetailComponent = (context, registry = defaultCampUiDetailBlockRen
1361
1520
  renderedRanges = [];
1362
1521
  visibleRanges = [];
1363
1522
  const model = context.readModel();
1364
- const selectTheme = getSelectListTheme7();
1523
+ const selectTheme = getSelectListTheme8();
1365
1524
  const workerId = model.state.selectedWorkerId;
1366
1525
  if (workerId === void 0) return [selectTheme.description("No worker selected")];
1367
1526
  const worker = findCampUiWorker(model.snapshot, workerId);
@@ -1464,11 +1623,11 @@ var makeCampUiDetailComponent = (context, registry = defaultCampUiDetailBlockRen
1464
1623
  };
1465
1624
 
1466
1625
  // packages/host-ui/src/pi/layout/campUiChrome.ts
1467
- import { getSelectListTheme as getSelectListTheme8 } from "@earendil-works/pi-coding-agent";
1626
+ import { getSelectListTheme as getSelectListTheme9 } from "@earendil-works/pi-coding-agent";
1468
1627
  var makeCampUiCampHeader = (context) => ({
1469
1628
  render: (viewport) => {
1470
1629
  const snapshot = context.readModel().snapshot;
1471
- const theme = getSelectListTheme8();
1630
+ const theme = getSelectListTheme9();
1472
1631
  const mode = snapshot.placement === "external" ? "agentless" : "foreman";
1473
1632
  return [
1474
1633
  fitCampUiLine(theme.description(snapshot.displayName), viewport.width),
@@ -1482,7 +1641,7 @@ var makeCampUiCampHeader = (context) => ({
1482
1641
  var makeCampUiSeat = (context) => ({
1483
1642
  render: (viewport) => {
1484
1643
  const snapshot = context.readModel().snapshot;
1485
- const theme = getSelectListTheme8();
1644
+ const theme = getSelectListTheme9();
1486
1645
  const external = snapshot.placement === "external";
1487
1646
  const controller = snapshot.controllerConnected ? renderCampUiStatus("live", CampUiTone.success, CampUiGlyph.live) : renderCampUiStatus("lost", CampUiTone.error);
1488
1647
  return [
@@ -1497,7 +1656,7 @@ var makeCampUiRoster = (context) => ({
1497
1656
  focusable: true,
1498
1657
  render: (viewport) => {
1499
1658
  const model = context.readModel();
1500
- const theme = getSelectListTheme8();
1659
+ const theme = getSelectListTheme9();
1501
1660
  const focused = model.state.focusedSlotId === CampUiSlot.roster;
1502
1661
  if (model.snapshot.workers.length === 0) {
1503
1662
  return [theme.description("No workers")];
@@ -1538,7 +1697,7 @@ var makeCampUiRoster = (context) => ({
1538
1697
  var makeCampUiSessionHeader = (context) => ({
1539
1698
  render: (viewport) => {
1540
1699
  const model = context.readModel();
1541
- const theme = getSelectListTheme8();
1700
+ const theme = getSelectListTheme9();
1542
1701
  const workerId = model.state.selectedWorkerId;
1543
1702
  if (workerId === void 0) {
1544
1703
  return [fitCampUiLine(theme.description("Select a worker"), viewport.width)];
@@ -1558,7 +1717,7 @@ var makeCampUiSessionHeader = (context) => ({
1558
1717
  });
1559
1718
 
1560
1719
  // packages/host-ui/src/pi/layout/campUiFooter.ts
1561
- import { getMarkdownTheme as getMarkdownTheme8, getSelectListTheme as getSelectListTheme9 } from "@earendil-works/pi-coding-agent";
1720
+ import { getMarkdownTheme as getMarkdownTheme8, getSelectListTheme as getSelectListTheme10 } from "@earendil-works/pi-coding-agent";
1562
1721
  var aggregateCampUsage = (workers) => {
1563
1722
  const usages = workers.flatMap(
1564
1723
  (worker) => worker.snapshot.session?.usage === void 0 ? [] : [worker.snapshot.session.usage]
@@ -1591,7 +1750,7 @@ var diagnosticText = (value) => {
1591
1750
  var makeCampUiCampFooter = (context) => ({
1592
1751
  render: (viewport) => {
1593
1752
  const model = context.readModel();
1594
- const theme = getSelectListTheme9();
1753
+ const theme = getSelectListTheme10();
1595
1754
  const health = model.snapshot.health;
1596
1755
  const usage = aggregateUsageText(aggregateCampUsage(model.snapshot.workers));
1597
1756
  const actionError = diagnosticText(model.state.lastActionError);
@@ -1610,7 +1769,7 @@ var makeCampUiCampFooter = (context) => ({
1610
1769
  var makeCampUiSessionFooter = (context) => ({
1611
1770
  render: (viewport) => {
1612
1771
  const model = context.readModel();
1613
- const theme = getSelectListTheme9();
1772
+ const theme = getSelectListTheme10();
1614
1773
  const workerId = model.state.selectedWorkerId;
1615
1774
  const worker = workerId === void 0 ? void 0 : findCampUiWorker(model.snapshot, workerId);
1616
1775
  const usage = worker?.snapshot.session?.usage;
@@ -1635,9 +1794,9 @@ var makeCampUiSessionFooter = (context) => ({
1635
1794
  });
1636
1795
 
1637
1796
  // packages/host-ui/src/pi/layout/campUiResources.ts
1638
- import { getSelectListTheme as getSelectListTheme10 } from "@earendil-works/pi-coding-agent";
1797
+ import { getSelectListTheme as getSelectListTheme11 } from "@earendil-works/pi-coding-agent";
1639
1798
  var renderResourceTree = (label, value, tone, width) => {
1640
- const theme = getSelectListTheme10();
1799
+ const theme = getSelectListTheme11();
1641
1800
  const lines = [
1642
1801
  theme.description(label),
1643
1802
  `${theme.description("\u2514\u2500")} ${renderCampUiStatus(value, tone)}`
@@ -1752,11 +1911,11 @@ var makeDefaultCampUiContributions = (tui, detailBlocks) => [
1752
1911
  ];
1753
1912
 
1754
1913
  // packages/host-ui/src/pi/layout/campUiSection.ts
1755
- import { getMarkdownTheme as getMarkdownTheme9, getSelectListTheme as getSelectListTheme11 } from "@earendil-works/pi-coding-agent";
1914
+ import { getMarkdownTheme as getMarkdownTheme9, getSelectListTheme as getSelectListTheme12 } from "@earendil-works/pi-coding-agent";
1756
1915
  import { visibleWidth as visibleWidth3 } from "@earendil-works/pi-tui";
1757
1916
  var renderHeader = (header, width) => {
1758
1917
  const theme = getMarkdownTheme9();
1759
- const selectTheme = getSelectListTheme11();
1918
+ const selectTheme = getSelectListTheme12();
1760
1919
  const rule2 = header.focused === true ? selectTheme.selectedPrefix : theme.codeBlockBorder;
1761
1920
  const title = header.focused === true ? selectTheme.selectedText : theme.heading;
1762
1921
  const ruleCharacter = header.focused === true ? "\u2501" : "\u2500";
@@ -2366,7 +2525,7 @@ var mountPiCampUi = (options) => Effect_exports.gen(function* () {
2366
2525
  });
2367
2526
 
2368
2527
  // packages/host-ui/src/run-selector/campRunSelector.ts
2369
- import { getMarkdownTheme as getMarkdownTheme11, getSelectListTheme as getSelectListTheme12, initTheme as initTheme2 } from "@earendil-works/pi-coding-agent";
2528
+ import { getMarkdownTheme as getMarkdownTheme11, getSelectListTheme as getSelectListTheme13, initTheme as initTheme2 } from "@earendil-works/pi-coding-agent";
2370
2529
  import {
2371
2530
  Key as Key4,
2372
2531
  matchesKey as matchesKey4,
@@ -2389,7 +2548,7 @@ var PiCampRunSelectorRoot = class {
2389
2548
  const height = Math.max(0, this.getHeight());
2390
2549
  const viewportWidth = Math.max(0, width - 1);
2391
2550
  const markdown = getMarkdownTheme11();
2392
- const selection = getSelectListTheme12();
2551
+ const selection = getSelectListTheme13();
2393
2552
  const header = `${markdown.codeBlockBorder("\u2500\u2500")} ${markdown.heading("Resume camp")} ${markdown.codeBlockBorder("\u2500".repeat(Math.max(0, viewportWidth - 16)))}`;
2394
2553
  const available = Math.max(0, height - 2);
2395
2554
  const capacity = Math.max(1, Math.floor(available / 2));
@@ -2524,6 +2683,13 @@ export {
2524
2683
  makeCampUiComposerComponent,
2525
2684
  campUiEquipmentBlockRenderer,
2526
2685
  renderCampUiPanel,
2686
+ CAMP_UI_EXPLORED_TOOL_NAMES,
2687
+ CAMP_UI_EXPLORED_COLLAPSED_PATHS,
2688
+ CampUiExploredStatus,
2689
+ isCampUiExploredTool,
2690
+ campUiExploredReadPath,
2691
+ campUiExploredReadRange,
2692
+ renderCampUiExploredGroup,
2527
2693
  CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
2528
2694
  CAMP_UI_BASH_PREVIEW_LINES,
2529
2695
  renderCampUiToolResult,
@@ -28,7 +28,7 @@ import {
28
28
  makePlatform,
29
29
  makeRunMain,
30
30
  stdin
31
- } from "./chunk-EBRDSFGF.js";
31
+ } from "./chunk-QX5EESCS.js";
32
32
  import {
33
33
  BaseProto,
34
34
  __export,
@@ -8,20 +8,22 @@ import {
8
8
  makeDoctorReport,
9
9
  resolveCampSurface,
10
10
  withCampRpc
11
- } from "./chunk-UDZECRNM.js";
11
+ } from "./chunk-XI3HWC7Q.js";
12
12
  import {
13
13
  PI_RUNTIME_VERSION,
14
14
  PiModelCatalogIssueCode,
15
15
  inspectPiModelCatalog,
16
16
  makePiOperatorResources
17
- } from "./chunk-FMIRO6TM.js";
17
+ } from "./chunk-44I2RCT5.js";
18
18
  import {
19
19
  CampHealthComponentStatus,
20
20
  CampHealthOverallStatus,
21
+ CampHealthVersionError,
21
22
  CampHostReadiness,
22
23
  CampLifecycle,
23
24
  CampManifestInvalidError,
24
25
  CampManifestVersionError,
26
+ DirectToolSandboxKind,
25
27
  FileSystem_exports,
26
28
  PRIIISK_HOST_VERSION,
27
29
  PRIIISK_PROTOCOL_PACKAGE_VERSION,
@@ -32,16 +34,21 @@ import {
32
34
  campManifestHostGeneration,
33
35
  campProjectPaths,
34
36
  campRecoveryDiagnosticFromCause,
37
+ currentDirectToolSandbox,
38
+ describeDirectToolSandbox,
39
+ describeProjectConfigOverrides,
35
40
  findCampControllerHealthFailure,
36
41
  findCampRecoveryHealthComponent,
37
42
  listWorkerModelCatalogEntries,
38
43
  loadCampHealth,
39
44
  loadCampManifest,
45
+ loadProjectWorkerConfig,
40
46
  loadWorkerConfig,
47
+ projectConfigPath,
41
48
  resolveCredentialsPath,
42
49
  resolveProjectScope,
43
50
  resolveWorkerConfigPath
44
- } from "./chunk-EBRDSFGF.js";
51
+ } from "./chunk-QX5EESCS.js";
45
52
  import {
46
53
  Clock_exports,
47
54
  Effect_exports,
@@ -71,12 +78,48 @@ var checkRuntime = () => {
71
78
  }
72
79
  );
73
80
  };
74
- var checkConfig = (fs) => Effect_exports.all([resolveWorkerConfigPath, loadWorkerConfig(fs)]).pipe(
81
+ var checkDirectToolSandbox = () => {
82
+ const sandbox = currentDirectToolSandbox();
83
+ const active = sandbox.kind !== DirectToolSandboxKind.none;
84
+ return doctorCheck(
85
+ "tools.sandbox",
86
+ active ? DoctorCheckStatus.pass : DoctorCheckStatus.warning,
87
+ describeDirectToolSandbox(sandbox),
88
+ {
89
+ mechanism: sandbox.kind,
90
+ ...sandbox.absence === void 0 ? {} : { absence: sandbox.absence },
91
+ ...sandbox.detail === void 0 ? {} : { detail: sandbox.detail }
92
+ }
93
+ );
94
+ };
95
+ var projectConfigDetails = (fs) => resolveProjectScope.pipe(
96
+ Effect_exports.flatMap(
97
+ (scope) => loadProjectWorkerConfig(fs, scope.cwd).pipe(
98
+ Effect_exports.map(
99
+ (project) => project === void 0 ? {} : {
100
+ projectConfigPath: projectConfigPath(scope.cwd),
101
+ projectOverrides: describeProjectConfigOverrides(project)
102
+ }
103
+ ),
104
+ Effect_exports.catchAll(() => Effect_exports.succeed({ projectConfigPath: projectConfigPath(scope.cwd) }))
105
+ )
106
+ )
107
+ );
108
+ var checkConfig = (fs) => Effect_exports.all([resolveWorkerConfigPath, loadWorkerConfig(fs), projectConfigDetails(fs)]).pipe(
75
109
  Effect_exports.map(
76
- ([path, config]) => config === void 0 ? doctorCheck("config", DoctorCheckStatus.warning, "User config is missing", { path }) : doctorCheck("config", DoctorCheckStatus.pass, "TOML config is valid", {
110
+ ([path, config, project]) => config === void 0 ? doctorCheck("config", DoctorCheckStatus.warning, "User config is missing", {
77
111
  path,
78
- schemaVersion: config.schemaVersion
79
- })
112
+ ...project
113
+ }) : doctorCheck(
114
+ "config",
115
+ DoctorCheckStatus.pass,
116
+ project.projectOverrides === void 0 ? "TOML config is valid" : `TOML config is valid, ${String(project.projectOverrides.length)} field(s) overridden by the project`,
117
+ {
118
+ path,
119
+ schemaVersion: config.schemaVersion,
120
+ ...project
121
+ }
122
+ )
80
123
  ),
81
124
  Effect_exports.catchAll(
82
125
  (cause) => resolveWorkerConfigPath.pipe(
@@ -312,7 +355,25 @@ var durableHealthFallback = (fs, paths, project, manifest, expectedLive) => Effe
312
355
  ),
313
356
  Effect_exports.catchAll(
314
357
  (cause) => Effect_exports.succeed(
315
- doctorCheck(
358
+ /*
359
+ * A file left by an earlier runtime version is outdated evidence, not a
360
+ * broken camp: the next `camp up` replaces it. Calling it invalid turned
361
+ * every upgrade into a red doctor report (priiisk-nss.6.18). Damage and a
362
+ * mismatch under the current version stay failures.
363
+ */
364
+ cause instanceof CampHealthVersionError ? doctorCheck(
365
+ "health.durable",
366
+ expectedLive ? DoctorCheckStatus.warning : DoctorCheckStatus.skipped,
367
+ "Durable health snapshot was written by an earlier runtime version",
368
+ {
369
+ path: paths.healthPath,
370
+ stale: true,
371
+ errorCode: "unsupported_version",
372
+ expectedVersion: cause.expectedVersion,
373
+ receivedVersion: cause.receivedVersion,
374
+ recoveryAction: "camp_up_fresh"
375
+ }
376
+ ) : doctorCheck(
316
377
  "health.durable",
317
378
  DoctorCheckStatus.failure,
318
379
  "Durable health snapshot is invalid",
@@ -549,6 +610,7 @@ var checkSurface = (manifest) => (manifest !== void 0 && manifest.lifecycle !==
549
610
  var runDoctor = Effect_exports.gen(function* () {
550
611
  const fs = yield* FileSystem_exports.FileSystem;
551
612
  const runtime = checkRuntime();
613
+ const sandbox = checkDirectToolSandbox();
552
614
  const config = yield* checkConfig(fs);
553
615
  const piModels = yield* checkPiModels(fs);
554
616
  const projectResult = yield* Effect_exports.either(resolveProjectScope);
@@ -570,6 +632,7 @@ var runDoctor = Effect_exports.gen(function* () {
570
632
  runtime,
571
633
  config,
572
634
  ...piModels,
635
+ sandbox,
573
636
  surface2,
574
637
  ...skipped
575
638
  ],
@@ -589,6 +652,7 @@ var runDoctor = Effect_exports.gen(function* () {
589
652
  runtime,
590
653
  config,
591
654
  ...piModels,
655
+ sandbox,
592
656
  storage,
593
657
  manifestResult.check,
594
658
  surface,
@@ -3,6 +3,8 @@ const require = __priiiskCreateRequire(import.meta.url);
3
3
  import {
4
4
  CAMP_UI_BASH_PREVIEW_LINES,
5
5
  CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
6
+ CAMP_UI_EXPLORED_COLLAPSED_PATHS,
7
+ CAMP_UI_EXPLORED_TOOL_NAMES,
6
8
  CAMP_UI_SUBSCRIPTION_BASE_DELAY_MS,
7
9
  CAMP_UI_SUBSCRIPTION_MAX_RETRIES,
8
10
  CampUiAssistantMessage,
@@ -11,6 +13,7 @@ import {
11
13
  CampUiCompositionError,
12
14
  CampUiContributionStrategy,
13
15
  CampUiControllerError,
16
+ CampUiExploredStatus,
14
17
  CampUiFocusDirection,
15
18
  CampUiGlyph,
16
19
  CampUiHealthStatus,
@@ -29,6 +32,8 @@ import {
29
32
  allocateCampUiSectionRows,
30
33
  campUiAskBlockId,
31
34
  campUiEquipmentBlockRenderer,
35
+ campUiExploredReadPath,
36
+ campUiExploredReadRange,
32
37
  campUiPendingAskBlockRenderer,
33
38
  campUiPendingAskTargets,
34
39
  campUiSubscriptionRetryDelay,
@@ -48,6 +53,7 @@ import {
48
53
  formatCampUiDuration,
49
54
  hasCampUiTextContent,
50
55
  hasPendingCampUiAsk,
56
+ isCampUiExploredTool,
51
57
  joinCampUiColumns,
52
58
  jsonText,
53
59
  makeCampUiComponentGroup,
@@ -66,6 +72,7 @@ import {
66
72
  renderCampUiDetailBlockLayout,
67
73
  renderCampUiDetailBlocks,
68
74
  renderCampUiDirectedBlock,
75
+ renderCampUiExploredGroup,
69
76
  renderCampUiPanel,
70
77
  renderCampUiState,
71
78
  renderCampUiStatus,
@@ -77,11 +84,13 @@ import {
77
84
  selectCampRun,
78
85
  styleCampUiTone,
79
86
  uniqueCampUiNames
80
- } from "./chunk-Z64QXV3O.js";
87
+ } from "./chunk-62BTCFUO.js";
81
88
  import "./chunk-KFSFN6L5.js";
82
89
  export {
83
90
  CAMP_UI_BASH_PREVIEW_LINES,
84
91
  CAMP_UI_DEFAULT_TOOL_PREVIEW_LINES,
92
+ CAMP_UI_EXPLORED_COLLAPSED_PATHS,
93
+ CAMP_UI_EXPLORED_TOOL_NAMES,
85
94
  CAMP_UI_SUBSCRIPTION_BASE_DELAY_MS,
86
95
  CAMP_UI_SUBSCRIPTION_MAX_RETRIES,
87
96
  CampUiAssistantMessage,
@@ -90,6 +99,7 @@ export {
90
99
  CampUiCompositionError,
91
100
  CampUiContributionStrategy,
92
101
  CampUiControllerError,
102
+ CampUiExploredStatus,
93
103
  CampUiFocusDirection,
94
104
  CampUiGlyph,
95
105
  CampUiHealthStatus,
@@ -108,6 +118,8 @@ export {
108
118
  allocateCampUiSectionRows,
109
119
  campUiAskBlockId,
110
120
  campUiEquipmentBlockRenderer,
121
+ campUiExploredReadPath,
122
+ campUiExploredReadRange,
111
123
  campUiPendingAskBlockRenderer,
112
124
  campUiPendingAskTargets,
113
125
  campUiSubscriptionRetryDelay,
@@ -127,6 +139,7 @@ export {
127
139
  formatCampUiDuration,
128
140
  hasCampUiTextContent,
129
141
  hasPendingCampUiAsk,
142
+ isCampUiExploredTool,
130
143
  joinCampUiColumns,
131
144
  jsonText,
132
145
  makeCampUiComponentGroup,
@@ -145,6 +158,7 @@ export {
145
158
  renderCampUiDetailBlockLayout,
146
159
  renderCampUiDetailBlocks,
147
160
  renderCampUiDirectedBlock,
161
+ renderCampUiExploredGroup,
148
162
  renderCampUiPanel,
149
163
  renderCampUiState,
150
164
  renderCampUiStatus,