@miphamai/cli 0.5.7 → 0.5.8
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/package.json +1 -1
- package/src/skills/loader.ts +13 -0
- package/src/ui/app.tsx +1 -1
- package/src/ui/commands.ts +329 -126
- package/src/ui/input.tsx +58 -26
package/package.json
CHANGED
package/src/skills/loader.ts
CHANGED
|
@@ -66,6 +66,19 @@ export class SkillsLoader {
|
|
|
66
66
|
return this.skills.has(name)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
countByType(): { standard: number; mipham: number; total: number } {
|
|
70
|
+
const all = this.list()
|
|
71
|
+
return {
|
|
72
|
+
standard: all.filter((s) => s.type === 'standard').length,
|
|
73
|
+
mipham: all.filter((s) => s.type === 'mipham').length,
|
|
74
|
+
total: all.length,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getNamesByType(type: 'standard' | 'mipham'): string[] {
|
|
79
|
+
return this.listByType(type).map((s) => s.name)
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
private loadDirectory(dir: string, type: 'standard' | 'mipham'): void {
|
|
70
83
|
try {
|
|
71
84
|
const entries = readdirSync(dir)
|
package/src/ui/app.tsx
CHANGED
|
@@ -423,7 +423,7 @@ export function App({
|
|
|
423
423
|
</Text>
|
|
424
424
|
<Text dimColor> · ⏵⏵ accept edits on</Text>
|
|
425
425
|
<Text dimColor> (Shift+Tab to cycle)</Text>
|
|
426
|
-
<Text dimColor> · Ctrl+P pick · /help · Esc cancel</Text>
|
|
426
|
+
<Text dimColor> · Ctrl+P pick · /help /commands · Esc cancel</Text>
|
|
427
427
|
<Text dimColor> · ← agents</Text>
|
|
428
428
|
</Box>
|
|
429
429
|
</Box>
|
package/src/ui/commands.ts
CHANGED
|
@@ -49,107 +49,123 @@ type CommandHandler = (
|
|
|
49
49
|
// Session & Identity
|
|
50
50
|
// ═══════════════════════════════════════════════════════════════
|
|
51
51
|
|
|
52
|
-
const helpCmd: CommandHandler = (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
── Session ──────────────────────────
|
|
57
|
-
/help Show this help
|
|
58
|
-
/version Show version info
|
|
59
|
-
/clear Clear conversation
|
|
60
|
-
/compact Compact context window
|
|
61
|
-
/context Show context stats
|
|
62
|
-
/status Session and system status
|
|
63
|
-
/cost Token usage estimate
|
|
64
|
-
/usage Detailed usage dashboard
|
|
65
|
-
/rename <name> Rename current session
|
|
66
|
-
/goal <text> Set session goal
|
|
67
|
-
/recap Summarize session so far
|
|
68
|
-
/export Export conversation to file
|
|
69
|
-
/doctor System diagnostics
|
|
70
|
-
/resume List saved sessions
|
|
71
|
-
/branch <name> Fork conversation
|
|
72
|
-
|
|
73
|
-
── History ─────────────────────────
|
|
74
|
-
/rewind Undo last AI turn
|
|
75
|
-
/undo Same as /rewind
|
|
76
|
-
/copy [N] Copy last response to clipboard
|
|
77
|
-
/focus Toggle focus view (last exchange only)
|
|
78
|
-
|
|
79
|
-
── Model & Provider ────────────────
|
|
80
|
-
/pick Open model picker (or Ctrl+P)
|
|
81
|
-
/model Show current model
|
|
82
|
-
/models List all available models
|
|
83
|
-
/provider Show current provider
|
|
84
|
-
/providers List configured providers
|
|
85
|
-
/switch <p> <m> Switch provider and model
|
|
86
|
-
/config View configuration
|
|
87
|
-
/fast [on|off] Toggle fast mode
|
|
88
|
-
/effort <lvl> Set reasoning effort (low|medium|high|xhigh|max)
|
|
89
|
-
/theme [dark|light|auto] Set terminal theme
|
|
90
|
-
|
|
91
|
-
── Tools & Skills ──────────────────
|
|
92
|
-
/tools List available tools (16 total)
|
|
93
|
-
/skills List loaded skills (14 built-in)
|
|
94
|
-
/reload-skills Reload all skills
|
|
95
|
-
/mcp MCP server status
|
|
96
|
-
|
|
97
|
-
── Workflow ────────────────────────
|
|
98
|
-
/plan Enter plan mode (read-only)
|
|
99
|
-
/no-plan Exit plan mode
|
|
100
|
-
/tdd TDD mode [stub]
|
|
101
|
-
/todos Task management
|
|
102
|
-
/tasks Background tasks
|
|
103
|
-
/review Code review workflow
|
|
104
|
-
/pr-comments PR review summary
|
|
105
|
-
/diff Show git diff
|
|
106
|
-
/workflows List workflow scripts
|
|
107
|
-
/loop <int> <p> Run prompt on interval
|
|
108
|
-
/schedule View scheduled tasks [stub]
|
|
109
|
-
|
|
110
|
-
── Project ─────────────────────────
|
|
111
|
-
/init Initialize .mipham config
|
|
112
|
-
/setup Guided project setup wizard
|
|
113
|
-
/permissions Show permission settings
|
|
114
|
-
/add-dir <dir> Add workspace directory
|
|
115
|
-
/security Security review checklist
|
|
116
|
-
/audit Same as /security
|
|
117
|
-
|
|
118
|
-
── Environment ─────────────────────
|
|
119
|
-
/upgrade Show upgrade instructions
|
|
120
|
-
/release-notes View version changelog
|
|
121
|
-
/ide IDE integration guide
|
|
122
|
-
/terminal-setup Shell & terminal config
|
|
123
|
-
/memory Manage AI memories
|
|
124
|
-
|
|
125
|
-
── Account ─────────────────────────
|
|
126
|
-
/login Show API key status
|
|
127
|
-
/logout Clear credentials guide
|
|
128
|
-
/feedback Send feedback
|
|
129
|
-
|
|
130
|
-
── Agents ──────────────────────────
|
|
131
|
-
/agents Agent view dashboard
|
|
132
|
-
/bg <prompt> Run a background agent task
|
|
133
|
-
|
|
134
|
-
Type /exit or Esc to quit.
|
|
135
|
-
`,
|
|
136
|
-
})
|
|
52
|
+
const helpCmd: CommandHandler = (ctx) => {
|
|
53
|
+
const skillCount = ctx.skillsLoader?.list().length ?? 14
|
|
54
|
+
const toolsCount = ctx.engine.getTools().size
|
|
55
|
+
const cmdCount = getCommandNames().length
|
|
137
56
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
57
|
+
return {
|
|
58
|
+
content: stripIndent`
|
|
59
|
+
Mipham Code v${PACKAGE_VERSION} — Commands
|
|
60
|
+
|
|
61
|
+
── Session ──────────────────────────
|
|
62
|
+
/help Show this help
|
|
63
|
+
/commands List all ${cmdCount} commands
|
|
64
|
+
/version Show version info
|
|
65
|
+
/clear Clear conversation
|
|
66
|
+
/compact Compact context window
|
|
67
|
+
/context Show context stats
|
|
68
|
+
/status Session and system status
|
|
69
|
+
/cost Token usage estimate
|
|
70
|
+
/usage Detailed usage dashboard
|
|
71
|
+
/rename <name> Rename current session
|
|
72
|
+
/goal <text> Set session goal
|
|
73
|
+
/recap Summarize session so far
|
|
74
|
+
/export Export conversation to file
|
|
75
|
+
/doctor System diagnostics
|
|
76
|
+
/resume List saved sessions
|
|
77
|
+
/branch <name> Fork conversation
|
|
78
|
+
|
|
79
|
+
── History ─────────────────────────
|
|
80
|
+
/rewind Undo last AI turn
|
|
81
|
+
/undo Same as /rewind
|
|
82
|
+
/copy [N] Copy last response to clipboard
|
|
83
|
+
/focus Toggle focus view (last exchange only)
|
|
84
|
+
|
|
85
|
+
── Model & Provider ────────────────
|
|
86
|
+
/pick Open model picker (or Ctrl+P)
|
|
87
|
+
/model Show current model
|
|
88
|
+
/models List all available models
|
|
89
|
+
/provider Show current provider
|
|
90
|
+
/providers List configured providers
|
|
91
|
+
/switch <p> <m> Switch provider and model
|
|
92
|
+
/config View configuration
|
|
93
|
+
/fast [on|off] Toggle fast mode
|
|
94
|
+
/effort <lvl> Set reasoning effort (low|medium|high|xhigh|max)
|
|
95
|
+
/theme [dark|light|auto] Set terminal theme
|
|
96
|
+
|
|
97
|
+
── Tools & Skills ──────────────────
|
|
98
|
+
/tools List available tools (${toolsCount} total)
|
|
99
|
+
/skills List loaded skills (${skillCount} built-in)
|
|
100
|
+
/reload-skills Reload all skills
|
|
101
|
+
/commands List all slash commands
|
|
102
|
+
/mcp MCP server status
|
|
103
|
+
|
|
104
|
+
── Workflow ────────────────────────
|
|
105
|
+
/plan Enter plan mode (read-only)
|
|
106
|
+
/no-plan Exit plan mode
|
|
107
|
+
/tdd TDD mode [stub]
|
|
108
|
+
/todos Task management
|
|
109
|
+
/tasks Background tasks
|
|
110
|
+
/review Code review workflow
|
|
111
|
+
/pr-comments PR review summary
|
|
112
|
+
/diff Show git diff
|
|
113
|
+
/workflows List workflow scripts
|
|
114
|
+
/loop <int> <p> Run prompt on interval
|
|
115
|
+
/schedule View scheduled tasks [stub]
|
|
116
|
+
|
|
117
|
+
── Project ─────────────────────────
|
|
118
|
+
/init Initialize .mipham config
|
|
119
|
+
/setup Guided project setup wizard
|
|
120
|
+
/permissions Show permission settings
|
|
121
|
+
/add-dir <dir> Add workspace directory
|
|
122
|
+
/security Security review checklist
|
|
123
|
+
/audit Same as /security
|
|
124
|
+
|
|
125
|
+
── Environment ─────────────────────
|
|
126
|
+
/upgrade Show upgrade instructions
|
|
127
|
+
/release-notes View version changelog
|
|
128
|
+
/ide IDE integration guide
|
|
129
|
+
/terminal-setup Shell & terminal config
|
|
130
|
+
/memory Manage AI memories
|
|
131
|
+
|
|
132
|
+
── Account ─────────────────────────
|
|
133
|
+
/login Show API key status
|
|
134
|
+
/logout Clear credentials guide
|
|
135
|
+
/feedback Send feedback
|
|
136
|
+
|
|
137
|
+
── Agents ──────────────────────────
|
|
138
|
+
/agents Agent view dashboard
|
|
139
|
+
/bg <prompt> Run a background agent task
|
|
140
|
+
|
|
141
|
+
Type /exit or Esc to quit.
|
|
142
|
+
`,
|
|
143
|
+
}
|
|
144
|
+
}
|
|
141
145
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
const versionCmd: CommandHandler = (ctx) => {
|
|
147
|
+
const skillCounts = ctx.skillsLoader?.countByType()
|
|
148
|
+
const skillsLine = skillCounts
|
|
149
|
+
? `Skills: ${skillCounts.total} built-in (${skillCounts.standard} standard + ${skillCounts.mipham} mipham)`
|
|
150
|
+
: `Skills: (loader unavailable)`
|
|
151
|
+
const toolsCount = ctx.engine.getTools().size
|
|
146
152
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
+
return {
|
|
154
|
+
content: stripIndent`
|
|
155
|
+
Mipham Code v${ctx.version}
|
|
156
|
+
|
|
157
|
+
Runtime: Bun ${typeof Bun !== 'undefined' ? Bun.version : '(Node.js)'}
|
|
158
|
+
Platform: ${process.platform} ${process.arch}
|
|
159
|
+
Node: ${process.version}
|
|
160
|
+
CWD: ${process.cwd()}
|
|
161
|
+
|
|
162
|
+
Provider: ${ctx.providerId} / ${ctx.modelId}
|
|
163
|
+
Tools: ${toolsCount} built-in
|
|
164
|
+
${skillsLine}
|
|
165
|
+
License: Apache 2.0
|
|
166
|
+
`,
|
|
167
|
+
}
|
|
168
|
+
}
|
|
153
169
|
|
|
154
170
|
const clearCmd: CommandHandler = (ctx) => {
|
|
155
171
|
ctx.engine.getContext().clear()
|
|
@@ -317,29 +333,25 @@ const toolsCmd: CommandHandler = (ctx) => {
|
|
|
317
333
|
return { content: `Available tools (${tools.size}):\n\n${sections.join('\n\n')}` }
|
|
318
334
|
}
|
|
319
335
|
|
|
320
|
-
const skillsCmd: CommandHandler = (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
14 skills loaded. Use Skill tool to invoke.
|
|
341
|
-
`,
|
|
342
|
-
})
|
|
336
|
+
const skillsCmd: CommandHandler = (ctx) => {
|
|
337
|
+
if (!ctx.skillsLoader) {
|
|
338
|
+
return { content: 'SkillsLoader not available.' }
|
|
339
|
+
}
|
|
340
|
+
const counts = ctx.skillsLoader.countByType()
|
|
341
|
+
const standard = ctx.skillsLoader.listByType('standard')
|
|
342
|
+
const mipham = ctx.skillsLoader.listByType('mipham')
|
|
343
|
+
|
|
344
|
+
const lines: string[] = [
|
|
345
|
+
`── Standard Skills (${counts.standard}) ──`,
|
|
346
|
+
...standard.map((s) => ` ${s.name.padEnd(28)} ${s.description}`),
|
|
347
|
+
'',
|
|
348
|
+
`── Mipham Exclusive (${counts.mipham}) ──`,
|
|
349
|
+
...mipham.map((s) => ` ${s.name.padEnd(20)} ${s.description}`),
|
|
350
|
+
'',
|
|
351
|
+
`${counts.total} skills loaded. Use Skill tool to invoke.`,
|
|
352
|
+
]
|
|
353
|
+
return { content: lines.join('\n') }
|
|
354
|
+
}
|
|
343
355
|
|
|
344
356
|
// ═══════════════════════════════════════════════════════════════
|
|
345
357
|
// Workflow
|
|
@@ -1500,16 +1512,19 @@ async function setupStep3(ctx: CommandContext): Promise<CommandResult> {
|
|
|
1500
1512
|
return { content: lines.join('\n') }
|
|
1501
1513
|
}
|
|
1502
1514
|
|
|
1503
|
-
async function setupStep4(
|
|
1515
|
+
async function setupStep4(ctx: CommandContext): Promise<CommandResult> {
|
|
1516
|
+
const counts = ctx.skillsLoader?.countByType() ?? { standard: 0, mipham: 0, total: 0 }
|
|
1517
|
+
const standardNames = ctx.skillsLoader?.getNamesByType('standard') ?? []
|
|
1518
|
+
const miphamNames = ctx.skillsLoader?.getNamesByType('mipham') ?? []
|
|
1519
|
+
|
|
1504
1520
|
return {
|
|
1505
1521
|
content: `── Step 4: Install Skills ──
|
|
1506
1522
|
|
|
1507
1523
|
Skills extend Mipham Code with specialized capabilities.
|
|
1508
1524
|
|
|
1509
|
-
Built-in skills (
|
|
1510
|
-
Standard (
|
|
1511
|
-
|
|
1512
|
-
Mipham (2): om-model-optimize, om-security
|
|
1525
|
+
Built-in skills (${counts.total} total):
|
|
1526
|
+
Standard (${counts.standard}): ${standardNames.join(', ')}
|
|
1527
|
+
Mipham (${counts.mipham}): ${miphamNames.join(', ')}
|
|
1513
1528
|
|
|
1514
1529
|
Community skills:
|
|
1515
1530
|
Coming soon — the Mipham Code skills marketplace will let you
|
|
@@ -2273,6 +2288,114 @@ const artifactBaseCmd: CommandHandler = (ctx, args) => {
|
|
|
2273
2288
|
// Remaining low-priority stubs (backend not yet available)
|
|
2274
2289
|
// ═══════════════════════════════════════════════════════════════
|
|
2275
2290
|
|
|
2291
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2292
|
+
// Commands — list all registered slash commands
|
|
2293
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2294
|
+
|
|
2295
|
+
const commandsListCmd: CommandHandler = () => {
|
|
2296
|
+
const names = getCommandNames()
|
|
2297
|
+
const categories: Record<string, string[]> = {
|
|
2298
|
+
'Session & Identity': [],
|
|
2299
|
+
History: [],
|
|
2300
|
+
'Model & Provider': [],
|
|
2301
|
+
'Tools & Skills': [],
|
|
2302
|
+
Workflow: [],
|
|
2303
|
+
Project: [],
|
|
2304
|
+
Environment: [],
|
|
2305
|
+
Account: [],
|
|
2306
|
+
Agents: [],
|
|
2307
|
+
Artifacts: [],
|
|
2308
|
+
Other: [],
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
const catMap: Record<string, string> = {
|
|
2312
|
+
'/help': 'Session & Identity',
|
|
2313
|
+
'/version': 'Session & Identity',
|
|
2314
|
+
'/clear': 'Session & Identity',
|
|
2315
|
+
'/exit': 'Session & Identity',
|
|
2316
|
+
'/quit': 'Session & Identity',
|
|
2317
|
+
'/compact': 'Session & Identity',
|
|
2318
|
+
'/context': 'Session & Identity',
|
|
2319
|
+
'/status': 'Session & Identity',
|
|
2320
|
+
'/cost': 'Session & Identity',
|
|
2321
|
+
'/usage': 'Session & Identity',
|
|
2322
|
+
'/rename': 'Session & Identity',
|
|
2323
|
+
'/goal': 'Session & Identity',
|
|
2324
|
+
'/recap': 'Session & Identity',
|
|
2325
|
+
'/export': 'Session & Identity',
|
|
2326
|
+
'/doctor': 'Session & Identity',
|
|
2327
|
+
'/resume': 'Session & Identity',
|
|
2328
|
+
'/branch': 'Session & Identity',
|
|
2329
|
+
'/rewind': 'History',
|
|
2330
|
+
'/undo': 'History',
|
|
2331
|
+
'/copy': 'History',
|
|
2332
|
+
'/focus': 'History',
|
|
2333
|
+
'/pick': 'Model & Provider',
|
|
2334
|
+
'/model': 'Model & Provider',
|
|
2335
|
+
'/models': 'Model & Provider',
|
|
2336
|
+
'/provider': 'Model & Provider',
|
|
2337
|
+
'/providers': 'Model & Provider',
|
|
2338
|
+
'/switch': 'Model & Provider',
|
|
2339
|
+
'/config': 'Model & Provider',
|
|
2340
|
+
'/fast': 'Model & Provider',
|
|
2341
|
+
'/effort': 'Model & Provider',
|
|
2342
|
+
'/theme': 'Model & Provider',
|
|
2343
|
+
'/upgrade': 'Model & Provider',
|
|
2344
|
+
'/tools': 'Tools & Skills',
|
|
2345
|
+
'/skills': 'Tools & Skills',
|
|
2346
|
+
'/reload-skills': 'Tools & Skills',
|
|
2347
|
+
'/mcp': 'Tools & Skills',
|
|
2348
|
+
'/commands': 'Tools & Skills',
|
|
2349
|
+
'/plan': 'Workflow',
|
|
2350
|
+
'/no-plan': 'Workflow',
|
|
2351
|
+
'/tdd': 'Workflow',
|
|
2352
|
+
'/todos': 'Workflow',
|
|
2353
|
+
'/tasks': 'Workflow',
|
|
2354
|
+
'/review': 'Workflow',
|
|
2355
|
+
'/pr-comments': 'Workflow',
|
|
2356
|
+
'/diff': 'Workflow',
|
|
2357
|
+
'/workflows': 'Workflow',
|
|
2358
|
+
'/loop': 'Workflow',
|
|
2359
|
+
'/init': 'Project',
|
|
2360
|
+
'/setup': 'Project',
|
|
2361
|
+
'/permissions': 'Project',
|
|
2362
|
+
'/add-dir': 'Project',
|
|
2363
|
+
'/security': 'Project',
|
|
2364
|
+
'/audit': 'Project',
|
|
2365
|
+
'/ide': 'Environment',
|
|
2366
|
+
'/terminal-setup': 'Environment',
|
|
2367
|
+
'/memory': 'Environment',
|
|
2368
|
+
'/release-notes': 'Environment',
|
|
2369
|
+
'/login': 'Account',
|
|
2370
|
+
'/logout': 'Account',
|
|
2371
|
+
'/feedback': 'Account',
|
|
2372
|
+
'/agents': 'Agents',
|
|
2373
|
+
'/bg': 'Agents',
|
|
2374
|
+
'/artifact': 'Artifacts',
|
|
2375
|
+
'/schedule': 'Other',
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
for (const name of names) {
|
|
2379
|
+
const cat = catMap[name] ?? 'Other'
|
|
2380
|
+
categories[cat]?.push(name)
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
const lines: string[] = [`── All Slash Commands (${names.length}) ──`, '']
|
|
2384
|
+
|
|
2385
|
+
for (const [cat, cmds] of Object.entries(categories)) {
|
|
2386
|
+
if (cmds.length === 0) continue
|
|
2387
|
+
lines.push(`── ${cat} (${cmds.length}) ──`)
|
|
2388
|
+
for (const c of cmds) {
|
|
2389
|
+
lines.push(` ${c}`)
|
|
2390
|
+
}
|
|
2391
|
+
lines.push('')
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
lines.push('Type /help for details, or /<command> to run.')
|
|
2395
|
+
|
|
2396
|
+
return { content: lines.join('\n') }
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2276
2399
|
// ═══════════════════════════════════════════════════════════════
|
|
2277
2400
|
// Command Registry
|
|
2278
2401
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -2314,6 +2437,7 @@ registry.set('/effort', effortCmd)
|
|
|
2314
2437
|
registry.set('/tools', toolsCmd)
|
|
2315
2438
|
registry.set('/skills', skillsCmd)
|
|
2316
2439
|
registry.set('/reload-skills', reloadSkillsCmd)
|
|
2440
|
+
registry.set('/commands', commandsListCmd)
|
|
2317
2441
|
|
|
2318
2442
|
// Workflow
|
|
2319
2443
|
registry.set('/plan', planCmd)
|
|
@@ -2375,6 +2499,85 @@ export function getCommandNames(): string[] {
|
|
|
2375
2499
|
return Array.from(registry.keys()).sort()
|
|
2376
2500
|
}
|
|
2377
2501
|
|
|
2502
|
+
export interface CommandEntry {
|
|
2503
|
+
name: string
|
|
2504
|
+
description: string
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
2508
|
+
'/help': 'Show help',
|
|
2509
|
+
'/commands': 'List all slash commands',
|
|
2510
|
+
'/version': 'Show version info',
|
|
2511
|
+
'/clear': 'Clear conversation',
|
|
2512
|
+
'/exit': 'Exit Mipham Code',
|
|
2513
|
+
'/quit': 'Exit Mipham Code',
|
|
2514
|
+
'/compact': 'Compact context window',
|
|
2515
|
+
'/context': 'Show context stats',
|
|
2516
|
+
'/status': 'Session and system status',
|
|
2517
|
+
'/cost': 'Token usage estimate',
|
|
2518
|
+
'/usage': 'Detailed usage dashboard',
|
|
2519
|
+
'/rename': 'Rename current session',
|
|
2520
|
+
'/goal': 'Set session goal',
|
|
2521
|
+
'/recap': 'Summarize session so far',
|
|
2522
|
+
'/export': 'Export conversation to file',
|
|
2523
|
+
'/doctor': 'System diagnostics',
|
|
2524
|
+
'/resume': 'List saved sessions',
|
|
2525
|
+
'/branch': 'Fork conversation',
|
|
2526
|
+
'/rewind': 'Undo last AI turn',
|
|
2527
|
+
'/undo': 'Same as /rewind',
|
|
2528
|
+
'/copy': 'Copy last response to clipboard',
|
|
2529
|
+
'/focus': 'Toggle focus view',
|
|
2530
|
+
'/pick': 'Open model picker',
|
|
2531
|
+
'/model': 'Show current model',
|
|
2532
|
+
'/models': 'List all available models',
|
|
2533
|
+
'/provider': 'Show current provider',
|
|
2534
|
+
'/providers': 'List configured providers',
|
|
2535
|
+
'/switch': 'Switch provider and model',
|
|
2536
|
+
'/config': 'View configuration',
|
|
2537
|
+
'/fast': 'Toggle fast mode',
|
|
2538
|
+
'/effort': 'Set reasoning effort',
|
|
2539
|
+
'/theme': 'Set terminal theme',
|
|
2540
|
+
'/tools': 'List available tools',
|
|
2541
|
+
'/skills': 'List loaded skills',
|
|
2542
|
+
'/reload-skills': 'Reload all skills',
|
|
2543
|
+
'/mcp': 'MCP server status',
|
|
2544
|
+
'/plan': 'Enter plan mode',
|
|
2545
|
+
'/no-plan': 'Exit plan mode',
|
|
2546
|
+
'/tdd': 'TDD mode',
|
|
2547
|
+
'/todos': 'Task management',
|
|
2548
|
+
'/tasks': 'Background tasks',
|
|
2549
|
+
'/review': 'Code review workflow',
|
|
2550
|
+
'/pr-comments': 'PR review summary',
|
|
2551
|
+
'/diff': 'Show git diff',
|
|
2552
|
+
'/workflows': 'List workflow scripts',
|
|
2553
|
+
'/loop': 'Run prompt on interval',
|
|
2554
|
+
'/init': 'Initialize .mipham config',
|
|
2555
|
+
'/setup': 'Guided project setup wizard',
|
|
2556
|
+
'/permissions': 'Show permission settings',
|
|
2557
|
+
'/add-dir': 'Add workspace directory',
|
|
2558
|
+
'/security': 'Security review checklist',
|
|
2559
|
+
'/audit': 'Same as /security',
|
|
2560
|
+
'/ide': 'IDE integration guide',
|
|
2561
|
+
'/terminal-setup': 'Shell & terminal config',
|
|
2562
|
+
'/memory': 'Manage AI memories',
|
|
2563
|
+
'/release-notes': 'View version changelog',
|
|
2564
|
+
'/upgrade': 'Show upgrade instructions',
|
|
2565
|
+
'/login': 'Show API key status',
|
|
2566
|
+
'/logout': 'Clear credentials guide',
|
|
2567
|
+
'/feedback': 'Send feedback',
|
|
2568
|
+
'/agents': 'Agent view dashboard',
|
|
2569
|
+
'/bg': 'Run a background agent task',
|
|
2570
|
+
'/artifact': 'Manage artifacts',
|
|
2571
|
+
'/schedule': 'View scheduled tasks',
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2574
|
+
export function getCommandList(): CommandEntry[] {
|
|
2575
|
+
return getCommandNames().map((name) => ({
|
|
2576
|
+
name,
|
|
2577
|
+
description: COMMAND_DESCRIPTIONS[name] ?? '',
|
|
2578
|
+
}))
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2378
2581
|
export function looksLikeSlashCommand(input: string): boolean {
|
|
2379
2582
|
return input.trim().startsWith('/')
|
|
2380
2583
|
}
|
package/src/ui/input.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef } from 'react'
|
|
1
|
+
import React, { useState, useEffect, useRef, useMemo } from 'react'
|
|
2
2
|
import { Box, Text, useInput } from 'ink'
|
|
3
3
|
import TextInput from 'ink-text-input'
|
|
4
4
|
import { VimMotionEngine, type VimMode } from './vim-motions.js'
|
|
5
|
+
import { getCommandList, type CommandEntry } from './commands.js'
|
|
5
6
|
|
|
6
7
|
interface InputBarProps {
|
|
7
8
|
onSubmit: (input: string) => void
|
|
@@ -111,6 +112,15 @@ export function InputBar({ onSubmit, isLoading }: InputBarProps) {
|
|
|
111
112
|
const [completionVerb, setCompletionVerb] = useState<string | null>(null)
|
|
112
113
|
const prevLoading = useRef(isLoading)
|
|
113
114
|
|
|
115
|
+
// ── Slash command hints ──
|
|
116
|
+
const allCommands = useMemo(() => getCommandList(), [])
|
|
117
|
+
const slashHints = useMemo(() => {
|
|
118
|
+
if (!value.startsWith('/')) return []
|
|
119
|
+
const filter = value.slice(1).toLowerCase()
|
|
120
|
+
if (!filter) return allCommands.slice(0, 12) // show first 12 when just "/"
|
|
121
|
+
return allCommands.filter((c) => c.name.toLowerCase().includes(filter)).slice(0, 8)
|
|
122
|
+
}, [value, allCommands])
|
|
123
|
+
|
|
114
124
|
// Rotate gerunds while loading
|
|
115
125
|
useEffect(() => {
|
|
116
126
|
if (!isLoading) return
|
|
@@ -249,32 +259,54 @@ export function InputBar({ onSubmit, isLoading }: InputBarProps) {
|
|
|
249
259
|
}
|
|
250
260
|
|
|
251
261
|
return (
|
|
252
|
-
<Box marginTop={1}>
|
|
253
|
-
<Box
|
|
254
|
-
<
|
|
255
|
-
{vimMode === 'normal' ? ':' : '
|
|
256
|
-
|
|
262
|
+
<Box flexDirection="column" marginTop={1}>
|
|
263
|
+
<Box>
|
|
264
|
+
<Box marginRight={1}>
|
|
265
|
+
<Text color={vimMode === 'normal' ? 'magenta' : isLoading ? 'yellow' : 'cyan'}>
|
|
266
|
+
{vimMode === 'normal' ? ':' : '>'}
|
|
267
|
+
</Text>
|
|
268
|
+
</Box>
|
|
269
|
+
<TextInput
|
|
270
|
+
value={value}
|
|
271
|
+
onChange={(val) => {
|
|
272
|
+
// Block text changes during search mode — keys go to search query
|
|
273
|
+
if (searchMode) return
|
|
274
|
+
setValue(val)
|
|
275
|
+
}}
|
|
276
|
+
onSubmit={handleSubmit}
|
|
277
|
+
placeholder={
|
|
278
|
+
searchMode
|
|
279
|
+
? `/${searchQuery}`
|
|
280
|
+
: vimMode === 'normal'
|
|
281
|
+
? '[NORMAL] h/j/k/l w/b 0/$ dd yy p u / (Esc to insert)'
|
|
282
|
+
: isLoading
|
|
283
|
+
? `${verb}...`
|
|
284
|
+
: completionVerb
|
|
285
|
+
? completionVerb
|
|
286
|
+
: 'Type a message (Esc to cancel)...'
|
|
287
|
+
}
|
|
288
|
+
/>
|
|
257
289
|
</Box>
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
290
|
+
{/* Slash command hints — shown when typing / in INSERT mode */}
|
|
291
|
+
{slashHints.length > 0 && vimMode === 'insert' && (
|
|
292
|
+
<Box marginTop={1} flexDirection="row" gap={1}>
|
|
293
|
+
<Text dimColor>Commands: </Text>
|
|
294
|
+
{slashHints.map((cmd, i) => (
|
|
295
|
+
<Text key={cmd.name} color="cyan">
|
|
296
|
+
{i > 0 ? ' ' : ''}
|
|
297
|
+
{cmd.name}
|
|
298
|
+
</Text>
|
|
299
|
+
))}
|
|
300
|
+
<Text dimColor>
|
|
301
|
+
{' '}
|
|
302
|
+
(
|
|
303
|
+
{slashHints.length === allCommands.length
|
|
304
|
+
? 'all'
|
|
305
|
+
: `${slashHints.length} of ${allCommands.length}`}
|
|
306
|
+
)
|
|
307
|
+
</Text>
|
|
308
|
+
</Box>
|
|
309
|
+
)}
|
|
278
310
|
</Box>
|
|
279
311
|
)
|
|
280
312
|
}
|