thoth-agents 0.2.10 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +21 -0
  3. package/README.md +301 -311
  4. package/dist/agents/configured-role-prompt.d.ts +9 -0
  5. package/dist/agents/prompt-sections.d.ts +8 -4
  6. package/dist/agents/prompt-utils.d.ts +0 -4
  7. package/dist/{chunk-YYVE7YHR.js → chunk-2MZ5C2RN.js} +1755 -1760
  8. package/dist/chunk-XO74DXBZ.js +1781 -0
  9. package/dist/{chunk-MF5NNCPC.js → chunk-YUCGIJPP.js} +12 -30
  10. package/dist/cli/claude-code-install.d.ts +24 -26
  11. package/dist/cli/claude-code-paths.d.ts +0 -28
  12. package/dist/cli/codex-install.d.ts +2 -2
  13. package/dist/cli/codex-paths.d.ts +0 -2
  14. package/dist/cli/config-io.d.ts +5 -0
  15. package/dist/cli/index.js +294 -133
  16. package/dist/cli/install.d.ts +5 -1
  17. package/dist/cli/model-catalog/cache.d.ts +1 -1
  18. package/dist/cli/operations/claude-code.d.ts +6 -3
  19. package/dist/cli/operations/codex.d.ts +2 -1
  20. package/dist/cli/operations/opencode.d.ts +2 -1
  21. package/dist/cli/operations/types.d.ts +11 -1
  22. package/dist/cli/package-root.d.ts +1 -0
  23. package/dist/cli/providers.d.ts +6 -116
  24. package/dist/cli/skills.d.ts +19 -32
  25. package/dist/cli/thoth-mem-install.d.ts +45 -0
  26. package/dist/cli/tui/components/StatusView.d.ts +12 -1
  27. package/dist/cli/tui/index.js +293 -106
  28. package/dist/cli/tui/operations.d.ts +4 -3
  29. package/dist/cli/types.d.ts +0 -10
  30. package/dist/config/constants.d.ts +20 -16
  31. package/dist/config/index.d.ts +0 -1
  32. package/dist/config/loader.d.ts +1 -1
  33. package/dist/config/schema.d.ts +2 -38
  34. package/dist/config/utils.d.ts +1 -2
  35. package/dist/harness/adapters/codex-surfaces.d.ts +3 -3
  36. package/dist/harness/core/agent-pack.d.ts +37 -29
  37. package/dist/harness/core/memory-governance.d.ts +24 -48
  38. package/dist/harness/core/sdd.d.ts +364 -131
  39. package/dist/harness/generate-integration-packages.d.ts +20 -0
  40. package/dist/harness/opencode-init-command.d.ts +11 -0
  41. package/dist/harness/types.d.ts +14 -1
  42. package/dist/harness/writers/claude-code-subagent.d.ts +3 -1
  43. package/dist/hooks/index.d.ts +0 -5
  44. package/dist/index.js +562 -1314
  45. package/dist/mcp/index.d.ts +1 -2
  46. package/package.json +17 -12
  47. package/plugin/.claude-plugin/.thoth-agents-plugin-assets.json +50 -0
  48. package/plugin/.claude-plugin/plugin.json +8 -0
  49. package/plugin/.codex-plugin/.thoth-agents-plugin-assets.json +16 -0
  50. package/plugin/.codex-plugin/plugin.json +7 -0
  51. package/plugin/.mcp.json +19 -0
  52. package/plugin/agents/deep.md +89 -0
  53. package/plugin/agents/designer.md +89 -0
  54. package/plugin/agents/explorer.md +90 -0
  55. package/plugin/agents/librarian.md +90 -0
  56. package/plugin/agents/oracle.md +92 -0
  57. package/plugin/agents/orchestrator.md +128 -0
  58. package/plugin/agents/quick.md +89 -0
  59. package/plugin/codex.mcp.json +17 -0
  60. package/plugin/settings.json +3 -0
  61. package/plugin/skills/thoth-archive/SKILL.md +40 -0
  62. package/plugin/skills/thoth-archive/scripts/archive.mjs +748 -0
  63. package/plugin/skills/thoth-constitution/SKILL.md +45 -0
  64. package/plugin/skills/thoth-constitution/scripts/validate.mjs +167 -0
  65. package/plugin/skills/thoth-constitution/templates/constitution.md +54 -0
  66. package/plugin/skills/thoth-init/SKILL.md +30 -0
  67. package/plugin/skills/thoth-init/scripts/init.mjs +141 -0
  68. package/plugin/skills/thoth-sdd/SKILL.md +83 -0
  69. package/plugin/skills/thoth-sdd/references/phases/analyze.md +21 -0
  70. package/plugin/skills/thoth-sdd/references/phases/checklist.md +20 -0
  71. package/plugin/skills/thoth-sdd/references/phases/clarify.md +15 -0
  72. package/plugin/skills/thoth-sdd/references/phases/converge.md +14 -0
  73. package/plugin/skills/thoth-sdd/references/phases/explore.md +10 -0
  74. package/plugin/skills/thoth-sdd/references/phases/implement.md +19 -0
  75. package/plugin/skills/thoth-sdd/references/phases/plan.md +15 -0
  76. package/plugin/skills/thoth-sdd/references/phases/specify.md +21 -0
  77. package/plugin/skills/thoth-sdd/references/phases/tasks.md +20 -0
  78. package/plugin/skills/thoth-sdd/references/phases/verify.md +22 -0
  79. package/plugin/skills/thoth-sdd/scripts/validate.mjs +1117 -0
  80. package/plugin/skills/thoth-sdd/templates/archive-report.md +25 -0
  81. package/plugin/skills/thoth-sdd/templates/checklist.md +27 -0
  82. package/plugin/skills/thoth-sdd/templates/plan.md +38 -0
  83. package/plugin/skills/thoth-sdd/templates/spec.md +54 -0
  84. package/plugin/skills/thoth-sdd/templates/tasks.md +29 -0
  85. package/plugin/skills/thoth-sdd/templates/verify-report.md +28 -0
  86. package/skills/README.md +12 -0
  87. package/skills/thoth-archive/SKILL.md +40 -0
  88. package/skills/thoth-archive/scripts/archive.mjs +748 -0
  89. package/skills/thoth-constitution/SKILL.md +45 -0
  90. package/skills/thoth-constitution/scripts/validate.mjs +167 -0
  91. package/skills/thoth-constitution/templates/constitution.md +54 -0
  92. package/skills/thoth-init/SKILL.md +30 -0
  93. package/skills/thoth-init/scripts/init.mjs +141 -0
  94. package/skills/thoth-sdd/SKILL.md +83 -0
  95. package/skills/thoth-sdd/references/phases/analyze.md +21 -0
  96. package/skills/thoth-sdd/references/phases/checklist.md +20 -0
  97. package/skills/thoth-sdd/references/phases/clarify.md +15 -0
  98. package/skills/thoth-sdd/references/phases/converge.md +14 -0
  99. package/skills/thoth-sdd/references/phases/explore.md +10 -0
  100. package/skills/thoth-sdd/references/phases/implement.md +19 -0
  101. package/skills/thoth-sdd/references/phases/plan.md +15 -0
  102. package/skills/thoth-sdd/references/phases/specify.md +21 -0
  103. package/skills/thoth-sdd/references/phases/tasks.md +20 -0
  104. package/skills/thoth-sdd/references/phases/verify.md +22 -0
  105. package/skills/thoth-sdd/scripts/validate.mjs +1117 -0
  106. package/skills/thoth-sdd/templates/archive-report.md +25 -0
  107. package/skills/thoth-sdd/templates/checklist.md +27 -0
  108. package/skills/thoth-sdd/templates/plan.md +38 -0
  109. package/skills/thoth-sdd/templates/spec.md +54 -0
  110. package/skills/thoth-sdd/templates/tasks.md +29 -0
  111. package/skills/thoth-sdd/templates/verify-report.md +28 -0
  112. package/thoth-agents.schema.json +0 -39
  113. package/dist/chunk-WBRGPRRB.js +0 -2353
  114. package/dist/cli/custom-skills.d.ts +0 -48
  115. package/dist/cli/skill-manifest.d.ts +0 -32
  116. package/dist/harness/core/skills.d.ts +0 -211
  117. package/dist/harness/generate-codex-plugin.d.ts +0 -9
  118. package/dist/harness/writers/claude-code-skill-layout.d.ts +0 -16
  119. package/dist/harness/writers/fs-skill-collect.d.ts +0 -7
  120. package/dist/harness/writers/skill-layout.d.ts +0 -16
  121. package/dist/hooks/chat-headers.d.ts +0 -16
  122. package/dist/hooks/phase-reminder/index.d.ts +0 -28
  123. package/dist/hooks/post-read-nudge/index.d.ts +0 -18
  124. package/dist/hooks/skill-sync.d.ts +0 -10
  125. package/dist/hooks/thoth-mem/index.d.ts +0 -46
  126. package/dist/hooks/thoth-mem/protocol.d.ts +0 -7
  127. package/dist/mcp/thoth.d.ts +0 -3
  128. package/dist/sdd/artifact-governance/artifact-loader.d.ts +0 -130
  129. package/dist/sdd/artifact-governance/index.d.ts +0 -6
  130. package/dist/sdd/artifact-governance/tasks-validator.d.ts +0 -17
  131. package/dist/sdd/artifact-governance/types.d.ts +0 -52
  132. package/dist/thoth/client.d.ts +0 -14
  133. package/dist/thoth/index.d.ts +0 -2
  134. package/src/skills/_shared/openspec-convention.md +0 -350
  135. package/src/skills/_shared/persistence-contract.md +0 -163
  136. package/src/skills/_shared/thoth-mem-convention.md +0 -123
  137. package/src/skills/executing-plans/SKILL.md +0 -288
  138. package/src/skills/plan-reviewer/SKILL.md +0 -219
  139. package/src/skills/requirements-interview/SKILL.md +0 -233
  140. package/src/skills/sdd-apply/SKILL.md +0 -89
  141. package/src/skills/sdd-archive/SKILL.md +0 -92
  142. package/src/skills/sdd-clarify/SKILL.md +0 -105
  143. package/src/skills/sdd-constitution/SKILL.md +0 -107
  144. package/src/skills/sdd-design/SKILL.md +0 -155
  145. package/src/skills/sdd-init/SKILL.md +0 -233
  146. package/src/skills/sdd-propose/SKILL.md +0 -101
  147. package/src/skills/sdd-spec/SKILL.md +0 -136
  148. package/src/skills/sdd-tasks/SKILL.md +0 -232
  149. package/src/skills/sdd-verify/SKILL.md +0 -131
  150. package/src/skills/thoth-mem-agents/SKILL.md +0 -210
@@ -2,15 +2,15 @@ import {
2
2
  defaultTuiOperations,
3
3
  effortChoicesForModel,
4
4
  listOperationHarnesses
5
- } from "../../chunk-YYVE7YHR.js";
6
- import "../../chunk-WBRGPRRB.js";
5
+ } from "../../chunk-2MZ5C2RN.js";
6
+ import "../../chunk-XO74DXBZ.js";
7
7
 
8
8
  // src/cli/tui/index.tsx
9
9
  import { render } from "ink";
10
10
 
11
11
  // src/cli/tui/App.tsx
12
12
  import { Box as Box8, Text as Text8, useApp, useInput } from "ink";
13
- import { useMemo, useRef, useState } from "react";
13
+ import { useEffect, useMemo, useRef, useState } from "react";
14
14
 
15
15
  // src/cli/tui/components/Header.tsx
16
16
  import { Box, Text } from "ink";
@@ -233,7 +233,7 @@ function ModelScreen({
233
233
  }
234
234
 
235
235
  // src/cli/tui/components/PlanPreview.tsx
236
- import { Box as Box6, Text as Text6 } from "ink";
236
+ import { Box as Box7, Text as Text7 } from "ink";
237
237
 
238
238
  // src/cli/tui/components/PathLine.tsx
239
239
  import { Box as Box5, Text as Text5 } from "ink";
@@ -253,81 +253,51 @@ function PathLine({ label, value, width }) {
253
253
  return /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: lines.map((line, index) => /* @__PURE__ */ jsx5(Text5, { color: theme.dim, children: index === 0 ? `${label ? `${label}: ` : ""}${line}` : ` ${line}` }, line)) });
254
254
  }
255
255
 
256
- // src/cli/tui/components/PlanPreview.tsx
257
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
258
- function PlanPreview({
259
- plan,
260
- selectedAction,
261
- result
256
+ // src/cli/tui/components/StatusView.tsx
257
+ import { Box as Box6, Text as Text6 } from "ink";
258
+ import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
259
+ var unsupportedEvidence = {
260
+ state: "unsupported",
261
+ source: "none",
262
+ basis: []
263
+ };
264
+ function ProviderCapabilityView({
265
+ evidence,
266
+ loading = false,
267
+ error,
268
+ showHeading = true
262
269
  }) {
270
+ const capability = evidence ?? unsupportedEvidence;
263
271
  return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
264
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: plan.title }),
265
- /* @__PURE__ */ jsx6(Text6, { children: plan.summary }),
266
- /* @__PURE__ */ jsxs5(Text6, { children: [
267
- "Target harness: ",
268
- /* @__PURE__ */ jsx6(Text6, { color: theme.accent, children: plan.harness })
269
- ] }),
270
- /* @__PURE__ */ jsxs5(Text6, { children: [
271
- "Action: ",
272
- plan.action
273
- ] }),
274
- /* @__PURE__ */ jsxs5(Text6, { children: [
275
- "Can apply: ",
276
- plan.canApply ? "yes" : "no"
277
- ] }),
278
- plan.surfaces.length > 0 ? /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Managed surfaces" }) : null,
279
- plan.surfaces.map((surface) => /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
272
+ showHeading ? /* @__PURE__ */ jsx6(Text6, { color: theme.accent, children: "Provider capability" }) : null,
273
+ loading ? /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Loading provider capability evidence\u2026" }) : error ? /* @__PURE__ */ jsxs5(Fragment, { children: [
274
+ /* @__PURE__ */ jsxs5(Text6, { color: theme.warning, children: [
275
+ "Provider evidence unavailable: ",
276
+ error
277
+ ] }),
278
+ /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Press r to retry provider evidence." })
279
+ ] }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
280
280
  /* @__PURE__ */ jsxs5(Text6, { children: [
281
- "- ",
282
- surface.label
281
+ "Provider capability:",
282
+ " ",
283
+ /* @__PURE__ */ jsx6(Text6, { color: stateColor(capability.state), children: capability.state })
283
284
  ] }),
284
- surface.path ? /* @__PURE__ */ jsx6(PathLine, { value: surface.path }) : null
285
- ] }, surface.id)),
286
- /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
287
- "Backup: ",
288
- plan.backup.required ? "required" : "not required",
289
- " (",
290
- plan.backup.strategy,
291
- ")"
292
- ] }),
293
- plan.backup.destinations?.map((path) => /* @__PURE__ */ jsx6(PathLine, { label: path.label, value: path.path }, path.path)),
294
- plan.items.length > 0 ? /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Preview" }) : null,
295
- plan.items.slice(0, 5).map((item) => /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
296
285
  /* @__PURE__ */ jsxs5(Text6, { children: [
297
- "- ",
298
- item.title
286
+ "Evidence source:",
287
+ " ",
288
+ /* @__PURE__ */ jsx6(Text6, { color: theme.accent, children: capability.source })
299
289
  ] }),
300
- item.target.path ? /* @__PURE__ */ jsx6(PathLine, { value: item.target.path }) : null,
301
- item.preview ? /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: item.preview.length > 120 ? `${item.preview.slice(0, 120)}...` : item.preview }) : null
302
- ] }, item.title)),
303
- plan.items.length > 5 ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
304
- "...",
305
- plan.items.length - 5,
306
- " more items"
307
- ] }) : null,
308
- plan.warnings.map((warning) => /* @__PURE__ */ jsxs5(Text6, { color: theme.warning, children: [
309
- "- [",
310
- warning.severity,
311
- "] ",
312
- warning.message
313
- ] }, warning.code ?? warning.message)),
314
- plan.disclaimers.map((disclaimer) => /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
315
- "- ",
316
- disclaimer.message
317
- ] }, disclaimer.code ?? disclaimer.message)),
318
- /* @__PURE__ */ jsxs5(Box6, { marginTop: 1, children: [
319
- /* @__PURE__ */ jsx6(Text6, { color: selectedAction === "apply" ? theme.accent : void 0, children: "[Apply]" }),
320
- /* @__PURE__ */ jsx6(Text6, { children: " " }),
321
- /* @__PURE__ */ jsx6(Text6, { color: selectedAction === "cancel" ? theme.accent : void 0, children: "[Cancel]" })
322
- ] }),
323
- /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Enter selects. a applies. c cancels." }),
324
- result ? /* @__PURE__ */ jsx6(Text6, { color: result.applied ? theme.ok : theme.warning, children: result.summary }) : null
290
+ capability.basis.length > 0 ? /* @__PURE__ */ jsxs5(Fragment, { children: [
291
+ /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Evidence basis" }),
292
+ capability.basis.map((basis) => /* @__PURE__ */ jsxs5(Text6, { children: [
293
+ "- ",
294
+ basis
295
+ ] }, basis))
296
+ ] }) : /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "No provider or harness evidence was supplied." }),
297
+ capability.state !== "supported" ? /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Refer to the installed provider guidance for authoritative capability details." }) : null
298
+ ] })
325
299
  ] });
326
300
  }
327
-
328
- // src/cli/tui/components/StatusView.tsx
329
- import { Box as Box7, Text as Text7 } from "ink";
330
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
331
301
  function countByState(report) {
332
302
  return report.targets.reduce(
333
303
  (counts, target) => {
@@ -348,10 +318,23 @@ var categoryOrder = [
348
318
  "Model state",
349
319
  "Other"
350
320
  ];
321
+ function titleCasePart(part) {
322
+ const normalized = part.toLowerCase();
323
+ switch (normalized) {
324
+ case "sdd":
325
+ return "SDD";
326
+ case "cli":
327
+ return "CLI";
328
+ case "mcp":
329
+ return "MCP";
330
+ case "opencode":
331
+ return "OpenCode";
332
+ default:
333
+ return `${part.charAt(0).toUpperCase()}${part.slice(1).toLowerCase()}`;
334
+ }
335
+ }
351
336
  function titleCase(value, separator = " ") {
352
- return value.split(/[-_\s]+/).filter(Boolean).map(
353
- (part) => part.toLowerCase() === "sdd" ? "SDD" : part.toLowerCase() === "cli" ? "CLI" : part.toLowerCase() === "mcp" ? "MCP" : part.toLowerCase() === "opencode" ? "OpenCode" : `${part.charAt(0).toUpperCase()}${part.slice(1).toLowerCase()}`
354
- ).join(separator);
337
+ return value.split(/[-_\s]+/).filter(Boolean).map(titleCasePart).join(separator);
355
338
  }
356
339
  function compactPath(path) {
357
340
  return path.replaceAll("\\", "/");
@@ -359,45 +342,56 @@ function compactPath(path) {
359
342
  function categorizeTarget(target) {
360
343
  const path = target.path ? compactPath(target.path) : "";
361
344
  const label = target.label ?? target.kind;
345
+ const detail = target.state !== "installed" ? target.observed : void 0;
362
346
  const agent = path.match(/thoth-agents-([a-z0-9_-]+)\.toml$/i);
363
347
  const skill = path.match(/skills\/([^/]+)\/SKILL\.md$/i);
364
348
  if (agent?.[1]) {
365
349
  return {
366
350
  category: "Agents",
367
351
  label: titleCase(agent[1]),
368
- state: target.state
352
+ state: target.state,
353
+ detail
369
354
  };
370
355
  }
371
356
  if (skill?.[1] || target.kind === "skill") {
372
357
  return {
373
358
  category: "Skills",
374
- label: titleCase(skill?.[1] ?? label, "-"),
375
- state: target.state
359
+ label: skill?.[1] ? titleCase(skill[1], "-") : label,
360
+ state: target.state,
361
+ detail
376
362
  };
377
363
  }
378
364
  if (/marketplace\.json$/i.test(path)) {
379
365
  return {
380
366
  category: "Marketplace",
381
367
  label: "Marketplace",
382
- state: target.state
368
+ state: target.state,
369
+ detail
383
370
  };
384
371
  }
385
372
  if (/\.mcp\.json$/i.test(path) || /plugin\.json$/i.test(path) || /plugin-assets/i.test(path) || /manifest/i.test(path)) {
386
373
  return {
387
374
  category: "Plugin/MCP",
388
375
  label: titleCase(label.replace(/^codex\s+/i, "")),
389
- state: target.state
376
+ state: target.state,
377
+ detail
390
378
  };
391
379
  }
392
380
  if (/AGENTS\.md$/i.test(path) || /root instructions/i.test(label)) {
393
381
  return {
394
382
  category: "Root instructions",
395
383
  label: "AGENTS.md",
396
- state: target.state
384
+ state: target.state,
385
+ detail
397
386
  };
398
387
  }
399
388
  if (/config\.toml$/i.test(path) || target.kind === "config") {
400
- return { category: "Config", label: titleCase(label), state: target.state };
389
+ return {
390
+ category: "Config",
391
+ label: titleCase(label),
392
+ state: target.state,
393
+ detail
394
+ };
401
395
  }
402
396
  if (target.kind === "memory-state" || /model/i.test(label)) {
403
397
  return {
@@ -433,7 +427,12 @@ function uniqueTargets(targets) {
433
427
  return true;
434
428
  });
435
429
  }
436
- function StatusView({ report }) {
430
+ function StatusView({
431
+ report,
432
+ providerEvidence = report.providerCapability,
433
+ providerEvidenceLoading = false,
434
+ providerEvidenceError
435
+ }) {
437
436
  const counts = countByState(report);
438
437
  const countText = Object.entries(counts).map(([state, count]) => `${state}: ${count}`).join(" ");
439
438
  const grouped = groupedTargets(report);
@@ -441,68 +440,92 @@ function StatusView({ report }) {
441
440
  const hiddenWarnings = report.diagnostics.length - warnings.length;
442
441
  const notes = (report.disclaimers ?? []).slice(0, 2);
443
442
  const hiddenNotes = (report.disclaimers?.length ?? 0) - notes.length;
444
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
445
- /* @__PURE__ */ jsxs6(Text7, { children: [
446
- "State: ",
447
- /* @__PURE__ */ jsx7(Text7, { color: stateColor(report.state), children: report.state })
443
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
444
+ /* @__PURE__ */ jsxs5(Text6, { children: [
445
+ "Consumer-managed state:",
446
+ " ",
447
+ /* @__PURE__ */ jsx6(Text6, { color: stateColor(report.state), children: report.state })
448
448
  ] }),
449
- /* @__PURE__ */ jsx7(Text7, { children: report.summary }),
450
- /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: countText || "No managed targets." }),
451
- /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
449
+ /* @__PURE__ */ jsx6(Text6, { children: report.summary }),
450
+ /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: countText || "No managed targets." }),
451
+ /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
452
452
  "Warnings: ",
453
453
  report.diagnostics.length,
454
454
  " Notes:",
455
455
  " ",
456
456
  report.disclaimers?.length ?? 0
457
457
  ] }),
458
+ /* @__PURE__ */ jsx6(
459
+ ProviderCapabilityView,
460
+ {
461
+ evidence: providerEvidence,
462
+ loading: providerEvidenceLoading,
463
+ error: providerEvidenceError
464
+ }
465
+ ),
466
+ report.actions.some((action) => action.supported === false) ? /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
467
+ /* @__PURE__ */ jsx6(Text6, { color: theme.warning, children: "Unavailable provider-dependent actions" }),
468
+ report.actions.filter((action) => action.supported === false).map((action) => /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
469
+ /* @__PURE__ */ jsxs5(Text6, { children: [
470
+ action.label,
471
+ ": unavailable"
472
+ ] }),
473
+ action.disabledReason ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
474
+ "- ",
475
+ action.disabledReason
476
+ ] }) : null
477
+ ] }, action.id))
478
+ ] }) : null,
458
479
  categoryOrder.map((category) => {
459
480
  const targets = uniqueTargets(grouped.get(category) ?? []);
460
481
  if (targets.length === 0) return null;
461
482
  const visible = targets.slice(0, 6);
462
483
  const hidden = targets.length - visible.length;
463
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
464
- /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: category }),
465
- visible.map((target) => /* @__PURE__ */ jsxs6(Text7, { children: [
484
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
485
+ /* @__PURE__ */ jsx6(Text6, { color: theme.accent, children: category }),
486
+ visible.map((target) => /* @__PURE__ */ jsxs5(Text6, { children: [
466
487
  "- ",
467
488
  target.label,
468
- target.state ? /* @__PURE__ */ jsxs6(Text7, { color: stateColor(target.state), children: [
489
+ target.state ? /* @__PURE__ */ jsxs5(Text6, { color: stateColor(target.state), children: [
469
490
  ": [",
470
491
  target.state,
471
492
  "]"
472
493
  ] }) : null,
473
- target.detail ? /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
494
+ target.detail ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
474
495
  " - ",
475
496
  target.detail
476
497
  ] }) : null
477
498
  ] }, `${category}-${target.label}-${target.state}`)),
478
- hidden > 0 ? /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
499
+ hidden > 0 ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
479
500
  " +",
480
501
  hidden,
481
502
  " more"
482
503
  ] }) : null
483
504
  ] }, category);
484
505
  }),
485
- report.diagnostics.length > 0 ? /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
486
- /* @__PURE__ */ jsx7(Text7, { color: theme.warning, children: "Warnings" }),
487
- warnings.map((warning) => /* @__PURE__ */ jsxs6(Text7, { color: theme.warning, children: [
506
+ report.diagnostics.length > 0 ? /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
507
+ /* @__PURE__ */ jsx6(Text6, { color: theme.warning, children: "Warnings" }),
508
+ warnings.map((warning) => /* @__PURE__ */ jsxs5(Text6, { color: theme.warning, children: [
488
509
  "- [",
489
510
  warning.severity,
490
- "] ",
511
+ "]",
512
+ warning.code ? ` [${warning.code}]` : "",
513
+ " ",
491
514
  warning.message
492
515
  ] }, warning.code ?? warning.message)),
493
- hiddenWarnings > 0 ? /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
516
+ hiddenWarnings > 0 ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
494
517
  " +",
495
518
  hiddenWarnings,
496
519
  " more warnings"
497
520
  ] }) : null
498
521
  ] }) : null,
499
- notes.length > 0 ? /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
500
- /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "Notes" }),
501
- notes.map((note) => /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
522
+ notes.length > 0 ? /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
523
+ /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "Notes" }),
524
+ notes.map((note) => /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
502
525
  "- ",
503
526
  note.message
504
527
  ] }, note.code ?? note.message)),
505
- hiddenNotes > 0 ? /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
528
+ hiddenNotes > 0 ? /* @__PURE__ */ jsxs5(Text6, { color: theme.dim, children: [
506
529
  " +",
507
530
  hiddenNotes,
508
531
  " more notes"
@@ -511,6 +534,134 @@ function StatusView({ report }) {
511
534
  ] });
512
535
  }
513
536
 
537
+ // src/cli/tui/components/PlanPreview.tsx
538
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
539
+ function targetText(target) {
540
+ const label = target.label ?? target.path ?? target.kind;
541
+ const state = target.state ? `: [${target.state}]` : "";
542
+ const observed = target.observed ? ` - ${target.observed}` : "";
543
+ return `${label}${state}${observed}`;
544
+ }
545
+ function warningText(warning) {
546
+ return `[${warning.severity}]${warning.code ? ` [${warning.code}]` : ""} ${warning.message}`;
547
+ }
548
+ function providerEvidenceFor(value) {
549
+ return value.providerCapability;
550
+ }
551
+ function PlanPreview({
552
+ plan,
553
+ selectedAction,
554
+ result
555
+ }) {
556
+ const blockerTargets = plan.blockerTargets ?? [];
557
+ const providerEvidence = providerEvidenceFor(result ?? plan);
558
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
559
+ /* @__PURE__ */ jsx7(Text7, { bold: true, children: plan.title }),
560
+ /* @__PURE__ */ jsx7(Text7, { children: plan.summary }),
561
+ /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: "Consumer operation" }),
562
+ /* @__PURE__ */ jsxs6(Text7, { children: [
563
+ "Target harness: ",
564
+ /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: plan.harness })
565
+ ] }),
566
+ /* @__PURE__ */ jsxs6(Text7, { children: [
567
+ "Managed action: ",
568
+ plan.action
569
+ ] }),
570
+ /* @__PURE__ */ jsxs6(Text7, { children: [
571
+ "Can apply: ",
572
+ plan.canApply ? "yes" : "no"
573
+ ] }),
574
+ providerEvidence ? /* @__PURE__ */ jsx7(ProviderCapabilityView, { evidence: providerEvidence }) : null,
575
+ !plan.canApply && blockerTargets.length > 0 ? /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
576
+ /* @__PURE__ */ jsx7(Text7, { color: theme.warning, children: "Blocker targets" }),
577
+ blockerTargets.map((target, index) => /* @__PURE__ */ jsxs6(
578
+ Text7,
579
+ {
580
+ children: [
581
+ "- ",
582
+ targetText(target)
583
+ ]
584
+ },
585
+ `${target.label ?? target.path ?? target.kind}-${index}`
586
+ ))
587
+ ] }) : null,
588
+ plan.surfaces.length > 0 ? /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "Managed surfaces" }) : null,
589
+ plan.surfaces.map((surface) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
590
+ /* @__PURE__ */ jsxs6(Text7, { children: [
591
+ "- ",
592
+ surface.label
593
+ ] }),
594
+ surface.path ? /* @__PURE__ */ jsx7(PathLine, { value: surface.path }) : null
595
+ ] }, surface.id)),
596
+ /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
597
+ "Backup: ",
598
+ plan.backup.required ? "required" : "not required",
599
+ " (",
600
+ plan.backup.strategy,
601
+ ")"
602
+ ] }),
603
+ plan.backup.destinations?.map((path) => /* @__PURE__ */ jsx7(PathLine, { label: path.label, value: path.path }, path.path)),
604
+ plan.items.length > 0 ? /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "Preview" }) : null,
605
+ plan.items.slice(0, 5).map((item) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
606
+ /* @__PURE__ */ jsxs6(Text7, { children: [
607
+ "- ",
608
+ item.title
609
+ ] }),
610
+ item.target.path ? /* @__PURE__ */ jsx7(PathLine, { value: item.target.path }) : null,
611
+ item.preview ? /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: item.preview.length > 120 ? `${item.preview.slice(0, 120)}...` : item.preview }) : null
612
+ ] }, item.title)),
613
+ plan.items.length > 5 ? /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
614
+ "...",
615
+ plan.items.length - 5,
616
+ " more items"
617
+ ] }) : null,
618
+ plan.warnings.map((warning) => /* @__PURE__ */ jsxs6(Text7, { color: theme.warning, children: [
619
+ "- ",
620
+ warningText(warning)
621
+ ] }, warning.code ?? warning.message)),
622
+ plan.disclaimers.map((disclaimer) => /* @__PURE__ */ jsxs6(Text7, { color: theme.dim, children: [
623
+ "- ",
624
+ disclaimer.message
625
+ ] }, disclaimer.code ?? disclaimer.message)),
626
+ /* @__PURE__ */ jsxs6(Box7, { marginTop: 1, children: [
627
+ /* @__PURE__ */ jsx7(Text7, { color: selectedAction === "apply" ? theme.accent : void 0, children: "[Apply]" }),
628
+ /* @__PURE__ */ jsx7(Text7, { children: " " }),
629
+ /* @__PURE__ */ jsx7(Text7, { color: selectedAction === "cancel" ? theme.accent : void 0, children: "[Cancel]" })
630
+ ] }),
631
+ /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "Enter selects. a applies. c cancels." }),
632
+ result ? /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
633
+ /* @__PURE__ */ jsxs6(Text7, { color: result.applied ? theme.ok : theme.warning, children: [
634
+ "Consumer result: ",
635
+ result.summary
636
+ ] }),
637
+ !result.applied && ((result.diagnosticTargets?.length ?? 0) > 0 || result.warnings.length > 0) ? /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
638
+ /* @__PURE__ */ jsx7(Text7, { color: theme.warning, children: "Apply diagnostics" }),
639
+ result.diagnosticTargets?.map((target, index) => /* @__PURE__ */ jsxs6(
640
+ Text7,
641
+ {
642
+ children: [
643
+ "- ",
644
+ targetText(target)
645
+ ]
646
+ },
647
+ `${target.label ?? target.path ?? target.kind}-${index}`
648
+ )),
649
+ result.warnings.map((warning) => /* @__PURE__ */ jsxs6(
650
+ Text7,
651
+ {
652
+ color: theme.warning,
653
+ children: [
654
+ "- ",
655
+ warningText(warning)
656
+ ]
657
+ },
658
+ warning.code ?? warning.message
659
+ ))
660
+ ] }) : null
661
+ ] }) : null
662
+ ] });
663
+ }
664
+
514
665
  // src/cli/tui/App.tsx
515
666
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
516
667
  var rootItems = [
@@ -671,6 +822,10 @@ function App({
671
822
  const [activeHarness, setActiveHarness] = useState("opencode");
672
823
  const [activeAction, setActiveAction] = useState("update");
673
824
  const [reportVersion, setReportVersion] = useState(0);
825
+ const [providerEvidence, setProviderEvidence] = useState();
826
+ const [providerEvidenceLoading, setProviderEvidenceLoading] = useState(false);
827
+ const [providerEvidenceError, setProviderEvidenceError] = useState();
828
+ const providerEvidenceRequest = useRef(0);
674
829
  const [plan, setPlan] = useState();
675
830
  const [result, setResult] = useState();
676
831
  const [previewAction, setPreviewAction] = useState(
@@ -693,6 +848,30 @@ function App({
693
848
  const [editDraft, setEditDraft] = useState("");
694
849
  const [modelResult, setModelResult] = useState();
695
850
  const report = view === "status" || view === "manageHarness" ? operations.status(activeHarness) : void 0;
851
+ useEffect(() => {
852
+ if (view !== "status" || !operations.providerCapability) return;
853
+ const request = providerEvidenceRequest.current + 1;
854
+ providerEvidenceRequest.current = request;
855
+ setProviderEvidence(void 0);
856
+ setProviderEvidenceLoading(true);
857
+ setProviderEvidenceError(void 0);
858
+ void operations.providerCapability(activeHarness).then((evidence) => {
859
+ if (providerEvidenceRequest.current !== request) return;
860
+ setProviderEvidence(evidence);
861
+ setProviderEvidenceLoading(false);
862
+ }).catch((error) => {
863
+ if (providerEvidenceRequest.current !== request) return;
864
+ setProviderEvidenceError(
865
+ error instanceof Error ? error.message : String(error)
866
+ );
867
+ setProviderEvidenceLoading(false);
868
+ });
869
+ return () => {
870
+ if (providerEvidenceRequest.current === request) {
871
+ providerEvidenceRequest.current += 1;
872
+ }
873
+ };
874
+ }, [activeHarness, operations, reportVersion, view]);
696
875
  const currentManageItems = report?.state === "missing" ? installManageItems : manageItems;
697
876
  const modelRows = modelRoles.map((role) => {
698
877
  const model = editedModels[role.role] ?? role.model;
@@ -1258,10 +1437,18 @@ function App({
1258
1437
  Header,
1259
1438
  {
1260
1439
  title: `${report.displayName ?? activeHarness} Status`,
1261
- subtitle: "Categorized summary. Escape returns. r refreshes."
1440
+ subtitle: "Consumer-managed state and external provider evidence. Escape returns. r refreshes."
1262
1441
  }
1263
1442
  ),
1264
- /* @__PURE__ */ jsx8(StatusView, { report })
1443
+ /* @__PURE__ */ jsx8(
1444
+ StatusView,
1445
+ {
1446
+ report,
1447
+ providerEvidence: operations.providerCapability ? providerEvidence : report.providerCapability,
1448
+ providerEvidenceLoading,
1449
+ providerEvidenceError
1450
+ }
1451
+ )
1265
1452
  ] }, reportVersion);
1266
1453
  }
1267
1454
 
@@ -1,11 +1,12 @@
1
- import type { HarnessId } from '../../harness/types';
1
+ import type { HarnessId, ProviderCapabilityEvidence, ProviderEvidenceInput } from '../../harness/types';
2
2
  import { type ClaudeCodeOperationContext } from '../operations/claude-code';
3
3
  import { type CodexOperationContext } from '../operations/codex';
4
4
  import type { HarnessStatusReport, ModelRoleInput, OperationApplyResult, OperationPlan } from '../operations/types';
5
5
  import { type ModelOption } from './model-catalog';
6
6
  export type TuiAction = 'status' | 'list' | 'install' | 'update' | 'sync' | 'model';
7
7
  export interface TuiOperations {
8
- status(harness: HarnessId): HarnessStatusReport;
8
+ status(harness: HarnessId, evidence?: ProviderEvidenceInput): HarnessStatusReport;
9
+ providerCapability?(harness: HarnessId): Promise<ProviderCapabilityEvidence>;
9
10
  modelRoles(harness: HarnessId): ModelRoleInput[];
10
11
  modelOptions(harness: HarnessId): Promise<ModelOption[]>;
11
12
  plan(harness: HarnessId, action: Exclude<TuiAction, 'status' | 'list'>): OperationPlan;
@@ -15,6 +16,6 @@ export interface TuiOperations {
15
16
  export declare const opencodeModelRoles: ModelRoleInput[];
16
17
  export declare const codexModelRoles: ModelRoleInput[];
17
18
  export declare function getCodexModelRoles(source?: CodexOperationContext): ModelRoleInput[];
18
- export declare function getClaudeCodeModelRoles(source?: ClaudeCodeOperationContext): ModelRoleInput[];
19
+ export declare function getClaudeCodeModelRoles(_source?: ClaudeCodeOperationContext): ModelRoleInput[];
19
20
  export declare function getOpenCodeModelRoles(): ModelRoleInput[];
20
21
  export declare const defaultTuiOperations: TuiOperations;
@@ -4,7 +4,6 @@ export interface InstallArgs {
4
4
  tui: boolean;
5
5
  agent?: InstallAgent;
6
6
  tmux?: BooleanArg;
7
- skills?: BooleanArg;
8
7
  dryRun?: boolean;
9
8
  reset?: boolean;
10
9
  }
@@ -54,8 +53,6 @@ export interface OpenCodeConfig {
54
53
  export interface InstallConfig {
55
54
  agent: InstallAgent;
56
55
  hasTmux: boolean;
57
- installSkills: boolean;
58
- installCustomSkills: boolean;
59
56
  dryRun?: boolean;
60
57
  reset: boolean;
61
58
  }
@@ -66,14 +63,7 @@ export interface ConfigMergeResult {
66
63
  }
67
64
  export interface DetectedConfig {
68
65
  isInstalled: boolean;
69
- hasKimi: boolean;
70
66
  hasOpenAI: boolean;
71
- hasAnthropic?: boolean;
72
- hasCopilot?: boolean;
73
- hasZaiPlan?: boolean;
74
- hasAntigravity: boolean;
75
- hasChutes?: boolean;
76
- hasOpencodeZen: boolean;
77
67
  hasTmux: boolean;
78
68
  }
79
69
  import type { EffortSelection } from './model-effort';