@orderful/droid 0.10.1 → 0.10.3

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 (36) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/commands/install.d.ts.map +1 -1
  3. package/dist/commands/install.js +3 -1
  4. package/dist/commands/install.js.map +1 -1
  5. package/dist/commands/setup.d.ts.map +1 -1
  6. package/dist/commands/setup.js +3 -5
  7. package/dist/commands/setup.js.map +1 -1
  8. package/dist/commands/skills.d.ts.map +1 -1
  9. package/dist/commands/skills.js +3 -1
  10. package/dist/commands/skills.js.map +1 -1
  11. package/dist/commands/tui.d.ts.map +1 -1
  12. package/dist/commands/tui.js +38 -41
  13. package/dist/commands/tui.js.map +1 -1
  14. package/dist/skills/brain/SKILL.md +41 -17
  15. package/dist/skills/brain/commands/brain.md +1 -0
  16. package/dist/skills/brain/commands/scratchpad.md +1 -0
  17. package/dist/skills/brain/references/metadata.md +14 -13
  18. package/dist/skills/brain/references/naming.md +12 -10
  19. package/dist/skills/brain/references/templates.md +5 -5
  20. package/dist/skills/brain/references/workflows.md +48 -24
  21. package/dist/skills/comments/SKILL.md +21 -13
  22. package/dist/skills/comments/SKILL.yaml +1 -1
  23. package/package.json +1 -1
  24. package/src/commands/install.ts +5 -1
  25. package/src/commands/setup.ts +3 -5
  26. package/src/commands/skills.ts +5 -1
  27. package/src/commands/tui.tsx +37 -65
  28. package/src/skills/brain/SKILL.md +41 -17
  29. package/src/skills/brain/commands/brain.md +1 -0
  30. package/src/skills/brain/commands/scratchpad.md +1 -0
  31. package/src/skills/brain/references/metadata.md +14 -13
  32. package/src/skills/brain/references/naming.md +12 -10
  33. package/src/skills/brain/references/templates.md +5 -5
  34. package/src/skills/brain/references/workflows.md +48 -24
  35. package/src/skills/comments/SKILL.md +21 -13
  36. package/src/skills/comments/SKILL.yaml +1 -1
@@ -8,14 +8,18 @@ Detailed procedures for each brain operation.
8
8
 
9
9
  **Steps:**
10
10
 
11
- 1. **Read config first**
12
- - Read `~/.droid/skills/brain/overrides.yaml`
13
- - Use `brain_dir` if configured, otherwise use default for current AI tool
11
+ 1. **Read config first (MANDATORY)**
12
+ - Use the Read tool on `~/.droid/skills/brain/overrides.yaml`
13
+ - If file exists and contains `brain_dir:`, use that path
14
+ - Only use defaults if the file doesn't exist or `brain_dir` is not set
15
+ - **Do NOT skip this step or assume defaults**
14
16
 
15
17
  2. **Search for matches**
18
+
16
19
  ```
17
20
  Glob: {brain_dir}/**/*{topic}*.md
18
21
  ```
22
+
19
23
  Fuzzy match the topic against doc filenames
20
24
 
21
25
  3. **Handle results:**
@@ -37,10 +41,12 @@ Detailed procedures for each brain operation.
37
41
 
38
42
  **Steps:**
39
43
 
40
- 1. **Read config first**
41
- - Read `~/.droid/skills/brain/overrides.yaml`
42
- - Use `brain_dir` if configured, otherwise use default for current AI tool
43
- - Use `inbox_folder` if configured
44
+ 1. **Read config first (MANDATORY)**
45
+ - Use the Read tool on `~/.droid/skills/brain/overrides.yaml`
46
+ - If file exists and contains `brain_dir:`, use that path
47
+ - Only use defaults if the file doesn't exist or `brain_dir` is not set
48
+ - Also check for `inbox_folder` setting
49
+ - **Do NOT skip this step or assume defaults**
44
50
 
45
51
  2. **Generate filename** using naming conventions (see `naming.md`):
46
52
  - Format: `{type}-{topic-slug}.md`
@@ -59,11 +65,16 @@ Detailed procedures for each brain operation.
59
65
  - Any constraints or requirements mentioned?
60
66
  - Related work or prior decisions?
61
67
 
62
- 7. **Write the doc** with template structure and initial context
68
+ 7. **Add placeholder comments** for sections needing user input:
69
+ - Read user's mention from `~/.droid/config.yaml` → `user_mention`
70
+ - Use `> @{user_mention}` for placeholders (e.g., `> @fry - Please provide requirements`)
71
+ - **CRITICAL:** NEVER use `@droid` - that's for user-to-AI comments, not AI-to-user
63
72
 
64
- 8. **Set as active doc**
73
+ 8. **Write the doc** with template structure and initial context
65
74
 
66
- 9. **Confirm creation** and summarize what was captured
75
+ 9. **Set as active doc**
76
+
77
+ 10. **Confirm creation** and summarize what was captured
67
78
 
68
79
  ## Notes
69
80
 
@@ -71,10 +82,12 @@ Detailed procedures for each brain operation.
71
82
 
72
83
  **Steps:**
73
84
 
74
- 1. **Read config first**
75
- - Read `~/.droid/skills/brain/overrides.yaml`
76
- - Use `brain_dir` if configured, otherwise use default for current AI tool
77
- - Use `inbox_folder` if configured
85
+ 1. **Read config first (MANDATORY)**
86
+ - Use the Read tool on `~/.droid/skills/brain/overrides.yaml`
87
+ - If file exists and contains `brain_dir:`, use that path
88
+ - Only use defaults if the file doesn't exist or `brain_dir` is not set
89
+ - Also check for `inbox_folder` setting
90
+ - **Do NOT skip this step or assume defaults**
78
91
 
79
92
  2. **Generate filename:**
80
93
  - Format: `note-{date}-{slug}.md` where date is `YYYYMMDD`
@@ -105,8 +118,8 @@ Detailed procedures for each brain operation.
105
118
  2. **Read current content** of active doc
106
119
 
107
120
  3. **Append new section:**
108
- ```markdown
109
121
 
122
+ ```markdown
110
123
  ---
111
124
 
112
125
  ## Update ({date})
@@ -133,18 +146,25 @@ Detailed procedures for each brain operation.
133
146
 
134
147
  2. **Read active doc**
135
148
 
136
- 3. **Find all `> @droid` comments**
149
+ 3. **Check preserve_comments setting:**
150
+ - Read `~/.droid/skills/comments/overrides.yaml` if it exists
151
+ - Look for `preserve_comments` (default: `true`)
152
+
153
+ 4. **Find all `> @droid` comments**
137
154
  - Pattern: Lines starting with `> @droid` (blockquote with mention)
138
155
 
139
- 4. **For each comment:**
156
+ 5. **For each comment:**
140
157
  - Show the comment and surrounding context
141
158
  - Address the question/request
142
- - Add response as `> @{user_mention}` reply
143
- - Or resolve inline if it was a simple note
159
+ - Add response as blockquote with user's mention: `> @{user_mention} Your response here`
160
+ - Example: `> @fry Yes, the index covers that query pattern.`
161
+ - **CRITICAL:** NEVER use `@droid` in your responses. Use `@{user_mention}` from config (e.g., `@fry`)
162
+ - **CRITICAL:** Always include the `>` prefix to maintain blockquote formatting
163
+ - **CRITICAL:** If `preserve_comments: true`, keep the original `@droid` comment and add your response below it. Do NOT remove the original comment.
144
164
 
145
- 5. **Update the doc** with responses
165
+ 6. **Update the doc** with responses
146
166
 
147
- 6. **Summarize** what was addressed
167
+ 7. **Summarize** what was addressed
148
168
 
149
169
  ## Finalizing
150
170
 
@@ -177,14 +197,18 @@ Detailed procedures for each brain operation.
177
197
 
178
198
  **Steps:**
179
199
 
180
- 1. **Read config first**
181
- - Read `~/.droid/skills/brain/overrides.yaml`
182
- - Use `brain_dir` if configured, otherwise use default for current AI tool
200
+ 1. **Read config first (MANDATORY)**
201
+ - Use the Read tool on `~/.droid/skills/brain/overrides.yaml`
202
+ - If file exists and contains `brain_dir:`, use that path
203
+ - Only use defaults if the file doesn't exist or `brain_dir` is not set
204
+ - **Do NOT skip this step or assume defaults**
183
205
 
184
206
  2. **Find recent docs:**
207
+
185
208
  ```
186
209
  Glob: {brain_dir}/**/*.md
187
210
  ```
211
+
188
212
  Sort by modification time, limit to 10-15
189
213
 
190
214
  3. **Present list** with:
@@ -31,21 +31,23 @@ The AI will respond with `> @{user_mention}` (configured in droid setup, e.g., `
31
31
  **CRITICAL: The `@mention` is who you're talking TO, not who is speaking.**
32
32
 
33
33
  Think of it like addressing someone in conversation:
34
+
34
35
  - "Hey @droid, what do you think?" → User talking TO the AI
35
36
  - "Good point @fry, here's my take..." → AI talking TO the user
36
37
 
37
38
  | When you see... | Who wrote it | Who it's addressed to |
38
- |-----------------|--------------|----------------------|
39
- | `> @droid ...` | User | AI (droid) |
40
- | `> @fry ...` | AI | User (fry) |
39
+ | --------------- | ------------ | --------------------- |
40
+ | `> @droid ...` | User | AI (droid) |
41
+ | `> @fry ...` | AI | User (fry) |
41
42
 
42
43
  **Examples:**
44
+
43
45
  ```markdown
44
- > @droid Can you explain this function? ← User asking AI
46
+ > @droid Can you explain this function? ← User asking AI
45
47
  > @fry This function calculates the hash... ← AI responding to user
46
48
 
47
- > @droid Should we refactor this? ← User asking AI
48
- > @fry Yes, I'd suggest extracting... ← AI responding to user
49
+ > @droid Should we refactor this? ← User asking AI
50
+ > @fry Yes, I'd suggest extracting... ← AI responding to user
49
51
  ```
50
52
 
51
53
  **Never flip this.** When responding to a `@droid` comment, always use `@{user}` (e.g., `@fry`) because you're addressing the user, not yourself.
@@ -76,13 +78,19 @@ When you find a `@droid` marker:
76
78
  ## Behavior
77
79
 
78
80
  ### On `/comments check`:
79
- 1. Search for `> @droid` (and any configured `ai_mentions`) in the specified scope
80
- 2. If there's a `git diff`, check those files first for relevant context
81
- 3. For each comment, determine intent:
82
- - **Action request** ("do X", "add Y", "fix Z") Execute the action, remove the comment
83
- - **Question** ("what do you think", "should we") → Respond with `> @{user_mention}`, keep original comment
81
+
82
+ 1. **Read config first:** Check `~/.droid/skills/comments/overrides.yaml` for `preserve_comments` setting (default: `true`)
83
+ 2. Search for `> @droid` (and any configured `ai_mentions`) in the specified scope
84
+ 3. If there's a `git diff`, check those files first for relevant context
85
+ 4. For each comment, determine intent:
86
+ - **Action request** ("do X", "add Y", "fix Z") → Execute the action
87
+ - **Question** ("what do you think", "should we") → Respond with `> @{user_mention}`
88
+ 5. **Handle original comment based on `preserve_comments`:**
89
+ - If `preserve_comments: true` → Keep the original `@droid` comment (add response below it)
90
+ - If `preserve_comments: false` → Remove the original comment after addressing
84
91
 
85
92
  ### On `/comments cleanup`:
93
+
86
94
  1. Find AI tag and `> @{user_mention}` pairs where conversation appears resolved
87
95
  2. Remove both markers
88
96
  3. Output a summary of what was discussed/decided
@@ -98,8 +106,8 @@ user_mention: "@fry"
98
106
  # Additional AI mentions to recognize (e.g., if you're used to @claude)
99
107
  ai_mentions: "@claude"
100
108
 
101
- # Keep comments after addressing them (default: false)
102
- preserve_comments: false
109
+ # Keep comments after addressing them (default: true)
110
+ preserve_comments: true
103
111
  ```
104
112
 
105
113
  ## File Type Support
@@ -15,7 +15,7 @@ config_schema:
15
15
  preserve_comments:
16
16
  type: boolean
17
17
  description: Keep original comments after addressing (vs removing them)
18
- default: false
18
+ default: true
19
19
  examples:
20
20
  - title: "Action request"
21
21
  code: |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orderful/droid",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "description": "AI workflow toolkit for sharing skills, commands, and agents across the team",
5
5
  "type": "module",
6
6
  "bin": {
@@ -34,7 +34,11 @@ export async function installCommand(skillName: string): Promise<void> {
34
34
  // Check if skill has configurable options
35
35
  const manifest = loadSkillManifest(join(getBundledSkillsDir(), skillName));
36
36
  if (manifest?.config_schema && Object.keys(manifest.config_schema).length > 0) {
37
- await promptForSkillConfig(skillName, manifest.config_schema, true);
37
+ // If any config option lacks a default, go straight to config (it's required)
38
+ const hasRequiredConfig = Object.values(manifest.config_schema).some(
39
+ (option) => option.default === undefined
40
+ );
41
+ await promptForSkillConfig(skillName, manifest.config_schema, !hasRequiredConfig);
38
42
  }
39
43
 
40
44
  // Show next steps
@@ -240,11 +240,9 @@ export async function setupCommand(): Promise<void> {
240
240
  name: 'user_mention',
241
241
  message: 'What @mention should be used for you?',
242
242
  default: '@user',
243
- validate: (input: string) => {
244
- if (!input.startsWith('@')) {
245
- return 'Mention should start with @';
246
- }
247
- return true;
243
+ filter: (input: string) => {
244
+ // Auto-add @ prefix if missing
245
+ return input.startsWith('@') ? input : `@${input}`;
248
246
  },
249
247
  },
250
248
  {
@@ -127,7 +127,11 @@ export async function skillsCommand(): Promise<void> {
127
127
  // Prompt for config if skill has options
128
128
  const manifest = loadSkillManifest(join(getBundledSkillsDir(), skill.name));
129
129
  if (manifest?.config_schema && Object.keys(manifest.config_schema).length > 0) {
130
- await promptForSkillConfig(skill.name, manifest.config_schema, true);
130
+ // If any config option lacks a default, go straight to config (it's required)
131
+ const hasRequiredConfig = Object.values(manifest.config_schema).some(
132
+ (option) => option.default === undefined
133
+ );
134
+ await promptForSkillConfig(skill.name, manifest.config_schema, !hasRequiredConfig);
131
135
  }
132
136
  } else {
133
137
  console.log(chalk.red(`\n✗ ${result.message}`));
@@ -23,7 +23,7 @@ import { getRandomQuote } from '../lib/quotes.js';
23
23
 
24
24
  type Tab = 'skills' | 'commands' | 'agents' | 'settings';
25
25
  type View = 'welcome' | 'setup' | 'menu' | 'detail' | 'configure' | 'readme';
26
- type SetupStep = 'ai_tool' | 'user_mention' | 'output_preference' | 'confirm';
26
+ type SetupStep = 'ai_tool' | 'user_mention' | 'confirm';
27
27
 
28
28
  const colors = {
29
29
  primary: '#6366f1',
@@ -101,20 +101,28 @@ function getCommandsFromSkills(): Command[] {
101
101
  return commands;
102
102
  }
103
103
 
104
- function detectAITool(): AITool | null {
104
+ function detectInstalledAITools(): Set<AITool> {
105
+ const installed = new Set<AITool>();
105
106
  try {
106
107
  execSync('claude --version', { stdio: 'ignore' });
107
- return AITool.ClaudeCode;
108
+ installed.add(AITool.ClaudeCode);
108
109
  } catch {
109
110
  // Claude Code not found
110
111
  }
111
112
  try {
112
113
  execSync('opencode --version', { stdio: 'ignore' });
113
- return AITool.OpenCode;
114
+ installed.add(AITool.OpenCode);
114
115
  } catch {
115
116
  // OpenCode not found
116
117
  }
117
- return null;
118
+ return installed;
119
+ }
120
+
121
+ function getDefaultAITool(): AITool {
122
+ const installed = detectInstalledAITools();
123
+ if (installed.has(AITool.ClaudeCode)) return AITool.ClaudeCode;
124
+ if (installed.has(AITool.OpenCode)) return AITool.OpenCode;
125
+ return AITool.ClaudeCode;
118
126
  }
119
127
 
120
128
  function getOutputOptions(): Array<{ label: string; value: OutputPreference }> {
@@ -320,33 +328,29 @@ interface SetupScreenProps {
320
328
  function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
321
329
  const [step, setStep] = useState<SetupStep>('ai_tool');
322
330
  const [aiTool, setAITool] = useState<AITool>(
323
- initialConfig?.ai_tool || detectAITool() || AITool.ClaudeCode
331
+ initialConfig?.ai_tool || getDefaultAITool()
324
332
  );
325
333
  const [userMention, setUserMention] = useState(initialConfig?.user_mention || '@user');
326
- const [outputPreference, setOutputPreference] = useState<OutputPreference>(
327
- initialConfig?.output_preference || BuiltInOutput.Terminal
328
- );
329
334
  const [selectedIndex, setSelectedIndex] = useState(0);
330
335
  const [error, setError] = useState<string | null>(null);
331
336
 
337
+ // Cache detection results once on mount (avoids re-running execSync on every render)
338
+ const installedTools = useMemo(() => detectInstalledAITools(), []);
332
339
  const aiToolOptions = useMemo(() => [
333
340
  { label: 'Claude Code', value: AITool.ClaudeCode },
334
341
  { label: 'OpenCode', value: AITool.OpenCode },
335
342
  ], []);
336
- const outputOptions = useMemo(() => getOutputOptions(), []);
337
343
 
338
- const steps: SetupStep[] = ['ai_tool', 'user_mention', 'output_preference', 'confirm'];
344
+ const steps: SetupStep[] = ['ai_tool', 'user_mention', 'confirm'];
339
345
  const stepIndex = steps.indexOf(step);
340
346
  const totalSteps = steps.length - 1; // Don't count confirm as a step
341
347
 
342
348
  const handleUserMentionSubmit = () => {
343
- if (!userMention.startsWith('@')) {
344
- setError('Mention should start with @');
345
- return;
346
- }
349
+ // Auto-add @ prefix if missing
350
+ const mention = userMention.startsWith('@') ? userMention : `@${userMention}`;
351
+ setUserMention(mention);
347
352
  setError(null);
348
- setStep('output_preference');
349
- setSelectedIndex(0);
353
+ setStep('confirm');
350
354
  };
351
355
 
352
356
  // Handle escape during text input (only intercept escape, nothing else)
@@ -362,11 +366,8 @@ function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
362
366
  if (key.escape) {
363
367
  if (step === 'ai_tool') {
364
368
  onSkip();
365
- } else if (step === 'output_preference') {
366
- setStep('user_mention');
367
369
  } else if (step === 'confirm') {
368
- setStep('output_preference');
369
- setSelectedIndex(0);
370
+ setStep('user_mention');
370
371
  }
371
372
  return;
372
373
  }
@@ -378,20 +379,13 @@ function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
378
379
  setAITool(aiToolOptions[selectedIndex].value);
379
380
  setStep('user_mention');
380
381
  }
381
- } else if (step === 'output_preference') {
382
- if (key.upArrow) setSelectedIndex((prev) => Math.max(0, prev - 1));
383
- if (key.downArrow) setSelectedIndex((prev) => Math.min(outputOptions.length - 1, prev + 1));
384
- if (key.return) {
385
- setOutputPreference(outputOptions[selectedIndex].value);
386
- setStep('confirm');
387
- }
388
382
  } else if (step === 'confirm') {
389
383
  if (key.return) {
390
384
  const config: DroidConfig = {
391
385
  ...loadConfig(),
392
386
  ai_tool: aiTool,
393
387
  user_mention: userMention,
394
- output_preference: outputPreference,
388
+ output_preference: BuiltInOutput.Terminal, // Default to terminal
395
389
  };
396
390
  saveConfig(config);
397
391
  configureAIToolPermissions(aiTool);
@@ -424,7 +418,7 @@ function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
424
418
  <Text key={option.value}>
425
419
  <Text color={colors.textDim}>{index === selectedIndex ? '>' : ' '} </Text>
426
420
  <Text color={index === selectedIndex ? colors.text : colors.textMuted}>{option.label}</Text>
427
- {option.value === detectAITool() && <Text color={colors.success}> (detected)</Text>}
421
+ {installedTools.has(option.value) && <Text color={colors.success}> (detected)</Text>}
428
422
  </Text>
429
423
  ))}
430
424
  </Box>
@@ -461,26 +455,6 @@ function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
461
455
  );
462
456
  }
463
457
 
464
- if (step === 'output_preference') {
465
- return (
466
- <Box flexDirection="column" padding={1}>
467
- {renderHeader()}
468
- <Text color={colors.text}>Default output preference for skill results?</Text>
469
- <Box flexDirection="column" marginTop={1}>
470
- {outputOptions.map((option, index) => (
471
- <Text key={option.value}>
472
- <Text color={colors.textDim}>{index === selectedIndex ? '>' : ' '} </Text>
473
- <Text color={index === selectedIndex ? colors.text : colors.textMuted}>{option.label}</Text>
474
- </Text>
475
- ))}
476
- </Box>
477
- <Box marginTop={1}>
478
- <Text color={colors.textDim}>↑↓ select · enter next · esc back</Text>
479
- </Box>
480
- </Box>
481
- );
482
- }
483
-
484
458
  // Confirm step
485
459
  return (
486
460
  <Box flexDirection="column" padding={1}>
@@ -495,10 +469,6 @@ function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenProps) {
495
469
  <Text color={colors.textDim}>Your @mention: </Text>
496
470
  <Text color={colors.text}>{userMention}</Text>
497
471
  </Text>
498
- <Text>
499
- <Text color={colors.textDim}>Output: </Text>
500
- <Text color={colors.text}>{outputOptions.find((o) => o.value === outputPreference)?.label || outputPreference}</Text>
501
- </Text>
502
472
  </Box>
503
473
  <Box marginTop={2}>
504
474
  <Text backgroundColor={colors.primary} color="#ffffff" bold>
@@ -1032,12 +1002,6 @@ function SettingsDetails({
1032
1002
  <Text color={colors.textDim}>Your @mention: </Text>
1033
1003
  <Text color={colors.text}>{config.user_mention}</Text>
1034
1004
  </Text>
1035
- <Text>
1036
- <Text color={colors.textDim}>Output: </Text>
1037
- <Text color={colors.text}>
1038
- {outputOptions.find((o) => o.value === config.output_preference)?.label || config.output_preference}
1039
- </Text>
1040
- </Text>
1041
1005
  </Box>
1042
1006
 
1043
1007
  <Box marginTop={1}>
@@ -1389,8 +1353,6 @@ function App() {
1389
1353
  useInput((input, key) => {
1390
1354
  if (message) setMessage(null);
1391
1355
 
1392
- if (view === 'welcome') return;
1393
-
1394
1356
  if (input === 'q') {
1395
1357
  exit();
1396
1358
  return;
@@ -1528,8 +1490,18 @@ function App() {
1528
1490
  type: result.success ? 'success' : 'error',
1529
1491
  });
1530
1492
  if (result.success) {
1531
- setView('menu');
1532
- setSelectedAction(0);
1493
+ // Check if skill has required config (options without defaults)
1494
+ const configSchema = skill.config_schema || {};
1495
+ const hasRequiredConfig = Object.values(configSchema).some(
1496
+ (option) => (option as ConfigOption).default === undefined
1497
+ );
1498
+ if (hasRequiredConfig) {
1499
+ // Go to configure view for required setup
1500
+ setView('configure');
1501
+ } else {
1502
+ setView('menu');
1503
+ setSelectedAction(0);
1504
+ }
1533
1505
  }
1534
1506
  }
1535
1507
  }
@@ -1590,7 +1562,7 @@ function App() {
1590
1562
  }
1591
1563
  }
1592
1564
  }
1593
- });
1565
+ }, { isActive: view !== 'welcome' && view !== 'setup' && view !== 'configure' });
1594
1566
 
1595
1567
  const selectedSkill = activeTab === 'skills' ? skills[selectedIndex] ?? null : null;
1596
1568
  const selectedCommand = activeTab === 'commands' ? commands[selectedIndex] ?? null : null;
@@ -38,12 +38,13 @@ Ideas develop through iteration, not single prompts.
38
38
 
39
39
  **IMPORTANT:** Before using any default paths, ALWAYS read `~/.droid/skills/brain/overrides.yaml` first. If `brain_dir` is configured there, use that path. Only fall back to defaults if the file doesn't exist or lacks a `brain_dir` setting.
40
40
 
41
- | Setting | Default | Description |
42
- |---------|---------|-------------|
43
- | `brain_dir` | (see below) | Where docs are stored |
44
- | `inbox_folder` | (empty) | Optional subfolder for new docs (omit for flat structure) |
41
+ | Setting | Default | Description |
42
+ | -------------- | ----------- | --------------------------------------------------------- |
43
+ | `brain_dir` | (see below) | Where docs are stored |
44
+ | `inbox_folder` | (empty) | Optional subfolder for new docs (omit for flat structure) |
45
45
 
46
46
  Default `brain_dir` by AI tool (only if not configured):
47
+
47
48
  - **claude-code**: `~/.claude/brain`
48
49
  - **opencode**: `~/.config/opencode/brain`
49
50
 
@@ -52,28 +53,44 @@ Default `brain_dir` by AI tool (only if not configured):
52
53
  **Active doc:** Opening or creating a brain doc makes it "active" for the session. Subsequent `/brain add` commands append to it without specifying a path.
53
54
 
54
55
  **Doc types:**
56
+
55
57
  - `plan` - Structured: Context → Exploration → Decision → Next Steps
56
58
  - `research` - Open-ended exploration of a topic
57
59
  - `review` - Code review, document review, or any evaluation task
58
60
  - `note` - Quick capture (fire-and-forget, doesn't become active)
59
61
 
60
- **Comment conventions:** Use `@droid` / `@{user}` markers for async back-and-forth. If droid's `comments` skill is installed, use `/comments check` for full support.
62
+ **Comment conventions:** In markdown files, ALWAYS use blockquote `>` prefix for @mention comments:
63
+
64
+ - `> @droid` - **User** leaves comment for AI to address
65
+ - `> @{user}` - **AI** leaves comment for user to address
66
+
67
+ **CRITICAL:** When YOU (the AI) respond to a comment or create a placeholder, you MUST use `> @{user_mention}` (e.g., `> @fry`). NEVER use `@droid` for your own responses - that tag is for the USER to address YOU.
68
+
69
+ Example conversation:
70
+
71
+ ```markdown
72
+ > @droid Should we add caching here?
73
+
74
+ > @fry Yes, Redis would work well for this use case.
75
+ ```
76
+
77
+ Read user's configured mention from `~/.droid/config.yaml` → `user_mention` (e.g., `@fry`). If droid's `comments` skill is installed, use `/comments check` for full support.
61
78
 
62
79
  **Status lifecycle:** `exploring` → `drafting` → `decided` → `done`
63
80
 
64
81
  ## Commands
65
82
 
66
- | Command | Action |
67
- |---------|--------|
68
- | `/brain` | List recent docs or create new |
69
- | `/brain {topic}` | **Search** for existing doc (fuzzy match) → becomes active |
70
- | `/brain plan {topic}` | Create planning doc (requires `plan` keyword) |
71
- | `/brain research {topic}` | Create research doc (requires `research` keyword) |
72
- | `/brain review {topic}` | Create review doc (requires `review` keyword) |
73
- | `/brain note {text}` | Quick capture (standalone, doesn't become active) |
74
- | `/brain add {text}` | Append to active doc |
75
- | `/brain check` | Address @droid comments in active doc |
76
- | `/brain done` | Finalize active doc, update status |
83
+ | Command | Action |
84
+ | ------------------------- | ---------------------------------------------------------- |
85
+ | `/brain` | List recent docs or create new |
86
+ | `/brain {topic}` | **Search** for existing doc (fuzzy match) → becomes active |
87
+ | `/brain plan {topic}` | Create planning doc (requires `plan` keyword) |
88
+ | `/brain research {topic}` | Create research doc (requires `research` keyword) |
89
+ | `/brain review {topic}` | Create review doc (requires `review` keyword) |
90
+ | `/brain note {text}` | Quick capture (standalone, doesn't become active) |
91
+ | `/brain add {text}` | Append to active doc |
92
+ | `/brain check` | Address @droid comments in active doc |
93
+ | `/brain done` | Finalize active doc, update status |
77
94
 
78
95
  **IMPORTANT:** The default action for `/brain {topic}` is to **SEARCH** for existing docs, NOT create. Only use `/brain plan {topic}` or `/brain research {topic}` when the user explicitly wants to create a new doc.
79
96
 
@@ -115,7 +132,7 @@ Full procedure: `references/workflows.md` § Adding
115
132
 
116
133
  **Trigger:** `/brain check`
117
134
 
118
- **TLDR:** Find `> @droid` comments in active doc, address each one.
135
+ **TLDR:** Find `> @droid` comments in active doc, address each one with `> @{user_mention}` response (always use blockquote `>`).
119
136
 
120
137
  Full procedure: `references/workflows.md` § Checking
121
138
 
@@ -132,11 +149,18 @@ Full procedure: `references/workflows.md` § Finalizing
132
149
  Before creating or modifying brain docs, check if any `brain-*` extension skills are installed:
133
150
 
134
151
  ```
152
+ # Claude Code
135
153
  ~/.claude/skills/brain-*/SKILL.md
154
+
155
+ # OpenCode
156
+ ~/.config/opencode/skills/brain-*/SKILL.md
157
+
158
+ # Shared (droid config)
136
159
  ~/.droid/skills/brain-*/SKILL.md
137
160
  ```
138
161
 
139
162
  If found (e.g., `brain-obsidian`), **ALWAYS** use the extension's templates, workflows, and configuration instead of this skill's defaults. Extensions may provide:
163
+
140
164
  - Alternative template formats (YAML frontmatter, wikilinks)
141
165
  - Folder organization (PARA structure)
142
166
  - Additional commands or integrations
@@ -42,6 +42,7 @@ $ARGUMENTS
42
42
  ## Behavior
43
43
 
44
44
  Refer to the brain skill for:
45
+
45
46
  - **Opening**: How to fuzzy-match, handle multiple matches, set active
46
47
  - **Creating**: Template structure by preset, naming conventions
47
48
  - **Notes**: Quick capture workflow
@@ -42,6 +42,7 @@ $ARGUMENTS
42
42
  ## Behavior
43
43
 
44
44
  Refer to the brain skill for:
45
+
45
46
  - **Opening**: How to fuzzy-match, handle multiple matches, set active
46
47
  - **Creating**: Template structure by preset, naming conventions
47
48
  - **Notes**: Quick capture workflow
@@ -20,12 +20,12 @@ Simple and portable. Works anywhere markdown is supported.
20
20
 
21
21
  ## Fields
22
22
 
23
- | Field | Required | Description |
24
- |-------|----------|-------------|
25
- | `Type` | Yes | Doc type: `plan`, `research`, `review`, or `note` |
26
- | `Status` | Yes (except notes) | Current lifecycle stage |
27
- | `Created` | Yes | Creation date |
28
- | `Updated` | No | Last modification date (add when doc changes) |
23
+ | Field | Required | Description |
24
+ | --------- | ------------------ | ------------------------------------------------- |
25
+ | `Type` | Yes | Doc type: `plan`, `research`, `review`, or `note` |
26
+ | `Status` | Yes (except notes) | Current lifecycle stage |
27
+ | `Created` | Yes | Creation date |
28
+ | `Updated` | No | Last modification date (add when doc changes) |
29
29
 
30
30
  ## Status Lifecycle
31
31
 
@@ -37,13 +37,13 @@ exploring → drafting → decided → done
37
37
 
38
38
  ### Status Definitions
39
39
 
40
- | Status | Meaning | Typical Actions |
41
- |--------|---------|-----------------|
42
- | `exploring` | Initial discovery, gathering information | Research, ask questions, explore options |
43
- | `drafting` | Forming opinions, narrowing options | Document trade-offs, propose approaches |
44
- | `decided` | Decision made, ready to act | Document decision rationale, plan implementation |
45
- | `done` | Work complete, doc is reference material | Archive or link from project |
46
- | `stale` | Abandoned or outdated | Review for archival or deletion |
40
+ | Status | Meaning | Typical Actions |
41
+ | ----------- | ---------------------------------------- | ------------------------------------------------ |
42
+ | `exploring` | Initial discovery, gathering information | Research, ask questions, explore options |
43
+ | `drafting` | Forming opinions, narrowing options | Document trade-offs, propose approaches |
44
+ | `decided` | Decision made, ready to act | Document decision rationale, plan implementation |
45
+ | `done` | Work complete, doc is reference material | Archive or link from project |
46
+ | `stale` | Abandoned or outdated | Review for archival or deletion |
47
47
 
48
48
  ### Transitions
49
49
 
@@ -55,5 +55,6 @@ exploring → drafting → decided → done
55
55
  ## Updating Metadata
56
56
 
57
57
  When modifying a doc:
58
+
58
59
  1. Add or update the `Updated` field to current date
59
60
  2. Update `Status` if the work has progressed