@drisp/cli 0.5.24 → 0.5.26

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.
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import "./chunk-HXBCZAP7.js";
3
3
  import {
4
4
  rotateGatewayToken
5
- } from "./chunk-7GEQJQMR.js";
5
+ } from "./chunk-4NX4WFPB.js";
6
6
  import {
7
7
  CREDENTIAL_SOURCES_TRIED,
8
8
  EXEC_EXIT_CODE,
@@ -27,7 +27,6 @@ import {
27
27
  createRelayQuestionCallback,
28
28
  createRuntime,
29
29
  createSessionStore,
30
- createWsClientTransport,
31
30
  credentialHelperKey,
32
31
  cursorToVisualPosition,
33
32
  daemonStatePaths,
@@ -61,6 +60,7 @@ import {
61
60
  makeSkippedProbe,
62
61
  mergeFeedItems,
63
62
  messageGlyphs,
63
+ parseFrontmatter,
64
64
  parseToolName,
65
65
  probeSkipReason,
66
66
  processRegistry,
@@ -74,6 +74,7 @@ import {
74
74
  renderInputLines,
75
75
  resolveClaudeBinary,
76
76
  resolveClaudeSettingsSurfacePaths,
77
+ resolveEffectiveCapabilities,
77
78
  resolveHarnessAdapter,
78
79
  resolveHookForwarderCommand,
79
80
  resolveRuntimeAuthOverlay,
@@ -95,13 +96,13 @@ import {
95
96
  visualPositionToOffset,
96
97
  wrapText,
97
98
  writeAttachmentMirror,
98
- writeGatewayClientConfig,
99
- wsClientOptionsForEndpoint
100
- } from "./chunk-QBMYQJFX.js";
99
+ writeGatewayClientConfig
100
+ } from "./chunk-YZ7RCBKO.js";
101
101
  import {
102
102
  generateId as generateId2
103
- } from "./chunk-BTKQ67RE.js";
103
+ } from "./chunk-QYB6N2OT.js";
104
104
  import {
105
+ createWsClientTransport,
105
106
  dashboardClientConfigPath,
106
107
  disableTelemetry,
107
108
  initTelemetry,
@@ -120,8 +121,9 @@ import {
120
121
  trackSetupCompleted,
121
122
  trackTelemetryOptedOut,
122
123
  writeDashboardClientConfig,
123
- writeGatewayTrace
124
- } from "./chunk-YU2WMPRC.js";
124
+ writeGatewayTrace,
125
+ wsClientOptionsForEndpoint
126
+ } from "./chunk-3U37HT4T.js";
125
127
  import {
126
128
  McpOptionsStep,
127
129
  StepSelector,
@@ -158,20 +160,20 @@ import {
158
160
  useWorkflowSessionController,
159
161
  writeGlobalConfig,
160
162
  writeProjectConfig
161
- } from "./chunk-7UUPLAP4.js";
163
+ } from "./chunk-73V7GXV6.js";
162
164
 
163
165
  // src/app/entry/cli.tsx
164
166
  import { render } from "ink";
165
167
  import meow from "meow";
166
- import fs9 from "fs";
168
+ import fs10 from "fs";
167
169
  import { createRequire as createRequire2 } from "module";
168
170
  import os7 from "os";
169
- import path9 from "path";
171
+ import path10 from "path";
170
172
  import { fileURLToPath as fileURLToPath3 } from "url";
171
173
 
172
174
  // src/app/shell/AppShell.tsx
173
175
  import process6 from "process";
174
- import React9, {
176
+ import React8, {
175
177
  Profiler,
176
178
  useState as useState18,
177
179
  useCallback as useCallback19,
@@ -179,7 +181,7 @@ import React9, {
179
181
  useEffect as useEffect14,
180
182
  useMemo as useMemo17
181
183
  } from "react";
182
- import { Box as Box19, Text as Text25, useApp, useInput as useInput17, useStdout as useStdout9 } from "ink";
184
+ import { Box as Box18, Text as Text24, useApp, useInput as useInput17, useStdout as useStdout9 } from "ink";
183
185
 
184
186
  // src/ui/components/PermissionDialog.tsx
185
187
  import { useCallback, useMemo } from "react";
@@ -2301,6 +2303,7 @@ function useHeaderMetrics(events) {
2301
2303
  return cachedRef.current;
2302
2304
  }
2303
2305
  let modelName = null;
2306
+ let effortLevel = null;
2304
2307
  let sessionStartTime = null;
2305
2308
  let toolCallCount = 0;
2306
2309
  let permissionsAllowed = 0;
@@ -2317,6 +2320,9 @@ function useHeaderMetrics(events) {
2317
2320
  modelName = event.data.model;
2318
2321
  }
2319
2322
  }
2323
+ if (typeof event.effort_level === "string") {
2324
+ effortLevel = event.effort_level;
2325
+ }
2320
2326
  if (event.kind === "agent.message" && typeof event.data.model === "string") {
2321
2327
  modelName = event.data.model;
2322
2328
  }
@@ -2369,6 +2375,7 @@ function useHeaderMetrics(events) {
2369
2375
  );
2370
2376
  const result = {
2371
2377
  modelName,
2378
+ effortLevel,
2372
2379
  toolCallCount,
2373
2380
  totalToolCallCount: toolCallCount + subagentToolTotal,
2374
2381
  subagentCount: subagentMap.size,
@@ -4437,6 +4444,8 @@ function getClipboardCommand() {
4437
4444
 
4438
4445
  // src/core/feed/defaultRender.ts
4439
4446
  var DEFAULT_RENDER = /* @__PURE__ */ new Set([
4447
+ "prompt.expansion",
4448
+ "tool.batch",
4440
4449
  "compact.post",
4441
4450
  "task.created",
4442
4451
  "cwd.changed",
@@ -4702,14 +4711,14 @@ function extractWebSearch(_input, response) {
4702
4711
  return { type: "text", content: extractTextContent(response), maxLines: 10 };
4703
4712
  }
4704
4713
  function extractNotebookEdit(input, _response) {
4705
- const path10 = typeof input["notebook_path"] === "string" ? input["notebook_path"] : "";
4714
+ const path11 = typeof input["notebook_path"] === "string" ? input["notebook_path"] : "";
4706
4715
  const mode = typeof input["edit_mode"] === "string" ? input["edit_mode"] : "replace";
4707
4716
  const source = typeof input["new_source"] === "string" ? input["new_source"] : "";
4708
- if (!source) return { type: "text", content: `${mode} cell in ${path10}` };
4717
+ if (!source) return { type: "text", content: `${mode} cell in ${path11}` };
4709
4718
  return {
4710
4719
  type: "code",
4711
4720
  content: source,
4712
- language: detectLanguage(path10),
4721
+ language: detectLanguage(path11),
4713
4722
  maxLines: 10
4714
4723
  };
4715
4724
  }
@@ -5233,10 +5242,10 @@ function extractToolSubject(toolName, toolInput) {
5233
5242
  const parts = [];
5234
5243
  const pattern = str(input, "pattern");
5235
5244
  const glob = str(input, "glob");
5236
- const path10 = str(input, "path");
5245
+ const path11 = str(input, "path");
5237
5246
  if (pattern) parts.push(`"${pattern}"`);
5238
5247
  if (glob) parts.push(glob);
5239
- if (path10) parts.push(`in ${path10}`);
5248
+ if (path11) parts.push(`in ${path11}`);
5240
5249
  return parts.length > 0 ? parts.join(" ") : void 0;
5241
5250
  }
5242
5251
  case "Skill":
@@ -5494,9 +5503,11 @@ function renderDetailLines(event, width, pairedPostEvent, theme = darkTheme) {
5494
5503
  case "setup":
5495
5504
  case "unknown.hook":
5496
5505
  case "todo.add":
5506
+ case "tool.batch":
5497
5507
  case "todo.update":
5498
5508
  case "todo.done":
5499
5509
  case "teammate.idle":
5510
+ case "prompt.expansion":
5500
5511
  case "task.created":
5501
5512
  case "task.completed":
5502
5513
  case "config.change":
@@ -6112,13 +6123,11 @@ function buildBodyLines({
6112
6123
  }
6113
6124
 
6114
6125
  // src/ui/components/FeedGrid.tsx
6115
- import React7 from "react";
6116
- import { Text as Text15 } from "ink";
6126
+ import React6 from "react";
6127
+ import { Text as Text14 } from "ink";
6117
6128
 
6118
6129
  // src/ui/components/FeedRow.tsx
6119
6130
  import { performance as performance2 } from "perf_hooks";
6120
- import React3 from "react";
6121
- import { Box as Box9, Text as Text12 } from "ink";
6122
6131
 
6123
6132
  // src/core/feed/cellFormatters.ts
6124
6133
  function isLifecycleOp(op) {
@@ -6332,7 +6341,6 @@ function formatDetails(opts) {
6332
6341
  }
6333
6342
 
6334
6343
  // src/ui/components/FeedRow.tsx
6335
- import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
6336
6344
  var ROW_LINE_CACHE_MAX_VARIANTS = 16;
6337
6345
  var ROW_LINE_CACHE_MAX_ENTRIES = 2e3;
6338
6346
  var rowLineCache = /* @__PURE__ */ new Map();
@@ -6549,40 +6557,11 @@ function formatFeedRowLine({
6549
6557
  logVisibleRowFormat(performance2.now() - startedAt);
6550
6558
  }
6551
6559
  }
6552
- function FeedRowImpl({
6553
- entry,
6554
- cols,
6555
- focused,
6556
- expanded,
6557
- matched,
6558
- ascii,
6559
- theme
6560
- }) {
6561
- const parts = lineParts({
6562
- entry,
6563
- cols,
6564
- focused,
6565
- expanded,
6566
- matched,
6567
- ascii,
6568
- theme
6569
- });
6570
- return /* @__PURE__ */ jsxs10(Fragment4, { children: [
6571
- /* @__PURE__ */ jsx11(Box9, { width: 1, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: parts.gutter }) }),
6572
- /* @__PURE__ */ jsx11(Box9, { width: 5, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: parts.time }) }),
6573
- /* @__PURE__ */ jsx11(Box9, { width: cols.gapW, flexShrink: 0 }),
6574
- /* @__PURE__ */ jsx11(Box9, { width: cols.toolW, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: parts.tool }) }),
6575
- /* @__PURE__ */ jsx11(Box9, { width: cols.gapW, flexShrink: 0 }),
6576
- /* @__PURE__ */ jsx11(Box9, { width: cols.detailsW, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: parts.detail }) }),
6577
- /* @__PURE__ */ jsx11(Box9, { flexGrow: 1, flexShrink: 1 })
6578
- ] });
6579
- }
6580
- var FeedRow = React3.memo(FeedRowImpl);
6581
6560
 
6582
6561
  // src/ui/components/FeedHeader.tsx
6583
- import React4 from "react";
6584
- import { Box as Box10, Text as Text13 } from "ink";
6585
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
6562
+ import React3 from "react";
6563
+ import { Box as Box9, Text as Text12 } from "ink";
6564
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
6586
6565
  function formatFeedHeaderLine(cols, theme, innerWidth) {
6587
6566
  const headerColor = theme.feed.headerLabel;
6588
6567
  const style = (s) => source_default.hex(headerColor)(s);
@@ -6597,17 +6576,17 @@ function formatFeedHeaderLine(cols, theme, innerWidth) {
6597
6576
  function FeedHeaderImpl({ cols, theme }) {
6598
6577
  const headerColor = theme.feed.headerLabel;
6599
6578
  const style = (s) => source_default.hex(headerColor)(s);
6600
- return /* @__PURE__ */ jsxs11(Fragment5, { children: [
6601
- /* @__PURE__ */ jsx12(Box10, { width: 1, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { children: " " }) }),
6602
- /* @__PURE__ */ jsx12(Box10, { width: 5, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { wrap: "truncate-end", children: style(fit("TIME", 5)) }) }),
6603
- /* @__PURE__ */ jsx12(Box10, { width: cols.gapW, flexShrink: 0 }),
6604
- /* @__PURE__ */ jsx12(Box10, { width: cols.toolW, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { wrap: "truncate-end", children: style(fit("ACTION", cols.toolW)) }) }),
6605
- /* @__PURE__ */ jsx12(Box10, { width: cols.gapW, flexShrink: 0 }),
6606
- /* @__PURE__ */ jsx12(Box10, { width: cols.detailsW, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { wrap: "truncate-end", children: style(fit("DETAILS", cols.detailsW)) }) }),
6607
- /* @__PURE__ */ jsx12(Box10, { flexGrow: 1, flexShrink: 1 })
6579
+ return /* @__PURE__ */ jsxs10(Fragment4, { children: [
6580
+ /* @__PURE__ */ jsx11(Box9, { width: 1, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { children: " " }) }),
6581
+ /* @__PURE__ */ jsx11(Box9, { width: 5, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: style(fit("TIME", 5)) }) }),
6582
+ /* @__PURE__ */ jsx11(Box9, { width: cols.gapW, flexShrink: 0 }),
6583
+ /* @__PURE__ */ jsx11(Box9, { width: cols.toolW, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: style(fit("ACTION", cols.toolW)) }) }),
6584
+ /* @__PURE__ */ jsx11(Box9, { width: cols.gapW, flexShrink: 0 }),
6585
+ /* @__PURE__ */ jsx11(Box9, { width: cols.detailsW, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text12, { wrap: "truncate-end", children: style(fit("DETAILS", cols.detailsW)) }) }),
6586
+ /* @__PURE__ */ jsx11(Box9, { flexGrow: 1, flexShrink: 1 })
6608
6587
  ] });
6609
6588
  }
6610
- var FeedHeader = React4.memo(FeedHeaderImpl);
6589
+ var FeedHeader = React3.memo(FeedHeaderImpl);
6611
6590
 
6612
6591
  // src/ui/components/rowCache.ts
6613
6592
  var DEFAULT_MAX_SIZE = 100;
@@ -6874,11 +6853,11 @@ function buildFeedSurface(params) {
6874
6853
  }
6875
6854
 
6876
6855
  // src/ui/components/FeedSurface.tsx
6877
- import React6 from "react";
6878
- import { Text as Text14 } from "ink";
6856
+ import React5 from "react";
6857
+ import { Text as Text13 } from "ink";
6879
6858
 
6880
6859
  // src/ui/components/IncrementalFeedSurface.tsx
6881
- import React5 from "react";
6860
+ import React4 from "react";
6882
6861
 
6883
6862
  // src/ui/components/feedSurfaceDiff.ts
6884
6863
  function diffFeedSurface(prev, next) {
@@ -6941,19 +6920,19 @@ function IncrementalFeedSurfaceImpl({
6941
6920
  feedStartCol,
6942
6921
  stdout = process.stdout
6943
6922
  }) {
6944
- const prevLinesRef = React5.useRef([]);
6945
- const prevFeedStartRowRef = React5.useRef(feedStartRow);
6946
- const prevFeedStartColRef = React5.useRef(feedStartCol);
6947
- const prevLineWidthRef = React5.useRef(surface.lineWidth);
6948
- const feedStartRowRef = React5.useRef(feedStartRow);
6949
- const feedStartColRef = React5.useRef(feedStartCol);
6950
- const lineWidthRef = React5.useRef(surface.lineWidth);
6951
- const stdoutRef = React5.useRef(stdout);
6923
+ const prevLinesRef = React4.useRef([]);
6924
+ const prevFeedStartRowRef = React4.useRef(feedStartRow);
6925
+ const prevFeedStartColRef = React4.useRef(feedStartCol);
6926
+ const prevLineWidthRef = React4.useRef(surface.lineWidth);
6927
+ const feedStartRowRef = React4.useRef(feedStartRow);
6928
+ const feedStartColRef = React4.useRef(feedStartCol);
6929
+ const lineWidthRef = React4.useRef(surface.lineWidth);
6930
+ const stdoutRef = React4.useRef(stdout);
6952
6931
  feedStartRowRef.current = feedStartRow;
6953
6932
  feedStartColRef.current = feedStartCol;
6954
6933
  lineWidthRef.current = surface.lineWidth;
6955
6934
  stdoutRef.current = stdout;
6956
- React5.useEffect(() => {
6935
+ React4.useEffect(() => {
6957
6936
  const prevLines = prevLinesRef.current;
6958
6937
  const nextLines = surface.allLines;
6959
6938
  const prevStartRow = prevFeedStartRowRef.current;
@@ -7010,7 +6989,7 @@ function IncrementalFeedSurfaceImpl({
7010
6989
  linesCleared: result.linesCleared
7011
6990
  });
7012
6991
  }, [surface, feedStartRow, feedStartCol, stdout]);
7013
- React5.useEffect(() => {
6992
+ React4.useEffect(() => {
7014
6993
  return () => {
7015
6994
  if (prevLinesRef.current.length > 0) {
7016
6995
  paintFeedSurface(
@@ -7026,10 +7005,10 @@ function IncrementalFeedSurfaceImpl({
7026
7005
  }, []);
7027
7006
  return null;
7028
7007
  }
7029
- var IncrementalFeedSurface = React5.memo(IncrementalFeedSurfaceImpl);
7008
+ var IncrementalFeedSurface = React4.memo(IncrementalFeedSurfaceImpl);
7030
7009
 
7031
7010
  // src/ui/components/FeedSurface.tsx
7032
- import { jsx as jsx13 } from "react/jsx-runtime";
7011
+ import { jsx as jsx12 } from "react/jsx-runtime";
7033
7012
  var VALID_BACKENDS = /* @__PURE__ */ new Set([
7034
7013
  "ink-full",
7035
7014
  "incremental"
@@ -7051,7 +7030,7 @@ function FeedSurfaceImpl({
7051
7030
  }) {
7052
7031
  const backend = resolveFeedBackend(backendProp);
7053
7032
  if (backend === "incremental") {
7054
- return /* @__PURE__ */ jsx13(
7033
+ return /* @__PURE__ */ jsx12(
7055
7034
  IncrementalFeedSurface,
7056
7035
  {
7057
7036
  surface,
@@ -7061,15 +7040,15 @@ function FeedSurfaceImpl({
7061
7040
  }
7062
7041
  );
7063
7042
  }
7064
- return /* @__PURE__ */ jsx13(InkFullFeedSurface, { surface, backend });
7043
+ return /* @__PURE__ */ jsx12(InkFullFeedSurface, { surface, backend });
7065
7044
  }
7066
7045
  function InkFullFeedSurface({
7067
7046
  surface,
7068
7047
  backend
7069
7048
  }) {
7070
- const output = React6.useMemo(() => surface.allLines.join("\n"), [surface]);
7071
- const prevLinesRef = React6.useRef(0);
7072
- React6.useEffect(() => {
7049
+ const output = React5.useMemo(() => surface.allLines.join("\n"), [surface]);
7050
+ const prevLinesRef = React5.useRef(0);
7051
+ React5.useEffect(() => {
7073
7052
  const linesRendered = surface.allLines.length;
7074
7053
  const prevLines = prevLinesRef.current;
7075
7054
  prevLinesRef.current = linesRendered;
@@ -7083,12 +7062,12 @@ function InkFullFeedSurface({
7083
7062
  linesCleared
7084
7063
  });
7085
7064
  }, [surface, backend]);
7086
- return /* @__PURE__ */ jsx13(Text14, { children: output });
7065
+ return /* @__PURE__ */ jsx12(Text13, { children: output });
7087
7066
  }
7088
- var FeedSurfaceView = React6.memo(FeedSurfaceImpl);
7067
+ var FeedSurfaceView = React5.memo(FeedSurfaceImpl);
7089
7068
 
7090
7069
  // src/ui/components/FeedGrid.tsx
7091
- import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
7070
+ import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
7092
7071
  function FeedGridImpl({
7093
7072
  feedHeaderRows,
7094
7073
  feedContentRows,
@@ -7108,16 +7087,16 @@ function FeedGridImpl({
7108
7087
  }) {
7109
7088
  const backend = resolveFeedBackend(backendProp);
7110
7089
  const isIncremental = backend === "incremental";
7111
- const rowCacheRef = React7.useRef(new RowCache());
7112
- const prevGlobalsRef = React7.useRef({ innerWidth, ascii, theme, cols });
7113
- React7.useEffect(() => {
7090
+ const rowCacheRef = React6.useRef(new RowCache());
7091
+ const prevGlobalsRef = React6.useRef({ innerWidth, ascii, theme, cols });
7092
+ React6.useEffect(() => {
7114
7093
  const prev = prevGlobalsRef.current;
7115
7094
  if (prev.innerWidth !== innerWidth || prev.ascii !== ascii || prev.theme !== theme || prev.cols !== cols) {
7116
7095
  rowCacheRef.current.bumpGeneration();
7117
7096
  prevGlobalsRef.current = { innerWidth, ascii, theme, cols };
7118
7097
  }
7119
7098
  }, [innerWidth, ascii, theme, cols]);
7120
- const surface = React7.useMemo(
7099
+ const surface = React6.useMemo(
7121
7100
  () => buildFeedSurface({
7122
7101
  feedHeaderRows,
7123
7102
  feedContentRows,
@@ -7149,7 +7128,7 @@ function FeedGridImpl({
7149
7128
  ]
7150
7129
  );
7151
7130
  const { visibleContentRows } = surface;
7152
- const visibleRowSignatures = React7.useMemo(() => {
7131
+ const visibleRowSignatures = React6.useMemo(() => {
7153
7132
  const signatures = [];
7154
7133
  if (visibleContentRows <= 0) return signatures;
7155
7134
  for (let offset = 0; offset < visibleContentRows; offset++) {
@@ -7178,8 +7157,8 @@ function FeedGridImpl({
7178
7157
  feedCursor,
7179
7158
  searchMatchSet
7180
7159
  ]);
7181
- const prevViewportRef = React7.useRef(null);
7182
- React7.useEffect(() => {
7160
+ const prevViewportRef = React6.useRef(null);
7161
+ React6.useEffect(() => {
7183
7162
  const previous = prevViewportRef.current;
7184
7163
  const current = {
7185
7164
  signatures: visibleRowSignatures,
@@ -7223,9 +7202,9 @@ function FeedGridImpl({
7223
7202
  if (isIncremental) {
7224
7203
  const totalFeedRows = feedHeaderRows + feedContentRows;
7225
7204
  const placeholderLines = "\n".repeat(Math.max(0, totalFeedRows - 1));
7226
- return /* @__PURE__ */ jsxs12(Fragment6, { children: [
7227
- /* @__PURE__ */ jsx14(Text15, { children: placeholderLines }),
7228
- /* @__PURE__ */ jsx14(
7205
+ return /* @__PURE__ */ jsxs11(Fragment5, { children: [
7206
+ /* @__PURE__ */ jsx13(Text14, { children: placeholderLines }),
7207
+ /* @__PURE__ */ jsx13(
7229
7208
  FeedSurfaceView,
7230
7209
  {
7231
7210
  surface,
@@ -7236,7 +7215,7 @@ function FeedGridImpl({
7236
7215
  )
7237
7216
  ] });
7238
7217
  }
7239
- return /* @__PURE__ */ jsx14(
7218
+ return /* @__PURE__ */ jsx13(
7240
7219
  FeedSurfaceView,
7241
7220
  {
7242
7221
  surface,
@@ -7245,11 +7224,11 @@ function FeedGridImpl({
7245
7224
  }
7246
7225
  );
7247
7226
  }
7248
- var FeedGrid = React7.memo(FeedGridImpl);
7227
+ var FeedGrid = React6.memo(FeedGridImpl);
7249
7228
 
7250
7229
  // src/ui/components/MessagePanel.tsx
7251
- import React8, { useMemo as useMemo11 } from "react";
7252
- import { Text as Text16 } from "ink";
7230
+ import React7, { useMemo as useMemo11 } from "react";
7231
+ import { Text as Text15 } from "ink";
7253
7232
 
7254
7233
  // src/core/feed/panelFilter.ts
7255
7234
  var USER_TAGS = /* @__PURE__ */ new Set(["msg.user", "prompt"]);
@@ -7297,7 +7276,7 @@ function messageText(entry) {
7297
7276
  }
7298
7277
 
7299
7278
  // src/ui/components/MessagePanel.tsx
7300
- import { jsx as jsx15 } from "react/jsx-runtime";
7279
+ import { jsx as jsx14 } from "react/jsx-runtime";
7301
7280
  var INDICATOR_OVERHEAD = 2;
7302
7281
  function buildRenderedLines(entries, width, theme) {
7303
7282
  const contentWidth2 = width - INDICATOR_OVERHEAD;
@@ -7432,9 +7411,9 @@ function MessagePanelImpl(props) {
7432
7411
  ),
7433
7412
  [wrapped, contentRows, viewportStart, style, width, messageCursorIndex]
7434
7413
  );
7435
- return /* @__PURE__ */ jsx15(Text16, { children: lines.join("\n") });
7414
+ return /* @__PURE__ */ jsx14(Text15, { children: lines.join("\n") });
7436
7415
  }
7437
- var MessagePanel = React8.memo(MessagePanelImpl);
7416
+ var MessagePanel = React7.memo(MessagePanelImpl);
7438
7417
 
7439
7418
  // src/ui/hooks/useFeedColumns.ts
7440
7419
  import { useMemo as useMemo12, useRef as useRef12 } from "react";
@@ -7646,6 +7625,7 @@ function buildHeaderModel(input) {
7646
7625
  workflow: workflowRef ?? "default",
7647
7626
  harness: detectHarness(input.harness),
7648
7627
  model_name: input.modelName ?? null,
7628
+ effort_level: input.effortLevel ?? null,
7649
7629
  context: { used: input.contextUsed ?? null, max: input.contextMax ?? null },
7650
7630
  total_tokens: input.totalTokens ?? null,
7651
7631
  token_label: codexHarness ? "Billable" : "Tokens",
@@ -7854,7 +7834,8 @@ function renderHeaderLines(model, width, hasColor, theme) {
7854
7834
  const sidText = `${sidLabel}${sidValue}${style(sidScope, palette.label)}`;
7855
7835
  const wfText = `${style("Workflow: ", palette.label)}${style(model.workflow, palette.value)}`;
7856
7836
  const harnessText = `${style("Harness: ", palette.label)}${style(model.harness, palette.value)}`;
7857
- const modelText = `${style("Model: ", palette.label)}${style(formatModelName(model.model_name), palette.value)}`;
7837
+ const effortSuffix = model.effort_level ? style(` with ${model.effort_level} effort`, palette.label) : "";
7838
+ const modelText = `${style("Model: ", palette.label)}${style(formatModelName(model.model_name), palette.value)}${effortSuffix}`;
7858
7839
  const tokenLabel = model.token_label ?? "Tokens";
7859
7840
  const runLabel = model.run_label ?? "Runs";
7860
7841
  const leftTokens = [
@@ -7982,8 +7963,8 @@ function executeCommand(command, args, ctx) {
7982
7963
 
7983
7964
  // src/ui/components/SessionPicker.tsx
7984
7965
  import { useState as useState11 } from "react";
7985
- import { Box as Box11, Text as Text17, useInput as useInput12, useStdout as useStdout5 } from "ink";
7986
- import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
7966
+ import { Box as Box10, Text as Text16, useInput as useInput12, useStdout as useStdout5 } from "ink";
7967
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
7987
7968
  var PICKER_CHROME_ROWS = 5;
7988
7969
  var ROWS_PER_SESSION = 3;
7989
7970
  function resolveVisibleCount(terminalRows) {
@@ -8025,13 +8006,13 @@ function SessionPicker({
8025
8006
  }
8026
8007
  });
8027
8008
  if (loading) {
8028
- return /* @__PURE__ */ jsxs13(Box11, { flexDirection: "column", padding: 1, children: [
8029
- /* @__PURE__ */ jsx16(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text17, { bold: true, color: theme.accent, children: "Sessions" }) }),
8030
- /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "Loading sessions\u2026" })
8009
+ return /* @__PURE__ */ jsxs12(Box10, { flexDirection: "column", padding: 1, children: [
8010
+ /* @__PURE__ */ jsx15(Box10, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text16, { bold: true, color: theme.accent, children: "Sessions" }) }),
8011
+ /* @__PURE__ */ jsx15(Text16, { dimColor: true, children: "Loading sessions\u2026" })
8031
8012
  ] });
8032
8013
  }
8033
8014
  if (sessions.length === 0) {
8034
- return /* @__PURE__ */ jsx16(Box11, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "No previous sessions found." }) });
8015
+ return /* @__PURE__ */ jsx15(Box10, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx15(Text16, { dimColor: true, children: "No previous sessions found." }) });
8035
8016
  }
8036
8017
  const scrollStart = Math.max(
8037
8018
  0,
@@ -8041,8 +8022,8 @@ function SessionPicker({
8041
8022
  )
8042
8023
  );
8043
8024
  const visible = sessions.slice(scrollStart, scrollStart + visibleCount);
8044
- return /* @__PURE__ */ jsxs13(Box11, { flexDirection: "column", padding: 1, children: [
8045
- /* @__PURE__ */ jsx16(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text17, { bold: true, color: theme.accent, children: "Sessions" }) }),
8025
+ return /* @__PURE__ */ jsxs12(Box10, { flexDirection: "column", padding: 1, children: [
8026
+ /* @__PURE__ */ jsx15(Box10, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text16, { bold: true, color: theme.accent, children: "Sessions" }) }),
8046
8027
  visible.map((session, vi) => {
8047
8028
  const realIndex = scrollStart + vi;
8048
8029
  const isFocused = realIndex === focusIndex;
@@ -8054,23 +8035,23 @@ function SessionPicker({
8054
8035
  const meta = `${shortId}${branch} \xB7 ${time}${msgs}`;
8055
8036
  const titleRaw = session.summary || session.firstPrompt || `Session ${shortId}`;
8056
8037
  const title = compactText(titleRaw.replace(/\n/g, " ").trim(), 60);
8057
- return /* @__PURE__ */ jsxs13(
8058
- Box11,
8038
+ return /* @__PURE__ */ jsxs12(
8039
+ Box10,
8059
8040
  {
8060
8041
  flexDirection: "column",
8061
8042
  marginBottom: vi === visible.length - 1 ? 0 : 1,
8062
8043
  children: [
8063
- /* @__PURE__ */ jsx16(Box11, { children: /* @__PURE__ */ jsxs13(Text17, { color: isFocused ? "cyan" : void 0, bold: isFocused, children: [
8044
+ /* @__PURE__ */ jsx15(Box10, { children: /* @__PURE__ */ jsxs12(Text16, { color: isFocused ? "cyan" : void 0, bold: isFocused, children: [
8064
8045
  isFocused ? "\u276F " : " ",
8065
8046
  title
8066
8047
  ] }) }),
8067
- /* @__PURE__ */ jsx16(Box11, { paddingLeft: 2, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: meta }) })
8048
+ /* @__PURE__ */ jsx15(Box10, { paddingLeft: 2, children: /* @__PURE__ */ jsx15(Text16, { dimColor: true, children: meta }) })
8068
8049
  ]
8069
8050
  },
8070
8051
  session.sessionId
8071
8052
  );
8072
8053
  }),
8073
- /* @__PURE__ */ jsx16(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u2191/\u2193 Navigate \xB7 Enter Select \xB7 Esc Cancel" }) })
8054
+ /* @__PURE__ */ jsx15(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text16, { dimColor: true, children: "\u2191/\u2193 Navigate \xB7 Enter Select \xB7 Esc Cancel" }) })
8074
8055
  ] });
8075
8056
  }
8076
8057
 
@@ -8091,7 +8072,7 @@ function renderYankLines(entry, width, theme) {
8091
8072
 
8092
8073
  // src/setup/SetupWizard.tsx
8093
8074
  import { useState as useState14, useCallback as useCallback15, useEffect as useEffect10, useRef as useRef13 } from "react";
8094
- import { Box as Box16, Text as Text22, useInput as useInput13 } from "ink";
8075
+ import { Box as Box15, Text as Text21, useInput as useInput13 } from "ink";
8095
8076
 
8096
8077
  // src/setup/useSetupState.ts
8097
8078
  import { useState as useState12, useCallback as useCallback13 } from "react";
@@ -8125,14 +8106,14 @@ function useSetupState() {
8125
8106
  }
8126
8107
 
8127
8108
  // src/setup/steps/ThemeStep.tsx
8128
- import { Box as Box12, Text as Text18 } from "ink";
8129
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
8109
+ import { Box as Box11, Text as Text17 } from "ink";
8110
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
8130
8111
  function ThemeStep({ onComplete, onPreview }) {
8131
8112
  const theme = useTheme();
8132
- return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", children: [
8133
- /* @__PURE__ */ jsx17(Text18, { bold: true, color: theme.accent, children: "Choose your display theme" }),
8134
- /* @__PURE__ */ jsx17(Text18, { color: theme.textMuted, children: "This applies immediately after setup completes." }),
8135
- /* @__PURE__ */ jsx17(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx17(
8113
+ return /* @__PURE__ */ jsxs13(Box11, { flexDirection: "column", children: [
8114
+ /* @__PURE__ */ jsx16(Text17, { bold: true, color: theme.accent, children: "Choose your display theme" }),
8115
+ /* @__PURE__ */ jsx16(Text17, { color: theme.textMuted, children: "This applies immediately after setup completes." }),
8116
+ /* @__PURE__ */ jsx16(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx16(
8136
8117
  StepSelector,
8137
8118
  {
8138
8119
  options: [
@@ -8162,8 +8143,8 @@ function ThemeStep({ onComplete, onPreview }) {
8162
8143
 
8163
8144
  // src/setup/steps/HarnessStep.tsx
8164
8145
  import { useState as useState13, useCallback as useCallback14 } from "react";
8165
- import { Box as Box13, Text as Text19 } from "ink";
8166
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
8146
+ import { Box as Box12, Text as Text18 } from "ink";
8147
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
8167
8148
  function HarnessStep({ onComplete, onError }) {
8168
8149
  const theme = useTheme();
8169
8150
  const capabilities = listHarnessCapabilities();
@@ -8174,7 +8155,7 @@ function HarnessStep({ onComplete, onError }) {
8174
8155
  (check) => {
8175
8156
  const glyph = check.status === "pass" ? "\u2713" : check.status === "fail" ? "\u2717" : "!";
8176
8157
  const color = check.status === "pass" ? theme.status.success : check.status === "fail" ? theme.status.error : theme.status.warning;
8177
- return /* @__PURE__ */ jsx18(Text19, { color, children: `${glyph} ${check.label}: ${check.message}` }, check.label);
8158
+ return /* @__PURE__ */ jsx17(Text18, { color, children: `${glyph} ${check.label}: ${check.message}` }, check.label);
8178
8159
  },
8179
8160
  [theme.status.error, theme.status.success, theme.status.warning]
8180
8161
  );
@@ -8206,10 +8187,10 @@ function HarnessStep({ onComplete, onError }) {
8206
8187
  },
8207
8188
  [capabilities, onComplete, onError]
8208
8189
  );
8209
- return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", children: [
8210
- /* @__PURE__ */ jsx18(Text19, { bold: true, color: theme.accent, children: "Select harness" }),
8211
- /* @__PURE__ */ jsx18(Text19, { color: theme.textMuted, children: "Choose your coding harness. You can skip this step with S." }),
8212
- status === "selecting" && /* @__PURE__ */ jsx18(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx18(
8190
+ return /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", children: [
8191
+ /* @__PURE__ */ jsx17(Text18, { bold: true, color: theme.accent, children: "Select harness" }),
8192
+ /* @__PURE__ */ jsx17(Text18, { color: theme.textMuted, children: "Choose your coding harness. You can skip this step with S." }),
8193
+ status === "selecting" && /* @__PURE__ */ jsx17(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx17(
8213
8194
  StepSelector,
8214
8195
  {
8215
8196
  options: capabilities.map((capability, index) => ({
@@ -8221,22 +8202,22 @@ function HarnessStep({ onComplete, onError }) {
8221
8202
  onSelect: (value) => handleSelect(value)
8222
8203
  }
8223
8204
  ) }),
8224
- (status === "verifying" || status === "success" || status === "error") && /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", marginTop: 1, children: [
8225
- /* @__PURE__ */ jsx18(
8205
+ (status === "verifying" || status === "success" || status === "error") && /* @__PURE__ */ jsxs14(Box12, { flexDirection: "column", marginTop: 1, children: [
8206
+ /* @__PURE__ */ jsx17(
8226
8207
  StepStatus,
8227
8208
  {
8228
8209
  status,
8229
8210
  message: message || "Verifying harness..."
8230
8211
  }
8231
8212
  ),
8232
- checks.length > 0 && /* @__PURE__ */ jsx18(Box13, { flexDirection: "column", marginTop: 1, children: checks.map(renderCheckLine) })
8213
+ checks.length > 0 && /* @__PURE__ */ jsx17(Box12, { flexDirection: "column", marginTop: 1, children: checks.map(renderCheckLine) })
8233
8214
  ] })
8234
8215
  ] });
8235
8216
  }
8236
8217
 
8237
8218
  // src/setup/components/WizardFrame.tsx
8238
- import { Box as Box14, Text as Text20, useStdout as useStdout6 } from "ink";
8239
- import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
8219
+ import { Box as Box13, Text as Text19, useStdout as useStdout6 } from "ink";
8220
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
8240
8221
  var MAX_WIDTH = 60;
8241
8222
  function WizardFrame({ title, header, footer, children }) {
8242
8223
  const theme = useTheme();
@@ -8250,25 +8231,25 @@ function WizardFrame({ title, header, footer, children }) {
8250
8231
  const topLine = `${g["frame.topLeft"]}${h.repeat(3)}${titlePadded}${h.repeat(topFillCount)}${g["frame.topRight"]}`;
8251
8232
  const teeLine = `${g["frame.teeLeft"]}${h.repeat(frameWidth - 2)}${g["frame.teeRight"]}`;
8252
8233
  const bottomLine = `${g["frame.bottomLeft"]}${h.repeat(frameWidth - 2)}${g["frame.bottomRight"]}`;
8253
- return /* @__PURE__ */ jsxs16(Box14, { flexDirection: "column", paddingX: 1, children: [
8254
- /* @__PURE__ */ jsx19(Text20, { color: theme.accent, children: topLine }),
8255
- /* @__PURE__ */ jsx19(Box14, { flexDirection: "column", paddingX: 1, paddingY: 1, children: header }),
8256
- /* @__PURE__ */ jsx19(Text20, { color: theme.accent, children: teeLine }),
8257
- /* @__PURE__ */ jsx19(Box14, { flexDirection: "column", paddingX: 1, paddingY: 1, children }),
8258
- /* @__PURE__ */ jsx19(Text20, { color: theme.accent, children: teeLine }),
8259
- /* @__PURE__ */ jsx19(Box14, { paddingX: 1, children: footer }),
8260
- /* @__PURE__ */ jsx19(Text20, { color: theme.accent, children: bottomLine })
8234
+ return /* @__PURE__ */ jsxs15(Box13, { flexDirection: "column", paddingX: 1, children: [
8235
+ /* @__PURE__ */ jsx18(Text19, { color: theme.accent, children: topLine }),
8236
+ /* @__PURE__ */ jsx18(Box13, { flexDirection: "column", paddingX: 1, paddingY: 1, children: header }),
8237
+ /* @__PURE__ */ jsx18(Text19, { color: theme.accent, children: teeLine }),
8238
+ /* @__PURE__ */ jsx18(Box13, { flexDirection: "column", paddingX: 1, paddingY: 1, children }),
8239
+ /* @__PURE__ */ jsx18(Text19, { color: theme.accent, children: teeLine }),
8240
+ /* @__PURE__ */ jsx18(Box13, { paddingX: 1, children: footer }),
8241
+ /* @__PURE__ */ jsx18(Text19, { color: theme.accent, children: bottomLine })
8261
8242
  ] });
8262
8243
  }
8263
8244
 
8264
8245
  // src/setup/components/WizardHints.tsx
8265
- import { Box as Box15, Text as Text21 } from "ink";
8266
- import { jsx as jsx20 } from "react/jsx-runtime";
8246
+ import { Box as Box14, Text as Text20 } from "ink";
8247
+ import { jsx as jsx19 } from "react/jsx-runtime";
8267
8248
  function WizardHints({ stepState, stepIndex }) {
8268
8249
  const theme = useTheme();
8269
8250
  const g = getGlyphs();
8270
8251
  if (stepState === "verifying" || stepState === "success") {
8271
- return /* @__PURE__ */ jsx20(Box15, {});
8252
+ return /* @__PURE__ */ jsx19(Box14, {});
8272
8253
  }
8273
8254
  const hints = [];
8274
8255
  if (stepState === "error") {
@@ -8280,7 +8261,7 @@ function WizardHints({ stepState, stepIndex }) {
8280
8261
  if (stepIndex > 0) hints.push(`${g["hint.escape"]} back`);
8281
8262
  hints.push("s skip");
8282
8263
  }
8283
- return /* @__PURE__ */ jsx20(Box15, { children: /* @__PURE__ */ jsx20(Text21, { color: theme.textMuted, children: hints.join(" ") }) });
8264
+ return /* @__PURE__ */ jsx19(Box14, { children: /* @__PURE__ */ jsx19(Text20, { color: theme.textMuted, children: hints.join(" ") }) });
8284
8265
  }
8285
8266
 
8286
8267
  // src/infra/telemetry/identity.ts
@@ -8290,7 +8271,7 @@ function generateDeviceId() {
8290
8271
  }
8291
8272
 
8292
8273
  // src/setup/SetupWizard.tsx
8293
- import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
8274
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
8294
8275
  var STEP_SUMMARIES = [
8295
8276
  { label: "Theme", summarize: (r) => r.theme },
8296
8277
  { label: "Harness", summarize: (r) => r.harness ?? "skipped" }
@@ -8411,12 +8392,12 @@ function SetupWizard({ onComplete, onThemePreview }) {
8411
8392
  }
8412
8393
  }
8413
8394
  }, [isComplete, result, onComplete, writeRetryCount]);
8414
- return /* @__PURE__ */ jsxs17(
8395
+ return /* @__PURE__ */ jsxs16(
8415
8396
  WizardFrame,
8416
8397
  {
8417
8398
  title: "ATHENA SETUP",
8418
- header: /* @__PURE__ */ jsx21(Text22, { color: theme.textMuted, children: "Configure your defaults in under a minute." }),
8419
- footer: /* @__PURE__ */ jsx21(
8399
+ header: /* @__PURE__ */ jsx20(Text21, { color: theme.textMuted, children: "Configure your defaults in under a minute." }),
8400
+ footer: /* @__PURE__ */ jsx20(
8420
8401
  WizardHints,
8421
8402
  {
8422
8403
  stepState: isComplete ? writeError ? "error" : "verifying" : stepState,
@@ -8427,21 +8408,21 @@ function SetupWizard({ onComplete, onThemePreview }) {
8427
8408
  STEP_SUMMARIES.slice(
8428
8409
  0,
8429
8410
  isComplete ? STEP_SUMMARIES.length : stepIndex
8430
- ).map((step, i) => /* @__PURE__ */ jsxs17(Text22, { color: theme.status.success, children: [
8411
+ ).map((step, i) => /* @__PURE__ */ jsxs16(Text21, { color: theme.status.success, children: [
8431
8412
  getGlyphs()["todo.done"],
8432
8413
  " ",
8433
8414
  step.label,
8434
8415
  " \xB7 ",
8435
8416
  step.summarize(result)
8436
8417
  ] }, i)),
8437
- stepIndex === 0 && !isComplete && /* @__PURE__ */ jsx21(
8418
+ stepIndex === 0 && !isComplete && /* @__PURE__ */ jsx20(
8438
8419
  ThemeStep,
8439
8420
  {
8440
8421
  onComplete: handleThemeComplete,
8441
8422
  onPreview: handleThemePreview
8442
8423
  }
8443
8424
  ),
8444
- stepIndex === 1 && !isComplete && /* @__PURE__ */ jsx21(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx21(
8425
+ stepIndex === 1 && !isComplete && /* @__PURE__ */ jsx20(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx20(
8445
8426
  HarnessStep,
8446
8427
  {
8447
8428
  onComplete: handleHarnessComplete,
@@ -8449,11 +8430,11 @@ function SetupWizard({ onComplete, onThemePreview }) {
8449
8430
  },
8450
8431
  retryCount
8451
8432
  ) }),
8452
- stepState === "error" && !isComplete && /* @__PURE__ */ jsx21(Text22, { color: theme.status.error, children: "Press r to retry this step." }),
8453
- isComplete && !writeError && /* @__PURE__ */ jsx21(StepStatus, { status: "verifying", message: "Saving setup..." }),
8454
- isComplete && writeError && /* @__PURE__ */ jsxs17(Fragment7, { children: [
8455
- /* @__PURE__ */ jsx21(StepStatus, { status: "error", message: writeError }),
8456
- /* @__PURE__ */ jsx21(Text22, { color: theme.textMuted, children: "Press r to retry saving." })
8433
+ stepState === "error" && !isComplete && /* @__PURE__ */ jsx20(Text21, { color: theme.status.error, children: "Press r to retry this step." }),
8434
+ isComplete && !writeError && /* @__PURE__ */ jsx20(StepStatus, { status: "verifying", message: "Saving setup..." }),
8435
+ isComplete && writeError && /* @__PURE__ */ jsxs16(Fragment6, { children: [
8436
+ /* @__PURE__ */ jsx20(StepStatus, { status: "error", message: writeError }),
8437
+ /* @__PURE__ */ jsx20(Text21, { color: theme.textMuted, children: "Press r to retry saving." })
8457
8438
  ] })
8458
8439
  ]
8459
8440
  }
@@ -8462,7 +8443,7 @@ function SetupWizard({ onComplete, onThemePreview }) {
8462
8443
 
8463
8444
  // src/app/workflow/WorkflowPicker.tsx
8464
8445
  import { useState as useState15, useCallback as useCallback16, useEffect as useEffect11 } from "react";
8465
- import { Box as Box17, Text as Text23, useInput as useInput14, useStdout as useStdout7 } from "ink";
8446
+ import { Box as Box16, Text as Text22, useInput as useInput14, useStdout as useStdout7 } from "ink";
8466
8447
 
8467
8448
  // src/core/workflows/workflowOptions.ts
8468
8449
  import fs3 from "fs";
@@ -8526,7 +8507,7 @@ function loadWorkflowOptions() {
8526
8507
  }
8527
8508
 
8528
8509
  // src/app/workflow/WorkflowPicker.tsx
8529
- import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
8510
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
8530
8511
  var DEFAULT_WORKFLOW_OPTION = {
8531
8512
  label: "default",
8532
8513
  value: "default",
@@ -8622,22 +8603,22 @@ function WorkflowPicker({
8622
8603
  } else if (phase.type === "error") {
8623
8604
  hints.push("r retry");
8624
8605
  }
8625
- return /* @__PURE__ */ jsx22(
8626
- Box17,
8606
+ return /* @__PURE__ */ jsx21(
8607
+ Box16,
8627
8608
  {
8628
8609
  flexDirection: "column",
8629
8610
  alignItems: "center",
8630
8611
  justifyContent: "center",
8631
8612
  height: rows,
8632
- children: /* @__PURE__ */ jsx22(Box17, { width: frameWidth + 4, children: /* @__PURE__ */ jsxs18(
8613
+ children: /* @__PURE__ */ jsx21(Box16, { width: frameWidth + 4, children: /* @__PURE__ */ jsxs17(
8633
8614
  WizardFrame,
8634
8615
  {
8635
8616
  title: "WORKFLOW",
8636
- header: /* @__PURE__ */ jsx22(Text23, { color: theme.textMuted, children: "Choose a workflow for this project." }),
8637
- footer: /* @__PURE__ */ jsx22(Text23, { color: theme.textMuted, children: hints.join(" ") }),
8617
+ header: /* @__PURE__ */ jsx21(Text22, { color: theme.textMuted, children: "Choose a workflow for this project." }),
8618
+ footer: /* @__PURE__ */ jsx21(Text22, { color: theme.textMuted, children: hints.join(" ") }),
8638
8619
  children: [
8639
- phase.type === "loading" && /* @__PURE__ */ jsx22(StepStatus, { status: "verifying", message: "Loading workflows..." }),
8640
- phase.type === "selecting" && /* @__PURE__ */ jsx22(
8620
+ phase.type === "loading" && /* @__PURE__ */ jsx21(StepStatus, { status: "verifying", message: "Loading workflows..." }),
8621
+ phase.type === "selecting" && /* @__PURE__ */ jsx21(
8641
8622
  StepSelector,
8642
8623
  {
8643
8624
  options: phase.options,
@@ -8645,15 +8626,15 @@ function WorkflowPicker({
8645
8626
  gap: 1
8646
8627
  }
8647
8628
  ),
8648
- phase.type === "installing" && /* @__PURE__ */ jsx22(StepStatus, { status: "verifying", message: "Installing workflow..." }),
8649
- phase.type === "mcp-options" && /* @__PURE__ */ jsx22(
8629
+ phase.type === "installing" && /* @__PURE__ */ jsx21(StepStatus, { status: "verifying", message: "Installing workflow..." }),
8630
+ phase.type === "mcp-options" && /* @__PURE__ */ jsx21(
8650
8631
  McpOptionsStep,
8651
8632
  {
8652
8633
  servers: phase.servers,
8653
8634
  onComplete: handleMcpComplete
8654
8635
  }
8655
8636
  ),
8656
- phase.type === "error" && /* @__PURE__ */ jsx22(Text23, { color: theme.status.error, children: phase.message })
8637
+ phase.type === "error" && /* @__PURE__ */ jsx21(Text22, { color: theme.status.error, children: phase.message })
8657
8638
  ]
8658
8639
  }
8659
8640
  ) })
@@ -8663,58 +8644,8 @@ function WorkflowPicker({
8663
8644
 
8664
8645
  // src/app/modelPreferences/ModelPicker.tsx
8665
8646
  import { useState as useState16, useEffect as useEffect12, useCallback as useCallback17 } from "react";
8666
- import { Box as Box18, Text as Text24, useInput as useInput15, useStdout as useStdout8 } from "ink";
8667
-
8668
- // src/app/modelPreferences/listAvailableModels.ts
8669
- var CLAUDE_MODEL_OPTIONS = [
8670
- {
8671
- value: "sonnet",
8672
- label: "Sonnet",
8673
- description: "Balanced default for day-to-day coding work."
8674
- },
8675
- {
8676
- value: "opus",
8677
- label: "Opus",
8678
- description: "Stronger reasoning for complex architecture and debugging."
8679
- },
8680
- {
8681
- value: "haiku",
8682
- label: "Haiku",
8683
- description: "Fastest option for lighter tasks."
8684
- },
8685
- {
8686
- value: "opusplan",
8687
- label: "OpusPlan",
8688
- description: "Uses Opus for planning and Sonnet for execution."
8689
- }
8690
- ];
8691
- function isCodexRuntimeWithModels(runtime) {
8692
- return Boolean(runtime && "listModels" in runtime);
8693
- }
8694
- async function listAvailableModels(input) {
8695
- switch (input.harness) {
8696
- case "claude-code":
8697
- return CLAUDE_MODEL_OPTIONS;
8698
- case "openai-codex": {
8699
- if (!isCodexRuntimeWithModels(input.runtime)) {
8700
- throw new Error("Codex runtime is not available");
8701
- }
8702
- const models = await input.runtime.listModels();
8703
- return models.map((model) => ({
8704
- value: model.model,
8705
- label: model.displayName,
8706
- description: model.description,
8707
- isDefault: model.isDefault
8708
- }));
8709
- }
8710
- case "opencode":
8711
- default:
8712
- return [];
8713
- }
8714
- }
8715
-
8716
- // src/app/modelPreferences/ModelPicker.tsx
8717
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
8647
+ import { Box as Box17, Text as Text23, useInput as useInput15, useStdout as useStdout8 } from "ink";
8648
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
8718
8649
  function ModelPicker({
8719
8650
  projectDir,
8720
8651
  rows,
@@ -8732,7 +8663,7 @@ function ModelPicker({
8732
8663
  const loadModels = useCallback17(() => {
8733
8664
  setPhase({ type: "loading" });
8734
8665
  setTimeout(() => {
8735
- void listAvailableModels({ harness, runtime }).then((options) => {
8666
+ void resolveHarnessAdapter(harness).listModels(runtime).then((options) => {
8736
8667
  if (options.length === 0) {
8737
8668
  setPhase({
8738
8669
  type: "error",
@@ -8780,28 +8711,28 @@ function ModelPicker({
8780
8711
  hints.push("r retry");
8781
8712
  if (onClose) hints.push(`${g["hint.escape"]} close`);
8782
8713
  }
8783
- return /* @__PURE__ */ jsx23(
8784
- Box18,
8714
+ return /* @__PURE__ */ jsx22(
8715
+ Box17,
8785
8716
  {
8786
8717
  flexDirection: "column",
8787
8718
  alignItems: "center",
8788
8719
  justifyContent: "center",
8789
8720
  height: rows,
8790
- children: /* @__PURE__ */ jsx23(Box18, { width: frameWidth + 4, children: /* @__PURE__ */ jsxs19(
8721
+ children: /* @__PURE__ */ jsx22(Box17, { width: frameWidth + 4, children: /* @__PURE__ */ jsxs18(
8791
8722
  WizardFrame,
8792
8723
  {
8793
8724
  title: "MODEL",
8794
- header: /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", children: [
8795
- /* @__PURE__ */ jsx23(Text24, { color: theme.textMuted, children: "Choose the preferred model for this project." }),
8796
- currentModelName ? /* @__PURE__ */ jsxs19(Text24, { color: theme.textMuted, children: [
8725
+ header: /* @__PURE__ */ jsxs18(Box17, { flexDirection: "column", children: [
8726
+ /* @__PURE__ */ jsx22(Text23, { color: theme.textMuted, children: "Choose the preferred model for this project." }),
8727
+ currentModelName ? /* @__PURE__ */ jsxs18(Text23, { color: theme.textMuted, children: [
8797
8728
  "Current: ",
8798
8729
  currentModelName
8799
8730
  ] }) : null
8800
8731
  ] }),
8801
- footer: /* @__PURE__ */ jsx23(Text24, { color: theme.textMuted, children: hints.join(" ") }),
8732
+ footer: /* @__PURE__ */ jsx22(Text23, { color: theme.textMuted, children: hints.join(" ") }),
8802
8733
  children: [
8803
- phase.type === "loading" && /* @__PURE__ */ jsx23(StepStatus, { status: "verifying", message: "Loading models..." }),
8804
- phase.type === "selecting" && /* @__PURE__ */ jsx23(
8734
+ phase.type === "loading" && /* @__PURE__ */ jsx22(StepStatus, { status: "verifying", message: "Loading models..." }),
8735
+ phase.type === "selecting" && /* @__PURE__ */ jsx22(
8805
8736
  StepSelector,
8806
8737
  {
8807
8738
  options: phase.options.map((option) => ({
@@ -8814,14 +8745,14 @@ function ModelPicker({
8814
8745
  gap: 1
8815
8746
  }
8816
8747
  ),
8817
- phase.type === "saving" && /* @__PURE__ */ jsx23(
8748
+ phase.type === "saving" && /* @__PURE__ */ jsx22(
8818
8749
  StepStatus,
8819
8750
  {
8820
8751
  status: "verifying",
8821
8752
  message: `Saving model preference (${phase.model})...`
8822
8753
  }
8823
8754
  ),
8824
- phase.type === "error" && /* @__PURE__ */ jsx23(Text24, { color: theme.status.error, children: phase.message })
8755
+ phase.type === "error" && /* @__PURE__ */ jsx22(Text23, { color: theme.status.error, children: phase.message })
8825
8756
  ]
8826
8757
  }
8827
8758
  ) })
@@ -9630,7 +9561,7 @@ function toSessionPickerEntries(sessions) {
9630
9561
 
9631
9562
  // src/app/shell/startupDiagnostics.ts
9632
9563
  function shouldTrackStartupDiagnostics(harness) {
9633
- return harness === "claude-code";
9564
+ return resolveHarnessAdapter(harness).capabilities.emitsStartupDiagnostics;
9634
9565
  }
9635
9566
  function createPendingStartupDiagnosticsEvent(args) {
9636
9567
  return {
@@ -9667,6 +9598,20 @@ function deriveStartupTimeoutFailure(args) {
9667
9598
  };
9668
9599
  }
9669
9600
 
9601
+ // src/app/shell/resolveAllowedTools.ts
9602
+ var BASELINE_ALLOWED_TOOLS = ["mcp__*"];
9603
+ function resolveAllowedTools(harness, allowedTools) {
9604
+ const extras = [
9605
+ ...BASELINE_ALLOWED_TOOLS,
9606
+ ...resolveHarnessAdapter(harness).capabilities.extraAllowedTools
9607
+ ];
9608
+ const merged = [...allowedTools ?? []];
9609
+ for (const tool of extras) {
9610
+ if (!merged.includes(tool)) merged.push(tool);
9611
+ }
9612
+ return merged;
9613
+ }
9614
+
9670
9615
  // src/app/shell/channelDispatchCompletion.ts
9671
9616
  function findChannelDispatchReply(feedEvents, afterFeedEventCount) {
9672
9617
  return feedEvents.slice(afterFeedEventCount).reverse().find(
@@ -9706,7 +9651,7 @@ function buildSessionTelemetrySummary(carry, metrics) {
9706
9651
  }
9707
9652
 
9708
9653
  // src/app/shell/AppShell.tsx
9709
- import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
9654
+ import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
9710
9655
  var EMPTY_SESSION_METRICS = {
9711
9656
  modelName: null,
9712
9657
  toolCallCount: 0,
@@ -9735,21 +9680,21 @@ function PermissionErrorFallback({ onDeny }) {
9735
9680
  useInput17((_input, key) => {
9736
9681
  if (key.escape) onDeny();
9737
9682
  });
9738
- return /* @__PURE__ */ jsx24(Text25, { color: theme.status.error, children: "[Permission dialog error -- press Escape to deny and continue]" });
9683
+ return /* @__PURE__ */ jsx23(Text24, { color: theme.status.error, children: "[Permission dialog error -- press Escape to deny and continue]" });
9739
9684
  }
9740
9685
  function QuestionErrorFallback({ onSkip }) {
9741
9686
  const theme = useTheme();
9742
9687
  useInput17((_input, key) => {
9743
9688
  if (key.escape) onSkip();
9744
9689
  });
9745
- return /* @__PURE__ */ jsx24(Text25, { color: theme.status.error, children: "[Question dialog error -- press Escape to skip and continue]" });
9690
+ return /* @__PURE__ */ jsx23(Text24, { color: theme.status.error, children: "[Question dialog error -- press Escape to skip and continue]" });
9746
9691
  }
9747
9692
  function DiagnosticsConsentErrorFallback({ onDismiss }) {
9748
9693
  const theme = useTheme();
9749
9694
  useInput17((_input, key) => {
9750
9695
  if (key.escape) onDismiss();
9751
9696
  });
9752
- return /* @__PURE__ */ jsx24(Text25, { color: theme.status.error, children: "[Diagnostics consent dialog error -- press Escape to dismiss]" });
9697
+ return /* @__PURE__ */ jsx23(Text24, { color: theme.status.error, children: "[Diagnostics consent dialog error -- press Escape to dismiss]" });
9753
9698
  }
9754
9699
  var STARTUP_HANDSHAKE_TIMEOUT_MS = 2500;
9755
9700
  function AppContent({
@@ -10793,6 +10738,7 @@ function AppContent({
10793
10738
  sessionTotal: sessionScope.total,
10794
10739
  harness,
10795
10740
  modelName: metrics.modelName ?? modelName,
10741
+ effortLevel: metrics.effortLevel ?? null,
10796
10742
  errorReason: startupFailure?.message
10797
10743
  });
10798
10744
  return renderHeaderLines(headerModel, innerWidth, hasColor, theme)[0];
@@ -10817,6 +10763,7 @@ function AppContent({
10817
10763
  harness,
10818
10764
  modelName,
10819
10765
  metrics.modelName,
10766
+ metrics.effortLevel,
10820
10767
  startupFailure?.message,
10821
10768
  innerWidth,
10822
10769
  hasColor,
@@ -10866,27 +10813,27 @@ function AppContent({
10866
10813
  [withBorderEdges, frameLine]
10867
10814
  );
10868
10815
  if (pagerActive) {
10869
- return /* @__PURE__ */ jsx24(Box19, {});
10816
+ return /* @__PURE__ */ jsx23(Box18, {});
10870
10817
  }
10871
- return /* @__PURE__ */ jsxs20(Box19, { flexDirection: "column", width: frameWidth, children: [
10872
- /* @__PURE__ */ jsx24(
10818
+ return /* @__PURE__ */ jsxs19(Box18, { flexDirection: "column", width: frameWidth, children: [
10819
+ /* @__PURE__ */ jsx23(
10873
10820
  MaybeProfiler,
10874
10821
  {
10875
10822
  enabled: perfEnabled,
10876
10823
  id: "app.main.header-frame",
10877
10824
  onRender: handleSectionProfilerRender,
10878
- children: /* @__PURE__ */ jsx24(Text25, { children: `${border(topBorder)}
10825
+ children: /* @__PURE__ */ jsx23(Text24, { children: `${border(topBorder)}
10879
10826
  ${withBorderEdges(frameLine(headerLine1))}
10880
10827
  ${border(sectionBorder)}` })
10881
10828
  }
10882
10829
  ),
10883
- /* @__PURE__ */ jsx24(
10830
+ /* @__PURE__ */ jsx23(
10884
10831
  MaybeProfiler,
10885
10832
  {
10886
10833
  enabled: perfEnabled,
10887
10834
  id: "app.main.todo-header",
10888
10835
  onRender: handleSectionProfilerRender,
10889
- children: /* @__PURE__ */ jsx24(
10836
+ children: /* @__PURE__ */ jsx23(
10890
10837
  TodoHeaderSection,
10891
10838
  {
10892
10839
  actualTodoRows,
@@ -10904,13 +10851,13 @@ ${border(sectionBorder)}` })
10904
10851
  )
10905
10852
  }
10906
10853
  ),
10907
- /* @__PURE__ */ jsx24(
10854
+ /* @__PURE__ */ jsx23(
10908
10855
  MaybeProfiler,
10909
10856
  {
10910
10857
  enabled: perfEnabled,
10911
10858
  id: "app.main.body-prefix",
10912
10859
  onRender: handleSectionProfilerRender,
10913
- children: /* @__PURE__ */ jsx24(
10860
+ children: /* @__PURE__ */ jsx23(
10914
10861
  TodoBodySection,
10915
10862
  {
10916
10863
  innerWidth,
@@ -10937,13 +10884,13 @@ ${border(sectionBorder)}` })
10937
10884
  )
10938
10885
  }
10939
10886
  ),
10940
- /* @__PURE__ */ jsx24(
10887
+ /* @__PURE__ */ jsx23(
10941
10888
  MaybeProfiler,
10942
10889
  {
10943
10890
  enabled: perfEnabled,
10944
10891
  id: "app.main.feed",
10945
10892
  onRender: handleSectionProfilerRender,
10946
- children: workflowPickerVisible ? /* @__PURE__ */ jsx24(
10893
+ children: workflowPickerVisible ? /* @__PURE__ */ jsx23(
10947
10894
  WorkflowPicker,
10948
10895
  {
10949
10896
  projectDir,
@@ -10954,7 +10901,7 @@ ${border(sectionBorder)}` })
10954
10901
  onWorkflowSelected(name);
10955
10902
  }
10956
10903
  }
10957
- ) : modelPickerVisible ? /* @__PURE__ */ jsx24(
10904
+ ) : modelPickerVisible ? /* @__PURE__ */ jsx23(
10958
10905
  ModelPicker,
10959
10906
  {
10960
10907
  projectDir,
@@ -10968,8 +10915,8 @@ ${border(sectionBorder)}` })
10968
10915
  onModelSelected(selectedModel);
10969
10916
  }
10970
10917
  }
10971
- ) : splitMode ? /* @__PURE__ */ jsxs20(Box19, { flexDirection: "row", children: [
10972
- /* @__PURE__ */ jsx24(Box19, { width: messagePanelWidth + 1, flexShrink: 0, children: /* @__PURE__ */ jsx24(
10918
+ ) : splitMode ? /* @__PURE__ */ jsxs19(Box18, { flexDirection: "row", children: [
10919
+ /* @__PURE__ */ jsx23(Box18, { width: messagePanelWidth + 1, flexShrink: 0, children: /* @__PURE__ */ jsx23(
10973
10920
  MessagePanel,
10974
10921
  {
10975
10922
  entries: messageEntries,
@@ -10981,7 +10928,7 @@ ${border(sectionBorder)}` })
10981
10928
  borderColor: theme.border
10982
10929
  }
10983
10930
  ) }),
10984
- /* @__PURE__ */ jsx24(Box19, { flexGrow: 1, children: /* @__PURE__ */ jsx24(
10931
+ /* @__PURE__ */ jsx23(Box18, { flexGrow: 1, children: /* @__PURE__ */ jsx23(
10985
10932
  FeedGrid,
10986
10933
  {
10987
10934
  feedHeaderRows,
@@ -11001,7 +10948,7 @@ ${border(sectionBorder)}` })
11001
10948
  onboarding: feedOnboarding
11002
10949
  }
11003
10950
  ) })
11004
- ] }) : /* @__PURE__ */ jsx24(
10951
+ ] }) : /* @__PURE__ */ jsx23(
11005
10952
  FeedGrid,
11006
10953
  {
11007
10954
  feedHeaderRows,
@@ -11023,13 +10970,13 @@ ${border(sectionBorder)}` })
11023
10970
  )
11024
10971
  }
11025
10972
  ),
11026
- /* @__PURE__ */ jsx24(
10973
+ /* @__PURE__ */ jsx23(
11027
10974
  MaybeProfiler,
11028
10975
  {
11029
10976
  enabled: perfEnabled,
11030
10977
  id: "app.main.input",
11031
10978
  onRender: handleSectionProfilerRender,
11032
- children: /* @__PURE__ */ jsx24(
10979
+ children: /* @__PURE__ */ jsx23(
11033
10980
  InputSection,
11034
10981
  {
11035
10982
  innerWidth,
@@ -11059,13 +11006,13 @@ ${border(sectionBorder)}` })
11059
11006
  )
11060
11007
  }
11061
11008
  ),
11062
- /* @__PURE__ */ jsx24(
11009
+ /* @__PURE__ */ jsx23(
11063
11010
  MaybeProfiler,
11064
11011
  {
11065
11012
  enabled: perfEnabled,
11066
11013
  id: "app.main.footer",
11067
11014
  onRender: handleSectionProfilerRender,
11068
- children: /* @__PURE__ */ jsx24(
11015
+ children: /* @__PURE__ */ jsx23(
11069
11016
  FooterSection,
11070
11017
  {
11071
11018
  frameFooterHelp: frame.footerHelp,
@@ -11076,22 +11023,22 @@ ${border(sectionBorder)}` })
11076
11023
  )
11077
11024
  }
11078
11025
  ),
11079
- /* @__PURE__ */ jsx24(
11026
+ /* @__PURE__ */ jsx23(
11080
11027
  MaybeProfiler,
11081
11028
  {
11082
11029
  enabled: perfEnabled,
11083
11030
  id: "app.main.diagnostics-dialog",
11084
11031
  onRender: handleSectionProfilerRender,
11085
- children: /* @__PURE__ */ jsx24(Fragment8, { children: pendingStartupDiagnostics && /* @__PURE__ */ jsx24(
11032
+ children: /* @__PURE__ */ jsx23(Fragment7, { children: pendingStartupDiagnostics && /* @__PURE__ */ jsx23(
11086
11033
  ErrorBoundary,
11087
11034
  {
11088
- fallback: /* @__PURE__ */ jsx24(
11035
+ fallback: /* @__PURE__ */ jsx23(
11089
11036
  DiagnosticsConsentErrorFallback,
11090
11037
  {
11091
11038
  onDismiss: () => setPendingStartupDiagnostics(null)
11092
11039
  }
11093
11040
  ),
11094
- children: /* @__PURE__ */ jsx24(
11041
+ children: /* @__PURE__ */ jsx23(
11095
11042
  DiagnosticsConsentDialog,
11096
11043
  {
11097
11044
  harnessLabel,
@@ -11102,22 +11049,22 @@ ${border(sectionBorder)}` })
11102
11049
  ) })
11103
11050
  }
11104
11051
  ),
11105
- /* @__PURE__ */ jsx24(
11052
+ /* @__PURE__ */ jsx23(
11106
11053
  MaybeProfiler,
11107
11054
  {
11108
11055
  enabled: perfEnabled,
11109
11056
  id: "app.main.permission-dialog",
11110
11057
  onRender: handleSectionProfilerRender,
11111
- children: /* @__PURE__ */ jsx24(Fragment8, { children: appMode.type === "permission" && currentPermissionRequest && /* @__PURE__ */ jsx24(
11058
+ children: /* @__PURE__ */ jsx23(Fragment7, { children: appMode.type === "permission" && currentPermissionRequest && /* @__PURE__ */ jsx23(
11112
11059
  ErrorBoundary,
11113
11060
  {
11114
- fallback: /* @__PURE__ */ jsx24(
11061
+ fallback: /* @__PURE__ */ jsx23(
11115
11062
  PermissionErrorFallback,
11116
11063
  {
11117
11064
  onDeny: () => handlePermissionDecision("deny")
11118
11065
  }
11119
11066
  ),
11120
- children: /* @__PURE__ */ jsx24(
11067
+ children: /* @__PURE__ */ jsx23(
11121
11068
  PermissionDialog,
11122
11069
  {
11123
11070
  request: currentPermissionRequest,
@@ -11129,17 +11076,17 @@ ${border(sectionBorder)}` })
11129
11076
  ) })
11130
11077
  }
11131
11078
  ),
11132
- /* @__PURE__ */ jsx24(
11079
+ /* @__PURE__ */ jsx23(
11133
11080
  MaybeProfiler,
11134
11081
  {
11135
11082
  enabled: perfEnabled,
11136
11083
  id: "app.main.question-dialog",
11137
11084
  onRender: handleSectionProfilerRender,
11138
- children: /* @__PURE__ */ jsx24(Fragment8, { children: appMode.type === "question" && currentQuestionRequest && /* @__PURE__ */ jsx24(
11085
+ children: /* @__PURE__ */ jsx23(Fragment7, { children: appMode.type === "question" && currentQuestionRequest && /* @__PURE__ */ jsx23(
11139
11086
  ErrorBoundary,
11140
11087
  {
11141
- fallback: /* @__PURE__ */ jsx24(QuestionErrorFallback, { onSkip: handleQuestionSkip }),
11142
- children: /* @__PURE__ */ jsx24(
11088
+ fallback: /* @__PURE__ */ jsx23(QuestionErrorFallback, { onSkip: handleQuestionSkip }),
11089
+ children: /* @__PURE__ */ jsx23(
11143
11090
  QuestionDialog,
11144
11091
  {
11145
11092
  request: currentQuestionRequest,
@@ -11160,10 +11107,10 @@ function MaybeProfiler({
11160
11107
  onRender,
11161
11108
  children
11162
11109
  }) {
11163
- if (!enabled) return /* @__PURE__ */ jsx24(Fragment8, { children });
11164
- return /* @__PURE__ */ jsx24(Profiler, { id, onRender, children });
11110
+ if (!enabled) return /* @__PURE__ */ jsx23(Fragment7, { children });
11111
+ return /* @__PURE__ */ jsx23(Profiler, { id, onRender, children });
11165
11112
  }
11166
- var TodoHeaderSection = React9.memo(function TodoHeaderSection2({
11113
+ var TodoHeaderSection = React8.memo(function TodoHeaderSection2({
11167
11114
  actualTodoRows,
11168
11115
  innerWidth,
11169
11116
  useAscii,
@@ -11202,9 +11149,9 @@ var TodoHeaderSection = React9.memo(function TodoHeaderSection2({
11202
11149
  theme
11203
11150
  ]
11204
11151
  );
11205
- return /* @__PURE__ */ jsx24(Fragment8, { children: todoHeaderLine !== null && /* @__PURE__ */ jsx24(Text25, { children: withBorderEdges(frameLine(todoHeaderLine)) }, "todo-header") });
11152
+ return /* @__PURE__ */ jsx23(Fragment7, { children: todoHeaderLine !== null && /* @__PURE__ */ jsx23(Text24, { children: withBorderEdges(frameLine(todoHeaderLine)) }, "todo-header") });
11206
11153
  });
11207
- var TodoBodySection = React9.memo(function TodoBodySection2({
11154
+ var TodoBodySection = React8.memo(function TodoBodySection2({
11208
11155
  innerWidth,
11209
11156
  actualTodoRows,
11210
11157
  todoScroll,
@@ -11291,9 +11238,9 @@ var TodoBodySection = React9.memo(function TodoBodySection2({
11291
11238
  ]
11292
11239
  );
11293
11240
  if (output === null) return null;
11294
- return /* @__PURE__ */ jsx24(Text25, { children: output });
11241
+ return /* @__PURE__ */ jsx23(Text24, { children: output });
11295
11242
  });
11296
- var FooterSection = React9.memo(function FooterSection2({
11243
+ var FooterSection = React8.memo(function FooterSection2({
11297
11244
  frameFooterHelp,
11298
11245
  toastMessage,
11299
11246
  hintTextColor,
@@ -11305,9 +11252,9 @@ var FooterSection = React9.memo(function FooterSection2({
11305
11252
  return fit(hint, innerWidth);
11306
11253
  }, [frameFooterHelp, toastMessage, hintTextColor, innerWidth]);
11307
11254
  if (output === null) return null;
11308
- return /* @__PURE__ */ jsx24(Text25, { children: output });
11255
+ return /* @__PURE__ */ jsx23(Text24, { children: output });
11309
11256
  });
11310
- var InputSection = React9.memo(function InputSection2({
11257
+ var InputSection = React8.memo(function InputSection2({
11311
11258
  innerWidth,
11312
11259
  useAscii,
11313
11260
  borderColor,
@@ -11332,7 +11279,7 @@ var InputSection = React9.memo(function InputSection2({
11332
11279
  topBorder,
11333
11280
  bottomBorder
11334
11281
  }) {
11335
- return /* @__PURE__ */ jsx24(
11282
+ return /* @__PURE__ */ jsx23(
11336
11283
  ShellInput2,
11337
11284
  {
11338
11285
  ref: inputRef,
@@ -11541,13 +11488,13 @@ function App({
11541
11488
  refreshRuntime();
11542
11489
  }, [refreshRuntime]);
11543
11490
  if (phase.type === "setup") {
11544
- return /* @__PURE__ */ jsx24(
11491
+ return /* @__PURE__ */ jsx23(
11545
11492
  MaybeProfiler,
11546
11493
  {
11547
11494
  enabled: perfEnabled,
11548
11495
  id: "app.setup",
11549
11496
  onRender: handleProfilerRender,
11550
- children: /* @__PURE__ */ jsx24(ThemeProvider, { value: activeTheme, children: /* @__PURE__ */ jsx24(
11497
+ children: /* @__PURE__ */ jsx23(ThemeProvider, { value: activeTheme, children: /* @__PURE__ */ jsx23(
11551
11498
  SetupWizard,
11552
11499
  {
11553
11500
  onThemePreview: (themeName) => {
@@ -11560,17 +11507,17 @@ function App({
11560
11507
  );
11561
11508
  }
11562
11509
  if (phase.type === "session-select") {
11563
- return /* @__PURE__ */ jsx24(
11510
+ return /* @__PURE__ */ jsx23(
11564
11511
  MaybeProfiler,
11565
11512
  {
11566
11513
  enabled: perfEnabled,
11567
11514
  id: "app.session-select",
11568
11515
  onRender: handleProfilerRender,
11569
- children: /* @__PURE__ */ jsx24(
11516
+ children: /* @__PURE__ */ jsx23(
11570
11517
  ErrorBoundary,
11571
11518
  {
11572
- fallback: /* @__PURE__ */ jsx24(Text25, { color: "red", children: "[Session picker error -- starting new session]" }),
11573
- children: /* @__PURE__ */ jsx24(
11519
+ fallback: /* @__PURE__ */ jsx23(Text24, { color: "red", children: "[Session picker error -- starting new session]" }),
11520
+ children: /* @__PURE__ */ jsx23(
11574
11521
  SessionPicker,
11575
11522
  {
11576
11523
  sessions,
@@ -11584,7 +11531,7 @@ function App({
11584
11531
  }
11585
11532
  );
11586
11533
  }
11587
- return /* @__PURE__ */ jsx24(ThemeProvider, { value: activeTheme, children: /* @__PURE__ */ jsx24(
11534
+ return /* @__PURE__ */ jsx23(ThemeProvider, { value: activeTheme, children: /* @__PURE__ */ jsx23(
11588
11535
  HookProvider,
11589
11536
  {
11590
11537
  projectDir,
@@ -11597,7 +11544,7 @@ function App({
11597
11544
  ),
11598
11545
  athenaSessionId,
11599
11546
  ...attachmentId !== void 0 ? { attachmentId } : {},
11600
- children: /* @__PURE__ */ jsx24(
11547
+ children: /* @__PURE__ */ jsx23(
11601
11548
  AppContent,
11602
11549
  {
11603
11550
  projectDir,
@@ -11633,15 +11580,6 @@ function App({
11633
11580
  }
11634
11581
  ) });
11635
11582
  }
11636
- function resolveAllowedTools(harness, allowedTools) {
11637
- const extras = harness === "openai-codex" ? ["mcp__*", "Permissions", "Bash", "Edit"] : ["mcp__*"];
11638
- const base = allowedTools ?? [];
11639
- const merged = [...base];
11640
- for (const tool of extras) {
11641
- if (!merged.includes(tool)) merged.push(tool);
11642
- }
11643
- return merged;
11644
- }
11645
11583
  function usePerfRenderLog(enabled, id) {
11646
11584
  const renderCountRef = useRef16(0);
11647
11585
  renderCountRef.current += 1;
@@ -12046,7 +11984,34 @@ async function runExecCommand(input, deps = {}) {
12046
11984
  outputLastMessagePath: input.flags.outputLastMessage,
12047
11985
  ephemeral: input.flags.ephemeral,
12048
11986
  timeoutMs: input.flags.timeoutMs,
12049
- channels: input.flags.channels
11987
+ channels: input.flags.channels,
11988
+ // Reporting-only summary: strip to name + source layer so secret-bearing
11989
+ // MCP env/command/args and skill paths never reach the startup notice or
11990
+ // the exec.started event (R3).
11991
+ personalCapabilities: {
11992
+ mcpServers: input.runtimeConfig.personalMcpServers.map((server) => ({
11993
+ name: server.name,
11994
+ sourceLayer: server.sourceLayer
11995
+ })),
11996
+ skills: input.runtimeConfig.personalSkills.map((skill) => ({
11997
+ name: skill.name,
11998
+ sourceLayer: skill.sourceLayer
11999
+ }))
12000
+ },
12001
+ // Same strip for shadowed (conflicting) capabilities — name + source
12002
+ // layer only, never the personal MCP env/command/args or skill path (R7).
12003
+ capabilityConflicts: {
12004
+ mcpServers: input.runtimeConfig.capabilityConflicts.mcpServers.map(
12005
+ (server) => ({
12006
+ name: server.name,
12007
+ sourceLayer: server.sourceLayer
12008
+ })
12009
+ ),
12010
+ skills: input.runtimeConfig.capabilityConflicts.skills.map((skill) => ({
12011
+ name: skill.name,
12012
+ sourceLayer: skill.sourceLayer
12013
+ }))
12014
+ }
12050
12015
  });
12051
12016
  return result.exitCode;
12052
12017
  }
@@ -12343,6 +12308,27 @@ function runWorkflowCommand(input, deps = {}) {
12343
12308
  ` note: project config overrides global at ${projectConfigPath(input.projectDir)}`
12344
12309
  );
12345
12310
  }
12311
+ const { mcpServers, skills } = resolveEffectiveCapabilities({
12312
+ globalConfig,
12313
+ projectConfig
12314
+ });
12315
+ if (mcpServers.length === 0 && skills.length === 0) {
12316
+ logOut("Personal capabilities: none configured");
12317
+ } else {
12318
+ logOut("Personal capabilities:");
12319
+ if (mcpServers.length > 0) {
12320
+ logOut(" MCP servers:");
12321
+ for (const server of mcpServers) {
12322
+ logOut(` ${server.name} [${server.sourceLayer}]`);
12323
+ }
12324
+ }
12325
+ if (skills.length > 0) {
12326
+ logOut(" Skills:");
12327
+ for (const skill of skills) {
12328
+ logOut(` ${skill.name} [${skill.sourceLayer}]`);
12329
+ }
12330
+ }
12331
+ }
12346
12332
  return 0;
12347
12333
  }
12348
12334
  default:
@@ -12351,6 +12337,343 @@ function runWorkflowCommand(input, deps = {}) {
12351
12337
  }
12352
12338
  }
12353
12339
 
12340
+ // src/app/entry/mcpCommand.ts
12341
+ function parseArgs(args, context) {
12342
+ let project = false;
12343
+ let global = false;
12344
+ const env2 = [];
12345
+ const positional = [];
12346
+ for (let i = 0; i < args.length; i++) {
12347
+ const arg = args[i];
12348
+ if (arg === "--project") {
12349
+ project = true;
12350
+ } else if (arg === "--global") {
12351
+ global = true;
12352
+ } else if (arg === "--env") {
12353
+ const value = args[i + 1];
12354
+ if (value === void 0) {
12355
+ return { error: `mcp ${context}: --env requires a KEY=VALUE argument` };
12356
+ }
12357
+ env2.push(value);
12358
+ i++;
12359
+ } else if (arg.startsWith("--")) {
12360
+ return { error: `Unknown flag for mcp ${context}: ${arg}` };
12361
+ } else {
12362
+ positional.push(arg);
12363
+ }
12364
+ }
12365
+ if (project && global) {
12366
+ return {
12367
+ error: `mcp ${context}: --project and --global are mutually exclusive`
12368
+ };
12369
+ }
12370
+ return { project, global, env: env2, positional };
12371
+ }
12372
+ function parseEnv(entries) {
12373
+ const env2 = {};
12374
+ for (const entry of entries) {
12375
+ const eq = entry.indexOf("=");
12376
+ if (eq <= 0) {
12377
+ return { error: `Invalid --env value (expected KEY=VALUE): ${entry}` };
12378
+ }
12379
+ env2[entry.slice(0, eq)] = entry.slice(eq + 1);
12380
+ }
12381
+ return env2;
12382
+ }
12383
+ function runMcpCommand(input, deps = {}) {
12384
+ const readGlobal = deps.readGlobalConfig ?? readGlobalConfig;
12385
+ const readProject = deps.readProjectConfig ?? readConfig;
12386
+ const writeGlobal = deps.writeGlobalConfig ?? writeGlobalConfig;
12387
+ const writeProject = deps.writeProjectConfig ?? writeProjectConfig;
12388
+ const logError = deps.logError ?? console.error;
12389
+ const logOut = deps.logOut ?? console.log;
12390
+ const { subcommand } = input;
12391
+ if (subcommand === "add") {
12392
+ const parsed = parseArgs(input.subcommandArgs, "add");
12393
+ if ("error" in parsed) {
12394
+ logError(parsed.error);
12395
+ return 1;
12396
+ }
12397
+ const name = parsed.positional[0];
12398
+ if (!name) {
12399
+ logError("mcp add: missing server name");
12400
+ return 1;
12401
+ }
12402
+ const [command, ...args] = input.serverCommandTokens;
12403
+ if (!command) {
12404
+ logError(
12405
+ `mcp add: missing server command. Usage: mcp add ${name} -- <command> [args...]`
12406
+ );
12407
+ return 1;
12408
+ }
12409
+ const envResult = parseEnv(parsed.env);
12410
+ if ("error" in envResult) {
12411
+ logError(envResult.error);
12412
+ return 1;
12413
+ }
12414
+ const server = { command };
12415
+ if (args.length > 0) {
12416
+ server.args = args;
12417
+ }
12418
+ if (Object.keys(envResult).length > 0) {
12419
+ server.env = envResult;
12420
+ }
12421
+ const layer = parsed.project ? "project" : "global";
12422
+ const existing = (layer === "project" ? readProject(input.projectDir).mcpServers : readGlobal().mcpServers) ?? {};
12423
+ const overwriting = name in existing;
12424
+ const merged = { ...existing, [name]: server };
12425
+ if (layer === "project") {
12426
+ writeProject(input.projectDir, { mcpServers: merged });
12427
+ } else {
12428
+ writeGlobal({ mcpServers: merged });
12429
+ }
12430
+ logOut(
12431
+ `${overwriting ? "Overwrote" : "Added"} personal MCP server '${name}' [${layer}]`
12432
+ );
12433
+ return 0;
12434
+ }
12435
+ if (subcommand === "list") {
12436
+ const parsed = parseArgs(input.subcommandArgs, "list");
12437
+ if ("error" in parsed) {
12438
+ logError(parsed.error);
12439
+ return 1;
12440
+ }
12441
+ const listSingleLayer = (servers, label) => {
12442
+ const names = Object.keys(servers);
12443
+ if (names.length === 0) {
12444
+ logOut(`No personal MCP servers configured (${label}).`);
12445
+ return;
12446
+ }
12447
+ logOut(`Personal MCP servers (${label}):`);
12448
+ for (const name of names) {
12449
+ logOut(` ${name} ${servers[name].command}`);
12450
+ }
12451
+ };
12452
+ if (parsed.global) {
12453
+ listSingleLayer(readGlobal().mcpServers ?? {}, "global");
12454
+ return 0;
12455
+ }
12456
+ if (parsed.project) {
12457
+ listSingleLayer(
12458
+ readProject(input.projectDir).mcpServers ?? {},
12459
+ "project"
12460
+ );
12461
+ return 0;
12462
+ }
12463
+ const { mcpServers } = resolveEffectiveCapabilities({
12464
+ globalConfig: readGlobal(),
12465
+ projectConfig: readProject(input.projectDir)
12466
+ });
12467
+ if (mcpServers.length === 0) {
12468
+ logOut("No personal MCP servers configured.");
12469
+ return 0;
12470
+ }
12471
+ logOut("Personal MCP servers (effective):");
12472
+ for (const server of mcpServers) {
12473
+ logOut(` ${server.name} ${server.command} [${server.sourceLayer}]`);
12474
+ }
12475
+ return 0;
12476
+ }
12477
+ if (subcommand === "remove") {
12478
+ const parsed = parseArgs(input.subcommandArgs, "remove");
12479
+ if ("error" in parsed) {
12480
+ logError(parsed.error);
12481
+ return 1;
12482
+ }
12483
+ const name = parsed.positional[0];
12484
+ if (!name) {
12485
+ logError("mcp remove: missing server name");
12486
+ return 1;
12487
+ }
12488
+ const layer = parsed.project ? "project" : "global";
12489
+ const existing = (layer === "project" ? readProject(input.projectDir).mcpServers : readGlobal().mcpServers) ?? {};
12490
+ if (!(name in existing)) {
12491
+ logError(
12492
+ `mcp remove: no personal MCP server '${name}' found in ${layer} config`
12493
+ );
12494
+ return 1;
12495
+ }
12496
+ const next = { ...existing };
12497
+ delete next[name];
12498
+ if (layer === "project") {
12499
+ writeProject(input.projectDir, { mcpServers: next });
12500
+ } else {
12501
+ writeGlobal({ mcpServers: next });
12502
+ }
12503
+ logOut(`Removed personal MCP server '${name}' [${layer}]`);
12504
+ return 0;
12505
+ }
12506
+ logError(`Unknown mcp subcommand: ${subcommand}`);
12507
+ return 1;
12508
+ }
12509
+
12510
+ // src/app/entry/skillCommand.ts
12511
+ import fs4 from "fs";
12512
+ import path4 from "path";
12513
+ function resolvePersonalSkill(ref, projectDir) {
12514
+ const absPath = path4.isAbsolute(ref) ? ref : path4.resolve(projectDir, ref);
12515
+ if (!fs4.existsSync(absPath)) {
12516
+ return { error: `skill install: path not found: ${ref}` };
12517
+ }
12518
+ let skillDir;
12519
+ let skillMdPath;
12520
+ if (fs4.statSync(absPath).isDirectory()) {
12521
+ skillDir = absPath;
12522
+ skillMdPath = path4.join(absPath, "SKILL.md");
12523
+ } else if (path4.basename(absPath) === "SKILL.md") {
12524
+ skillDir = path4.dirname(absPath);
12525
+ skillMdPath = absPath;
12526
+ } else {
12527
+ return {
12528
+ error: `skill install: expected a directory containing SKILL.md or a SKILL.md file: ${ref}`
12529
+ };
12530
+ }
12531
+ if (!fs4.existsSync(skillMdPath)) {
12532
+ return { error: `skill install: no SKILL.md found at ${skillDir}` };
12533
+ }
12534
+ try {
12535
+ const { frontmatter } = parseFrontmatter(
12536
+ fs4.readFileSync(skillMdPath, "utf-8")
12537
+ );
12538
+ return { name: frontmatter.name, source: ref, path: skillDir };
12539
+ } catch (error) {
12540
+ const message = error instanceof Error ? error.message : String(error);
12541
+ return { error: `skill install: invalid SKILL.md (${message})` };
12542
+ }
12543
+ }
12544
+ function parseArgs2(args, context) {
12545
+ let project = false;
12546
+ let global = false;
12547
+ const positional = [];
12548
+ for (const arg of args) {
12549
+ if (arg === "--project") {
12550
+ project = true;
12551
+ } else if (arg === "--global") {
12552
+ global = true;
12553
+ } else if (arg.startsWith("--")) {
12554
+ return { error: `Unknown flag for skill ${context}: ${arg}` };
12555
+ } else {
12556
+ positional.push(arg);
12557
+ }
12558
+ }
12559
+ if (project && global) {
12560
+ return {
12561
+ error: `skill ${context}: --project and --global are mutually exclusive`
12562
+ };
12563
+ }
12564
+ return { project, global, positional };
12565
+ }
12566
+ function runSkillCommand(input, deps = {}) {
12567
+ const readGlobal = deps.readGlobalConfig ?? readGlobalConfig;
12568
+ const readProject = deps.readProjectConfig ?? readConfig;
12569
+ const writeGlobal = deps.writeGlobalConfig ?? writeGlobalConfig;
12570
+ const writeProject = deps.writeProjectConfig ?? writeProjectConfig;
12571
+ const resolveSkill = deps.resolveSkill ?? resolvePersonalSkill;
12572
+ const logError = deps.logError ?? console.error;
12573
+ const logOut = deps.logOut ?? console.log;
12574
+ const { subcommand } = input;
12575
+ if (subcommand === "install") {
12576
+ const parsed = parseArgs2(input.subcommandArgs, "install");
12577
+ if ("error" in parsed) {
12578
+ logError(parsed.error);
12579
+ return 1;
12580
+ }
12581
+ const ref = parsed.positional[0];
12582
+ if (!ref) {
12583
+ logError(
12584
+ "skill install: missing skill path. Usage: skill install <path>"
12585
+ );
12586
+ return 1;
12587
+ }
12588
+ const resolved = resolveSkill(ref, input.projectDir);
12589
+ if ("error" in resolved) {
12590
+ logError(resolved.error);
12591
+ return 1;
12592
+ }
12593
+ const layer = parsed.project ? "project" : "global";
12594
+ const existing = (layer === "project" ? readProject(input.projectDir).skills : readGlobal().skills) ?? [];
12595
+ const overwriting = existing.some((s) => s.name === resolved.name);
12596
+ const next = [...existing.filter((s) => s.name !== resolved.name), resolved];
12597
+ if (layer === "project") {
12598
+ writeProject(input.projectDir, { skills: next });
12599
+ } else {
12600
+ writeGlobal({ skills: next });
12601
+ }
12602
+ logOut(
12603
+ `${overwriting ? "Reinstalled" : "Installed"} personal skill '${resolved.name}' [${layer}]`
12604
+ );
12605
+ return 0;
12606
+ }
12607
+ if (subcommand === "list") {
12608
+ const parsed = parseArgs2(input.subcommandArgs, "list");
12609
+ if ("error" in parsed) {
12610
+ logError(parsed.error);
12611
+ return 1;
12612
+ }
12613
+ const listSingleLayer = (skills2, label) => {
12614
+ if (skills2.length === 0) {
12615
+ logOut(`No personal skills configured (${label}).`);
12616
+ return;
12617
+ }
12618
+ logOut(`Personal skills (${label}):`);
12619
+ for (const skill of skills2) {
12620
+ logOut(` ${skill.name} ${skill.source}`);
12621
+ }
12622
+ };
12623
+ if (parsed.global) {
12624
+ listSingleLayer(readGlobal().skills ?? [], "global");
12625
+ return 0;
12626
+ }
12627
+ if (parsed.project) {
12628
+ listSingleLayer(readProject(input.projectDir).skills ?? [], "project");
12629
+ return 0;
12630
+ }
12631
+ const { skills } = resolveEffectiveCapabilities({
12632
+ globalConfig: readGlobal(),
12633
+ projectConfig: readProject(input.projectDir)
12634
+ });
12635
+ if (skills.length === 0) {
12636
+ logOut("No personal skills configured.");
12637
+ return 0;
12638
+ }
12639
+ logOut("Personal skills (effective):");
12640
+ for (const skill of skills) {
12641
+ logOut(` ${skill.name} ${skill.source} [${skill.sourceLayer}]`);
12642
+ }
12643
+ return 0;
12644
+ }
12645
+ if (subcommand === "remove") {
12646
+ const parsed = parseArgs2(input.subcommandArgs, "remove");
12647
+ if ("error" in parsed) {
12648
+ logError(parsed.error);
12649
+ return 1;
12650
+ }
12651
+ const target = parsed.positional[0];
12652
+ if (!target) {
12653
+ logError("skill remove: missing skill name or source");
12654
+ return 1;
12655
+ }
12656
+ const layer = parsed.project ? "project" : "global";
12657
+ const existing = (layer === "project" ? readProject(input.projectDir).skills : readGlobal().skills) ?? [];
12658
+ const next = existing.filter((s) => s.name !== target && s.source !== target);
12659
+ if (next.length === existing.length) {
12660
+ logError(
12661
+ `skill remove: no personal skill '${target}' found in ${layer} config`
12662
+ );
12663
+ return 1;
12664
+ }
12665
+ if (layer === "project") {
12666
+ writeProject(input.projectDir, { skills: next });
12667
+ } else {
12668
+ writeGlobal({ skills: next });
12669
+ }
12670
+ logOut(`Removed personal skill '${target}' [${layer}]`);
12671
+ return 0;
12672
+ }
12673
+ logError(`Unknown skill subcommand: ${subcommand}`);
12674
+ return 1;
12675
+ }
12676
+
12354
12677
  // src/app/entry/marketplaceCommand.ts
12355
12678
  var DEFAULT_MARKETPLACE_SLUG3 = "lespaceman/athena-workflow-marketplace";
12356
12679
  var USAGE2 = `Usage: athena-flow marketplace <subcommand>
@@ -12466,9 +12789,9 @@ Default: ${DEFAULT_MARKETPLACE_SLUG3}`
12466
12789
  }
12467
12790
 
12468
12791
  // src/app/entry/channelCommand.ts
12469
- import fs4 from "fs";
12792
+ import fs5 from "fs";
12470
12793
  import os3 from "os";
12471
- import path4 from "path";
12794
+ import path5 from "path";
12472
12795
  var USAGE3 = `Usage: athena-flow channel telegram configure --bot-token <token> --user-id <id> [--chat-id <id>]
12473
12796
 
12474
12797
  Configures ~/.config/athena/channels/telegram.json and enables telegram in the global channels list.`;
@@ -12479,16 +12802,16 @@ function parseTelegramId(flagName, value) {
12479
12802
  return Number(value);
12480
12803
  }
12481
12804
  function writeTelegramChannelConfig(config) {
12482
- const dir = path4.join(os3.homedir(), ".config", "athena", "channels");
12483
- const configPath = path4.join(dir, "telegram.json");
12484
- fs4.mkdirSync(dir, { recursive: true, mode: 448 });
12485
- fs4.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", {
12805
+ const dir = path5.join(os3.homedir(), ".config", "athena", "channels");
12806
+ const configPath = path5.join(dir, "telegram.json");
12807
+ fs5.mkdirSync(dir, { recursive: true, mode: 448 });
12808
+ fs5.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", {
12486
12809
  encoding: "utf-8",
12487
12810
  mode: 384
12488
12811
  });
12489
12812
  if (process.platform !== "win32") {
12490
- fs4.chmodSync(dir, 448);
12491
- fs4.chmodSync(configPath, 384);
12813
+ fs5.chmodSync(dir, 448);
12814
+ fs5.chmodSync(configPath, 384);
12492
12815
  }
12493
12816
  }
12494
12817
  function runChannelCommand(input, deps = {}) {
@@ -12535,22 +12858,22 @@ function runChannelCommand(input, deps = {}) {
12535
12858
  // src/app/entry/dashboardCommand.ts
12536
12859
  import crypto3 from "crypto";
12537
12860
  import { spawn } from "child_process";
12538
- import fs6 from "fs";
12861
+ import fs7 from "fs";
12539
12862
  import { createRequire } from "module";
12540
12863
  import os5 from "os";
12541
- import path6 from "path";
12864
+ import path7 from "path";
12542
12865
  import { fileURLToPath } from "url";
12543
12866
 
12544
12867
  // src/infra/daemon/serviceUnit.ts
12545
- import fs5 from "fs";
12868
+ import fs6 from "fs";
12546
12869
  import os4 from "os";
12547
- import path5 from "path";
12870
+ import path6 from "path";
12548
12871
  function installServiceUnit(options) {
12549
12872
  const platform = options.platform ?? process.platform;
12550
12873
  const env2 = options.env ?? process.env;
12551
12874
  const home = env2["HOME"] ?? os4.homedir();
12552
12875
  if (platform === "darwin") {
12553
- const target = options.targetPath ?? path5.join(home, "Library", "LaunchAgents", "ai.drisp.daemon.plist");
12876
+ const target = options.targetPath ?? path6.join(home, "Library", "LaunchAgents", "ai.drisp.daemon.plist");
12554
12877
  const paths = daemonStatePaths(env2);
12555
12878
  const plist = renderLaunchdPlist({
12556
12879
  label: "ai.drisp.daemon",
@@ -12570,7 +12893,7 @@ function installServiceUnit(options) {
12570
12893
  };
12571
12894
  }
12572
12895
  if (platform === "linux") {
12573
- const target = options.targetPath ?? path5.join(home, ".config", "systemd", "user", "drisp-daemon.service");
12896
+ const target = options.targetPath ?? path6.join(home, ".config", "systemd", "user", "drisp-daemon.service");
12574
12897
  const unit = renderSystemdUnit({
12575
12898
  description: "Drisp dashboard runtime daemon",
12576
12899
  nodeBinary: options.nodeBinary,
@@ -12592,16 +12915,16 @@ function installServiceUnit(options) {
12592
12915
  };
12593
12916
  }
12594
12917
  function writeIfChanged(target, content) {
12595
- const dir = path5.dirname(target);
12596
- fs5.mkdirSync(dir, { recursive: true, mode: 448 });
12918
+ const dir = path6.dirname(target);
12919
+ fs6.mkdirSync(dir, { recursive: true, mode: 448 });
12597
12920
  let existing = null;
12598
12921
  try {
12599
- existing = fs5.readFileSync(target, "utf-8");
12922
+ existing = fs6.readFileSync(target, "utf-8");
12600
12923
  } catch (err) {
12601
12924
  if (err.code !== "ENOENT") throw err;
12602
12925
  }
12603
12926
  if (existing === content) return;
12604
- fs5.writeFileSync(target, content, { mode: 384 });
12927
+ fs6.writeFileSync(target, content, { mode: 384 });
12605
12928
  }
12606
12929
  function renderLaunchdPlist(input) {
12607
12930
  const argv = [input.nodeBinary, input.daemonEntry].map((s) => ` <string>${escapeXml(s)}</string>`).join("\n");
@@ -12702,7 +13025,7 @@ var cachedVersion = null;
12702
13025
  function readPackageVersion() {
12703
13026
  if (cachedVersion !== null) return cachedVersion;
12704
13027
  try {
12705
- const injected = "0.5.24";
13028
+ const injected = "0.5.26";
12706
13029
  if (typeof injected === "string" && injected.length > 0) {
12707
13030
  cachedVersion = injected;
12708
13031
  return cachedVersion;
@@ -13689,11 +14012,11 @@ function resolveDaemonEntry() {
13689
14012
  return null;
13690
14013
  }
13691
14014
  const candidates = [
13692
- path6.join(path6.dirname(here), "dashboard-daemon.js"),
14015
+ path7.join(path7.dirname(here), "dashboard-daemon.js"),
13693
14016
  // When invoked via `npm run start`, `here` may be the unbundled source
13694
14017
  // path. Walk up until we hit a `dist/` sibling.
13695
- path6.join(
13696
- path6.dirname(here),
14018
+ path7.join(
14019
+ path7.dirname(here),
13697
14020
  "..",
13698
14021
  "..",
13699
14022
  "..",
@@ -13703,7 +14026,7 @@ function resolveDaemonEntry() {
13703
14026
  ];
13704
14027
  for (const candidate of candidates) {
13705
14028
  try {
13706
- fs6.accessSync(candidate, fs6.constants.R_OK);
14029
+ fs7.accessSync(candidate, fs7.constants.R_OK);
13707
14030
  return candidate;
13708
14031
  } catch {
13709
14032
  }
@@ -13888,14 +14211,14 @@ async function defaultTailDaemonLog(opts) {
13888
14211
  let stream2 = null;
13889
14212
  let watcher = null;
13890
14213
  try {
13891
- const stat = fs6.statSync(paths.logPath);
14214
+ const stat = fs7.statSync(paths.logPath);
13892
14215
  const size = stat.size;
13893
14216
  const buf = Buffer.alloc(Math.min(size, opts.tail * 1024));
13894
- const fd = fs6.openSync(paths.logPath, "r");
14217
+ const fd = fs7.openSync(paths.logPath, "r");
13895
14218
  try {
13896
- fs6.readSync(fd, buf, 0, buf.length, Math.max(0, size - buf.length));
14219
+ fs7.readSync(fd, buf, 0, buf.length, Math.max(0, size - buf.length));
13897
14220
  } finally {
13898
- fs6.closeSync(fd);
14221
+ fs7.closeSync(fd);
13899
14222
  }
13900
14223
  const lines = buf.toString("utf-8").split("\n").filter((l) => l.length > 0);
13901
14224
  const tail = lines.slice(-opts.tail);
@@ -13913,22 +14236,22 @@ async function defaultTailDaemonLog(opts) {
13913
14236
  }
13914
14237
  throw err;
13915
14238
  }
13916
- let position = fs6.statSync(paths.logPath).size;
14239
+ let position = fs7.statSync(paths.logPath).size;
13917
14240
  return await new Promise((resolve) => {
13918
14241
  let pollTimer = null;
13919
14242
  const drain = () => {
13920
14243
  try {
13921
- const stat = fs6.statSync(paths.logPath);
14244
+ const stat = fs7.statSync(paths.logPath);
13922
14245
  if (stat.size < position) {
13923
14246
  position = 0;
13924
14247
  }
13925
14248
  if (stat.size > position) {
13926
- const fd = fs6.openSync(paths.logPath, "r");
14249
+ const fd = fs7.openSync(paths.logPath, "r");
13927
14250
  const buf = Buffer.alloc(stat.size - position);
13928
14251
  try {
13929
- fs6.readSync(fd, buf, 0, buf.length, position);
14252
+ fs7.readSync(fd, buf, 0, buf.length, position);
13930
14253
  } finally {
13931
- fs6.closeSync(fd);
14254
+ fs7.closeSync(fd);
13932
14255
  }
13933
14256
  position = stat.size;
13934
14257
  process.stdout.write(buf);
@@ -13943,7 +14266,7 @@ async function defaultTailDaemonLog(opts) {
13943
14266
  }
13944
14267
  };
13945
14268
  try {
13946
- watcher = fs6.watch(paths.logPath, { persistent: true }, () => {
14269
+ watcher = fs7.watch(paths.logPath, { persistent: true }, () => {
13947
14270
  drain();
13948
14271
  });
13949
14272
  } catch {
@@ -14147,8 +14470,8 @@ function parsePairedRunner(raw) {
14147
14470
 
14148
14471
  // src/app/entry/gatewayCommand.ts
14149
14472
  import { spawn as spawn2 } from "child_process";
14150
- import fs7 from "fs";
14151
- import path7 from "path";
14473
+ import fs8 from "fs";
14474
+ import path8 from "path";
14152
14475
  import { fileURLToPath as fileURLToPath2 } from "url";
14153
14476
  var USAGE5 = `Usage: athena-flow gateway <subcommand> [--json]
14154
14477
 
@@ -14167,12 +14490,12 @@ Subcommands:
14167
14490
  reload-channels Reload channel sidecars without restarting the daemon.
14168
14491
  `;
14169
14492
  function defaultResolveDaemonEntry() {
14170
- const here = path7.dirname(fileURLToPath2(import.meta.url));
14171
- return path7.resolve(here, "athena-gateway.js");
14493
+ const here = path8.dirname(fileURLToPath2(import.meta.url));
14494
+ return path8.resolve(here, "athena-gateway.js");
14172
14495
  }
14173
14496
  function readToken(tokenPath) {
14174
14497
  try {
14175
- return fs7.readFileSync(tokenPath, "utf-8").trim();
14498
+ return fs8.readFileSync(tokenPath, "utf-8").trim();
14176
14499
  } catch (err) {
14177
14500
  const code = err.code;
14178
14501
  if (code === "ENOENT") {
@@ -14522,9 +14845,9 @@ import process7 from "process";
14522
14845
 
14523
14846
  // src/harnesses/claude/system/doctorEnvironment.ts
14524
14847
  import { execFileSync } from "child_process";
14525
- import * as fs8 from "fs";
14848
+ import * as fs9 from "fs";
14526
14849
  import * as os6 from "os";
14527
- import * as path8 from "path";
14850
+ import * as path9 from "path";
14528
14851
  var MANAGED_POLICY_KEYS = [
14529
14852
  "forceLoginMethod",
14530
14853
  "forceLoginOrgUUID",
@@ -14628,8 +14951,8 @@ function collectEnvironment(options = {}) {
14628
14951
  const detectVersion = options.detectClaudeVersionFn ?? detectClaudeVersion;
14629
14952
  const runAuthStatus = options.runClaudeAuthStatusFn ?? runClaudeAuthStatus;
14630
14953
  const resolveForwarder = options.resolveHookForwarderCommandFn ?? resolveHookForwarderCommand;
14631
- const statFn = options.statFn ?? ((p) => fs8.statSync(p));
14632
- const readFileFn = options.readFileFn ?? ((p) => fs8.readFileSync(p, "utf8"));
14954
+ const statFn = options.statFn ?? ((p) => fs9.statSync(p));
14955
+ const readFileFn = options.readFileFn ?? ((p) => fs9.readFileSync(p, "utf8"));
14633
14956
  const settingsPaths = resolveClaudeSettingsSurfacePaths(
14634
14957
  homeDir,
14635
14958
  cwd,
@@ -14674,7 +14997,7 @@ function collectEnvironment(options = {}) {
14674
14997
  });
14675
14998
  let globalConfigPresent = false;
14676
14999
  try {
14677
- statFn(path8.join(homeDir, ".claude.json"));
15000
+ statFn(path9.join(homeDir, ".claude.json"));
14678
15001
  globalConfigPresent = true;
14679
15002
  } catch {
14680
15003
  globalConfigPresent = false;
@@ -15083,15 +15406,15 @@ async function runDoctorCommand(options) {
15083
15406
  }
15084
15407
 
15085
15408
  // src/app/entry/cli.tsx
15086
- import { jsx as jsx25 } from "react/jsx-runtime";
15409
+ import { jsx as jsx24 } from "react/jsx-runtime";
15087
15410
  function resolvePackageJsonPath(entryUrl) {
15088
- let currentDir = path9.dirname(fileURLToPath3(entryUrl));
15411
+ let currentDir = path10.dirname(fileURLToPath3(entryUrl));
15089
15412
  for (; ; ) {
15090
- const candidatePath = path9.join(currentDir, "package.json");
15091
- if (fs9.existsSync(candidatePath)) {
15413
+ const candidatePath = path10.join(currentDir, "package.json");
15414
+ if (fs10.existsSync(candidatePath)) {
15092
15415
  return candidatePath;
15093
15416
  }
15094
- const parentDir = path9.dirname(currentDir);
15417
+ const parentDir = path10.dirname(currentDir);
15095
15418
  if (parentDir === currentDir) {
15096
15419
  throw new Error("Could not locate package.json for CLI metadata.");
15097
15420
  }
@@ -15106,6 +15429,8 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
15106
15429
  "resume",
15107
15430
  "exec",
15108
15431
  "workflow",
15432
+ "mcp",
15433
+ "skill",
15109
15434
  "marketplace",
15110
15435
  "channel",
15111
15436
  "gateway",
@@ -15182,6 +15507,38 @@ function printExecDryRunSummary(runtimeConfig, context) {
15182
15507
  lines.push(
15183
15508
  ` plugin mcp config: ${runtimeConfig.pluginMcpConfig ?? "<none>"}`
15184
15509
  );
15510
+ const mcpLabel = "personal mcp servers:";
15511
+ const skillLabel = "personal skills:";
15512
+ const personalLabelWidth = mcpLabel.length;
15513
+ lines.push(" personal capabilities:");
15514
+ if (runtimeConfig.personalMcpServers.length === 0) {
15515
+ lines.push(` ${mcpLabel.padEnd(personalLabelWidth)} <none>`);
15516
+ } else {
15517
+ lines.push(` ${mcpLabel}`);
15518
+ for (const server of runtimeConfig.personalMcpServers) {
15519
+ lines.push(` - ${server.name} [${server.sourceLayer}]`);
15520
+ }
15521
+ }
15522
+ if (runtimeConfig.personalSkills.length === 0) {
15523
+ lines.push(` ${skillLabel.padEnd(personalLabelWidth)} <none>`);
15524
+ } else {
15525
+ lines.push(` ${skillLabel}`);
15526
+ for (const skill of runtimeConfig.personalSkills) {
15527
+ lines.push(` - ${skill.name} [${skill.sourceLayer}]`);
15528
+ }
15529
+ }
15530
+ const { mcpServers: conflictMcp, skills: conflictSkills } = runtimeConfig.capabilityConflicts;
15531
+ if (conflictMcp.length === 0 && conflictSkills.length === 0) {
15532
+ lines.push(" conflicts (shadowed by workflow plugin): <none>");
15533
+ } else {
15534
+ lines.push(" conflicts (shadowed by workflow plugin):");
15535
+ for (const server of conflictMcp) {
15536
+ lines.push(` - ${server.name} [${server.sourceLayer}]`);
15537
+ }
15538
+ for (const skill of conflictSkills) {
15539
+ lines.push(` - ${skill.name} [${skill.sourceLayer}]`);
15540
+ }
15541
+ }
15185
15542
  for (const line of lines) {
15186
15543
  console.log(line);
15187
15544
  }
@@ -15212,6 +15569,8 @@ var cli = meow(
15212
15569
  resume [sessionId] Resume most recent (or specified) session
15213
15570
  exec "<prompt>" Run non-interactively (CI/script mode)
15214
15571
  workflow <sub> Manage workflows (install, list, search, remove, upgrade, use)
15572
+ mcp <sub> Manage personal MCP servers (add, remove, list)
15573
+ skill <sub> Manage personal skills (install, remove, list)
15215
15574
  marketplace <sub> Manage marketplace sources (add, refresh, remove, list)
15216
15575
  channel <sub> Manage external channels
15217
15576
  dashboard <sub> Manage dashboard pairing and runtime daemon (pair, status, daemon, unpair)
@@ -15394,6 +15753,10 @@ var cli = meow(
15394
15753
  type: "boolean",
15395
15754
  default: false
15396
15755
  },
15756
+ env: {
15757
+ type: "string",
15758
+ isMultiple: true
15759
+ },
15397
15760
  printApiKey: {
15398
15761
  type: "boolean",
15399
15762
  default: false
@@ -15405,7 +15768,7 @@ var cli = meow(
15405
15768
  }
15406
15769
  );
15407
15770
  async function main() {
15408
- const projectDir = path9.resolve(cli.flags.projectDir);
15771
+ const projectDir = path10.resolve(cli.flags.projectDir);
15409
15772
  const [command, ...commandArgs] = cli.input;
15410
15773
  if (command && !KNOWN_COMMANDS.has(command)) {
15411
15774
  console.error(
@@ -15449,9 +15812,9 @@ Available commands: ${[...KNOWN_COMMANDS].join(", ")}`
15449
15812
  await exitWith(1);
15450
15813
  return;
15451
15814
  }
15452
- const { default: WorkflowInstallWizard } = await import("./WorkflowInstallWizard-IMU47QWB.js");
15815
+ const { default: WorkflowInstallWizard } = await import("./WorkflowInstallWizard-5FENJHBW.js");
15453
15816
  const { waitUntilExit } = render(
15454
- /* @__PURE__ */ jsx25(
15817
+ /* @__PURE__ */ jsx24(
15455
15818
  WorkflowInstallWizard,
15456
15819
  {
15457
15820
  source: resolvedSource,
@@ -15470,6 +15833,40 @@ Available commands: ${[...KNOWN_COMMANDS].join(", ")}`
15470
15833
  );
15471
15834
  return;
15472
15835
  }
15836
+ if (command === "mcp") {
15837
+ const rawArgs = process.argv.slice(2);
15838
+ const dashIdx = rawArgs.indexOf("--");
15839
+ const serverCommandTokens = dashIdx >= 0 ? rawArgs.slice(dashIdx + 1) : [];
15840
+ const cleanArgs = serverCommandTokens.length > 0 ? commandArgs.slice(0, commandArgs.length - serverCommandTokens.length) : commandArgs;
15841
+ const [subcommand = "", ...subcommandArgs] = cleanArgs;
15842
+ if (cli.flags.project) subcommandArgs.push("--project");
15843
+ if (cli.flags.global) subcommandArgs.push("--global");
15844
+ for (const entry of cli.flags.env ?? []) {
15845
+ subcommandArgs.push("--env", entry);
15846
+ }
15847
+ await exitWith(
15848
+ runMcpCommand({
15849
+ subcommand,
15850
+ subcommandArgs,
15851
+ serverCommandTokens,
15852
+ projectDir
15853
+ })
15854
+ );
15855
+ return;
15856
+ }
15857
+ if (command === "skill") {
15858
+ const [subcommand = "", ...subcommandArgs] = commandArgs;
15859
+ if (cli.flags.project) subcommandArgs.push("--project");
15860
+ if (cli.flags.global) subcommandArgs.push("--global");
15861
+ await exitWith(
15862
+ runSkillCommand({
15863
+ subcommand,
15864
+ subcommandArgs,
15865
+ projectDir
15866
+ })
15867
+ );
15868
+ return;
15869
+ }
15473
15870
  if (command === "marketplace") {
15474
15871
  const [subcommand = "", ...subcommandArgs] = commandArgs;
15475
15872
  await exitWith(runMarketplaceCommand({ subcommand, subcommandArgs }));
@@ -15596,8 +15993,8 @@ Available commands: ${[...KNOWN_COMMANDS].join(", ")}`
15596
15993
  const showSetup = command === "exec" ? false : shouldShowSetup({
15597
15994
  cliInput: cli.input,
15598
15995
  setupComplete: globalConfig.setupComplete,
15599
- globalConfigExists: fs9.existsSync(
15600
- path9.join(os7.homedir(), ".config", "athena", "config.json")
15996
+ globalConfigExists: fs10.existsSync(
15997
+ path10.join(os7.homedir(), ".config", "athena", "config.json")
15601
15998
  )
15602
15999
  });
15603
16000
  let runtimeConfig;
@@ -15690,7 +16087,7 @@ Available commands: ${[...KNOWN_COMMANDS].join(", ")}`
15690
16087
  const { athenaSessionId, initialSessionId } = interactiveSession;
15691
16088
  const instanceId = process.pid;
15692
16089
  render(
15693
- /* @__PURE__ */ jsx25(
16090
+ /* @__PURE__ */ jsx24(
15694
16091
  App,
15695
16092
  {
15696
16093
  projectDir,