@orderful/droid 0.15.0 → 0.16.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/CLAUDE.md +19 -1
- package/CHANGELOG.md +13 -0
- package/dist/bin/droid.js +8 -8
- package/dist/bin/droid.js.map +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/install.js +3 -3
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/setup.d.ts +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +3 -3
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skills.js +4 -4
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/tui/components/Badge.d.ts +13 -0
- package/dist/commands/tui/components/Badge.d.ts.map +1 -0
- package/dist/commands/tui/components/Badge.js +29 -0
- package/dist/commands/tui/components/Badge.js.map +1 -0
- package/dist/commands/tui/components/Markdown.d.ts +5 -0
- package/dist/commands/tui/components/Markdown.d.ts.map +1 -0
- package/dist/commands/tui/components/Markdown.js +42 -0
- package/dist/commands/tui/components/Markdown.js.map +1 -0
- package/dist/commands/tui/components/SettingsDetails.d.ts +5 -0
- package/dist/commands/tui/components/SettingsDetails.d.ts.map +1 -0
- package/dist/commands/tui/components/SettingsDetails.js +11 -0
- package/dist/commands/tui/components/SettingsDetails.js.map +1 -0
- package/dist/commands/tui/components/TabBar.d.ts +10 -0
- package/dist/commands/tui/components/TabBar.d.ts.map +1 -0
- package/dist/commands/tui/components/TabBar.js +7 -0
- package/dist/commands/tui/components/TabBar.js.map +1 -0
- package/dist/commands/tui/components/ToolDetails.d.ts +8 -0
- package/dist/commands/tui/components/ToolDetails.d.ts.map +1 -0
- package/dist/commands/tui/components/ToolDetails.js +35 -0
- package/dist/commands/tui/components/ToolDetails.js.map +1 -0
- package/dist/commands/tui/components/ToolItem.d.ts +9 -0
- package/dist/commands/tui/components/ToolItem.d.ts.map +1 -0
- package/dist/commands/tui/components/ToolItem.js +11 -0
- package/dist/commands/tui/components/ToolItem.js.map +1 -0
- package/dist/commands/tui/constants.d.ts +16 -0
- package/dist/commands/tui/constants.d.ts.map +1 -0
- package/dist/commands/tui/constants.js +17 -0
- package/dist/commands/tui/constants.js.map +1 -0
- package/dist/commands/tui/hooks/useAppUpdate.d.ts +13 -0
- package/dist/commands/tui/hooks/useAppUpdate.d.ts.map +1 -0
- package/dist/commands/tui/hooks/useAppUpdate.js +52 -0
- package/dist/commands/tui/hooks/useAppUpdate.js.map +1 -0
- package/dist/commands/tui/hooks/useToolUpdates.d.ts +22 -0
- package/dist/commands/tui/hooks/useToolUpdates.d.ts.map +1 -0
- package/dist/commands/tui/hooks/useToolUpdates.js +77 -0
- package/dist/commands/tui/hooks/useToolUpdates.js.map +1 -0
- package/dist/commands/tui/types.d.ts +5 -0
- package/dist/commands/tui/types.d.ts.map +1 -0
- package/dist/commands/tui/types.js +2 -0
- package/dist/commands/tui/types.js.map +1 -0
- package/dist/commands/tui/views/ReadmeViewer.d.ts +7 -0
- package/dist/commands/tui/views/ReadmeViewer.d.ts.map +1 -0
- package/dist/commands/tui/views/ReadmeViewer.js +56 -0
- package/dist/commands/tui/views/ReadmeViewer.js.map +1 -0
- package/dist/commands/tui/views/SetupScreen.d.ts +8 -0
- package/dist/commands/tui/views/SetupScreen.d.ts.map +1 -0
- package/dist/commands/tui/views/SetupScreen.js +114 -0
- package/dist/commands/tui/views/SetupScreen.js.map +1 -0
- package/dist/commands/tui/views/SkillConfigScreen.d.ts +8 -0
- package/dist/commands/tui/views/SkillConfigScreen.d.ts.map +1 -0
- package/dist/commands/tui/views/SkillConfigScreen.js +148 -0
- package/dist/commands/tui/views/SkillConfigScreen.js.map +1 -0
- package/dist/commands/tui/views/ToolExplorer.d.ts +8 -0
- package/dist/commands/tui/views/ToolExplorer.d.ts.map +1 -0
- package/dist/commands/tui/views/ToolExplorer.js +86 -0
- package/dist/commands/tui/views/ToolExplorer.js.map +1 -0
- package/dist/commands/tui/views/ToolUpdatePrompt.d.ts +10 -0
- package/dist/commands/tui/views/ToolUpdatePrompt.d.ts.map +1 -0
- package/dist/commands/tui/views/ToolUpdatePrompt.js +38 -0
- package/dist/commands/tui/views/ToolUpdatePrompt.js.map +1 -0
- package/dist/commands/tui/views/WelcomeScreen.d.ts +11 -0
- package/dist/commands/tui/views/WelcomeScreen.d.ts.map +1 -0
- package/dist/commands/tui/views/WelcomeScreen.js +46 -0
- package/dist/commands/tui/views/WelcomeScreen.js.map +1 -0
- package/dist/commands/tui.d.ts.map +1 -1
- package/dist/commands/tui.js +54 -755
- package/dist/commands/tui.js.map +1 -1
- package/dist/commands/uninstall.js +2 -2
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/agents.d.ts +1 -1
- package/dist/lib/agents.d.ts.map +1 -1
- package/dist/lib/agents.js +4 -4
- package/dist/lib/agents.js.map +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/platforms.d.ts +1 -1
- package/dist/lib/platforms.d.ts.map +1 -1
- package/dist/lib/platforms.js +1 -1
- package/dist/lib/platforms.js.map +1 -1
- package/dist/lib/skill-config.d.ts +1 -1
- package/dist/lib/skill-config.d.ts.map +1 -1
- package/dist/lib/skill-config.js +2 -2
- package/dist/lib/skill-config.js.map +1 -1
- package/dist/lib/skills.d.ts +1 -1
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +5 -5
- package/dist/lib/skills.js.map +1 -1
- package/dist/lib/tools.d.ts +1 -1
- package/dist/lib/tools.d.ts.map +1 -1
- package/dist/lib/tools.js +3 -3
- package/dist/lib/tools.js.map +1 -1
- package/package.json +3 -3
- package/src/bin/droid.ts +8 -8
- package/src/commands/config.ts +1 -1
- package/src/commands/install.ts +3 -3
- package/src/commands/setup.test.ts +1 -1
- package/src/commands/setup.ts +3 -3
- package/src/commands/skills.ts +4 -4
- package/src/commands/tui/components/Badge.tsx +86 -0
- package/src/commands/tui/components/Markdown.tsx +48 -0
- package/src/commands/tui/components/SettingsDetails.tsx +70 -0
- package/src/commands/tui/components/TabBar.tsx +26 -0
- package/src/commands/tui/components/ToolDetails.tsx +117 -0
- package/src/commands/tui/components/ToolItem.tsx +39 -0
- package/src/commands/tui/constants.ts +17 -0
- package/src/commands/tui/hooks/useAppUpdate.ts +67 -0
- package/src/commands/tui/hooks/useToolUpdates.ts +110 -0
- package/src/commands/tui/types.ts +4 -0
- package/src/commands/tui/views/ReadmeViewer.tsx +93 -0
- package/src/commands/tui/views/SetupScreen.tsx +242 -0
- package/src/commands/tui/views/SkillConfigScreen.tsx +278 -0
- package/src/commands/tui/views/ToolExplorer.tsx +190 -0
- package/src/commands/tui/views/ToolUpdatePrompt.tsx +109 -0
- package/src/commands/tui/views/WelcomeScreen.tsx +149 -0
- package/src/commands/tui.tsx +65 -1587
- package/src/commands/uninstall.ts +2 -2
- package/src/commands/update.ts +1 -1
- package/src/index.ts +4 -4
- package/src/lib/agents.ts +4 -4
- package/src/lib/config.ts +1 -1
- package/src/lib/platforms.ts +1 -1
- package/src/lib/skill-config.ts +2 -2
- package/src/lib/skills.test.ts +2 -2
- package/src/lib/skills.ts +5 -5
- package/src/lib/tools.ts +3 -3
- package/src/lib/types.test.ts +1 -1
- package/src/lib/version.test.ts +1 -1
package/dist/lib/tools.d.ts
CHANGED
package/dist/lib/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,SAAS,CAAC;AAMjF;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAyBrE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,EAAE,CAmBhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAczD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBvE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAuBpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAyBtD"}
|
package/dist/lib/tools.js
CHANGED
|
@@ -2,9 +2,9 @@ import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
|
2
2
|
import { join, dirname } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import YAML from 'yaml';
|
|
5
|
-
import { loadConfig } from './config
|
|
6
|
-
import { getPlatformTools } from './types
|
|
7
|
-
import { compareSemver } from './version
|
|
5
|
+
import { loadConfig } from './config';
|
|
6
|
+
import { getPlatformTools } from './types';
|
|
7
|
+
import { compareSemver } from './version';
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
const BUNDLED_TOOLS_DIR = join(__dirname, '../tools');
|
|
10
10
|
/**
|
package/dist/lib/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orderful/droid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "AI workflow toolkit for sharing skills, commands, and agents across the team",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc && cp -r src/tools dist/",
|
|
11
|
+
"build": "eslint src --ext .ts,.tsx && tsc && cp -r src/tools dist/",
|
|
12
12
|
"dev": "tsc --watch",
|
|
13
13
|
"start": "bun dist/bin/droid.js",
|
|
14
14
|
"test": "bun test src/",
|
|
15
15
|
"test:watch": "bun test src/ --watch",
|
|
16
|
-
"lint": "eslint src --ext .ts",
|
|
16
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
17
17
|
"format": "prettier --write 'src/**/*.ts'",
|
|
18
18
|
"changeset": "changeset",
|
|
19
19
|
"version": "changeset version",
|
package/src/bin/droid.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { program } from 'commander';
|
|
4
|
-
import { setupCommand } from '../commands/setup
|
|
5
|
-
import { configCommand } from '../commands/config
|
|
6
|
-
import { skillsCommand } from '../commands/skills
|
|
7
|
-
import { installCommand } from '../commands/install
|
|
8
|
-
import { uninstallCommand } from '../commands/uninstall
|
|
9
|
-
import { updateCommand } from '../commands/update
|
|
10
|
-
import { tuiCommand } from '../commands/tui
|
|
11
|
-
import { getVersion } from '../lib/version
|
|
4
|
+
import { setupCommand } from '../commands/setup';
|
|
5
|
+
import { configCommand } from '../commands/config';
|
|
6
|
+
import { skillsCommand } from '../commands/skills';
|
|
7
|
+
import { installCommand } from '../commands/install';
|
|
8
|
+
import { uninstallCommand } from '../commands/uninstall';
|
|
9
|
+
import { updateCommand } from '../commands/update';
|
|
10
|
+
import { tuiCommand } from '../commands/tui';
|
|
11
|
+
import { getVersion } from '../lib/version';
|
|
12
12
|
|
|
13
13
|
const version = getVersion();
|
|
14
14
|
|
package/src/commands/config.ts
CHANGED
package/src/commands/install.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { installSkill } from '../lib/skills
|
|
3
|
-
import { getBundledTools, isToolInstalled } from '../lib/tools
|
|
4
|
-
import { promptForSkillConfig } from '../lib/skill-config
|
|
2
|
+
import { installSkill } from '../lib/skills';
|
|
3
|
+
import { getBundledTools, isToolInstalled } from '../lib/tools';
|
|
4
|
+
import { promptForSkillConfig } from '../lib/skill-config';
|
|
5
5
|
|
|
6
6
|
export async function installCommand(toolName: string): Promise<void> {
|
|
7
7
|
// Check if tool exists
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:te
|
|
|
2
2
|
import { existsSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { tmpdir } from 'os';
|
|
5
|
-
import { Platform } from '../lib/types
|
|
5
|
+
import { Platform } from '../lib/types';
|
|
6
6
|
|
|
7
7
|
// We need to mock homedir() before importing the module
|
|
8
8
|
// Create a test directory that will act as our fake home
|
package/src/commands/setup.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { execSync } from 'child_process';
|
|
|
4
4
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
import { homedir } from 'os';
|
|
7
|
-
import { loadConfig, saveConfig, configExists } from '../lib/config
|
|
8
|
-
import { getBundledSkills } from '../lib/skills
|
|
9
|
-
import { Platform, BuiltInOutput, type DroidConfig, type OutputPreference } from '../lib/types
|
|
7
|
+
import { loadConfig, saveConfig, configExists } from '../lib/config';
|
|
8
|
+
import { getBundledSkills } from '../lib/skills';
|
|
9
|
+
import { Platform, BuiltInOutput, type DroidConfig, type OutputPreference } from '../lib/types';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Permissions droid needs to operate without constant prompts
|
package/src/commands/skills.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { installSkill, uninstallSkill } from '../lib/skills
|
|
4
|
-
import { getBundledTools, isToolInstalled, getInstalledToolVersion } from '../lib/tools
|
|
5
|
-
import { promptForSkillConfig } from '../lib/skill-config
|
|
6
|
-
import { SkillStatus, type ToolManifest } from '../lib/types
|
|
3
|
+
import { installSkill, uninstallSkill } from '../lib/skills';
|
|
4
|
+
import { getBundledTools, isToolInstalled, getInstalledToolVersion } from '../lib/tools';
|
|
5
|
+
import { promptForSkillConfig } from '../lib/skill-config';
|
|
6
|
+
import { SkillStatus, type ToolManifest } from '../lib/types';
|
|
7
7
|
|
|
8
8
|
function formatToolChoice(tool: ToolManifest): string {
|
|
9
9
|
const installed = isToolInstalled(tool.name);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import type { ComponentType } from '../types';
|
|
3
|
+
import { colors } from '../constants';
|
|
4
|
+
import type { ToolManifest } from '../../../lib/types';
|
|
5
|
+
|
|
6
|
+
export function Badge({
|
|
7
|
+
type,
|
|
8
|
+
label,
|
|
9
|
+
isSelected = false,
|
|
10
|
+
dimmed = false,
|
|
11
|
+
}: {
|
|
12
|
+
type: ComponentType;
|
|
13
|
+
label?: string;
|
|
14
|
+
isSelected?: boolean;
|
|
15
|
+
dimmed?: boolean;
|
|
16
|
+
}) {
|
|
17
|
+
const color = colors[type];
|
|
18
|
+
const displayLabel = label || type.charAt(0).toUpperCase() + type.slice(1);
|
|
19
|
+
|
|
20
|
+
if (dimmed) {
|
|
21
|
+
return (
|
|
22
|
+
<Text color={colors.textDim}>{displayLabel}</Text>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Text
|
|
28
|
+
backgroundColor={isSelected ? color : undefined}
|
|
29
|
+
color={isSelected ? '#000000' : color}
|
|
30
|
+
bold={isSelected}
|
|
31
|
+
>
|
|
32
|
+
{isSelected ? ` ${displayLabel} ` : displayLabel}
|
|
33
|
+
</Text>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ComponentBadges({ tool, compact = false }: { tool: ToolManifest; compact?: boolean }) {
|
|
38
|
+
const hasSkills = tool.includes.skills.length > 0;
|
|
39
|
+
const hasCommands = tool.includes.commands.length > 0;
|
|
40
|
+
const hasAgents = tool.includes.agents.length > 0;
|
|
41
|
+
|
|
42
|
+
if (compact) {
|
|
43
|
+
// Show colored squares for list view (single char with spacing)
|
|
44
|
+
const parts: string[] = [];
|
|
45
|
+
if (hasSkills) parts.push('skill');
|
|
46
|
+
if (hasCommands) parts.push('command');
|
|
47
|
+
if (hasAgents) parts.push('agent');
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Box flexDirection="row">
|
|
51
|
+
{parts.map((type, i) => (
|
|
52
|
+
<Text key={type}>
|
|
53
|
+
<Text backgroundColor={colors[type as ComponentType]}> </Text>
|
|
54
|
+
{i < parts.length - 1 && ' '}
|
|
55
|
+
</Text>
|
|
56
|
+
))}
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Box flexDirection="row">
|
|
63
|
+
{hasSkills && (
|
|
64
|
+
<Box marginRight={1}>
|
|
65
|
+
<Text backgroundColor={colors.skill} color="#000000" bold>
|
|
66
|
+
{` ${tool.includes.skills.length} skill${tool.includes.skills.length > 1 ? 's' : ''} `}
|
|
67
|
+
</Text>
|
|
68
|
+
</Box>
|
|
69
|
+
)}
|
|
70
|
+
{hasCommands && (
|
|
71
|
+
<Box marginRight={1}>
|
|
72
|
+
<Text backgroundColor={colors.command} color="#000000" bold>
|
|
73
|
+
{` ${tool.includes.commands.length} cmd${tool.includes.commands.length > 1 ? 's' : ''} `}
|
|
74
|
+
</Text>
|
|
75
|
+
</Box>
|
|
76
|
+
)}
|
|
77
|
+
{hasAgents && (
|
|
78
|
+
<Box marginRight={1}>
|
|
79
|
+
<Text backgroundColor={colors.agent} color="#000000" bold>
|
|
80
|
+
{` ${tool.includes.agents.length} agent${tool.includes.agents.length > 1 ? 's' : ''} `}
|
|
81
|
+
</Text>
|
|
82
|
+
</Box>
|
|
83
|
+
)}
|
|
84
|
+
</Box>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Text } from 'ink';
|
|
2
|
+
import { colors } from '../constants';
|
|
3
|
+
|
|
4
|
+
export function MarkdownLine({ line, inCodeBlock }: { line: string; inCodeBlock: boolean }) {
|
|
5
|
+
// Code block content
|
|
6
|
+
if (inCodeBlock) {
|
|
7
|
+
return <Text color="#a5d6ff">{line || ' '}</Text>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Code block delimiter
|
|
11
|
+
if (line.startsWith('```')) {
|
|
12
|
+
return <Text color={colors.textDim}>{line}</Text>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Headers
|
|
16
|
+
if (line.startsWith('# ')) {
|
|
17
|
+
return <Text color={colors.text} bold>{line.slice(2)}</Text>;
|
|
18
|
+
}
|
|
19
|
+
if (line.startsWith('## ')) {
|
|
20
|
+
return <Text color={colors.text} bold>{line.slice(3)}</Text>;
|
|
21
|
+
}
|
|
22
|
+
if (line.startsWith('### ')) {
|
|
23
|
+
return <Text color="#c9d1d9" bold>{line.slice(4)}</Text>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// YAML frontmatter delimiter
|
|
27
|
+
if (line === '---') {
|
|
28
|
+
return <Text color={colors.textDim}>{line}</Text>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// List items
|
|
32
|
+
if (line.match(/^[\s]*[-*]\s/)) {
|
|
33
|
+
return <Text color={colors.textMuted}>{line}</Text>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Blockquotes
|
|
37
|
+
if (line.startsWith('>')) {
|
|
38
|
+
return <Text color="#8b949e" italic>{line}</Text>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Table rows
|
|
42
|
+
if (line.includes('|')) {
|
|
43
|
+
return <Text color={colors.textMuted}>{line}</Text>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Default
|
|
47
|
+
return <Text color={colors.textMuted}>{line || ' '}</Text>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import { loadConfig, getAutoUpdateConfig } from '../../../lib/config';
|
|
3
|
+
import { Platform } from '../../../lib/types';
|
|
4
|
+
import { colors } from '../constants';
|
|
5
|
+
|
|
6
|
+
export interface SettingsDetailsProps {
|
|
7
|
+
isFocused: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function SettingsDetails({
|
|
11
|
+
isFocused,
|
|
12
|
+
}: SettingsDetailsProps) {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const autoUpdateConfig = getAutoUpdateConfig();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Box flexDirection="column" paddingLeft={2} flexGrow={1}>
|
|
18
|
+
<Text color={colors.text} bold>Settings</Text>
|
|
19
|
+
|
|
20
|
+
<Box flexDirection="column" marginTop={1}>
|
|
21
|
+
<Text>
|
|
22
|
+
<Text color={colors.textDim}>Platform: </Text>
|
|
23
|
+
<Text color={colors.text}>
|
|
24
|
+
{config.platform === Platform.ClaudeCode ? 'Claude Code' : 'OpenCode'}
|
|
25
|
+
</Text>
|
|
26
|
+
</Text>
|
|
27
|
+
<Text>
|
|
28
|
+
<Text color={colors.textDim}>Your @mention: </Text>
|
|
29
|
+
<Text color={colors.text}>{config.user_mention}</Text>
|
|
30
|
+
</Text>
|
|
31
|
+
<Text>
|
|
32
|
+
<Text color={colors.textDim}>Auto-update tools: </Text>
|
|
33
|
+
<Text color={colors.text}>{autoUpdateConfig.tools ? 'enabled' : 'disabled'}</Text>
|
|
34
|
+
</Text>
|
|
35
|
+
<Text>
|
|
36
|
+
<Text color={colors.textDim}>Auto-update app: </Text>
|
|
37
|
+
<Text color={colors.text}>{autoUpdateConfig.app ? 'enabled' : 'disabled'}</Text>
|
|
38
|
+
</Text>
|
|
39
|
+
</Box>
|
|
40
|
+
|
|
41
|
+
<Box marginTop={2}>
|
|
42
|
+
<Text color={colors.textDim}>Config: ~/.droid/config.yaml</Text>
|
|
43
|
+
</Box>
|
|
44
|
+
|
|
45
|
+
{isFocused && (
|
|
46
|
+
<Box marginTop={2}>
|
|
47
|
+
<Text
|
|
48
|
+
backgroundColor={colors.primary}
|
|
49
|
+
color="#ffffff"
|
|
50
|
+
bold
|
|
51
|
+
>
|
|
52
|
+
{' '}Edit{' '}
|
|
53
|
+
</Text>
|
|
54
|
+
</Box>
|
|
55
|
+
)}
|
|
56
|
+
|
|
57
|
+
{isFocused && (
|
|
58
|
+
<Box marginTop={1}>
|
|
59
|
+
<Text color={colors.textDim}>enter edit · esc back</Text>
|
|
60
|
+
</Box>
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
{!isFocused && (
|
|
64
|
+
<Box marginTop={2}>
|
|
65
|
+
<Text color={colors.textDim}>press enter to edit</Text>
|
|
66
|
+
</Box>
|
|
67
|
+
)}
|
|
68
|
+
</Box>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import type { Tab } from '../types';
|
|
3
|
+
import { colors } from '../constants';
|
|
4
|
+
|
|
5
|
+
export interface TabBarProps {
|
|
6
|
+
tabs: { id: Tab; label: string }[];
|
|
7
|
+
activeTab: Tab;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function TabBar({ tabs, activeTab }: TabBarProps) {
|
|
11
|
+
return (
|
|
12
|
+
<Box flexDirection="row" flexWrap="wrap">
|
|
13
|
+
{tabs.map((tab) => (
|
|
14
|
+
<Text
|
|
15
|
+
key={tab.id}
|
|
16
|
+
backgroundColor={tab.id === activeTab ? colors.primary : undefined}
|
|
17
|
+
color={tab.id === activeTab ? '#ffffff' : colors.textMuted}
|
|
18
|
+
bold={tab.id === activeTab}
|
|
19
|
+
wrap="truncate"
|
|
20
|
+
>
|
|
21
|
+
{' '}{tab.label}{' '}
|
|
22
|
+
</Text>
|
|
23
|
+
))}
|
|
24
|
+
</Box>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import { isToolInstalled, getInstalledToolVersion, getToolUpdateStatus } from '../../../lib/tools';
|
|
3
|
+
import type { ToolManifest } from '../../../lib/types';
|
|
4
|
+
import { colors } from '../constants';
|
|
5
|
+
import { ComponentBadges } from './Badge';
|
|
6
|
+
|
|
7
|
+
export interface ToolDetailsProps {
|
|
8
|
+
tool: ToolManifest | null;
|
|
9
|
+
isFocused: boolean;
|
|
10
|
+
selectedAction: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ToolDetails({
|
|
14
|
+
tool,
|
|
15
|
+
isFocused,
|
|
16
|
+
selectedAction,
|
|
17
|
+
}: ToolDetailsProps) {
|
|
18
|
+
if (!tool) {
|
|
19
|
+
return (
|
|
20
|
+
<Box paddingLeft={2} flexGrow={1}>
|
|
21
|
+
<Text color={colors.textDim}>Select a tool</Text>
|
|
22
|
+
</Box>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const installed = isToolInstalled(tool.name);
|
|
27
|
+
const installedVersion = getInstalledToolVersion(tool.name);
|
|
28
|
+
const updateStatus = getToolUpdateStatus(tool.name);
|
|
29
|
+
const isSystemTool = (tool as ToolManifest & { system?: boolean }).system === true;
|
|
30
|
+
|
|
31
|
+
const actions = installed
|
|
32
|
+
? [
|
|
33
|
+
{ id: 'explore', label: 'Explore', variant: 'default' },
|
|
34
|
+
...(updateStatus.hasUpdate
|
|
35
|
+
? [{ id: 'update', label: `Update (${updateStatus.bundledVersion})`, variant: 'primary' }]
|
|
36
|
+
: []),
|
|
37
|
+
{ id: 'configure', label: 'Configure', variant: 'default' },
|
|
38
|
+
// System tools can't be uninstalled
|
|
39
|
+
...(!isSystemTool ? [{ id: 'uninstall', label: 'Uninstall', variant: 'danger' }] : []),
|
|
40
|
+
]
|
|
41
|
+
: [
|
|
42
|
+
{ id: 'explore', label: 'Explore', variant: 'default' },
|
|
43
|
+
// System tools auto-install, but show Install for manual trigger if needed
|
|
44
|
+
{ id: 'install', label: 'Install', variant: 'primary' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Box flexDirection="column" paddingLeft={2} flexGrow={1}>
|
|
49
|
+
<Text color={colors.text} bold>{tool.name}</Text>
|
|
50
|
+
|
|
51
|
+
<Box marginTop={1}>
|
|
52
|
+
<Text color={colors.textDim}>
|
|
53
|
+
{tool.version}
|
|
54
|
+
{tool.status && ` · ${tool.status}`}
|
|
55
|
+
{installed && <Text color={colors.success}> · installed</Text>}
|
|
56
|
+
{updateStatus.hasUpdate && (
|
|
57
|
+
<Text color={colors.primary}> · update ({installedVersion} → {updateStatus.bundledVersion})</Text>
|
|
58
|
+
)}
|
|
59
|
+
</Text>
|
|
60
|
+
</Box>
|
|
61
|
+
|
|
62
|
+
<Box marginTop={1}>
|
|
63
|
+
<Text color={colors.textMuted}>{tool.description}</Text>
|
|
64
|
+
</Box>
|
|
65
|
+
|
|
66
|
+
{/* Colored component badges */}
|
|
67
|
+
<Box flexDirection="column" marginTop={1}>
|
|
68
|
+
<Text color={colors.textDim}>Includes:</Text>
|
|
69
|
+
<Box marginTop={1}>
|
|
70
|
+
<ComponentBadges tool={tool} />
|
|
71
|
+
</Box>
|
|
72
|
+
{/* Show names below badges */}
|
|
73
|
+
<Box flexDirection="column" marginTop={1} marginLeft={1}>
|
|
74
|
+
{tool.includes.skills.length > 0 && (
|
|
75
|
+
<Text>
|
|
76
|
+
<Text color={colors.skill}>Skills: </Text>
|
|
77
|
+
<Text color={colors.textMuted}>{tool.includes.skills.map(s => s.name).join(', ')}</Text>
|
|
78
|
+
</Text>
|
|
79
|
+
)}
|
|
80
|
+
{tool.includes.commands.length > 0 && (
|
|
81
|
+
<Text>
|
|
82
|
+
<Text color={colors.command}>Commands: </Text>
|
|
83
|
+
<Text color={colors.textMuted}>{tool.includes.commands.map(c => `/${c}`).join(', ')}</Text>
|
|
84
|
+
</Text>
|
|
85
|
+
)}
|
|
86
|
+
{tool.includes.agents.length > 0 && (
|
|
87
|
+
<Text>
|
|
88
|
+
<Text color={colors.agent}>Agents: </Text>
|
|
89
|
+
<Text color={colors.textMuted}>{tool.includes.agents.join(', ')}</Text>
|
|
90
|
+
</Text>
|
|
91
|
+
)}
|
|
92
|
+
</Box>
|
|
93
|
+
</Box>
|
|
94
|
+
|
|
95
|
+
{isFocused && (
|
|
96
|
+
<Box flexDirection="row" marginTop={1}>
|
|
97
|
+
{actions.map((action, index) => (
|
|
98
|
+
<Text
|
|
99
|
+
key={action.id}
|
|
100
|
+
backgroundColor={
|
|
101
|
+
selectedAction === index
|
|
102
|
+
? action.variant === 'danger'
|
|
103
|
+
? colors.error
|
|
104
|
+
: colors.primary
|
|
105
|
+
: colors.bgSelected
|
|
106
|
+
}
|
|
107
|
+
color={selectedAction === index ? '#ffffff' : colors.textMuted}
|
|
108
|
+
bold={selectedAction === index}
|
|
109
|
+
>
|
|
110
|
+
{' '}{action.label}{' '}
|
|
111
|
+
</Text>
|
|
112
|
+
))}
|
|
113
|
+
</Box>
|
|
114
|
+
)}
|
|
115
|
+
</Box>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Box, Text } from 'ink';
|
|
2
|
+
import { isToolInstalled, getInstalledToolVersion, getToolUpdateStatus } from '../../../lib/tools';
|
|
3
|
+
import type { ToolManifest } from '../../../lib/types';
|
|
4
|
+
import { colors } from '../constants';
|
|
5
|
+
|
|
6
|
+
export interface ToolItemProps {
|
|
7
|
+
tool: ToolManifest;
|
|
8
|
+
isSelected: boolean;
|
|
9
|
+
isActive: boolean;
|
|
10
|
+
wasAutoUpdated?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ToolItem({
|
|
14
|
+
tool,
|
|
15
|
+
isSelected,
|
|
16
|
+
isActive,
|
|
17
|
+
wasAutoUpdated,
|
|
18
|
+
}: ToolItemProps) {
|
|
19
|
+
const installed = isToolInstalled(tool.name);
|
|
20
|
+
const installedVersion = getInstalledToolVersion(tool.name);
|
|
21
|
+
const updateStatus = getToolUpdateStatus(tool.name);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Box paddingX={1} backgroundColor={isActive ? colors.bgSelected : undefined}>
|
|
25
|
+
<Text wrap="truncate">
|
|
26
|
+
<Text color={colors.textDim}>{isSelected ? '>' : ' '} </Text>
|
|
27
|
+
<Text color={isSelected || isActive ? colors.text : colors.textMuted}>{tool.name}</Text>
|
|
28
|
+
{installed && installedVersion && <Text color={colors.textDim}> v{installedVersion}</Text>}
|
|
29
|
+
{installed && <Text color={colors.success}> ✓</Text>}
|
|
30
|
+
{wasAutoUpdated && <Text color={colors.success}> ↑</Text>}
|
|
31
|
+
{updateStatus.hasUpdate && !wasAutoUpdated && <Text color={colors.primary}> ↑</Text>}
|
|
32
|
+
<Text> </Text>
|
|
33
|
+
{tool.includes.skills.length > 0 && <Text color={colors.skill}>● </Text>}
|
|
34
|
+
{tool.includes.commands.length > 0 && <Text color={colors.command}>● </Text>}
|
|
35
|
+
{tool.includes.agents.length > 0 && <Text color={colors.agent}>●</Text>}
|
|
36
|
+
</Text>
|
|
37
|
+
</Box>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const colors = {
|
|
2
|
+
primary: '#6366f1',
|
|
3
|
+
bgSelected: '#2d2d2d',
|
|
4
|
+
border: '#3a3a3a',
|
|
5
|
+
text: '#e8e8e8',
|
|
6
|
+
textMuted: '#999999',
|
|
7
|
+
textDim: '#6a6a6a',
|
|
8
|
+
success: '#4ade80',
|
|
9
|
+
error: '#f87171',
|
|
10
|
+
// Component type badges
|
|
11
|
+
skill: '#ec4899', // pink/magenta
|
|
12
|
+
command: '#22d3ee', // cyan
|
|
13
|
+
agent: '#fbbf24', // yellow/amber
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
export const MAX_VISIBLE_ITEMS = 6;
|
|
17
|
+
export const MAX_VISIBLE_CONFIG_ITEMS = 4; // Each config item takes ~3 lines
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useState, useMemo } from 'react';
|
|
2
|
+
import { useApp } from 'ink';
|
|
3
|
+
import { getUpdateInfo, runUpdate, type UpdateInfo } from '../../../lib/version';
|
|
4
|
+
import { setAutoUpdateConfig } from '../../../lib/config';
|
|
5
|
+
|
|
6
|
+
export interface UseAppUpdateOptions {
|
|
7
|
+
onUpdateSuccess: (message: string) => void;
|
|
8
|
+
onUpdateFailure: (error: string) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface UseAppUpdateResult {
|
|
12
|
+
updateInfo: UpdateInfo;
|
|
13
|
+
isUpdating: boolean;
|
|
14
|
+
handleUpdate: () => void;
|
|
15
|
+
handleAlwaysUpdate: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function useAppUpdate({ onUpdateSuccess, onUpdateFailure }: UseAppUpdateOptions): UseAppUpdateResult {
|
|
19
|
+
const { exit } = useApp();
|
|
20
|
+
const [isUpdating, setIsUpdating] = useState(false);
|
|
21
|
+
|
|
22
|
+
const updateInfo = useMemo(() => getUpdateInfo(), []);
|
|
23
|
+
|
|
24
|
+
const handleUpdate = () => {
|
|
25
|
+
setIsUpdating(true);
|
|
26
|
+
// Run update in next tick to allow UI to show "Updating..."
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
const result = runUpdate();
|
|
29
|
+
if (result.success) {
|
|
30
|
+
// Build exit message with ANSI colors
|
|
31
|
+
const blue = '\x1b[38;2;99;102;241m'; // #6366f1
|
|
32
|
+
const dim = '\x1b[38;2;106;106;106m';
|
|
33
|
+
const reset = '\x1b[0m';
|
|
34
|
+
const message = `
|
|
35
|
+
${dim}────────────────────────────────────────────────────────${reset}
|
|
36
|
+
|
|
37
|
+
${dim}╔═════╗${reset}
|
|
38
|
+
${dim}║${reset} ${blue}●${reset} ${blue}●${reset} ${dim}║${reset} ${blue}"It's quite possible this system${reset}
|
|
39
|
+
${dim}╚═╦═╦═╝${reset} ${blue}is now fully operational."${reset}
|
|
40
|
+
|
|
41
|
+
Run ${blue}droid${reset} to start the new version.
|
|
42
|
+
|
|
43
|
+
${dim}────────────────────────────────────────────────────────${reset}
|
|
44
|
+
`;
|
|
45
|
+
onUpdateSuccess(message);
|
|
46
|
+
exit();
|
|
47
|
+
} else {
|
|
48
|
+
setIsUpdating(false);
|
|
49
|
+
onUpdateFailure(result.message);
|
|
50
|
+
}
|
|
51
|
+
}, 100);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleAlwaysUpdate = () => {
|
|
55
|
+
// Enable auto-update for app in config
|
|
56
|
+
setAutoUpdateConfig({ app: true });
|
|
57
|
+
// Then run the update
|
|
58
|
+
handleUpdate();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
updateInfo,
|
|
63
|
+
isUpdating,
|
|
64
|
+
handleUpdate,
|
|
65
|
+
handleAlwaysUpdate,
|
|
66
|
+
};
|
|
67
|
+
}
|