@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.
- package/.claude-plugin/marketplace.json +114 -0
- package/.github/workflows/ci.yml +20 -0
- package/AGENTS.md +53 -0
- package/CHANGELOG.md +44 -0
- package/README.md +30 -4
- package/dist/bin/droid.js +62 -51
- package/dist/index.js +9 -1
- package/dist/lib/skill-config.d.ts.map +1 -1
- package/dist/tools/README.md +1 -1
- package/dist/tools/brain/.claude-plugin/plugin.json +16 -0
- package/dist/tools/brain/commands/brain.md +1 -1
- package/dist/tools/brain/commands/scratchpad.md +1 -1
- package/dist/tools/brain/skills/droid-brain/SKILL.md +1 -1
- package/dist/tools/brain/skills/droid-brain-obsidian/SKILL.md +1 -1
- package/dist/tools/coach/.claude-plugin/plugin.json +16 -0
- package/dist/tools/coach/commands/coach.md +1 -1
- package/dist/tools/coach/skills/droid-coach/SKILL.md +1 -1
- package/dist/tools/code-review/.claude-plugin/plugin.json +16 -0
- package/dist/tools/code-review/commands/code-review.md +1 -1
- package/dist/tools/code-review/skills/droid-code-review/SKILL.md +1 -1
- package/dist/tools/codex/.claude-plugin/plugin.json +16 -0
- package/dist/tools/codex/TOOL.yaml +2 -2
- package/dist/tools/codex/commands/codex.md +1 -1
- package/dist/tools/codex/skills/droid-codex/SKILL.md +1 -1
- package/dist/tools/comments/.claude-plugin/plugin.json +16 -0
- package/dist/tools/comments/commands/comments.md +1 -1
- package/dist/tools/comments/skills/droid-comments/SKILL.md +1 -1
- package/dist/tools/droid/.claude-plugin/plugin.json +15 -0
- package/dist/tools/droid/TOOL.yaml +1 -1
- package/dist/tools/droid/skills/droid/SKILL.md +1 -1
- package/dist/tools/project/.claude-plugin/plugin.json +16 -0
- package/dist/tools/project/commands/project.md +1 -1
- package/dist/tools/project/skills/droid-project/SKILL.md +1 -1
- package/dist/tools/tech-design/.claude-plugin/plugin.json +16 -0
- package/dist/tools/tech-design/TOOL.yaml +18 -0
- package/dist/tools/tech-design/commands/tech-design.md +93 -0
- package/dist/tools/tech-design/skills/droid-tech-design/SKILL.md +218 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/draft.md +321 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/gaps.md +328 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/publish.md +409 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/research-doc-template.md +129 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/rollup-template.md +55 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/start.md +353 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/think.md +356 -0
- package/dist/tools/tech-design/skills/droid-tech-design/references/thought-doc-template.md +72 -0
- package/package.json +3 -2
- package/scripts/build-plugins.ts +207 -0
- package/src/lib/skill-config.ts +95 -57
- package/src/lib/skills.ts +2 -2
- package/src/tools/README.md +1 -1
- package/src/tools/brain/.claude-plugin/plugin.json +16 -0
- package/src/tools/brain/commands/brain.md +1 -1
- package/src/tools/brain/commands/scratchpad.md +1 -1
- package/src/tools/brain/skills/droid-brain/SKILL.md +1 -1
- package/src/tools/brain/skills/droid-brain-obsidian/SKILL.md +1 -1
- package/src/tools/coach/.claude-plugin/plugin.json +16 -0
- package/src/tools/coach/commands/coach.md +1 -1
- package/src/tools/coach/skills/droid-coach/SKILL.md +1 -1
- package/src/tools/code-review/.claude-plugin/plugin.json +16 -0
- package/src/tools/code-review/commands/code-review.md +1 -1
- package/src/tools/code-review/skills/droid-code-review/SKILL.md +1 -1
- package/src/tools/codex/.claude-plugin/plugin.json +16 -0
- package/src/tools/codex/TOOL.yaml +2 -2
- package/src/tools/codex/commands/codex.md +1 -1
- package/src/tools/codex/skills/droid-codex/SKILL.md +1 -1
- package/src/tools/comments/.claude-plugin/plugin.json +16 -0
- package/src/tools/comments/commands/comments.md +1 -1
- package/src/tools/comments/skills/droid-comments/SKILL.md +1 -1
- package/src/tools/droid/.claude-plugin/plugin.json +15 -0
- package/src/tools/droid/TOOL.yaml +1 -1
- package/src/tools/droid/skills/droid/SKILL.md +1 -1
- package/src/tools/project/.claude-plugin/plugin.json +16 -0
- package/src/tools/project/commands/project.md +1 -1
- package/src/tools/project/skills/droid-project/SKILL.md +1 -1
- package/src/tools/tech-design/.claude-plugin/plugin.json +16 -0
- package/src/tools/tech-design/TOOL.yaml +18 -0
- package/src/tools/tech-design/commands/tech-design.md +93 -0
- package/src/tools/tech-design/skills/droid-tech-design/SKILL.md +218 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/draft.md +321 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/gaps.md +328 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/publish.md +409 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/research-doc-template.md +129 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/rollup-template.md +55 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/start.md +353 -0
- package/src/tools/tech-design/skills/droid-tech-design/references/think.md +356 -0
- 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.
|
|
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
|
+
}
|
package/src/lib/skill-config.ts
CHANGED
|
@@ -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 {
|
|
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<{
|
|
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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
39
|
+
let overrides: SkillOverrides = {};
|
|
40
|
+
|
|
41
|
+
if (shouldPrompt) {
|
|
42
|
+
console.log(chalk.bold(`\n⚙️ Configure ${skillName}\n`));
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const questions = Object.entries(configSchema).map(([key, option]) => {
|
|
45
|
+
const baseQuestion = {
|
|
46
|
+
name: key,
|
|
47
|
+
message: option.description,
|
|
48
|
+
};
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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 (!
|
|
417
|
+
if (!isToolInstalled(dep)) {
|
|
418
418
|
return {
|
|
419
419
|
success: false,
|
|
420
420
|
message: `Missing dependency: '${dep}'. Install it first with \`droid install ${dep}\``,
|
package/src/tools/README.md
CHANGED
|
@@ -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
|
|
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: "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
|
|
@@ -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
|
+
}
|