sequant 2.0.0 → 2.1.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 (61) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +7 -6
  4. package/dist/bin/cli.js +2 -1
  5. package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
  6. package/dist/marketplace/external_plugins/sequant/.mcp.json +6 -0
  7. package/dist/marketplace/external_plugins/sequant/README.md +58 -8
  8. package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +19 -8
  9. package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +36 -49
  10. package/dist/marketplace/external_plugins/sequant/skills/_shared/references/subagent-types.md +158 -48
  11. package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +354 -352
  12. package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +1155 -33
  13. package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +35 -4
  14. package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +2157 -104
  15. package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +1 -1
  16. package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +386 -0
  17. package/dist/marketplace/external_plugins/sequant/skills/solve/SKILL.md +38 -664
  18. package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +505 -120
  19. package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +246 -1
  20. package/dist/marketplace/external_plugins/sequant/skills/testgen/SKILL.md +138 -1
  21. package/dist/src/commands/dashboard.js +1 -1
  22. package/dist/src/commands/doctor.js +1 -1
  23. package/dist/src/commands/init.js +10 -10
  24. package/dist/src/commands/logs.js +1 -1
  25. package/dist/src/commands/run.js +49 -39
  26. package/dist/src/commands/state.js +3 -3
  27. package/dist/src/commands/status.js +5 -5
  28. package/dist/src/commands/sync.js +8 -8
  29. package/dist/src/commands/update.js +16 -16
  30. package/dist/src/lib/cli-ui.js +20 -19
  31. package/dist/src/lib/merge-check/index.js +2 -2
  32. package/dist/src/lib/settings.d.ts +8 -0
  33. package/dist/src/lib/settings.js +1 -0
  34. package/dist/src/lib/shutdown.js +1 -1
  35. package/dist/src/lib/templates.js +2 -0
  36. package/dist/src/lib/wizard.js +6 -4
  37. package/dist/src/lib/workflow/batch-executor.d.ts +9 -1
  38. package/dist/src/lib/workflow/batch-executor.js +39 -2
  39. package/dist/src/lib/workflow/log-writer.js +6 -6
  40. package/dist/src/lib/workflow/metrics-writer.js +5 -3
  41. package/dist/src/lib/workflow/phase-executor.d.ts +1 -1
  42. package/dist/src/lib/workflow/phase-executor.js +52 -22
  43. package/dist/src/lib/workflow/platforms/github.js +5 -1
  44. package/dist/src/lib/workflow/state-cleanup.js +1 -1
  45. package/dist/src/lib/workflow/state-manager.js +15 -13
  46. package/dist/src/lib/workflow/state-rebuild.js +2 -2
  47. package/dist/src/lib/workflow/types.d.ts +27 -0
  48. package/dist/src/lib/workflow/worktree-manager.js +40 -41
  49. package/dist/src/lib/worktree-isolation.d.ts +130 -0
  50. package/dist/src/lib/worktree-isolation.js +310 -0
  51. package/package.json +24 -14
  52. package/templates/agents/sequant-explorer.md +23 -0
  53. package/templates/agents/sequant-implementer.md +18 -0
  54. package/templates/agents/sequant-qa-checker.md +24 -0
  55. package/templates/agents/sequant-testgen.md +25 -0
  56. package/templates/scripts/cleanup-worktree.sh +18 -0
  57. package/templates/skills/_shared/references/subagent-types.md +158 -48
  58. package/templates/skills/exec/SKILL.md +72 -6
  59. package/templates/skills/qa/SKILL.md +8 -217
  60. package/templates/skills/spec/SKILL.md +446 -120
  61. package/templates/skills/testgen/SKILL.md +138 -1
@@ -42,10 +42,127 @@ The `/test` phase is invoked by `/fullsolve` based on issue labels:
42
42
  2. **Execution Phase:** Run tests systematically with browser automation
43
43
  3. **Reporting Phase:** Generate test results and GitHub comment
44
44
 
45
+ ## Orchestration Context
46
+
47
+ When running as part of an orchestrated workflow (e.g., `sequant run` or `/fullsolve`), this skill receives environment variables that indicate the orchestration context:
48
+
49
+ | Environment Variable | Description | Example Value |
50
+ |---------------------|-------------|---------------|
51
+ | `SEQUANT_ORCHESTRATOR` | The orchestrator invoking this skill | `sequant-run` |
52
+ | `SEQUANT_PHASE` | Current phase in the workflow | `test` |
53
+ | `SEQUANT_ISSUE` | Issue number being processed | `123` |
54
+ | `SEQUANT_WORKTREE` | Path to the feature worktree | `/path/to/worktrees/feature/...` |
55
+
56
+ **Behavior when orchestrated (SEQUANT_ORCHESTRATOR is set):**
57
+
58
+ 1. **Skip issue fetch** - Use `SEQUANT_ISSUE` directly, orchestrator has context
59
+ 2. **Use provided worktree** - Work in `SEQUANT_WORKTREE` path
60
+ 3. **Reduce GitHub comment frequency** - Defer progress updates to orchestrator
61
+ 4. **Trust dev server status** - Orchestrator may have started it already
62
+
63
+ **Behavior when standalone (SEQUANT_ORCHESTRATOR is NOT set):**
64
+
65
+ - Fetch fresh issue context from GitHub
66
+ - Locate or prompt for worktree
67
+ - Post progress updates to GitHub
68
+ - Start dev server if needed
69
+
70
+ ## Pre-flight: Stale Branch Detection
71
+
72
+ **Skip this section if `SEQUANT_ORCHESTRATOR` is set** - the orchestrator handles branch freshness checks.
73
+
74
+ **Purpose:** Detect when the feature branch is significantly behind main before running browser tests. Testing stale code is wasteful because:
75
+ - Test results may not apply to the merged state
76
+ - Features may have conflicts that need resolution first
77
+ - Time spent on testing is lost if rebase is required
78
+
79
+ **Detection:**
80
+
81
+ ```bash
82
+ # Ensure we have latest remote state
83
+ git fetch origin 2>/dev/null || true
84
+
85
+ # Count commits behind main
86
+ behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo "0")
87
+ echo "Feature branch is $behind commits behind main"
88
+ ```
89
+
90
+ **Threshold Configuration:**
91
+
92
+ The stale branch threshold is configurable in `.sequant/settings.json`:
93
+
94
+ ```json
95
+ {
96
+ "run": {
97
+ "staleBranchThreshold": 5
98
+ }
99
+ }
100
+ ```
101
+
102
+ Default: 5 commits
103
+
104
+ **Behavior:**
105
+
106
+ | Commits Behind | Action |
107
+ |----------------|--------|
108
+ | 0 | āœ… Proceed normally |
109
+ | 1 to threshold | āš ļø **Warning:** "Feature branch is N commits behind main. Consider rebasing before testing." |
110
+ | > threshold | āŒ **Block:** "STALE_BRANCH: Feature branch is N commits behind main (threshold: T). Rebase required before testing." |
111
+
112
+ **Implementation:**
113
+
114
+ ```bash
115
+ # Read threshold from settings (default: 5)
116
+ threshold=$(jq -r '.run.staleBranchThreshold // 5' .sequant/settings.json 2>/dev/null || echo "5")
117
+
118
+ behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo "0")
119
+
120
+ if [[ $behind -gt $threshold ]]; then
121
+ echo "āŒ STALE_BRANCH: Feature branch is $behind commits behind main (threshold: $threshold)"
122
+ echo " Rebase required before testing:"
123
+ echo " git fetch origin && git rebase origin/main"
124
+ # Exit with error - testing should not proceed
125
+ exit 1
126
+ elif [[ $behind -gt 0 ]]; then
127
+ echo "āš ļø Warning: Feature branch is $behind commits behind main."
128
+ echo " Consider rebasing before testing: git fetch origin && git rebase origin/main"
129
+ # Continue with warning
130
+ fi
131
+ ```
132
+
133
+ **Output Format:**
134
+
135
+ ```markdown
136
+ ### Stale Branch Check
137
+
138
+ | Check | Value |
139
+ |-------|-------|
140
+ | Commits behind main | N |
141
+ | Threshold | T |
142
+ | Status | āœ… OK / āš ļø Warning / āŒ Blocked |
143
+
144
+ [Warning/blocking message if applicable]
145
+ ```
146
+
147
+ **Verdict Impact:**
148
+
149
+ | Status | Verdict Impact |
150
+ |--------|----------------|
151
+ | OK (0 behind) | No impact |
152
+ | Warning (1 to threshold) | Note in test output, recommend rebase |
153
+ | Blocked (> threshold) | **Cannot proceed** - rebase first |
154
+
45
155
  ## Phase 1: Setup
46
156
 
47
157
  ### 1.1 Fetch Issue Context
48
158
 
159
+ **If orchestrated (SEQUANT_ORCHESTRATOR is set):**
160
+ - Use `SEQUANT_ISSUE` for the issue number
161
+ - Skip fetching issue context (orchestrator has already done this)
162
+ - Parse any context passed in the orchestrator's prompt
163
+
164
+ **If standalone:**
165
+
49
166
  ```bash
50
167
  gh issue view <issue-number> --json title,body,labels
51
168
  gh issue view <issue-number> --comments
@@ -132,7 +249,99 @@ Wait for server ready before proceeding.
132
249
 
133
250
  **Note:** If `{{DEV_URL}}` or `{{PM_RUN}}` are not replaced with actual values, the defaults are:
134
251
  - DEV_URL: `http://localhost:3000` (Next.js), `http://localhost:4321` (Astro), `http://localhost:5173` (Vite-based)
135
- - PM_RUN: `npm run` (or `bun run`, `yarn`, `pnpm run` based on lockfile)
252
+ - PM_RUN: `npm run` (or `bun run`, `yarn`, `pnpm run`, `poetry run`, `uv run`, `python -m` based on lockfile)
253
+
254
+ ### 1.5 Test Coverage Analysis (REQUIRED)
255
+
256
+ **Purpose:** Warn when new/modified source files lack corresponding test files.
257
+
258
+ **Before executing tests**, analyze coverage for changed files:
259
+
260
+ 1. **Get changed source files:**
261
+ ```bash
262
+ # Get changed source files (excluding tests themselves)
263
+ changed=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx)$' | grep -v -E '\.test\.|\.spec\.|__tests__' || true)
264
+ echo "Changed source files:"
265
+ echo "$changed"
266
+ ```
267
+
268
+ 2. **Check for corresponding test files:**
269
+ ```bash
270
+ # For each changed file, check if a test file exists
271
+ for file in $changed; do
272
+ base=$(basename "$file" | sed -E 's/\.(ts|tsx|js|jsx)$//')
273
+ dir=$(dirname "$file")
274
+
275
+ # Look for test files in common locations
276
+ test_found=false
277
+
278
+ # Check co-located test file
279
+ if ls "$dir/$base.test."* 2>/dev/null | grep -q .; then
280
+ test_found=true
281
+ fi
282
+
283
+ # Check __tests__ directory
284
+ if ls "$dir/__tests__/$base.test."* 2>/dev/null | grep -q .; then
285
+ test_found=true
286
+ fi
287
+
288
+ # Check root __tests__ with path structure
289
+ if ls "__tests__/${file%.ts*}.test."* 2>/dev/null | grep -q .; then
290
+ test_found=true
291
+ fi
292
+
293
+ if [ "$test_found" = false ]; then
294
+ echo "āš ļø NO TEST: $file"
295
+ fi
296
+ done
297
+ ```
298
+
299
+ 3. **Generate Coverage Warning Report:**
300
+
301
+ ```markdown
302
+ ### Test Coverage Analysis
303
+
304
+ | Source File | Has Test? | Notes |
305
+ |-------------|-----------|-------|
306
+ | `src/lib/feature.ts` | āš ļø No | New file, no test coverage |
307
+ | `src/lib/utils.ts` | āœ… Yes | `src/lib/utils.test.ts` |
308
+ | `app/admin/page.tsx` | - | UI component (browser tested) |
309
+
310
+ **Coverage:** X/Y changed source files have corresponding tests
311
+
312
+ **Warning:** The following new/modified files lack test coverage:
313
+ - `src/lib/feature.ts` - Consider adding `src/lib/feature.test.ts`
314
+ ```
315
+
316
+ 4. **Coverage Tier Classification:**
317
+
318
+ | Tier | File Pattern | Coverage Recommendation |
319
+ |------|--------------|------------------------|
320
+ | **Critical** | `auth/*`, `payment/*`, `security/*`, `middleware/*` | āš ļø Flag prominently if missing |
321
+ | **Standard** | `lib/*`, `utils/*`, `api/*`, `server/*` | Note if missing |
322
+ | **UI/Browser** | `app/**/page.tsx`, `components/*` | Browser testing covers these |
323
+ | **Config/Types** | `*.config.*`, `types/*`, `*.d.ts` | No test required |
324
+
325
+ 5. **Detection Heuristic for Critical Paths:**
326
+ ```bash
327
+ # Flag critical path changes without tests
328
+ critical=$(echo "$changed" | grep -E 'auth|payment|security|middleware|server-action' || true)
329
+ if [[ -n "$critical" ]]; then
330
+ echo "āš ļø CRITICAL PATH CHANGES - test coverage strongly recommended:"
331
+ echo "$critical"
332
+ fi
333
+ ```
334
+
335
+ 6. **Behavior:**
336
+ - **Warning-only**: Does NOT block test execution
337
+ - Include coverage analysis in test results report
338
+ - Recommend adding tests for uncovered critical paths
339
+ - Note UI files are covered by browser testing (this skill)
340
+
341
+ **Why this matters:** Catching missing test coverage early:
342
+ - Prevents regressions from shipping untested code
343
+ - Ensures new logic has corresponding test validation
344
+ - Highlights critical paths that need extra scrutiny
136
345
 
137
346
  ## Decision Point: Feature Implemented or Not?
138
347
 
@@ -369,6 +578,13 @@ Create structured test results:
369
578
 
370
579
  ### 3.2 GitHub Comment
371
580
 
581
+ **If orchestrated (SEQUANT_ORCHESTRATOR is set):**
582
+ - Skip posting GitHub comment (orchestrator handles summary)
583
+ - Include test summary in output for orchestrator to capture
584
+ - Let orchestrator aggregate results across phases
585
+
586
+ **If standalone:**
587
+
372
588
  Draft comment for Issue #<N>:
373
589
 
374
590
  ```markdown
@@ -436,6 +652,8 @@ If no explicit tests, use AC as test cases:
436
652
 
437
653
  ## Browser Testing Best Practices
438
654
 
655
+ **Reference:** See [Browser Testing Patterns](references/browser-testing-patterns.md) for comprehensive patterns including forms, modals, grids, async content, and troubleshooting.
656
+
439
657
  ### Snapshots vs. Screenshots
440
658
 
441
659
  **Use `take_snapshot()` when:**
@@ -587,6 +805,33 @@ Both can be used together:
587
805
 
588
806
  ---
589
807
 
808
+ ## State Tracking
809
+
810
+ **IMPORTANT:** Update workflow state when running standalone (not orchestrated).
811
+
812
+ ### State Updates (Standalone Only)
813
+
814
+ When NOT orchestrated (`SEQUANT_ORCHESTRATOR` is not set):
815
+
816
+ **At skill start:**
817
+ ```bash
818
+ npx tsx scripts/state/update.ts start <issue-number> test
819
+ ```
820
+
821
+ **On successful completion:**
822
+ ```bash
823
+ npx tsx scripts/state/update.ts complete <issue-number> test
824
+ ```
825
+
826
+ **On failure:**
827
+ ```bash
828
+ npx tsx scripts/state/update.ts fail <issue-number> test "X/Y tests failed"
829
+ ```
830
+
831
+ **Why this matters:** State tracking enables dashboard visibility, resume capability, and workflow orchestration. Skills update state when standalone; orchestrators handle state when running workflows.
832
+
833
+ ---
834
+
590
835
  ## Output Verification
591
836
 
592
837
  **Before responding, verify your output includes ALL of these:**
@@ -17,7 +17,7 @@ allowed-tools:
17
17
  - Bash(git worktree list:*)
18
18
  - Bash(ls:*)
19
19
  - Bash(mkdir:*)
20
- - Task(general-purpose)
20
+ - Agent(sequant-testgen)
21
21
  ---
22
22
 
23
23
  # Test Generation Command
@@ -39,6 +39,116 @@ When invoked as `/testgen <issue-number>`, your job is to:
39
39
  - `/testgen 123` - Generate test stubs for issue #123 based on /spec comment
40
40
  - `/testgen` - Generate stubs for the most recently discussed issue in conversation
41
41
 
42
+ ## Token Optimization with Haiku Sub-Agents
43
+
44
+ **Purpose:** Test stub generation is highly mechanical and benefits from using haiku sub-agents to minimize token cost.
45
+
46
+ **Pattern:** Use `Agent(subagent_type="sequant-testgen")` for:
47
+ 1. Parsing verification criteria from /spec comments
48
+ 2. Generating individual test stubs from templates
49
+ 3. Writing test file content
50
+
51
+ **Benefits:**
52
+ - 90% token cost reduction for mechanical generation
53
+ - Faster execution for templated operations
54
+ - Main agent focuses on orchestration and decisions
55
+
56
+ ### Sub-Agent Usage
57
+
58
+ **Step 1: Parse Verification Criteria (use haiku)**
59
+
60
+ ```javascript
61
+ Agent(subagent_type="sequant-testgen", prompt=`
62
+ Parse the following /spec comment and extract verification criteria.
63
+
64
+ For each AC, extract:
65
+ - AC number and description
66
+ - Verification method (Unit Test, Integration Test, Browser Test, Manual Test)
67
+ - Test scenario (Given/When/Then)
68
+ - Integration points
69
+ - Assumptions to validate
70
+
71
+ Return as JSON:
72
+ {
73
+ "criteria": [
74
+ {
75
+ "acNumber": "AC-1",
76
+ "description": "...",
77
+ "verificationMethod": "Unit Test",
78
+ "scenario": { "given": "...", "when": "...", "then": "..." },
79
+ "integrationPoints": ["..."],
80
+ "assumptions": ["..."]
81
+ }
82
+ ]
83
+ }
84
+
85
+ /spec comment:
86
+ ${specComment}
87
+ `)
88
+ ```
89
+
90
+ **Step 2: Generate Test Stubs (use haiku for each AC)**
91
+
92
+ ```javascript
93
+ // For each AC with Unit Test or Integration Test verification method
94
+ Agent(subagent_type="sequant-testgen", prompt=`
95
+ Generate a Jest test stub for the following verification criteria.
96
+
97
+ AC: ${ac.acNumber}: ${ac.description}
98
+ Verification Method: ${ac.verificationMethod}
99
+ Test Scenario:
100
+ - Given: ${ac.scenario.given}
101
+ - When: ${ac.scenario.when}
102
+ - Then: ${ac.scenario.then}
103
+
104
+ Use the template format:
105
+ - Include Given/When/Then as comments
106
+ - Add TODO markers where implementation is needed
107
+ - Include failure path stubs based on the action verb
108
+ - Use throw new Error('Test stub - implement this test')
109
+
110
+ Return ONLY the test code, no explanation.
111
+ `)
112
+ ```
113
+
114
+ **Step 3: Write Test Files (main agent)**
115
+
116
+ The main agent handles file operations to ensure proper coordination:
117
+ - Check if files exist (don't overwrite)
118
+ - Create directories if needed
119
+ - Write generated stubs to correct locations
120
+
121
+ ### When to Use Sub-Agents vs Main Agent
122
+
123
+ | Task | Agent | Reasoning |
124
+ |------|-------|-----------|
125
+ | Parse /spec comment | haiku | Mechanical text extraction |
126
+ | Generate test stub code | haiku | Templated generation |
127
+ | Identify failure scenarios | haiku | Pattern matching |
128
+ | Decide file locations | main | Requires codebase context |
129
+ | Write files | main | File system coordination |
130
+ | Post GitHub comment | main | Session context needed |
131
+
132
+ ### Parallel Sub-Agent Execution
133
+
134
+ When multiple ACs need test stubs, spawn haiku agents in parallel:
135
+
136
+ ```javascript
137
+ // Spawn all stub generation agents in a single message
138
+ const stubPromises = criteria
139
+ .filter(ac => ac.verificationMethod === 'Unit Test' || ac.verificationMethod === 'Integration Test')
140
+ .map(ac => Agent(subagent_type="sequant-testgen", prompt=`Generate test stub for ${ac.acNumber}...`))
141
+
142
+ // Collect results
143
+ // Main agent writes all files
144
+ ```
145
+
146
+ **Cost savings example:**
147
+ - 5 AC items with Unit Test verification
148
+ - Without haiku: ~50K tokens (main agent generates all)
149
+ - With haiku: ~5K tokens (main orchestrates, haiku generates)
150
+ - Savings: ~90%
151
+
42
152
  ## Workflow
43
153
 
44
154
  ### Step 1: Read Verification Criteria from GitHub Issue
@@ -562,6 +672,33 @@ Generated with [Claude Code](https://claude.com/claude-code)
562
672
 
563
673
  ---
564
674
 
675
+ ## State Tracking
676
+
677
+ **IMPORTANT:** Update workflow state when running standalone (not orchestrated).
678
+
679
+ ### State Updates (Standalone Only)
680
+
681
+ When NOT orchestrated (`SEQUANT_ORCHESTRATOR` is not set):
682
+
683
+ **At skill start:**
684
+ ```bash
685
+ npx tsx scripts/state/update.ts start <issue-number> testgen
686
+ ```
687
+
688
+ **On successful completion:**
689
+ ```bash
690
+ npx tsx scripts/state/update.ts complete <issue-number> testgen
691
+ ```
692
+
693
+ **On failure:**
694
+ ```bash
695
+ npx tsx scripts/state/update.ts fail <issue-number> testgen "Failed to generate test stubs"
696
+ ```
697
+
698
+ **Note:** `/testgen` is an optional skill that generates test stubs. State tracking is informational - it doesn't block subsequent phases.
699
+
700
+ ---
701
+
565
702
  ## Output Verification
566
703
 
567
704
  **Before responding, verify your output includes ALL of these:**
@@ -19,7 +19,7 @@ export async function dashboardCommand(options = {}) {
19
19
  const port = options.port ?? 3456;
20
20
  const shouldOpen = !options.noOpen;
21
21
  const verbose = options.verbose ?? false;
22
- console.log(chalk.bold("\nšŸ“Š Sequant Dashboard\n"));
22
+ console.log(chalk.bold("\nSequant Dashboard\n"));
23
23
  try {
24
24
  // Dynamic import to avoid loading dashboard code unless needed
25
25
  const { startDashboard } = await import("../../dashboard/server.js");
@@ -82,7 +82,7 @@ export async function doctorCommand(options = {}) {
82
82
  message: `Outdated: ${versionResult.currentVersion} → ${versionResult.latestVersion} available`,
83
83
  });
84
84
  // Show remediation steps
85
- console.log(chalk.yellow(` āš ļø ${getVersionWarning(versionResult.currentVersion, versionResult.latestVersion, versionResult.isLocalInstall)}`));
85
+ console.log(chalk.yellow(` ! ${getVersionWarning(versionResult.currentVersion, versionResult.latestVersion, versionResult.isLocalInstall)}`));
86
86
  console.log("");
87
87
  }
88
88
  else {
@@ -67,7 +67,7 @@ async function updateGitignore() {
67
67
  * Log a default value being used in non-interactive mode
68
68
  */
69
69
  function logDefault(label, value) {
70
- console.log(chalk.blue(`šŸ“¦ ${label}: ${value} (default)`));
70
+ console.log(chalk.blue(`${label}: ${value} (default)`));
71
71
  }
72
72
  export async function initCommand(options) {
73
73
  // Show banner
@@ -106,14 +106,14 @@ export async function initCommand(options) {
106
106
  if (wizardRemainingIssues.length > 0 ||
107
107
  (options.skipSetup && warnings.length > 0)) {
108
108
  if (wizardRemainingIssues.length > 0) {
109
- console.log(chalk.yellow("āš ļø Remaining setup issues:\n"));
109
+ console.log(chalk.yellow("! Remaining setup issues:\n"));
110
110
  for (const issue of wizardRemainingIssues) {
111
111
  console.log(chalk.yellow(` • ${issue}`));
112
112
  }
113
113
  console.log();
114
114
  }
115
115
  else if (warnings.length > 0) {
116
- console.log(chalk.yellow("āš ļø Prerequisites:\n"));
116
+ console.log(chalk.yellow("! Prerequisites:\n"));
117
117
  for (const warning of warnings) {
118
118
  console.log(chalk.yellow(` • ${warning}`));
119
119
  }
@@ -126,7 +126,7 @@ export async function initCommand(options) {
126
126
  // Check if already initialized
127
127
  const configExists = await fileExists(".claude/settings.json");
128
128
  if (configExists && !options.force) {
129
- console.log(chalk.yellow("āš ļø Sequant appears to be already initialized (.claude/settings.json exists)"));
129
+ console.log(chalk.yellow("! Sequant appears to be already initialized (.claude/settings.json exists)"));
130
130
  console.log(chalk.gray(" Use --force to reinitialize\n"));
131
131
  if (!skipPrompts) {
132
132
  const { proceed } = await inquirer.prompt([
@@ -151,7 +151,7 @@ export async function initCommand(options) {
151
151
  const allDetectedStacks = !skipPrompts ? await detectAllStacks() : [];
152
152
  if (allDetectedStacks.length > 1 && !skipPrompts) {
153
153
  // Multi-stack project detected - show checkbox selection
154
- console.log(chalk.blue(`\nšŸ” Detected ${allDetectedStacks.length} stacks in this project:`));
154
+ console.log(chalk.blue(`\nDetected ${allDetectedStacks.length} stacks in this project:`));
155
155
  for (const ds of allDetectedStacks) {
156
156
  const location = ds.path ? ` (${ds.path}/)` : " (root)";
157
157
  console.log(chalk.gray(` • ${STACKS[ds.stack]?.displayName || ds.stack}${location}`));
@@ -258,7 +258,7 @@ export async function initCommand(options) {
258
258
  // Detect package manager
259
259
  const packageManager = await detectPackageManager();
260
260
  if (packageManager) {
261
- console.log(chalk.blue(`šŸ“¦ Package Manager: ${packageManager}`));
261
+ console.log(chalk.blue(`Package Manager: ${packageManager}`));
262
262
  }
263
263
  // Get stack config for default dev URL
264
264
  const stackConfig = getStackConfig(stack);
@@ -381,14 +381,14 @@ export async function initCommand(options) {
381
381
  // Some symlinks may have fallen back to copies
382
382
  const fallbacks = symlinkResults.filter((r) => r.fallbackToCopy);
383
383
  if (fallbacks.length > 0) {
384
- console.log(chalk.yellow("āš ļø Some scripts were copied instead of symlinked:"));
384
+ console.log(chalk.yellow("! Some scripts were copied instead of symlinked:"));
385
385
  for (const fb of fallbacks) {
386
386
  console.log(chalk.gray(` ${fb.path}: ${fb.reason}`));
387
387
  }
388
388
  }
389
389
  const skipped = symlinkResults.filter((r) => r.skipped);
390
390
  if (skipped.length > 0) {
391
- console.log(chalk.yellow("āš ļø Some scripts were skipped (existing files found):"));
391
+ console.log(chalk.yellow("! Some scripts were skipped (existing files found):"));
392
392
  for (const s of skipped) {
393
393
  console.log(chalk.gray(` ${s.path}: ${s.reason}`));
394
394
  }
@@ -444,7 +444,7 @@ export async function initCommand(options) {
444
444
  for (const client of detectedClients) {
445
445
  console.log(chalk.gray(` • ${client.name}`));
446
446
  }
447
- let addMcp = false;
447
+ let addMcp;
448
448
  if (skipPrompts) {
449
449
  // --yes alone skips MCP config; --yes --mcp explicitly opts in
450
450
  addMcp = !!options.mcp;
@@ -483,7 +483,7 @@ export async function initCommand(options) {
483
483
  // Build prerequisites reminder if there were remaining issues from wizard or warnings
484
484
  const hasRemainingIssues = wizardRemainingIssues.length > 0 || warnings.length > 0;
485
485
  const prereqReminder = hasRemainingIssues
486
- ? `\n${chalk.yellow("āš ļø Remember to install missing dependencies before using issue workflows.")}\n${chalk.gray(" Run 'sequant doctor' to verify your setup.\n")}`
486
+ ? `\n${chalk.yellow("! Remember to install missing dependencies before using issue workflows.")}\n${chalk.gray(" Run 'sequant doctor' to verify your setup.\n")}`
487
487
  : "";
488
488
  // Success message with boxed output
489
489
  const nextStepsContent = `${chalk.bold("Next steps:")}
@@ -171,7 +171,7 @@ function filterLogs(logs, options) {
171
171
  async function handleRotation(logDir, dryRun) {
172
172
  const settings = await getSettings();
173
173
  const stats = getLogStats(logDir, settings.run.rotation);
174
- console.log(chalk.blue("\nšŸ“ Log Rotation\n"));
174
+ console.log(chalk.blue("\nLog Rotation\n"));
175
175
  console.log(chalk.gray(` Log directory: ${logDir}`));
176
176
  console.log(chalk.gray(` Current: ${stats.fileCount} files, ${formatBytes(stats.totalSizeBytes)}`));
177
177
  console.log(chalk.gray(` Thresholds: ${settings.run.rotation.maxFiles} files, ${settings.run.rotation.maxSizeMB} MB`));