@orderful/droid 0.25.2 → 0.26.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 (86) hide show
  1. package/.claude-plugin/marketplace.json +114 -0
  2. package/.github/workflows/ci.yml +20 -0
  3. package/AGENTS.md +53 -0
  4. package/CHANGELOG.md +44 -0
  5. package/README.md +30 -4
  6. package/dist/bin/droid.js +62 -51
  7. package/dist/index.js +9 -1
  8. package/dist/lib/skill-config.d.ts.map +1 -1
  9. package/dist/tools/README.md +1 -1
  10. package/dist/tools/brain/.claude-plugin/plugin.json +16 -0
  11. package/dist/tools/brain/commands/brain.md +1 -1
  12. package/dist/tools/brain/commands/scratchpad.md +1 -1
  13. package/dist/tools/brain/skills/droid-brain/SKILL.md +1 -1
  14. package/dist/tools/brain/skills/droid-brain-obsidian/SKILL.md +1 -1
  15. package/dist/tools/coach/.claude-plugin/plugin.json +16 -0
  16. package/dist/tools/coach/commands/coach.md +1 -1
  17. package/dist/tools/coach/skills/droid-coach/SKILL.md +1 -1
  18. package/dist/tools/code-review/.claude-plugin/plugin.json +16 -0
  19. package/dist/tools/code-review/commands/code-review.md +1 -1
  20. package/dist/tools/code-review/skills/droid-code-review/SKILL.md +1 -1
  21. package/dist/tools/codex/.claude-plugin/plugin.json +16 -0
  22. package/dist/tools/codex/TOOL.yaml +2 -2
  23. package/dist/tools/codex/commands/codex.md +1 -1
  24. package/dist/tools/codex/skills/droid-codex/SKILL.md +1 -1
  25. package/dist/tools/comments/.claude-plugin/plugin.json +16 -0
  26. package/dist/tools/comments/commands/comments.md +1 -1
  27. package/dist/tools/comments/skills/droid-comments/SKILL.md +1 -1
  28. package/dist/tools/droid/.claude-plugin/plugin.json +15 -0
  29. package/dist/tools/droid/TOOL.yaml +1 -1
  30. package/dist/tools/droid/skills/droid/SKILL.md +1 -1
  31. package/dist/tools/project/.claude-plugin/plugin.json +16 -0
  32. package/dist/tools/project/commands/project.md +1 -1
  33. package/dist/tools/project/skills/droid-project/SKILL.md +1 -1
  34. package/dist/tools/tech-design/.claude-plugin/plugin.json +16 -0
  35. package/dist/tools/tech-design/TOOL.yaml +18 -0
  36. package/dist/tools/tech-design/commands/tech-design.md +93 -0
  37. package/dist/tools/tech-design/skills/droid-tech-design/SKILL.md +218 -0
  38. package/dist/tools/tech-design/skills/droid-tech-design/references/draft.md +321 -0
  39. package/dist/tools/tech-design/skills/droid-tech-design/references/gaps.md +328 -0
  40. package/dist/tools/tech-design/skills/droid-tech-design/references/publish.md +409 -0
  41. package/dist/tools/tech-design/skills/droid-tech-design/references/research-doc-template.md +129 -0
  42. package/dist/tools/tech-design/skills/droid-tech-design/references/rollup-template.md +55 -0
  43. package/dist/tools/tech-design/skills/droid-tech-design/references/start.md +353 -0
  44. package/dist/tools/tech-design/skills/droid-tech-design/references/think.md +356 -0
  45. package/dist/tools/tech-design/skills/droid-tech-design/references/thought-doc-template.md +72 -0
  46. package/package.json +3 -2
  47. package/scripts/build-plugins.ts +207 -0
  48. package/src/lib/skill-config.ts +95 -57
  49. package/src/lib/skills.ts +2 -2
  50. package/src/tools/README.md +1 -1
  51. package/src/tools/brain/.claude-plugin/plugin.json +16 -0
  52. package/src/tools/brain/commands/brain.md +1 -1
  53. package/src/tools/brain/commands/scratchpad.md +1 -1
  54. package/src/tools/brain/skills/droid-brain/SKILL.md +1 -1
  55. package/src/tools/brain/skills/droid-brain-obsidian/SKILL.md +1 -1
  56. package/src/tools/coach/.claude-plugin/plugin.json +16 -0
  57. package/src/tools/coach/commands/coach.md +1 -1
  58. package/src/tools/coach/skills/droid-coach/SKILL.md +1 -1
  59. package/src/tools/code-review/.claude-plugin/plugin.json +16 -0
  60. package/src/tools/code-review/commands/code-review.md +1 -1
  61. package/src/tools/code-review/skills/droid-code-review/SKILL.md +1 -1
  62. package/src/tools/codex/.claude-plugin/plugin.json +16 -0
  63. package/src/tools/codex/TOOL.yaml +2 -2
  64. package/src/tools/codex/commands/codex.md +1 -1
  65. package/src/tools/codex/skills/droid-codex/SKILL.md +1 -1
  66. package/src/tools/comments/.claude-plugin/plugin.json +16 -0
  67. package/src/tools/comments/commands/comments.md +1 -1
  68. package/src/tools/comments/skills/droid-comments/SKILL.md +1 -1
  69. package/src/tools/droid/.claude-plugin/plugin.json +15 -0
  70. package/src/tools/droid/TOOL.yaml +1 -1
  71. package/src/tools/droid/skills/droid/SKILL.md +1 -1
  72. package/src/tools/project/.claude-plugin/plugin.json +16 -0
  73. package/src/tools/project/commands/project.md +1 -1
  74. package/src/tools/project/skills/droid-project/SKILL.md +1 -1
  75. package/src/tools/tech-design/.claude-plugin/plugin.json +16 -0
  76. package/src/tools/tech-design/TOOL.yaml +18 -0
  77. package/src/tools/tech-design/commands/tech-design.md +93 -0
  78. package/src/tools/tech-design/skills/droid-tech-design/SKILL.md +218 -0
  79. package/src/tools/tech-design/skills/droid-tech-design/references/draft.md +321 -0
  80. package/src/tools/tech-design/skills/droid-tech-design/references/gaps.md +328 -0
  81. package/src/tools/tech-design/skills/droid-tech-design/references/publish.md +409 -0
  82. package/src/tools/tech-design/skills/droid-tech-design/references/research-doc-template.md +129 -0
  83. package/src/tools/tech-design/skills/droid-tech-design/references/rollup-template.md +55 -0
  84. package/src/tools/tech-design/skills/droid-tech-design/references/start.md +353 -0
  85. package/src/tools/tech-design/skills/droid-tech-design/references/think.md +356 -0
  86. package/src/tools/tech-design/skills/droid-tech-design/references/thought-doc-template.md +72 -0
@@ -0,0 +1,72 @@
1
+ # Thought Doc Template
2
+
3
+ Used when creating thought doc via `/brain plan tech-design-{project}`.
4
+
5
+ ```markdown
6
+ # [Tech Design] {Project Name}
7
+
8
+ **Type:** plan
9
+ **Status:** exploring
10
+ **Created:** {YYYY-MM-DD}
11
+ **PRD:** [[codex:projects/{project}/PRD]]
12
+ **Research:** [[tech-design-{project}-research]]
13
+
14
+ Tech design for {project}.
15
+
16
+ ## Background
17
+
18
+ {Why we're doing this - 2-3 paragraphs from PRD}
19
+
20
+ {What problem we're solving, who it's for, why it matters}
21
+
22
+ See research doc for codebase context and discovered patterns.
23
+
24
+ ## Proposal
25
+
26
+ {What we're building - to be drafted}
27
+
28
+ ## Open Questions
29
+
30
+ {What we don't know yet - to be explored}
31
+ ```
32
+
33
+ ## Variable Substitutions
34
+
35
+ | Variable | Example | Notes |
36
+ | ---------------- | ----------------------- | --------------------------- |
37
+ | `{Project Name}` | "Transaction Templates" | Human-readable project name |
38
+ | `{YYYY-MM-DD}` | "2026-01-10" | Current date |
39
+ | `{project}` | "transaction-templates" | Codex project slug |
40
+
41
+ ## Philosophy
42
+
43
+ **Start minimal:** 3 sections (Background, Proposal, Open Questions)
44
+
45
+ **Gaps surface more:** Use `/tech-design gaps` to discover what sections to add (Data Model, API Surface, Rollout Plan, etc.)
46
+
47
+ **Research doc separation:** The thought doc references the research doc but doesn't duplicate codebase discoveries. Keep the thought doc focused on architectural decisions.
48
+
49
+ ## Sections That Can Be Added
50
+
51
+ Via `/tech-design draft {section}` or `/tech-design gaps`:
52
+
53
+ - **Scope** - What's in/out explicitly
54
+ - **Data Model** - Tables, schemas, types
55
+ - **API Surface** - Endpoints, methods, interfaces
56
+ - **Implementation Plan** - Step-by-step approach
57
+ - **Key Decisions** - Options considered, what we chose and why
58
+ - **Trade-off Analysis** - Pros/cons of approach
59
+ - **Risks & Mitigations** - What could go wrong, how to handle it
60
+ - **Metrics** - What we'll measure
61
+ - **Rollout Plan** - Phased deployment, feature flags, rollback
62
+ - **Security Considerations** - Auth, validation, audit logging
63
+
64
+ ## Template Evolution
65
+
66
+ The template starts with 3 sections, but the thought doc grows based on:
67
+
68
+ 1. **User adds via `/draft {section}`** - AI generates section from research
69
+ 2. **User explores via `/think {topic}`** - May add sections organically
70
+ 3. **User identifies via `/gaps`** - Shows what's missing, suggests adding
71
+
72
+ The minimal start reduces cognitive load. Sections appear when needed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orderful/droid",
3
- "version": "0.25.2",
3
+ "version": "0.26.0",
4
4
  "description": "AI workflow toolkit for sharing skills, commands, and agents across the team",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,8 @@
8
8
  },
9
9
  "main": "dist/index.js",
10
10
  "scripts": {
11
- "build": "bun run lint && bun scripts/build.ts",
11
+ "build": "bun run lint && bun scripts/build.ts && bun scripts/build-plugins.ts",
12
+ "build:plugins": "bun scripts/build-plugins.ts",
12
13
  "dev": "tsc --watch",
13
14
  "start": "bun dist/bin/droid.js",
14
15
  "test": "bun test src/",
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Build Claude Code plugin manifests from src/tools/
4
+ *
5
+ * This script generates:
6
+ * - src/tools/{tool}/.claude-plugin/plugin.json (from TOOL.yaml)
7
+ * - .claude-plugin/marketplace.json (at repo root)
8
+ *
9
+ * No file duplication - skills, commands, and agents stay in place.
10
+ * The src/tools/ directory serves both TUI and plugin distribution.
11
+ *
12
+ * Note: All tools are published to the marketplace, including those with
13
+ * `system: true` in their TOOL.yaml. System tools can still be installed
14
+ * individually via the plugin system.
15
+ */
16
+
17
+ import { mkdirSync, writeFileSync, existsSync, readdirSync, readFileSync } from 'fs';
18
+ import { join } from 'path';
19
+ import { parse as parseYaml } from 'yaml';
20
+
21
+ interface ToolManifest {
22
+ name: string;
23
+ description: string;
24
+ version: string;
25
+ status?: string;
26
+ system?: boolean;
27
+ includes: {
28
+ skills: Array<{ name: string; required: boolean; description?: string }>;
29
+ commands: string[];
30
+ agents: string[];
31
+ };
32
+ dependencies?: string[];
33
+ config_schema?: Record<string, unknown>;
34
+ }
35
+
36
+ interface PluginJson {
37
+ name: string;
38
+ version: string;
39
+ description: string;
40
+ author: {
41
+ name: string;
42
+ url?: string;
43
+ };
44
+ repository?: string;
45
+ license?: string;
46
+ keywords?: string[];
47
+ }
48
+
49
+ interface MarketplacePlugin {
50
+ name: string;
51
+ description: string;
52
+ version: string;
53
+ source: {
54
+ source: string;
55
+ repo: string;
56
+ path: string;
57
+ };
58
+ author: {
59
+ name: string;
60
+ };
61
+ }
62
+
63
+ interface MarketplaceJson {
64
+ name: string;
65
+ description: string;
66
+ owner: {
67
+ name: string;
68
+ url?: string;
69
+ };
70
+ plugins: MarketplacePlugin[];
71
+ }
72
+
73
+ const TOOLS_DIR = 'src/tools';
74
+ const AUTHOR = {
75
+ name: 'Orderful',
76
+ url: 'https://github.com/orderful',
77
+ };
78
+ const REPO = 'https://github.com/orderful/droid';
79
+ const REPO_SHORT = 'orderful/droid';
80
+
81
+ /**
82
+ * Get the plugin name with droid- prefix (for namespace isolation).
83
+ * The 'droid' core tool keeps its name as-is to avoid 'droid-droid'.
84
+ */
85
+ function getPluginName(toolName: string): string {
86
+ if (toolName === 'droid') return 'droid';
87
+ return toolName.startsWith('droid-') ? toolName : `droid-${toolName}`;
88
+ }
89
+
90
+ function loadToolManifest(toolDir: string): ToolManifest | null {
91
+ const manifestPath = join(toolDir, 'TOOL.yaml');
92
+ if (!existsSync(manifestPath)) {
93
+ return null;
94
+ }
95
+ try {
96
+ const content = readFileSync(manifestPath, 'utf-8');
97
+ const parsed = parseYaml(content) as ToolManifest;
98
+ if (!parsed.name || !parsed.description || !parsed.version) {
99
+ console.error(`Invalid TOOL.yaml in ${toolDir}: missing required fields (name, description, version)`);
100
+ return null;
101
+ }
102
+ return parsed;
103
+ } catch (err) {
104
+ console.error(`Failed to parse TOOL.yaml in ${toolDir}:`, err);
105
+ return null;
106
+ }
107
+ }
108
+
109
+ function getToolDirs(): string[] {
110
+ const entries = readdirSync(TOOLS_DIR, { withFileTypes: true });
111
+ return entries
112
+ .filter((e) => e.isDirectory())
113
+ .map((e) => join(TOOLS_DIR, e.name))
114
+ .filter((dir) => existsSync(join(dir, 'TOOL.yaml')));
115
+ }
116
+
117
+ function createPluginJson(manifest: ToolManifest, pluginName: string): PluginJson {
118
+ return {
119
+ name: pluginName,
120
+ version: manifest.version,
121
+ description: manifest.description,
122
+ author: AUTHOR,
123
+ repository: REPO,
124
+ license: 'MIT',
125
+ keywords: [...new Set(['droid', 'ai', manifest.name])],
126
+ };
127
+ }
128
+
129
+ function buildPluginManifest(toolDir: string): MarketplacePlugin | null {
130
+ const manifest = loadToolManifest(toolDir);
131
+ if (!manifest) {
132
+ return null;
133
+ }
134
+
135
+ const pluginName = getPluginName(manifest.name);
136
+
137
+ console.log(`Generating plugin.json for: ${pluginName} (v${manifest.version})`);
138
+
139
+ // Create .claude-plugin directory in the tool directory
140
+ const claudePluginDir = join(toolDir, '.claude-plugin');
141
+ mkdirSync(claudePluginDir, { recursive: true });
142
+
143
+ // Generate plugin.json
144
+ const pluginJson = createPluginJson(manifest, pluginName);
145
+ writeFileSync(join(claudePluginDir, 'plugin.json'), JSON.stringify(pluginJson, null, 2) + '\n');
146
+
147
+ // Return marketplace entry (path is relative to repo root)
148
+ return {
149
+ name: pluginName,
150
+ description: manifest.description,
151
+ version: manifest.version,
152
+ source: {
153
+ source: 'github',
154
+ repo: REPO_SHORT,
155
+ path: toolDir, // e.g., "src/tools/brain"
156
+ },
157
+ author: {
158
+ name: AUTHOR.name,
159
+ },
160
+ };
161
+ }
162
+
163
+ function buildMarketplace(plugins: MarketplacePlugin[]): void {
164
+ // Create marketplace.json at repo root for clean discovery
165
+ const marketplaceDir = '.claude-plugin';
166
+ mkdirSync(marketplaceDir, { recursive: true });
167
+
168
+ const marketplace: MarketplaceJson = {
169
+ name: 'droid',
170
+ description: 'AI-powered development tools for Claude Code',
171
+ owner: AUTHOR,
172
+ plugins: plugins.sort((a, b) => a.name.localeCompare(b.name)),
173
+ };
174
+
175
+ writeFileSync(join(marketplaceDir, 'marketplace.json'), JSON.stringify(marketplace, null, 2) + '\n');
176
+ console.log(`\nMarketplace manifest created at .claude-plugin/marketplace.json with ${plugins.length} plugins`);
177
+ }
178
+
179
+ function main(): void {
180
+ console.log('Generating Claude Code plugin manifests in src/tools/\n');
181
+
182
+ // Build plugin.json for each tool
183
+ const toolDirs = getToolDirs();
184
+ const plugins: MarketplacePlugin[] = [];
185
+
186
+ for (const toolDir of toolDirs) {
187
+ const plugin = buildPluginManifest(toolDir);
188
+ if (plugin) {
189
+ plugins.push(plugin);
190
+ }
191
+ }
192
+
193
+ // Build marketplace manifest
194
+ buildMarketplace(plugins);
195
+
196
+ console.log('\nPlugin manifest generation complete!');
197
+ console.log(`\nTo test locally:`);
198
+ console.log(` /plugin marketplace add ${process.cwd()}`);
199
+ console.log(` /plugin install droid-brain@droid`);
200
+ }
201
+
202
+ try {
203
+ main();
204
+ } catch (err) {
205
+ console.error(err);
206
+ process.exit(1);
207
+ }
@@ -1,7 +1,11 @@
1
1
  import chalk from 'chalk';
2
2
  import inquirer from 'inquirer';
3
3
  import { saveSkillOverrides, loadConfig, loadSkillOverrides } from './config';
4
- import { ConfigOptionType, type SkillOverrides, type ConfigOption } from './types';
4
+ import {
5
+ ConfigOptionType,
6
+ type SkillOverrides,
7
+ type ConfigOption,
8
+ } from './types';
5
9
 
6
10
  /**
7
11
  * Prompt user to configure a skill after install
@@ -9,12 +13,15 @@ import { ConfigOptionType, type SkillOverrides, type ConfigOption } from './type
9
13
  export async function promptForSkillConfig(
10
14
  skillName: string,
11
15
  configSchema: Record<string, ConfigOption>,
12
- askFirst: boolean = true
16
+ askFirst: boolean = true,
13
17
  ): Promise<void> {
14
18
  const globalConfig = loadConfig();
19
+ let shouldPrompt = true;
15
20
 
16
21
  if (askFirst) {
17
- const { wantsConfigure } = await inquirer.prompt<{ wantsConfigure: boolean }>([
22
+ const { wantsConfigure } = await inquirer.prompt<{
23
+ wantsConfigure: boolean;
24
+ }>([
18
25
  {
19
26
  type: 'confirm',
20
27
  name: 'wantsConfigure',
@@ -23,73 +30,104 @@ export async function promptForSkillConfig(
23
30
  },
24
31
  ]);
25
32
 
26
- if (!wantsConfigure) {
27
- return;
28
- }
33
+ shouldPrompt = wantsConfigure;
29
34
  }
30
35
 
31
- console.log(chalk.bold(`\n⚙️ Configure ${skillName}\n`));
32
-
33
36
  // Load existing overrides to use as defaults
34
37
  const existingOverrides = loadSkillOverrides(skillName);
35
38
 
36
- const questions = Object.entries(configSchema).map(([key, option]) => {
37
- const baseQuestion = {
38
- name: key,
39
- message: option.description,
40
- };
39
+ let overrides: SkillOverrides = {};
40
+
41
+ if (shouldPrompt) {
42
+ console.log(chalk.bold(`\n⚙️ Configure ${skillName}\n`));
41
43
 
42
- // Use existing override as default if present
43
- const existingValue = existingOverrides[key];
44
+ const questions = Object.entries(configSchema).map(([key, option]) => {
45
+ const baseQuestion = {
46
+ name: key,
47
+ message: option.description,
48
+ };
44
49
 
45
- switch (option.type) {
46
- case ConfigOptionType.Boolean:
47
- return {
48
- ...baseQuestion,
49
- type: 'confirm' as const,
50
- default: existingValue ?? option.default ?? false,
51
- };
52
- case ConfigOptionType.Select:
53
- return {
54
- ...baseQuestion,
55
- type: 'list' as const,
56
- choices: option.options || [],
57
- default: existingValue ?? option.default,
58
- };
59
- case ConfigOptionType.String:
60
- default: {
61
- // For user_mention, default to global config value if no existing override
62
- let defaultValue = existingValue ?? option.default ?? '';
63
- if (key === 'user_mention' && !existingValue && globalConfig.user_mention) {
64
- defaultValue = globalConfig.user_mention;
50
+ // Use existing override as default if present
51
+ const existingValue = existingOverrides[key];
52
+
53
+ switch (option.type) {
54
+ case ConfigOptionType.Boolean:
55
+ return {
56
+ ...baseQuestion,
57
+ type: 'confirm' as const,
58
+ default: existingValue ?? option.default ?? false,
59
+ };
60
+ case ConfigOptionType.Select:
61
+ return {
62
+ ...baseQuestion,
63
+ type: 'list' as const,
64
+ choices: option.options || [],
65
+ default: existingValue ?? option.default,
66
+ };
67
+ case ConfigOptionType.String:
68
+ default: {
69
+ // For user_mention, default to global config value if no existing override
70
+ let defaultValue = existingValue ?? option.default ?? '';
71
+ if (
72
+ key === 'user_mention' &&
73
+ !existingValue &&
74
+ globalConfig.user_mention
75
+ ) {
76
+ defaultValue = globalConfig.user_mention;
77
+ }
78
+ return {
79
+ ...baseQuestion,
80
+ type: 'input' as const,
81
+ default: defaultValue,
82
+ };
65
83
  }
66
- return {
67
- ...baseQuestion,
68
- type: 'input' as const,
69
- default: defaultValue,
70
- };
84
+ }
85
+ });
86
+
87
+ const answers = await inquirer.prompt(questions);
88
+
89
+ // Save all answers (including defaults)
90
+ for (const [key, value] of Object.entries(answers)) {
91
+ // Save all non-empty values
92
+ if (value !== '' && value !== undefined && value !== null) {
93
+ overrides[key] = value as string | boolean | number;
71
94
  }
72
95
  }
73
- });
96
+ } else {
97
+ // User declined to configure - use defaults from schema
98
+ for (const [key, option] of Object.entries(configSchema)) {
99
+ const existingValue = existingOverrides[key];
100
+ let defaultValue =
101
+ existingValue ??
102
+ option.default ??
103
+ (option.type === ConfigOptionType.Boolean ? false : '');
74
104
 
75
- const answers = await inquirer.prompt(questions);
105
+ // Special handling for user_mention
106
+ if (
107
+ key === 'user_mention' &&
108
+ !existingValue &&
109
+ globalConfig.user_mention
110
+ ) {
111
+ defaultValue = globalConfig.user_mention;
112
+ }
76
113
 
77
- // Filter out empty/default values to keep overrides minimal
78
- const overrides: SkillOverrides = {};
79
- for (const [key, value] of Object.entries(answers)) {
80
- const schema = configSchema[key];
81
- // Only save if different from default
82
- if (value !== schema.default && value !== '' && value !== false) {
83
- overrides[key] = value as string | boolean | number;
114
+ if (
115
+ defaultValue !== '' &&
116
+ defaultValue !== undefined &&
117
+ defaultValue !== null
118
+ ) {
119
+ overrides[key] = defaultValue as string | boolean | number;
120
+ }
84
121
  }
85
122
  }
86
123
 
87
- if (Object.keys(overrides).length > 0) {
88
- saveSkillOverrides(skillName, overrides);
89
- // Strip droid- prefix for display since that's where the file actually goes
90
- const displayName = skillName.replace(/^droid-/, '');
91
- console.log(chalk.green(`\n✓ Configuration saved to ~/.droid/skills/${displayName}/overrides.yaml`));
92
- } else {
93
- console.log(chalk.gray('\nNo custom configuration set (using defaults).'));
94
- }
124
+ // Always save overrides.yaml when a skill has a config schema
125
+ // Skills expect this file to exist even if all values are defaults
126
+ saveSkillOverrides(skillName, overrides);
127
+ const displayName = skillName.replace(/^droid-/, '');
128
+ console.log(
129
+ chalk.green(
130
+ `\n✓ Configuration saved to ~/.droid/skills/${displayName}/overrides.yaml`,
131
+ ),
132
+ );
95
133
  }
package/src/lib/skills.ts CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  isAgentInstalled,
26
26
  } from './agents';
27
27
  import { getSkillsPath, getCommandsPath, getConfigPath } from './platforms';
28
- import { loadToolManifest } from './tools';
28
+ import { loadToolManifest, isToolInstalled } from './tools';
29
29
  import { runToolMigrations } from './migrations';
30
30
 
31
31
  // Marker comments for CLAUDE.md skill registration
@@ -414,7 +414,7 @@ export function installSkill(skillName: string): {
414
414
  // Check dependencies
415
415
  if (manifest.dependencies) {
416
416
  for (const dep of manifest.dependencies) {
417
- if (!isSkillInstalled(dep)) {
417
+ if (!isToolInstalled(dep)) {
418
418
  return {
419
419
  success: false,
420
420
  message: `Missing dependency: '${dep}'. Install it first with \`droid install ${dep}\``,
@@ -57,7 +57,7 @@ description: "What this skill does"
57
57
  globs:
58
58
  - "**/*.ts" # File patterns this skill applies to
59
59
  alwaysApply: false # Always include in context?
60
- allowed-tools: Read, Grep, Glob # Pre-authorize tools (reduces permission prompts)
60
+ allowed-tools: [Read, Grep, Glob] # Pre-authorize tools (reduces permission prompts)
61
61
  ---
62
62
 
63
63
  # My Skill
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "droid-brain",
3
+ "version": "0.2.3",
4
+ "description": "Your scratchpad (or brain) - a collaborative space for planning and research. Create docs with /brain plan, /brain research, or /brain review. Use @mentions for async discussion. Docs persist across sessions.",
5
+ "author": {
6
+ "name": "Orderful",
7
+ "url": "https://github.com/orderful"
8
+ },
9
+ "repository": "https://github.com/orderful/droid",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "droid",
13
+ "ai",
14
+ "brain"
15
+ ]
16
+ }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Collaborative scratchpad for planning and research
3
3
  argument-hint: "[{topic} | plan|research|review {topic} | idea|add {text} | check|done]"
4
- allowed-tools: Read, Write, Edit, Glob, Grep, Bash(mkdir:*), Bash(ls:*)
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash(mkdir:*), Bash(ls:*)]
5
5
  ---
6
6
 
7
7
  # /brain
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Collaborative scratchpad for planning and research
3
3
  argument-hint: "[{topic} | plan|research|review {topic} | idea|add {text} | check|done]"
4
- allowed-tools: Read, Write, Edit, Glob, Grep, Bash(mkdir:*), Bash(ls:*)
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash(mkdir:*), Bash(ls:*)]
5
5
  ---
6
6
 
7
7
  # /scratchpad
@@ -4,7 +4,7 @@ description: "Collaborative scratchpad for planning and research. Use when plann
4
4
  globs:
5
5
  - "**/brain/**/*.md"
6
6
  alwaysApply: false
7
- allowed-tools: Read, Write, Glob, Grep, Bash
7
+ allowed-tools: [Read, Write, Glob, Grep, Bash]
8
8
  ---
9
9
 
10
10
  # Brain Skill
@@ -4,7 +4,7 @@ description: "Obsidian extension for brain skill with YAML frontmatter, wikilink
4
4
  globs:
5
5
  - "**/brain/**/*.md"
6
6
  alwaysApply: false
7
- allowed-tools: Read, Write, Glob, Grep, Bash
7
+ allowed-tools: [Read, Write, Glob, Grep, Bash]
8
8
  ---
9
9
 
10
10
  # Brain Obsidian Extension
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "droid-coach",
3
+ "version": "0.1.3",
4
+ "description": "Learning-mode AI assistance - AI as coach, not crutch. Use /coach plan for co-authored planning, /coach scaffold for structure with hints, /coach review for Socratic questions.",
5
+ "author": {
6
+ "name": "Orderful",
7
+ "url": "https://github.com/orderful"
8
+ },
9
+ "repository": "https://github.com/orderful/droid",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "droid",
13
+ "ai",
14
+ "coach"
15
+ ]
16
+ }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: "Learning-mode AI assistance - scaffolds don't implement, questions don't fix"
3
3
  argument-hint: "[plan {task} | scaffold [{path}] | review [{path}] | check | challenge [{path}]]"
4
- allowed-tools: Read, Write, Edit, Glob, Grep, Bash(ls:*)
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash(ls:*)]
5
5
  ---
6
6
 
7
7
  # /coach
@@ -2,7 +2,7 @@
2
2
  name: droid-coach
3
3
  description: "Learning-mode AI assistance - scaffolds don't implement, questions don't fix. Use when learning a new codebase, wanting to understand deeply, or building skills to retain. User prompts like 'coach me on', 'help me think through', 'I want to learn how to', 'don't just give me the answer'."
4
4
  alwaysApply: false
5
- allowed-tools: Read, Grep, Glob
5
+ allowed-tools: [Read, Grep, Glob]
6
6
  ---
7
7
 
8
8
  # Coach Skill
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "droid-code-review",
3
+ "version": "0.1.2",
4
+ "description": "Comprehensive code review using specialized agents. Reviews PRs, staged changes, branches, or specific files with confidence scoring.",
5
+ "author": {
6
+ "name": "Orderful",
7
+ "url": "https://github.com/orderful"
8
+ },
9
+ "repository": "https://github.com/orderful/droid",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "droid",
13
+ "ai",
14
+ "code-review"
15
+ ]
16
+ }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Run comprehensive code review using specialized agents. Accepts PR number, 'staged', 'branch', or file path.
3
3
  argument-hint: "[#123 | staged | branch | path/to/file.ts]"
4
- allowed-tools: Task, Bash(git:*), Bash(gh:*), Read, Glob
4
+ allowed-tools: [Task, Bash(git:*), Bash(gh:*), Read, Glob]
5
5
  ---
6
6
 
7
7
  # /code-review - Run comprehensive code review using specialized agents
@@ -4,7 +4,7 @@ description: "Comprehensive code review using specialized agents. Use when revie
4
4
  globs:
5
5
  - "**/*"
6
6
  alwaysApply: false
7
- allowed-tools: Read, Grep, Glob, Bash, Task
7
+ allowed-tools: [Read, Grep, Glob, Bash, Task]
8
8
  ---
9
9
 
10
10
  # Code Review Skill
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "droid-codex",
3
+ "version": "0.1.5",
4
+ "description": "Shared organizational knowledge - PRDs, tech designs, domains, proposals, patterns, and explored topics. Use when loading project context, searching codex, capturing decisions, or creating new entries.",
5
+ "author": {
6
+ "name": "Orderful",
7
+ "url": "https://github.com/orderful"
8
+ },
9
+ "repository": "https://github.com/orderful/droid",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "droid",
13
+ "ai",
14
+ "codex"
15
+ ]
16
+ }