sequant 1.20.2 → 2.0.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 (137) hide show
  1. package/.claude-plugin/marketplace.json +2 -4
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +29 -9
  4. package/dist/bin/cli.js +25 -2
  5. package/dist/src/commands/doctor.js +42 -9
  6. package/dist/src/commands/init.d.ts +1 -0
  7. package/dist/src/commands/init.js +52 -0
  8. package/dist/src/commands/logs.d.ts +1 -0
  9. package/dist/src/commands/logs.js +18 -2
  10. package/dist/src/commands/run.d.ts +7 -0
  11. package/dist/src/commands/run.js +235 -68
  12. package/dist/src/commands/serve.d.ts +13 -0
  13. package/dist/src/commands/serve.js +131 -0
  14. package/dist/src/commands/stats.d.ts +1 -0
  15. package/dist/src/commands/stats.js +185 -26
  16. package/dist/src/commands/status.d.ts +2 -0
  17. package/dist/src/commands/status.js +99 -50
  18. package/dist/src/index.d.ts +2 -2
  19. package/dist/src/index.js +4 -1
  20. package/dist/src/lib/ac-parser.d.ts +2 -0
  21. package/dist/src/lib/ac-parser.js +12 -2
  22. package/dist/src/lib/assess-comment-parser.d.ts +137 -0
  23. package/dist/src/lib/assess-comment-parser.js +344 -0
  24. package/dist/src/lib/ci/config.d.ts +22 -0
  25. package/dist/src/lib/ci/config.js +134 -0
  26. package/dist/src/lib/ci/index.d.ts +12 -0
  27. package/dist/src/lib/ci/index.js +10 -0
  28. package/dist/src/lib/ci/inputs.d.ts +29 -0
  29. package/dist/src/lib/ci/inputs.js +103 -0
  30. package/dist/src/lib/ci/labels.d.ts +34 -0
  31. package/dist/src/lib/ci/labels.js +101 -0
  32. package/dist/src/lib/ci/outputs.d.ts +25 -0
  33. package/dist/src/lib/ci/outputs.js +84 -0
  34. package/dist/src/lib/ci/triggers.d.ts +9 -0
  35. package/dist/src/lib/ci/triggers.js +86 -0
  36. package/dist/src/lib/ci/types.d.ts +131 -0
  37. package/dist/src/lib/ci/types.js +47 -0
  38. package/dist/src/lib/mcp-config.d.ts +54 -0
  39. package/dist/src/lib/mcp-config.js +172 -0
  40. package/dist/src/lib/merge-check/index.js +6 -12
  41. package/dist/src/lib/merge-check/types.d.ts +20 -7
  42. package/dist/src/lib/merge-check/types.js +11 -0
  43. package/dist/src/lib/phase-signal.d.ts +3 -3
  44. package/dist/src/lib/phase-signal.js +5 -3
  45. package/dist/src/lib/settings.d.ts +52 -0
  46. package/dist/src/lib/settings.js +41 -0
  47. package/dist/src/lib/shutdown.d.ts +16 -5
  48. package/dist/src/lib/shutdown.js +32 -12
  49. package/dist/src/lib/solve-comment-parser.d.ts +9 -102
  50. package/dist/src/lib/solve-comment-parser.js +13 -248
  51. package/dist/src/lib/stacks.d.ts +8 -0
  52. package/dist/src/lib/stacks.js +34 -0
  53. package/dist/src/lib/system.js +3 -7
  54. package/dist/src/lib/test-tautology-detector.d.ts +10 -0
  55. package/dist/src/lib/test-tautology-detector.js +43 -4
  56. package/dist/src/lib/upstream/assessment.js +9 -59
  57. package/dist/src/lib/upstream/issues.js +12 -75
  58. package/dist/src/lib/version-check.d.ts +2 -2
  59. package/dist/src/lib/version-check.js +6 -3
  60. package/dist/src/lib/version.d.ts +4 -0
  61. package/dist/src/lib/version.js +25 -0
  62. package/dist/src/lib/workflow/batch-executor.d.ts +18 -86
  63. package/dist/src/lib/workflow/batch-executor.js +232 -55
  64. package/dist/src/lib/workflow/drivers/agent-driver.d.ts +56 -0
  65. package/dist/src/lib/workflow/drivers/agent-driver.js +8 -0
  66. package/dist/src/lib/workflow/drivers/aider.d.ts +18 -0
  67. package/dist/src/lib/workflow/drivers/aider.js +160 -0
  68. package/dist/src/lib/workflow/drivers/claude-code.d.ts +17 -0
  69. package/dist/src/lib/workflow/drivers/claude-code.js +165 -0
  70. package/dist/src/lib/workflow/drivers/index.d.ts +20 -0
  71. package/dist/src/lib/workflow/drivers/index.js +27 -0
  72. package/dist/src/lib/workflow/error-classifier.d.ts +16 -0
  73. package/dist/src/lib/workflow/error-classifier.js +90 -0
  74. package/dist/src/lib/workflow/log-writer.d.ts +6 -3
  75. package/dist/src/lib/workflow/log-writer.js +57 -27
  76. package/dist/src/lib/workflow/metrics-schema.d.ts +9 -9
  77. package/dist/src/lib/workflow/phase-detection.d.ts +23 -0
  78. package/dist/src/lib/workflow/phase-detection.js +45 -29
  79. package/dist/src/lib/workflow/phase-executor.d.ts +42 -3
  80. package/dist/src/lib/workflow/phase-executor.js +345 -220
  81. package/dist/src/lib/workflow/phase-mapper.d.ts +1 -1
  82. package/dist/src/lib/workflow/phase-mapper.js +7 -7
  83. package/dist/src/lib/workflow/platforms/github.d.ts +157 -0
  84. package/dist/src/lib/workflow/platforms/github.js +466 -0
  85. package/dist/src/lib/workflow/platforms/index.d.ts +17 -0
  86. package/dist/src/lib/workflow/platforms/index.js +25 -0
  87. package/dist/src/lib/workflow/platforms/platform-provider.d.ts +67 -0
  88. package/dist/src/lib/workflow/platforms/platform-provider.js +8 -0
  89. package/dist/src/lib/workflow/pr-status.d.ts +2 -4
  90. package/dist/src/lib/workflow/pr-status.js +3 -16
  91. package/dist/src/lib/workflow/qa-cache.d.ts +58 -0
  92. package/dist/src/lib/workflow/qa-cache.js +88 -0
  93. package/dist/src/lib/workflow/reconcile.d.ts +69 -0
  94. package/dist/src/lib/workflow/reconcile.js +290 -0
  95. package/dist/src/lib/workflow/ring-buffer.d.ts +17 -0
  96. package/dist/src/lib/workflow/ring-buffer.js +37 -0
  97. package/dist/src/lib/workflow/run-log-schema.d.ts +115 -24
  98. package/dist/src/lib/workflow/run-log-schema.js +47 -12
  99. package/dist/src/lib/workflow/run-reflect.js +1 -1
  100. package/dist/src/lib/workflow/state-cleanup.js +21 -0
  101. package/dist/src/lib/workflow/state-manager.d.ts +34 -3
  102. package/dist/src/lib/workflow/state-manager.js +278 -126
  103. package/dist/src/lib/workflow/state-schema.d.ts +34 -30
  104. package/dist/src/lib/workflow/state-schema.js +35 -25
  105. package/dist/src/lib/workflow/state-utils.d.ts +3 -1
  106. package/dist/src/lib/workflow/state-utils.js +1 -0
  107. package/dist/src/lib/workflow/types.d.ts +208 -6
  108. package/dist/src/lib/workflow/types.js +20 -1
  109. package/dist/src/lib/workflow/worktree-discovery.d.ts +1 -1
  110. package/dist/src/lib/workflow/worktree-discovery.js +6 -14
  111. package/dist/src/lib/workflow/worktree-manager.js +33 -51
  112. package/dist/src/mcp/index.d.ts +4 -0
  113. package/dist/src/mcp/index.js +4 -0
  114. package/dist/src/mcp/resources.d.ts +7 -0
  115. package/dist/src/mcp/resources.js +111 -0
  116. package/dist/src/mcp/run-registry.d.ts +34 -0
  117. package/dist/src/mcp/run-registry.js +42 -0
  118. package/dist/src/mcp/server.d.ts +12 -0
  119. package/dist/src/mcp/server.js +50 -0
  120. package/dist/src/mcp/tools/logs.d.ts +7 -0
  121. package/dist/src/mcp/tools/logs.js +149 -0
  122. package/dist/src/mcp/tools/run.d.ts +121 -0
  123. package/dist/src/mcp/tools/run.js +591 -0
  124. package/dist/src/mcp/tools/status.d.ts +7 -0
  125. package/dist/src/mcp/tools/status.js +127 -0
  126. package/package.json +10 -1
  127. package/templates/hooks/post-tool.sh +19 -8
  128. package/templates/hooks/pre-tool.sh +36 -49
  129. package/templates/mcp.json +6 -0
  130. package/templates/skills/assess/SKILL.md +354 -352
  131. package/templates/skills/exec/SKILL.md +64 -1
  132. package/templates/skills/fullsolve/SKILL.md +35 -4
  133. package/templates/skills/qa/SKILL.md +486 -9
  134. package/templates/skills/qa/scripts/quality-checks.sh +1 -1
  135. package/templates/skills/setup/SKILL.md +386 -0
  136. package/templates/skills/solve/SKILL.md +38 -664
  137. package/templates/skills/spec/SKILL.md +90 -31
@@ -1,7 +1,5 @@
1
1
  {
2
- "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
2
  "name": "sequant",
4
- "description": "Sequant plugin marketplace - structured workflow system for Claude Code",
5
3
  "owner": {
6
4
  "name": "sequant-io",
7
5
  "email": "hello@sequant.io"
@@ -9,8 +7,8 @@
9
7
  "plugins": [
10
8
  {
11
9
  "name": "sequant",
12
- "description": "Structured workflow system for Claude Code - GitHub issue resolution with spec, exec, test, and QA phases. Includes 16 skills for planning, implementation, testing, code review, and quality assurance.",
13
- "version": "1.17.0",
10
+ "description": "Structured workflow system for Claude Code - GitHub issue resolution with spec, exec, test, and QA phases. Includes 17 skills, MCP server with workflow tools, and pre/post-tool hooks.",
11
+ "version": "1.20.3",
14
12
  "author": {
15
13
  "name": "sequant-io",
16
14
  "email": "hello@sequant.io"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sequant",
3
3
  "description": "Structured workflow system for Claude Code - GitHub issue resolution with spec, exec, test, and QA phases",
4
- "version": "1.20.2",
4
+ "version": "2.0.0",
5
5
  "author": {
6
6
  "name": "sequant-io",
7
7
  "email": "hello@sequant.io"
package/README.md CHANGED
@@ -9,20 +9,41 @@ Solve GitHub issues with structured phases and quality gates — from issue to m
9
9
  [![npm version](https://img.shields.io/npm/v/sequant.svg)](https://www.npmjs.com/package/sequant)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
11
11
 
12
+ ### What's new in 2.0
13
+
14
+ - **MCP server** — `sequant serve` exposes workflow orchestration as MCP tools (`sequant_run`, `sequant_status`, `sequant_logs`). Any MCP client can drive Sequant headlessly.
15
+ - **`/assess` unification** — `/solve` is merged into `/assess` with a 6-action vocabulary (PROCEED, CLOSE, MERGE, REWRITE, CLARIFY, PARK). `/solve` still works as an alias.
16
+ - **Parallel execution** — multi-issue runs are concurrent by default with `--concurrency`.
17
+ - **Multi-agent** — `--agent aider` as an alternative backend, with a driver interface for future agents.
18
+ - **GitHub Actions** — label-triggered and comment-triggered CI workflows out of the box.
19
+
20
+ Upgrading from v1.x? See the [migration guide](CHANGELOG.md#migration-from-v1x).
21
+
12
22
  ## Quick Start
13
23
 
14
- ### Install
24
+ ### Option A: Plugin (interactive users)
25
+
26
+ In Claude Code:
27
+ ```
28
+ /plugin install sequant@sequant-io/sequant
29
+ /sequant:setup
30
+ ```
31
+
32
+ You get skills, hooks, and MCP tools — no npm required.
33
+
34
+ ### Option B: Package install (power users / CI)
15
35
 
16
36
  ```bash
17
- # In your project directory
18
- npm install sequant
19
- npx sequant init # Install skills to your project
20
- npx sequant doctor # Verify setup
37
+ npm install sequant # npm
38
+ pnpm add sequant # pnpm
39
+ yarn add sequant # yarn
40
+ bun add sequant # bun
21
41
  ```
22
42
 
23
- To update:
43
+ Then initialize:
24
44
  ```bash
25
- npm update sequant
45
+ npx sequant init # Install skills to your project
46
+ npx sequant doctor # Verify setup
26
47
  ```
27
48
 
28
49
  ### Start Using
@@ -151,7 +172,7 @@ npx sequant merge --check # Verify batch before merging
151
172
  | Command | Purpose |
152
173
  |---------|---------|
153
174
  | `/fullsolve` | Complete pipeline in one command |
154
- | `/solve` | Recommend optimal workflow for issue |
175
+ | `/assess` | Triage issue, recommend workflow (6-action vocabulary) |
155
176
  | `/loop` | Fix iteration when checks fail |
156
177
 
157
178
  ### Integration
@@ -167,7 +188,6 @@ npx sequant merge --check # Verify batch before merging
167
188
 
168
189
  | Command | Purpose |
169
190
  |---------|---------|
170
- | `/assess` | Issue triage and status assessment |
171
191
  | `/docs` | Generate feature documentation |
172
192
  | `/clean` | Repository cleanup |
173
193
  | `/improve` | Codebase analysis and improvement discovery |
package/dist/bin/cli.js CHANGED
@@ -13,6 +13,7 @@ import { initCommand } from "../src/commands/init.js";
13
13
  import { isLocalNodeModulesInstall } from "../src/lib/version-check.js";
14
14
  import { configureUI, banner } from "../src/lib/cli-ui.js";
15
15
  import { isCI, isStdoutTTY } from "../src/lib/tty.js";
16
+ import { detectPackageManagerSync, getPackageManagerCommands, } from "../src/lib/stacks.js";
16
17
  // Read version from package.json dynamically
17
18
  // Works from both source (bin/) and compiled (dist/bin/) locations
18
19
  function getVersion() {
@@ -64,9 +65,10 @@ configureUI({
64
65
  // Warn if running from local node_modules (not npx cache or global)
65
66
  // This helps users who accidentally have a stale local install
66
67
  if (!process.argv.includes("--quiet") && isLocalNodeModulesInstall()) {
68
+ const pmCommands = getPackageManagerCommands(detectPackageManagerSync());
67
69
  console.warn(chalk.yellow("⚠️ Running sequant from local node_modules\n" +
68
70
  " For latest version: npx sequant@latest\n" +
69
- " To remove local: npm uninstall sequant\n"));
71
+ ` To remove local: ${pmCommands.removePkg} sequant\n`));
70
72
  }
71
73
  program
72
74
  .name("sequant")
@@ -83,6 +85,7 @@ program
83
85
  .option("--skip-setup", "Skip the dependency setup wizard")
84
86
  .option("--no-symlinks", "Use copies instead of symlinks for scripts/dev/ files")
85
87
  .option("--no-agents-md", "Skip AGENTS.md generation")
88
+ .option("--mcp", "Add Sequant MCP server to detected clients (use with --yes)")
86
89
  .action(initCommand);
87
90
  program
88
91
  .command("update")
@@ -111,7 +114,8 @@ program
111
114
  .option("--cleanup", "Clean up stale/orphaned entries")
112
115
  .option("--dry-run", "Preview cleanup without changes")
113
116
  .option("--max-age <days>", "Remove entries older than N days", parseInt)
114
- .option("--all", "Remove all orphaned entries (merged and abandoned)")
117
+ .option("--all", "Show all entries including expired; with --cleanup removes all orphaned")
118
+ .option("--offline", "Skip GitHub queries (pure local state)")
115
119
  .action((issue, options) => {
116
120
  // Support positional arg: `sequant status 42` → --issue 42
117
121
  if (issue) {
@@ -147,7 +151,9 @@ program
147
151
  .option("--no-rebase", "Skip pre-PR rebase onto origin/main (use when you want to handle rebasing manually)")
148
152
  .option("--no-pr", "Skip PR creation after successful QA (manual PR workflow)")
149
153
  .option("-f, --force", "Force re-execution of completed issues (bypass pre-flight state guard)")
154
+ .option("--concurrency <n>", "Max concurrent issues in parallel mode (default: 3)", parseInt)
150
155
  .option("--reflect", "Analyze run results and suggest improvements")
156
+ .option("--agent <name>", 'Agent driver for phase execution (default: "claude-code")')
151
157
  .action(runCommand);
152
158
  program
153
159
  .command("merge")
@@ -178,6 +184,7 @@ program
178
184
  .option("--failed", "Show only failed runs")
179
185
  .option("--rotate", "Rotate logs (delete oldest to meet thresholds)")
180
186
  .option("-d, --dry-run", "Show what would be rotated without deleting")
187
+ .option("-v, --verbose", "Show full error context (all stderr lines)")
181
188
  .action(logsCommand);
182
189
  program
183
190
  .command("stats")
@@ -185,6 +192,7 @@ program
185
192
  .option("-p, --path <path>", "Custom log directory path")
186
193
  .option("--csv", "Output as CSV")
187
194
  .option("--json", "Output as JSON")
195
+ .option("--detailed", "Show detailed analytics (QA verdicts, trends, label segmentation)")
188
196
  .action(statsCommand);
189
197
  program
190
198
  .command("dashboard")
@@ -193,6 +201,21 @@ program
193
201
  .option("--no-open", "Don't automatically open browser")
194
202
  .option("-v, --verbose", "Enable verbose logging")
195
203
  .action(dashboardCommand);
204
+ program
205
+ .command("serve")
206
+ .description("Start MCP server for workflow orchestration")
207
+ .option("--transport <type>", "Transport type: stdio (default) or sse", "stdio")
208
+ .option("--port <port>", "Port for SSE transport (default: 3100)", parseInt)
209
+ .action(async (options) => {
210
+ const mod = await import("../src/commands/serve.js").catch(() => null);
211
+ if (!mod) {
212
+ const pmCmds = getPackageManagerCommands(detectPackageManagerSync());
213
+ console.error(chalk.red("Error: MCP server requires @modelcontextprotocol/sdk\n" +
214
+ `Install it with: ${pmCmds.addPkg} @modelcontextprotocol/sdk`));
215
+ process.exit(1);
216
+ }
217
+ return mod.serveCommand(options);
218
+ });
196
219
  // State management command with subcommands
197
220
  const stateCmd = program
198
221
  .command("state")
@@ -4,9 +4,11 @@
4
4
  import chalk from "chalk";
5
5
  import { execSync } from "child_process";
6
6
  import { ui, colors } from "../lib/cli-ui.js";
7
+ import { GitHubProvider } from "../lib/workflow/platforms/github.js";
7
8
  import { fileExists, isExecutable } from "../lib/fs.js";
8
9
  import { getManifest } from "../lib/manifest.js";
9
10
  import { commandExists, isGhAuthenticated, isNativeWindows, isWSL, checkOptionalMcpServers, getMcpServersConfig, OPTIONAL_MCP_SERVERS, } from "../lib/system.js";
11
+ import { getSettings } from "../lib/settings.js";
10
12
  import { checkVersionThorough, getVersionWarning, } from "../lib/version-check.js";
11
13
  import { areSkillsOutdated } from "./sync.js";
12
14
  import { readAgentsMd, checkAgentsMdConsistency, AGENTS_MD_PATH, } from "../lib/agents-md.js";
@@ -33,15 +35,8 @@ export function checkClosedIssues() {
33
35
  sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
34
36
  const sevenDaysAgoISO = sevenDaysAgo.toISOString();
35
37
  // Fetch closed issues from last 7 days
36
- let closedIssues;
37
- try {
38
- const output = execSync(`gh issue list --state closed --json number,title,closedAt,labels --limit 100`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
39
- closedIssues = JSON.parse(output);
40
- }
41
- catch {
42
- // gh command failed - return empty (graceful degradation)
43
- return [];
44
- }
38
+ const github = new GitHubProvider();
39
+ const closedIssues = github.listClosedIssuesSync(100);
45
40
  // Filter to last 7 days
46
41
  const recentIssues = closedIssues.filter((issue) => issue.closedAt >= sevenDaysAgoISO);
47
42
  // Filter out issues with skip labels
@@ -335,6 +330,24 @@ export async function doctorCommand(options = {}) {
335
330
  message: "claude CLI not installed - see: https://docs.anthropic.com/en/docs/claude-code",
336
331
  });
337
332
  }
333
+ // Check: Aider CLI (when configured as agent)
334
+ const settings = await getSettings();
335
+ if (settings.run.agent === "aider") {
336
+ if (commandExists("aider")) {
337
+ checks.push({
338
+ name: "Aider CLI",
339
+ status: "pass",
340
+ message: "aider CLI is installed (configured as default agent)",
341
+ });
342
+ }
343
+ else {
344
+ checks.push({
345
+ name: "Aider CLI",
346
+ status: "fail",
347
+ message: "aider CLI not installed but configured as default agent - install: pip install aider-chat",
348
+ });
349
+ }
350
+ }
338
351
  // Check 12: jq installed (optional but recommended)
339
352
  if (commandExists("jq")) {
340
353
  checks.push({
@@ -415,6 +428,26 @@ export async function doctorCommand(options = {}) {
415
428
  message: "Not available for sequant run (no Claude Desktop config found or empty mcpServers)",
416
429
  });
417
430
  }
431
+ // Check: Sequant MCP server health
432
+ try {
433
+ // Verify MCP server can be created (validates SDK availability)
434
+ const { createServer } = await import("../mcp/server.js");
435
+ const { getVersion } = await import("../lib/version.js");
436
+ const mcpServerInstance = createServer(getVersion());
437
+ await mcpServerInstance.close();
438
+ checks.push({
439
+ name: "MCP Server",
440
+ status: "pass",
441
+ message: "Sequant MCP server can be started (sequant serve)",
442
+ });
443
+ }
444
+ catch (error) {
445
+ checks.push({
446
+ name: "MCP Server",
447
+ status: "warn",
448
+ message: `Sequant MCP server unavailable: ${error instanceof Error ? error.message : String(error)}`,
449
+ });
450
+ }
418
451
  // Check: Closed issue verification (only if gh available, authenticated, and not skipped)
419
452
  if (!options.skipIssueCheck && ghAvailable && ghAuthenticated && gitExists) {
420
453
  const missingCommitIssues = checkClosedIssues();
@@ -9,6 +9,7 @@ interface InitOptions {
9
9
  skipSetup?: boolean;
10
10
  noSymlinks?: boolean;
11
11
  agentsMd?: boolean;
12
+ mcp?: boolean;
12
13
  }
13
14
  export declare function initCommand(options: InitOptions): Promise<void>;
14
15
  export {};
@@ -293,6 +293,7 @@ export async function initCommand(options) {
293
293
  if (options.agentsMd !== false) {
294
294
  console.log(chalk.gray(" AGENTS.md (universal agent instructions)"));
295
295
  }
296
+ console.log(chalk.gray(" .mcp.json (Claude Code MCP server config)"));
296
297
  if (!skipPrompts) {
297
298
  const { confirm } = await inquirer.prompt([
298
299
  {
@@ -423,6 +424,57 @@ export async function initCommand(options) {
423
424
  else {
424
425
  console.log(chalk.gray("Skipping AGENTS.md generation (--no-agents-md)"));
425
426
  }
427
+ // Create .mcp.json for Claude Code (always, regardless of --mcp flag)
428
+ const { createProjectMcpJson, detectMcpClients, addSequantToMcpConfig } = await import("../lib/mcp-config.js");
429
+ const mcpJsonResult = createProjectMcpJson();
430
+ if (mcpJsonResult.created) {
431
+ ui.printStatus("success", "Created .mcp.json (Claude Code MCP config)");
432
+ }
433
+ else if (mcpJsonResult.merged) {
434
+ ui.printStatus("success", "Added Sequant to existing .mcp.json");
435
+ }
436
+ else {
437
+ console.log(chalk.gray(" .mcp.json: sequant already configured (skipped)"));
438
+ }
439
+ // Offer MCP server configuration for detected clients (global configs)
440
+ const mcpClients = detectMcpClients();
441
+ const detectedClients = mcpClients.filter((c) => c.exists);
442
+ if (detectedClients.length > 0) {
443
+ console.log(chalk.blue(`\nDetected ${detectedClients.length} MCP-compatible client(s):`));
444
+ for (const client of detectedClients) {
445
+ console.log(chalk.gray(` • ${client.name}`));
446
+ }
447
+ let addMcp = false;
448
+ if (skipPrompts) {
449
+ // --yes alone skips MCP config; --yes --mcp explicitly opts in
450
+ addMcp = !!options.mcp;
451
+ if (!addMcp) {
452
+ console.log(chalk.gray(" Skipping MCP config (use --mcp to auto-add in non-interactive mode)"));
453
+ }
454
+ }
455
+ else {
456
+ const { confirm } = await inquirer.prompt([
457
+ {
458
+ type: "confirm",
459
+ name: "confirm",
460
+ message: "Add Sequant MCP server to detected clients? (enables AI tools to use Sequant)",
461
+ default: true,
462
+ },
463
+ ]);
464
+ addMcp = confirm;
465
+ }
466
+ if (addMcp) {
467
+ for (const client of detectedClients) {
468
+ const added = addSequantToMcpConfig(client.configPath, client.clientType);
469
+ if (added) {
470
+ ui.printStatus("success", `Added Sequant MCP to ${client.name}`);
471
+ }
472
+ else {
473
+ console.log(chalk.gray(` ${client.name}: already configured (skipped)`));
474
+ }
475
+ }
476
+ }
477
+ }
426
478
  // Build optional suggestions section
427
479
  const optionalSuggestions = suggestions.filter((s) => s.startsWith("Optional"));
428
480
  const optionalSection = optionalSuggestions.length > 0
@@ -11,6 +11,7 @@ interface LogsOptions {
11
11
  failed?: boolean;
12
12
  rotate?: boolean;
13
13
  dryRun?: boolean;
14
+ verbose?: boolean;
14
15
  }
15
16
  /**
16
17
  * Main logs command
@@ -78,7 +78,7 @@ function formatTime(isoString) {
78
78
  /**
79
79
  * Display a single log summary
80
80
  */
81
- function displayLogSummary(log, filename) {
81
+ function displayLogSummary(log, filename, options) {
82
82
  const passed = log.summary.passed;
83
83
  const failed = log.summary.failed;
84
84
  const total = log.summary.totalIssues;
@@ -112,6 +112,22 @@ function displayLogSummary(log, filename) {
112
112
  const phaseDuration = chalk.gray(`(${formatDuration(phase.durationSeconds)})`);
113
113
  const error = phase.error ? chalk.red(` - ${phase.error}`) : "";
114
114
  console.log(` ${phaseStatus} ${phase.phase} ${phaseDuration}${error}`);
115
+ // Show error context when available (#447 AC-3)
116
+ if (phase.errorContext) {
117
+ const ctx = phase.errorContext;
118
+ console.log(chalk.gray(` category: ${chalk.yellow(ctx.category)}`));
119
+ if (ctx.stderrTail && ctx.stderrTail.length > 0) {
120
+ const maxLines = options?.verbose ? ctx.stderrTail.length : 5;
121
+ const lines = ctx.stderrTail.slice(-maxLines);
122
+ console.log(chalk.gray(" stderr tail:"));
123
+ for (const line of lines) {
124
+ console.log(chalk.gray(` ${line}`));
125
+ }
126
+ if (!options?.verbose && ctx.stderrTail.length > 5) {
127
+ console.log(chalk.gray(` ... ${ctx.stderrTail.length - 5} more lines (use --verbose to see all)`));
128
+ }
129
+ }
130
+ }
115
131
  // Show observability data (AC-9)
116
132
  if (phase.commitHash) {
117
133
  console.log(chalk.gray(` commit: ${phase.commitHash.slice(0, 8)}`));
@@ -228,7 +244,7 @@ export async function logsCommand(options) {
228
244
  else {
229
245
  // Human-readable output
230
246
  for (const { log, filename } of filteredLogs) {
231
- displayLogSummary(log, filename);
247
+ displayLogSummary(log, filename, { verbose: options.verbose });
232
248
  }
233
249
  // Summary
234
250
  console.log("\n" + ui.divider());
@@ -7,6 +7,8 @@
7
7
  * - phase-mapper: Label-to-phase detection and workflow parsing
8
8
  * - batch-executor: Batch execution, dependency sorting, issue logging
9
9
  */
10
+ /** @internal Log a non-fatal warning: one-line summary always, detail in verbose. */
11
+ export declare function logNonFatalWarning(message: string, error: unknown, verbose: boolean): void;
10
12
  import type { RunOptions } from "../lib/workflow/batch-executor.js";
11
13
  export { parseQaVerdict, formatDuration, executePhaseWithRetry, } from "../lib/workflow/phase-executor.js";
12
14
  export { detectDefaultBranch, checkWorktreeFreshness, removeStaleWorktree, listWorktrees, getWorktreeChangedFiles, getWorktreeDiffStats, readCacheMetrics, filterResumedPhases, ensureWorktree, createCheckpointCommit, reinstallIfLockfileChanged, rebaseBeforePR, createPR, } from "../lib/workflow/worktree-manager.js";
@@ -14,6 +16,11 @@ export type { WorktreeInfo, RebaseResult, PRCreationResult, } from "../lib/workf
14
16
  export { detectPhasesFromLabels, parseRecommendedWorkflow, determinePhasesForIssue, } from "../lib/workflow/phase-mapper.js";
15
17
  export { getIssueInfo, sortByDependencies, parseBatches, getEnvConfig, executeBatch, runIssueWithLogging, } from "../lib/workflow/batch-executor.js";
16
18
  export type { RunOptions } from "../lib/workflow/batch-executor.js";
19
+ /**
20
+ * Normalize Commander.js --no-X flags into typed RunOptions fields.
21
+ * Replaces the `as any` cast (#402 AC-4).
22
+ */
23
+ export declare function normalizeCommanderOptions(options: RunOptions): RunOptions;
17
24
  /**
18
25
  * Main run command
19
26
  */