@sentry/warden 0.1.0 → 0.1.1

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.
@@ -175,30 +175,6 @@ remote = "getsentry/skills@abc123"
175
175
 
176
176
  **Cache TTL:** 24 hours for unpinned refs (override with `WARDEN_SKILL_CACHE_TTL` in seconds)
177
177
 
178
- **Inline skill in warden.toml:**
179
-
180
- ```toml
181
- [[skills]]
182
- name = "custom-check"
183
- description = "Check for TODO comments"
184
- prompt = """
185
- Find TODO comments that have been in the code for too long.
186
- Report as low severity findings.
187
- """
188
-
189
- [skills.tools]
190
- allowed = ["Read", "Grep", "Glob"]
191
- ```
192
-
193
- ## Built-in Skills
194
-
195
- | Skill | Purpose |
196
- |-------|---------|
197
- | `find-bugs` | Logical/functional bugs, null handling, async issues |
198
- | `security-review` | Injection, auth, CSRF, crypto, race conditions |
199
- | `code-simplifier` | Readability, consistency, redundancy removal |
200
- | `performance-review` | N+1 queries, blocking I/O, memory leaks |
201
-
202
178
  ## Common Patterns
203
179
 
204
180
  **Strict security on critical files:**
@@ -7,7 +7,6 @@ version = 1 # Required, must be 1
7
7
 
8
8
  [defaults] # Optional, inherited by all triggers
9
9
  [[triggers]] # Required, array of trigger configs
10
- [[skills]] # Optional, inline skill definitions
11
10
  ```
12
11
 
13
12
  ## Defaults Section
@@ -81,22 +80,6 @@ fixBranchPrefix = "security-fix" # Branch name prefix
81
80
  **Actions (for non-schedule):**
82
81
  - `opened`, `synchronize`, `reopened`, `closed`
83
82
 
84
- ## Skills Section (Inline Skills)
85
-
86
- ```toml
87
- [[skills]]
88
- name = "custom-skill"
89
- description = "What this skill checks"
90
- prompt = """
91
- Analysis instructions here.
92
- Look for specific issues.
93
- """
94
-
95
- [skills.tools]
96
- allowed = ["Read", "Grep", "Glob"] # Whitelist tools
97
- denied = ["Write", "Edit", "Bash"] # Blacklist tools (optional)
98
- ```
99
-
100
83
  ## Severity Values
101
84
 
102
85
  Used in `failOn` and `commentOn`:
@@ -8,4 +8,8 @@ export declare const ICON_CHECK = "\u2713";
8
8
  export declare const ICON_SKIPPED = "\u2193";
9
9
  /** Braille spinner frames for loading animation */
10
10
  export declare const SPINNER_FRAMES: string[];
11
+ /** Circle for pending states */
12
+ export declare const ICON_PENDING = "\u25CB";
13
+ /** X mark for error states */
14
+ export declare const ICON_ERROR = "\u2717";
11
15
  //# sourceMappingURL=icons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["file:///home/runner/work/warden/warden/src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,oCAAoC;AACpC,eAAO,MAAM,YAAY,WAAM,CAAC;AAEhC,mDAAmD;AACnD,eAAO,MAAM,cAAc,UAAuG,CAAC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["file:///home/runner/work/warden/warden/src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,oCAAoC;AACpC,eAAO,MAAM,YAAY,WAAM,CAAC;AAEhC,mDAAmD;AACnD,eAAO,MAAM,cAAc,UAAuG,CAAC;AAEnI,gCAAgC;AAChC,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,8BAA8B;AAC9B,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -1,5 +1,25 @@
1
1
  /**
2
2
  * Ink-based skill runner with real-time progress display.
3
+ *
4
+ * ## Ink Rendering Constraints
5
+ *
6
+ * This file uses Ink (React for CLIs) which has specific constraints that,
7
+ * if violated, cause duplicate output lines or corrupted display:
8
+ *
9
+ * 1. **Single Static component**: Ink's Static uses `position: 'absolute'`.
10
+ * Multiple Static components cause layout conflicts. We print the header
11
+ * before Ink starts to avoid needing a second Static.
12
+ *
13
+ * 2. **Stable item references**: Static tracks items by reference equality.
14
+ * Never wrap items in new objects (e.g., `{ type: 'skill', skill }`) on
15
+ * each render. Pass the original objects directly.
16
+ *
17
+ * 3. **Batched updates**: Rapid consecutive rerender() calls cause duplicate
18
+ * output. The updateUI() function batches updates using setImmediate().
19
+ *
20
+ * 4. **No direct writes to stderr**: Writing to process.stderr while Ink is
21
+ * running corrupts cursor tracking. The onLargePrompt/onPromptSize callbacks
22
+ * are exceptions that may cause minor display glitches in edge cases.
3
23
  */
4
24
  import { type SkillTaskOptions, type SkillTaskResult, type RunTasksOptions } from './tasks.js';
5
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ink-runner.d.ts","sourceRoot":"","sources":["file:///home/runner/work/warden/warden/src/cli/output/ink-runner.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AA0KpB;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,EAAE,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAkJ5B"}
1
+ {"version":3,"file":"ink-runner.d.ts","sourceRoot":"","sources":["file:///home/runner/work/warden/warden/src/cli/output/ink-runner.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAoKpB;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,EAAE,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAiK5B"}
@@ -8,4 +8,8 @@ export declare const ICON_CHECK = "\u2713";
8
8
  export declare const ICON_SKIPPED = "\u2193";
9
9
  /** Braille spinner frames for loading animation */
10
10
  export declare const SPINNER_FRAMES: string[];
11
+ /** Circle for pending states */
12
+ export declare const ICON_PENDING = "\u25CB";
13
+ /** X mark for error states */
14
+ export declare const ICON_ERROR = "\u2717";
11
15
  //# sourceMappingURL=icons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,oCAAoC;AACpC,eAAO,MAAM,YAAY,WAAM,CAAC;AAEhC,mDAAmD;AACnD,eAAO,MAAM,cAAc,UAAuG,CAAC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,UAAU,WAAM,CAAC;AAE9B,oCAAoC;AACpC,eAAO,MAAM,YAAY,WAAM,CAAC;AAEhC,mDAAmD;AACnD,eAAO,MAAM,cAAc,UAAuG,CAAC;AAEnI,gCAAgC;AAChC,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,8BAA8B;AAC9B,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -8,4 +8,8 @@ export const ICON_CHECK = '✓'; // U+2713 CHECK MARK
8
8
  export const ICON_SKIPPED = '↓'; // U+2193 DOWNWARDS ARROW
9
9
  /** Braille spinner frames for loading animation */
10
10
  export const SPINNER_FRAMES = ['\u280B', '\u2819', '\u2839', '\u2838', '\u283C', '\u2834', '\u2826', '\u2827', '\u2807', '\u280F'];
11
+ /** Circle for pending states */
12
+ export const ICON_PENDING = '\u25CB'; // ○ WHITE CIRCLE
13
+ /** X mark for error states */
14
+ export const ICON_ERROR = '\u2717'; // ✗ BALLOT X
11
15
  //# sourceMappingURL=icons.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../../src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,oBAAoB;AAEnD,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC,CAAC,yBAAyB;AAE1D,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../../src/cli/output/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,oBAAoB;AAEnD,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC,CAAC,yBAAyB;AAE1D,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEnI,gCAAgC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,iBAAiB;AAEvD,8BAA8B;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,aAAa"}
@@ -1,5 +1,25 @@
1
1
  /**
2
2
  * Ink-based skill runner with real-time progress display.
3
+ *
4
+ * ## Ink Rendering Constraints
5
+ *
6
+ * This file uses Ink (React for CLIs) which has specific constraints that,
7
+ * if violated, cause duplicate output lines or corrupted display:
8
+ *
9
+ * 1. **Single Static component**: Ink's Static uses `position: 'absolute'`.
10
+ * Multiple Static components cause layout conflicts. We print the header
11
+ * before Ink starts to avoid needing a second Static.
12
+ *
13
+ * 2. **Stable item references**: Static tracks items by reference equality.
14
+ * Never wrap items in new objects (e.g., `{ type: 'skill', skill }`) on
15
+ * each render. Pass the original objects directly.
16
+ *
17
+ * 3. **Batched updates**: Rapid consecutive rerender() calls cause duplicate
18
+ * output. The updateUI() function batches updates using setImmediate().
19
+ *
20
+ * 4. **No direct writes to stderr**: Writing to process.stderr while Ink is
21
+ * running corrupts cursor tracking. The onLargePrompt/onPromptSize callbacks
22
+ * are exceptions that may cause minor display glitches in edge cases.
3
23
  */
4
24
  import { type SkillTaskOptions, type SkillTaskResult, type RunTasksOptions } from './tasks.js';
5
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ink-runner.d.ts","sourceRoot":"","sources":["../../../src/cli/output/ink-runner.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AA0KpB;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,EAAE,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAkJ5B"}
1
+ {"version":3,"file":"ink-runner.d.ts","sourceRoot":"","sources":["../../../src/cli/output/ink-runner.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAoKpB;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,EAAE,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAiK5B"}
@@ -1,13 +1,33 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * Ink-based skill runner with real-time progress display.
4
+ *
5
+ * ## Ink Rendering Constraints
6
+ *
7
+ * This file uses Ink (React for CLIs) which has specific constraints that,
8
+ * if violated, cause duplicate output lines or corrupted display:
9
+ *
10
+ * 1. **Single Static component**: Ink's Static uses `position: 'absolute'`.
11
+ * Multiple Static components cause layout conflicts. We print the header
12
+ * before Ink starts to avoid needing a second Static.
13
+ *
14
+ * 2. **Stable item references**: Static tracks items by reference equality.
15
+ * Never wrap items in new objects (e.g., `{ type: 'skill', skill }`) on
16
+ * each render. Pass the original objects directly.
17
+ *
18
+ * 3. **Batched updates**: Rapid consecutive rerender() calls cause duplicate
19
+ * output. The updateUI() function batches updates using setImmediate().
20
+ *
21
+ * 4. **No direct writes to stderr**: Writing to process.stderr while Ink is
22
+ * running corrupts cursor tracking. The onLargePrompt/onPromptSize callbacks
23
+ * are exceptions that may cause minor display glitches in edge cases.
4
24
  */
5
25
  import { useState, useEffect } from 'react';
6
26
  import { render, Box, Text, Static } from 'ink';
7
27
  import { runSkillTask, } from './tasks.js';
8
28
  import { formatDuration, truncate, countBySeverity, formatSeverityDot } from './formatters.js';
9
29
  import { Verbosity } from './verbosity.js';
10
- import { ICON_CHECK, ICON_SKIPPED, SPINNER_FRAMES } from './icons.js';
30
+ import { ICON_CHECK, ICON_SKIPPED, ICON_PENDING, ICON_ERROR, SPINNER_FRAMES } from './icons.js';
11
31
  import figures from 'figures';
12
32
  function Spinner() {
13
33
  const [frame, setFrame] = useState(0);
@@ -37,7 +57,7 @@ function CompletedSkill({ skill }) {
37
57
  return (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: ICON_SKIPPED }), _jsxs(Text, { children: [" ", skill.displayName] }), _jsx(Text, { dimColor: true, children: " [skipped]" })] }));
38
58
  }
39
59
  if (skill.status === 'error') {
40
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "red", children: '\u2717' }), _jsxs(Text, { children: [" ", skill.displayName] }), duration && _jsxs(Text, { dimColor: true, children: [" [", duration, "]"] })] }), skill.error && _jsxs(Text, { color: "red", children: [" Error: ", skill.error] })] }));
60
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "red", children: ICON_ERROR }), _jsxs(Text, { children: [" ", skill.displayName] }), duration && _jsxs(Text, { dimColor: true, children: [" [", duration, "]"] })] }), skill.error && _jsxs(Text, { color: "red", children: [" Error: ", skill.error] })] }));
41
61
  }
42
62
  return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: ICON_CHECK }), _jsxs(Text, { children: [" ", skill.displayName] }), duration && _jsxs(Text, { dimColor: true, children: [" [", duration, "]"] })] }));
43
63
  }
@@ -45,22 +65,21 @@ function RunningSkill({ skill }) {
45
65
  const visibleFiles = skill.files.filter((f) => f.status !== 'pending');
46
66
  return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Spinner, {}), _jsxs(Text, { children: [" ", skill.displayName] })] }), visibleFiles.map((file) => (_jsx(Box, { marginLeft: 2, children: _jsx(FileProgress, { file: file }) }, file.filename)))] }));
47
67
  }
68
+ /**
69
+ * Renders the skill execution UI.
70
+ *
71
+ * IMPORTANT: Ink's Static component tracks items by reference equality.
72
+ * Items passed to Static must have stable references across renders.
73
+ * Creating new wrapper objects causes Static to mishandle its internal
74
+ * state, resulting in duplicate output lines.
75
+ *
76
+ * We use a SINGLE Static component to avoid layout conflicts from multiple
77
+ * absolutely-positioned Static containers.
78
+ */
48
79
  function SkillRunner({ skills, completedItems }) {
49
80
  const running = skills.filter((s) => s.status === 'running');
50
81
  const pending = skills.filter((s) => s.status === 'pending');
51
- // Build static items: header first, then completed skills
52
- const staticItems = [
53
- { type: 'header' },
54
- ...completedItems.map((skill) => ({ type: 'skill', skill })),
55
- ];
56
- return (_jsxs(_Fragment, { children: [_jsx(Static, { items: staticItems, children: (item) => {
57
- switch (item.type) {
58
- case 'header':
59
- return (_jsx(Text, { bold: true, children: "SKILLS" }, "header"));
60
- case 'skill':
61
- return _jsx(CompletedSkill, { skill: item.skill }, item.skill.name);
62
- }
63
- } }), _jsxs(Box, { flexDirection: "column", children: [running.map((skill) => (_jsx(RunningSkill, { skill: skill }, skill.name))), pending.map((skill) => (_jsxs(Text, { dimColor: true, children: ['\u25CB', " ", skill.displayName] }, skill.name)))] })] }));
82
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: completedItems, children: (skill) => _jsx(CompletedSkill, { skill: skill }, skill.name) }), running.map((skill) => (_jsx(RunningSkill, { skill: skill }, skill.name))), pending.map((skill) => (_jsxs(Text, { dimColor: true, children: [ICON_PENDING, " ", skill.displayName] }, skill.name)))] }));
64
83
  }
65
84
  /** No-op callbacks for quiet mode. */
66
85
  // eslint-disable-next-line @typescript-eslint/no-empty-function
@@ -91,10 +110,24 @@ export async function runSkillTasksWithInk(tasks, options) {
91
110
  const skillStates = [];
92
111
  const completedItems = [];
93
112
  const completedNames = new Set();
113
+ // Print header before Ink starts - this avoids multiple Static components
114
+ // which can cause layout conflicts due to absolute positioning
115
+ process.stderr.write('\x1b[1mSKILLS\x1b[0m\n');
94
116
  // Create Ink instance
95
117
  const { rerender, unmount } = render(_jsx(SkillRunner, { skills: skillStates, completedItems: completedItems }), { stdout: process.stderr });
118
+ // Batch UI updates to prevent rapid consecutive rerenders that cause duplicate lines.
119
+ // Without batching, multiple callbacks firing in quick succession (e.g., 5 files
120
+ // starting simultaneously) trigger 5 immediate rerenders, which Ink cannot
121
+ // process correctly, resulting in the same line appearing multiple times.
122
+ let updatePending = false;
96
123
  const updateUI = () => {
97
- rerender(_jsx(SkillRunner, { skills: [...skillStates], completedItems: [...completedItems] }));
124
+ if (updatePending)
125
+ return;
126
+ updatePending = true;
127
+ setImmediate(() => {
128
+ updatePending = false;
129
+ rerender(_jsx(SkillRunner, { skills: [...skillStates], completedItems: [...completedItems] }));
130
+ });
98
131
  };
99
132
  // Callbacks to update state
100
133
  const callbacks = {
@@ -171,13 +204,14 @@ export async function runSkillTasksWithInk(tasks, options) {
171
204
  }
172
205
  updateUI();
173
206
  },
174
- // Warn about large prompts - write directly to stderr to avoid Ink interference
207
+ // CAUTION: Direct stderr writes while Ink is running can cause display glitches.
208
+ // These callbacks are rare (large prompts, debug mode) so the tradeoff is acceptable.
209
+ // If these cause issues, consider queueing messages and printing after unmount().
175
210
  onLargePrompt: (_skillName, filename, lineRange, chars, estimatedTokens) => {
176
211
  const location = `${filename}:${lineRange}`;
177
212
  const size = `${Math.round(chars / 1000)}k chars (~${Math.round(estimatedTokens / 1000)}k tokens)`;
178
213
  process.stderr.write(`\x1b[33m${figures.warning}\x1b[0m Large prompt for ${location}: ${size}\n`);
179
214
  },
180
- // Debug mode: show prompt sizes
181
215
  onPromptSize: verbosity >= Verbosity.Debug
182
216
  ? (_skillName, filename, lineRange, systemChars, userChars, totalChars, estimatedTokens) => {
183
217
  const location = `${filename}:${lineRange}`;
@@ -1 +1 @@
1
- {"version":3,"file":"ink-runner.js","sourceRoot":"","sources":["../../../src/cli/output/ink-runner.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ink-runner.js","sourceRoot":"","sources":["../../../src/cli/output/ink-runner.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/warden",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Event-driven agent that reacts to GitHub events and executes skills via Claude Code SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,3 +11,9 @@ export const ICON_SKIPPED = '↓'; // U+2193 DOWNWARDS ARROW
11
11
 
12
12
  /** Braille spinner frames for loading animation */
13
13
  export const SPINNER_FRAMES = ['\u280B', '\u2819', '\u2839', '\u2838', '\u283C', '\u2834', '\u2826', '\u2827', '\u2807', '\u280F'];
14
+
15
+ /** Circle for pending states */
16
+ export const ICON_PENDING = '\u25CB'; // ○ WHITE CIRCLE
17
+
18
+ /** X mark for error states */
19
+ export const ICON_ERROR = '\u2717'; // ✗ BALLOT X
@@ -1,5 +1,25 @@
1
1
  /**
2
2
  * Ink-based skill runner with real-time progress display.
3
+ *
4
+ * ## Ink Rendering Constraints
5
+ *
6
+ * This file uses Ink (React for CLIs) which has specific constraints that,
7
+ * if violated, cause duplicate output lines or corrupted display:
8
+ *
9
+ * 1. **Single Static component**: Ink's Static uses `position: 'absolute'`.
10
+ * Multiple Static components cause layout conflicts. We print the header
11
+ * before Ink starts to avoid needing a second Static.
12
+ *
13
+ * 2. **Stable item references**: Static tracks items by reference equality.
14
+ * Never wrap items in new objects (e.g., `{ type: 'skill', skill }`) on
15
+ * each render. Pass the original objects directly.
16
+ *
17
+ * 3. **Batched updates**: Rapid consecutive rerender() calls cause duplicate
18
+ * output. The updateUI() function batches updates using setImmediate().
19
+ *
20
+ * 4. **No direct writes to stderr**: Writing to process.stderr while Ink is
21
+ * running corrupts cursor tracking. The onLargePrompt/onPromptSize callbacks
22
+ * are exceptions that may cause minor display glitches in edge cases.
3
23
  */
4
24
 
5
25
  import React, { useState, useEffect } from 'react';
@@ -15,11 +35,9 @@ import {
15
35
  } from './tasks.js';
16
36
  import { formatDuration, truncate, countBySeverity, formatSeverityDot } from './formatters.js';
17
37
  import { Verbosity } from './verbosity.js';
18
- import { ICON_CHECK, ICON_SKIPPED, SPINNER_FRAMES } from './icons.js';
38
+ import { ICON_CHECK, ICON_SKIPPED, ICON_PENDING, ICON_ERROR, SPINNER_FRAMES } from './icons.js';
19
39
  import figures from 'figures';
20
40
 
21
- type StaticItem = { type: 'header' } | { type: 'skill'; skill: SkillState };
22
-
23
41
  interface SkillRunnerProps {
24
42
  skills: SkillState[];
25
43
  completedItems: SkillState[];
@@ -91,7 +109,7 @@ function CompletedSkill({ skill }: { skill: SkillState }): React.ReactElement {
91
109
  return (
92
110
  <Box flexDirection="column">
93
111
  <Box>
94
- <Text color="red">{'\u2717'}</Text>
112
+ <Text color="red">{ICON_ERROR}</Text>
95
113
  <Text> {skill.displayName}</Text>
96
114
  {duration && <Text dimColor> [{duration}]</Text>}
97
115
  </Box>
@@ -127,46 +145,42 @@ function RunningSkill({ skill }: { skill: SkillState }): React.ReactElement {
127
145
  );
128
146
  }
129
147
 
148
+ /**
149
+ * Renders the skill execution UI.
150
+ *
151
+ * IMPORTANT: Ink's Static component tracks items by reference equality.
152
+ * Items passed to Static must have stable references across renders.
153
+ * Creating new wrapper objects causes Static to mishandle its internal
154
+ * state, resulting in duplicate output lines.
155
+ *
156
+ * We use a SINGLE Static component to avoid layout conflicts from multiple
157
+ * absolutely-positioned Static containers.
158
+ */
130
159
  function SkillRunner({ skills, completedItems }: SkillRunnerProps): React.ReactElement {
131
160
  const running = skills.filter((s) => s.status === 'running');
132
161
  const pending = skills.filter((s) => s.status === 'pending');
133
162
 
134
- // Build static items: header first, then completed skills
135
- const staticItems: StaticItem[] = [
136
- { type: 'header' },
137
- ...completedItems.map((skill) => ({ type: 'skill' as const, skill })),
138
- ];
139
-
140
163
  return (
141
- <>
142
- {/* Static content: header + completed skills */}
143
- <Static items={staticItems}>
144
- {(item) => {
145
- switch (item.type) {
146
- case 'header':
147
- return (
148
- <Text key="header" bold>
149
- SKILLS
150
- </Text>
151
- );
152
- case 'skill':
153
- return <CompletedSkill key={item.skill.name} skill={item.skill} />;
154
- }
155
- }}
164
+ <Box flexDirection="column">
165
+ {/*
166
+ * Completed skills - passed directly to Static WITHOUT wrapper objects.
167
+ * completedItems elements have stable references (same objects from parent),
168
+ * so Ink can correctly track which items are new vs already rendered.
169
+ */}
170
+ <Static items={completedItems}>
171
+ {(skill) => <CompletedSkill key={skill.name} skill={skill} />}
156
172
  </Static>
157
173
 
158
- {/* Dynamic content: running + pending */}
159
- <Box flexDirection="column">
160
- {running.map((skill) => (
161
- <RunningSkill key={skill.name} skill={skill} />
162
- ))}
163
- {pending.map((skill) => (
164
- <Text key={skill.name} dimColor>
165
- {'\u25CB'} {skill.displayName}
166
- </Text>
167
- ))}
168
- </Box>
169
- </>
174
+ {/* Dynamic content - updates in place */}
175
+ {running.map((skill) => (
176
+ <RunningSkill key={skill.name} skill={skill} />
177
+ ))}
178
+ {pending.map((skill) => (
179
+ <Text key={skill.name} dimColor>
180
+ {ICON_PENDING} {skill.displayName}
181
+ </Text>
182
+ ))}
183
+ </Box>
170
184
  );
171
185
  }
172
186
 
@@ -206,14 +220,28 @@ export async function runSkillTasksWithInk(
206
220
  const completedItems: SkillState[] = [];
207
221
  const completedNames = new Set<string>();
208
222
 
223
+ // Print header before Ink starts - this avoids multiple Static components
224
+ // which can cause layout conflicts due to absolute positioning
225
+ process.stderr.write('\x1b[1mSKILLS\x1b[0m\n');
226
+
209
227
  // Create Ink instance
210
228
  const { rerender, unmount } = render(
211
229
  <SkillRunner skills={skillStates} completedItems={completedItems} />,
212
230
  { stdout: process.stderr }
213
231
  );
214
232
 
233
+ // Batch UI updates to prevent rapid consecutive rerenders that cause duplicate lines.
234
+ // Without batching, multiple callbacks firing in quick succession (e.g., 5 files
235
+ // starting simultaneously) trigger 5 immediate rerenders, which Ink cannot
236
+ // process correctly, resulting in the same line appearing multiple times.
237
+ let updatePending = false;
215
238
  const updateUI = () => {
216
- rerender(<SkillRunner skills={[...skillStates]} completedItems={[...completedItems]} />);
239
+ if (updatePending) return;
240
+ updatePending = true;
241
+ setImmediate(() => {
242
+ updatePending = false;
243
+ rerender(<SkillRunner skills={[...skillStates]} completedItems={[...completedItems]} />);
244
+ });
217
245
  };
218
246
 
219
247
  // Callbacks to update state
@@ -297,13 +325,14 @@ export async function runSkillTasksWithInk(
297
325
 
298
326
  updateUI();
299
327
  },
300
- // Warn about large prompts - write directly to stderr to avoid Ink interference
328
+ // CAUTION: Direct stderr writes while Ink is running can cause display glitches.
329
+ // These callbacks are rare (large prompts, debug mode) so the tradeoff is acceptable.
330
+ // If these cause issues, consider queueing messages and printing after unmount().
301
331
  onLargePrompt: (_skillName, filename, lineRange, chars, estimatedTokens) => {
302
332
  const location = `${filename}:${lineRange}`;
303
333
  const size = `${Math.round(chars / 1000)}k chars (~${Math.round(estimatedTokens / 1000)}k tokens)`;
304
334
  process.stderr.write(`\x1b[33m${figures.warning}\x1b[0m Large prompt for ${location}: ${size}\n`);
305
335
  },
306
- // Debug mode: show prompt sizes
307
336
  onPromptSize: verbosity >= Verbosity.Debug
308
337
  ? (_skillName, filename, lineRange, systemChars, userChars, totalChars, estimatedTokens) => {
309
338
  const location = `${filename}:${lineRange}`;