@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.
Files changed (149) hide show
  1. package/.claude/CLAUDE.md +19 -1
  2. package/CHANGELOG.md +13 -0
  3. package/dist/bin/droid.js +8 -8
  4. package/dist/bin/droid.js.map +1 -1
  5. package/dist/commands/config.js +1 -1
  6. package/dist/commands/config.js.map +1 -1
  7. package/dist/commands/install.js +3 -3
  8. package/dist/commands/install.js.map +1 -1
  9. package/dist/commands/setup.d.ts +1 -1
  10. package/dist/commands/setup.d.ts.map +1 -1
  11. package/dist/commands/setup.js +3 -3
  12. package/dist/commands/setup.js.map +1 -1
  13. package/dist/commands/skills.js +4 -4
  14. package/dist/commands/skills.js.map +1 -1
  15. package/dist/commands/tui/components/Badge.d.ts +13 -0
  16. package/dist/commands/tui/components/Badge.d.ts.map +1 -0
  17. package/dist/commands/tui/components/Badge.js +29 -0
  18. package/dist/commands/tui/components/Badge.js.map +1 -0
  19. package/dist/commands/tui/components/Markdown.d.ts +5 -0
  20. package/dist/commands/tui/components/Markdown.d.ts.map +1 -0
  21. package/dist/commands/tui/components/Markdown.js +42 -0
  22. package/dist/commands/tui/components/Markdown.js.map +1 -0
  23. package/dist/commands/tui/components/SettingsDetails.d.ts +5 -0
  24. package/dist/commands/tui/components/SettingsDetails.d.ts.map +1 -0
  25. package/dist/commands/tui/components/SettingsDetails.js +11 -0
  26. package/dist/commands/tui/components/SettingsDetails.js.map +1 -0
  27. package/dist/commands/tui/components/TabBar.d.ts +10 -0
  28. package/dist/commands/tui/components/TabBar.d.ts.map +1 -0
  29. package/dist/commands/tui/components/TabBar.js +7 -0
  30. package/dist/commands/tui/components/TabBar.js.map +1 -0
  31. package/dist/commands/tui/components/ToolDetails.d.ts +8 -0
  32. package/dist/commands/tui/components/ToolDetails.d.ts.map +1 -0
  33. package/dist/commands/tui/components/ToolDetails.js +35 -0
  34. package/dist/commands/tui/components/ToolDetails.js.map +1 -0
  35. package/dist/commands/tui/components/ToolItem.d.ts +9 -0
  36. package/dist/commands/tui/components/ToolItem.d.ts.map +1 -0
  37. package/dist/commands/tui/components/ToolItem.js +11 -0
  38. package/dist/commands/tui/components/ToolItem.js.map +1 -0
  39. package/dist/commands/tui/constants.d.ts +16 -0
  40. package/dist/commands/tui/constants.d.ts.map +1 -0
  41. package/dist/commands/tui/constants.js +17 -0
  42. package/dist/commands/tui/constants.js.map +1 -0
  43. package/dist/commands/tui/hooks/useAppUpdate.d.ts +13 -0
  44. package/dist/commands/tui/hooks/useAppUpdate.d.ts.map +1 -0
  45. package/dist/commands/tui/hooks/useAppUpdate.js +52 -0
  46. package/dist/commands/tui/hooks/useAppUpdate.js.map +1 -0
  47. package/dist/commands/tui/hooks/useToolUpdates.d.ts +22 -0
  48. package/dist/commands/tui/hooks/useToolUpdates.d.ts.map +1 -0
  49. package/dist/commands/tui/hooks/useToolUpdates.js +77 -0
  50. package/dist/commands/tui/hooks/useToolUpdates.js.map +1 -0
  51. package/dist/commands/tui/types.d.ts +5 -0
  52. package/dist/commands/tui/types.d.ts.map +1 -0
  53. package/dist/commands/tui/types.js +2 -0
  54. package/dist/commands/tui/types.js.map +1 -0
  55. package/dist/commands/tui/views/ReadmeViewer.d.ts +7 -0
  56. package/dist/commands/tui/views/ReadmeViewer.d.ts.map +1 -0
  57. package/dist/commands/tui/views/ReadmeViewer.js +56 -0
  58. package/dist/commands/tui/views/ReadmeViewer.js.map +1 -0
  59. package/dist/commands/tui/views/SetupScreen.d.ts +8 -0
  60. package/dist/commands/tui/views/SetupScreen.d.ts.map +1 -0
  61. package/dist/commands/tui/views/SetupScreen.js +114 -0
  62. package/dist/commands/tui/views/SetupScreen.js.map +1 -0
  63. package/dist/commands/tui/views/SkillConfigScreen.d.ts +8 -0
  64. package/dist/commands/tui/views/SkillConfigScreen.d.ts.map +1 -0
  65. package/dist/commands/tui/views/SkillConfigScreen.js +148 -0
  66. package/dist/commands/tui/views/SkillConfigScreen.js.map +1 -0
  67. package/dist/commands/tui/views/ToolExplorer.d.ts +8 -0
  68. package/dist/commands/tui/views/ToolExplorer.d.ts.map +1 -0
  69. package/dist/commands/tui/views/ToolExplorer.js +86 -0
  70. package/dist/commands/tui/views/ToolExplorer.js.map +1 -0
  71. package/dist/commands/tui/views/ToolUpdatePrompt.d.ts +10 -0
  72. package/dist/commands/tui/views/ToolUpdatePrompt.d.ts.map +1 -0
  73. package/dist/commands/tui/views/ToolUpdatePrompt.js +38 -0
  74. package/dist/commands/tui/views/ToolUpdatePrompt.js.map +1 -0
  75. package/dist/commands/tui/views/WelcomeScreen.d.ts +11 -0
  76. package/dist/commands/tui/views/WelcomeScreen.d.ts.map +1 -0
  77. package/dist/commands/tui/views/WelcomeScreen.js +46 -0
  78. package/dist/commands/tui/views/WelcomeScreen.js.map +1 -0
  79. package/dist/commands/tui.d.ts.map +1 -1
  80. package/dist/commands/tui.js +54 -755
  81. package/dist/commands/tui.js.map +1 -1
  82. package/dist/commands/uninstall.js +2 -2
  83. package/dist/commands/uninstall.js.map +1 -1
  84. package/dist/commands/update.js +1 -1
  85. package/dist/commands/update.js.map +1 -1
  86. package/dist/index.d.ts +4 -4
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +4 -4
  89. package/dist/index.js.map +1 -1
  90. package/dist/lib/agents.d.ts +1 -1
  91. package/dist/lib/agents.d.ts.map +1 -1
  92. package/dist/lib/agents.js +4 -4
  93. package/dist/lib/agents.js.map +1 -1
  94. package/dist/lib/config.d.ts +1 -1
  95. package/dist/lib/config.d.ts.map +1 -1
  96. package/dist/lib/config.js +1 -1
  97. package/dist/lib/config.js.map +1 -1
  98. package/dist/lib/platforms.d.ts +1 -1
  99. package/dist/lib/platforms.d.ts.map +1 -1
  100. package/dist/lib/platforms.js +1 -1
  101. package/dist/lib/platforms.js.map +1 -1
  102. package/dist/lib/skill-config.d.ts +1 -1
  103. package/dist/lib/skill-config.d.ts.map +1 -1
  104. package/dist/lib/skill-config.js +2 -2
  105. package/dist/lib/skill-config.js.map +1 -1
  106. package/dist/lib/skills.d.ts +1 -1
  107. package/dist/lib/skills.d.ts.map +1 -1
  108. package/dist/lib/skills.js +5 -5
  109. package/dist/lib/skills.js.map +1 -1
  110. package/dist/lib/tools.d.ts +1 -1
  111. package/dist/lib/tools.d.ts.map +1 -1
  112. package/dist/lib/tools.js +3 -3
  113. package/dist/lib/tools.js.map +1 -1
  114. package/package.json +3 -3
  115. package/src/bin/droid.ts +8 -8
  116. package/src/commands/config.ts +1 -1
  117. package/src/commands/install.ts +3 -3
  118. package/src/commands/setup.test.ts +1 -1
  119. package/src/commands/setup.ts +3 -3
  120. package/src/commands/skills.ts +4 -4
  121. package/src/commands/tui/components/Badge.tsx +86 -0
  122. package/src/commands/tui/components/Markdown.tsx +48 -0
  123. package/src/commands/tui/components/SettingsDetails.tsx +70 -0
  124. package/src/commands/tui/components/TabBar.tsx +26 -0
  125. package/src/commands/tui/components/ToolDetails.tsx +117 -0
  126. package/src/commands/tui/components/ToolItem.tsx +39 -0
  127. package/src/commands/tui/constants.ts +17 -0
  128. package/src/commands/tui/hooks/useAppUpdate.ts +67 -0
  129. package/src/commands/tui/hooks/useToolUpdates.ts +110 -0
  130. package/src/commands/tui/types.ts +4 -0
  131. package/src/commands/tui/views/ReadmeViewer.tsx +93 -0
  132. package/src/commands/tui/views/SetupScreen.tsx +242 -0
  133. package/src/commands/tui/views/SkillConfigScreen.tsx +278 -0
  134. package/src/commands/tui/views/ToolExplorer.tsx +190 -0
  135. package/src/commands/tui/views/ToolUpdatePrompt.tsx +109 -0
  136. package/src/commands/tui/views/WelcomeScreen.tsx +149 -0
  137. package/src/commands/tui.tsx +65 -1587
  138. package/src/commands/uninstall.ts +2 -2
  139. package/src/commands/update.ts +1 -1
  140. package/src/index.ts +4 -4
  141. package/src/lib/agents.ts +4 -4
  142. package/src/lib/config.ts +1 -1
  143. package/src/lib/platforms.ts +1 -1
  144. package/src/lib/skill-config.ts +2 -2
  145. package/src/lib/skills.test.ts +2 -2
  146. package/src/lib/skills.ts +5 -5
  147. package/src/lib/tools.ts +3 -3
  148. package/src/lib/types.test.ts +1 -1
  149. package/src/lib/version.test.ts +1 -1
@@ -1,4 +1,4 @@
1
- import { type ToolManifest } from './types.js';
1
+ import { type ToolManifest } from './types';
2
2
  /**
3
3
  * Get the path to bundled tools directory
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,YAAY,CAAC;AAMpF;;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"}
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.js';
6
- import { getPlatformTools } from './types.js';
7
- import { compareSemver } from './version.js';
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
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"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"}
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.15.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.js';
5
- import { configCommand } from '../commands/config.js';
6
- import { skillsCommand } from '../commands/skills.js';
7
- import { installCommand } from '../commands/install.js';
8
- import { uninstallCommand } from '../commands/uninstall.js';
9
- import { updateCommand } from '../commands/update.js';
10
- import { tuiCommand } from '../commands/tui.js';
11
- import { getVersion } from '../lib/version.js';
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
 
@@ -6,7 +6,7 @@ import {
6
6
  getConfigValue,
7
7
  setConfigValue,
8
8
  configExists,
9
- } from '../lib/config.js';
9
+ } from '../lib/config';
10
10
 
11
11
  interface ConfigOptions {
12
12
  edit?: boolean;
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
- import { installSkill } from '../lib/skills.js';
3
- import { getBundledTools, isToolInstalled } from '../lib/tools.js';
4
- import { promptForSkillConfig } from '../lib/skill-config.js';
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.js';
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
@@ -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.js';
8
- import { getBundledSkills } from '../lib/skills.js';
9
- import { Platform, BuiltInOutput, type DroidConfig, type OutputPreference } from '../lib/types.js';
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
@@ -1,9 +1,9 @@
1
1
  import inquirer from 'inquirer';
2
2
  import chalk from 'chalk';
3
- import { installSkill, uninstallSkill } from '../lib/skills.js';
4
- import { getBundledTools, isToolInstalled, getInstalledToolVersion } from '../lib/tools.js';
5
- import { promptForSkillConfig } from '../lib/skill-config.js';
6
- import { SkillStatus, type ToolManifest } from '../lib/types.js';
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
+ }