@miphamai/cli 0.7.7 → 0.7.9
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/ui/app.tsx +6 -6
- package/src/ui/commands.ts +138 -90
package/package.json
CHANGED
package/src/ui/app.tsx
CHANGED
|
@@ -175,12 +175,12 @@ export function App({
|
|
|
175
175
|
return
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
let
|
|
178
|
+
let forwardToAI: string | undefined
|
|
179
179
|
|
|
180
180
|
const handler = getCommand(command)
|
|
181
181
|
if (handler) {
|
|
182
182
|
const result = await handler(mkCtx(), args)
|
|
183
|
-
|
|
183
|
+
forwardToAI = result.forwardToAI
|
|
184
184
|
setMessages((prev) => [
|
|
185
185
|
...prev,
|
|
186
186
|
{ role: 'user', content: input },
|
|
@@ -206,12 +206,12 @@ export function App({
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
// Bridge: if command set
|
|
210
|
-
if (
|
|
211
|
-
input =
|
|
209
|
+
// Bridge: if command set forwardToAI, route the message to AI processing
|
|
210
|
+
if (forwardToAI) {
|
|
211
|
+
input = forwardToAI
|
|
212
212
|
// fall through to normal AI processing below
|
|
213
213
|
} else {
|
|
214
|
-
//
|
|
214
|
+
// No handler matched or handler didn't request AI routing — stop here
|
|
215
215
|
return
|
|
216
216
|
}
|
|
217
217
|
}
|
package/src/ui/commands.ts
CHANGED
|
@@ -40,8 +40,9 @@ export interface CommandResult {
|
|
|
40
40
|
clearMessages?: boolean
|
|
41
41
|
/** Content to copy to clipboard (handled by caller) */
|
|
42
42
|
copyContent?: string
|
|
43
|
-
/** If set,
|
|
44
|
-
|
|
43
|
+
/** If set, route this message to the AI engine — bridges slash commands → skill/agent invocation.
|
|
44
|
+
* The app layer replaces the user input with this string and falls through to AI processing. */
|
|
45
|
+
forwardToAI?: string
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
type CommandHandler = (
|
|
@@ -121,8 +122,8 @@ const helpCmd: CommandHandler = (ctx) => {
|
|
|
121
122
|
── Workflow ────────────────────────
|
|
122
123
|
/plan Enter plan mode (read-only)
|
|
123
124
|
/no-plan Exit plan mode
|
|
124
|
-
/tdd
|
|
125
|
-
/todos
|
|
125
|
+
/tdd [goal] Test-Driven Development workflow
|
|
126
|
+
/todos [list|create] Task management
|
|
126
127
|
/tasks Background tasks
|
|
127
128
|
/review Code review workflow
|
|
128
129
|
/pr-comments PR review summary
|
|
@@ -132,7 +133,7 @@ const helpCmd: CommandHandler = (ctx) => {
|
|
|
132
133
|
/loop init Scaffold .mipham/ vault structure
|
|
133
134
|
/batch Apply changes across files
|
|
134
135
|
/hooks Manage lifecycle hook scripts
|
|
135
|
-
/schedule View scheduled tasks
|
|
136
|
+
/schedule View scheduled tasks
|
|
136
137
|
|
|
137
138
|
── Git & GitHub ─────────────────────
|
|
138
139
|
/commit Review staged changes + commit
|
|
@@ -401,25 +402,71 @@ const planCmd: CommandHandler = (_ctx) => ({
|
|
|
401
402
|
`,
|
|
402
403
|
})
|
|
403
404
|
|
|
404
|
-
const tddCmd: CommandHandler = (_ctx) =>
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
})
|
|
405
|
+
const tddCmd: CommandHandler = (_ctx, args) => {
|
|
406
|
+
const target = args.join(' ') || 'the current task'
|
|
407
|
+
return {
|
|
408
|
+
content: stripIndent`
|
|
409
|
+
── TDD Mode ──
|
|
410
|
+
Starting Test-Driven Development workflow for: ${target}
|
|
411
411
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
• Create: Task tool with action=create
|
|
417
|
-
• List: Task tool with action=list
|
|
418
|
-
• Update: Task tool with action=update
|
|
412
|
+
Cycle: 🔴 RED → 🟢 GREEN → 🔵 REFACTOR
|
|
413
|
+
RED: Write a failing test first
|
|
414
|
+
GREEN: Write minimal code to pass
|
|
415
|
+
REFACTOR: Clean up while keeping tests green
|
|
419
416
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
417
|
+
The AI will guide you through each cycle.
|
|
418
|
+
`,
|
|
419
|
+
forwardToAI: `Follow the Test-Driven Development workflow for ${target}:
|
|
420
|
+
1. RED — Write a failing test that defines the expected behavior. Use the project's test framework (Vitest/Jest/pytest). Show me the test code and confirm it fails.
|
|
421
|
+
2. GREEN — Write the minimum code needed to make the test pass. Run the test to verify it passes.
|
|
422
|
+
3. REFACTOR — Clean up both test and implementation code. Remove duplication, improve names, simplify. Keep tests green.
|
|
423
|
+
Repeat for each behavior. Do NOT write implementation before tests.`,
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const todosCmd: CommandHandler = (_ctx, args) => {
|
|
428
|
+
const sub = args[0]
|
|
429
|
+
if (sub === 'create') {
|
|
430
|
+
const title = args.slice(1).join(' ')
|
|
431
|
+
if (!title.trim()) {
|
|
432
|
+
return {
|
|
433
|
+
content:
|
|
434
|
+
'Usage: /todos create <task-title>\n\nExample: /todos create Add user authentication',
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
content: `── Create Task ──\n\nCreating task: "${title.trim()}"\n\nPassing to AI for structured task creation with TaskCreate...`,
|
|
439
|
+
forwardToAI: `Create a new task using TaskCreate with subject "${title.trim()}". Set a clear description and activeForm.`,
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (sub === 'list' || !sub) {
|
|
444
|
+
return {
|
|
445
|
+
content: stripIndent`
|
|
446
|
+
── Task Management ──
|
|
447
|
+
Fetching current task list...
|
|
448
|
+
|
|
449
|
+
Shortcuts:
|
|
450
|
+
/todos list Show all tasks
|
|
451
|
+
/todos create <title> Create a new task
|
|
452
|
+
`,
|
|
453
|
+
forwardToAI:
|
|
454
|
+
'Use TaskList to show all current tasks. Present them in a clear summary grouped by status (pending/in_progress/completed). If there are no tasks, suggest creating one.',
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return {
|
|
459
|
+
content: stripIndent`
|
|
460
|
+
── Task Management ──
|
|
461
|
+
/todos list Show all tasks
|
|
462
|
+
/todos create <title> Create a new task
|
|
463
|
+
|
|
464
|
+
The AI manages task state via TaskCreate, TaskList, TaskUpdate, and TaskGet tools.
|
|
465
|
+
Tasks appear in the /tasks view and persist across the session.
|
|
466
|
+
`,
|
|
467
|
+
forwardToAI: 'Use TaskList to show all current tasks, then present them clearly.',
|
|
468
|
+
}
|
|
469
|
+
}
|
|
423
470
|
|
|
424
471
|
// ═══════════════════════════════════════════════════════════════
|
|
425
472
|
// Project
|
|
@@ -1196,7 +1243,7 @@ const loopCmd: CommandHandler = async (_ctx, args) => {
|
|
|
1196
1243
|
|
|
1197
1244
|
return {
|
|
1198
1245
|
content: `── Loop Started ──\n\nInterval: ${interval} (${seconds}s)\nPrompt: "${prompt}"\n\nScheduling via ScheduleWakeup — the prompt will re-schedule itself each cycle.\nUse /schedule to view active loops.`,
|
|
1199
|
-
|
|
1246
|
+
forwardToAI: `use ScheduleWakeup to set up a recurring loop. delaySeconds=${seconds}, prompt: "${prompt}". Include at the end of the prompt: "Then call ScheduleWakeup again with delaySeconds=${seconds} and the same prompt to continue the loop."`,
|
|
1200
1247
|
}
|
|
1201
1248
|
}
|
|
1202
1249
|
|
|
@@ -1204,16 +1251,17 @@ const scheduleCmd: CommandHandler = (_ctx) => ({
|
|
|
1204
1251
|
content: stripIndent`
|
|
1205
1252
|
── Scheduled Tasks ──
|
|
1206
1253
|
|
|
1254
|
+
Fetching active scheduled tasks and loops...
|
|
1255
|
+
|
|
1207
1256
|
Active loops are managed via ScheduleWakeup (in-session) and
|
|
1208
1257
|
CronCreate (durable, survives restarts).
|
|
1209
1258
|
|
|
1210
1259
|
Use /loop <interval> <prompt> to start a recurring task.
|
|
1211
1260
|
Use CronList to view all scheduled jobs.
|
|
1212
1261
|
Use CronDelete <id> to cancel a durable job.
|
|
1213
|
-
|
|
1214
|
-
The ScheduleWakeup mechanism automatically re-schedules on
|
|
1215
|
-
each wake, creating a self-perpetuating loop within the session.
|
|
1216
1262
|
`,
|
|
1263
|
+
forwardToAI:
|
|
1264
|
+
'Use CronList to show all currently scheduled cron jobs (both durable and session-only). Present them in a clear table with: name/ID, schedule (cron expression), type (recurring vs one-shot), and status. Also note any active ScheduleWakeup loops if visible in the current session. If no scheduled tasks exist, suggest: "No scheduled tasks. Use /loop <interval> <prompt> to create a recurring task."',
|
|
1217
1265
|
})
|
|
1218
1266
|
|
|
1219
1267
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -1430,82 +1478,71 @@ const issueCmd: CommandHandler = async () => {
|
|
|
1430
1478
|
}
|
|
1431
1479
|
}
|
|
1432
1480
|
|
|
1433
|
-
// ═══════════════════════════════════════════════════════════════
|
|
1434
|
-
// Code Quality Commands (Claude Code parity)
|
|
1435
|
-
// ═══════════════════════════════════════════════════════════════
|
|
1436
|
-
|
|
1437
1481
|
// ═══════════════════════════════════════════════════════════════
|
|
1438
1482
|
// Code Quality — bridge slash commands to skills (Claude Code parity)
|
|
1439
1483
|
// ═══════════════════════════════════════════════════════════════
|
|
1440
1484
|
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1485
|
+
/** Factory for git-diff-based commands that bridge to AI skills via forwardToAI. */
|
|
1486
|
+
function gitDiffBridgeCmd(opts: {
|
|
1487
|
+
label: string
|
|
1488
|
+
noChangesHint: string
|
|
1489
|
+
runningMsg: string
|
|
1490
|
+
forwardToAI: string
|
|
1491
|
+
}): CommandHandler {
|
|
1492
|
+
return async () => {
|
|
1493
|
+
try {
|
|
1494
|
+
const { execSync } = await import('node:child_process')
|
|
1495
|
+
const diff = execSync('git diff --stat', { encoding: 'utf-8', timeout: 5000 }).trim()
|
|
1496
|
+
if (!diff) {
|
|
1497
|
+
return { content: `─ ${opts.label} ─\n\n${opts.noChangesHint}` }
|
|
1449
1498
|
}
|
|
1450
|
-
}
|
|
1451
|
-
return {
|
|
1452
|
-
content:
|
|
1453
|
-
'─ Code Review ─\n\nReviewing uncommitted changes with the code-review skill (7 dimensions: correctness, security, performance, code quality, architecture, testing, language-specific)...',
|
|
1454
|
-
injectMessage:
|
|
1455
|
-
'use the code-review skill to review all uncommitted changes. Check all 7 dimensions: correctness, security, performance, code quality, architecture & design, testing, and language-specific issues.',
|
|
1456
|
-
}
|
|
1457
|
-
} catch {
|
|
1458
|
-
return { content: '─ Code Review ─\n\nCould not detect changes. Are you in a git repository?' }
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
const simplifyCmd: CommandHandler = async () => {
|
|
1463
|
-
try {
|
|
1464
|
-
const { execSync } = await import('node:child_process')
|
|
1465
|
-
const diff = execSync('git diff --stat', { encoding: 'utf-8', timeout: 5000 }).trim()
|
|
1466
|
-
if (!diff) {
|
|
1467
1499
|
return {
|
|
1468
|
-
content:
|
|
1469
|
-
|
|
1500
|
+
content: `─ ${opts.label} ─\n\n${opts.runningMsg}\n\nChanged files:\n${diff}`,
|
|
1501
|
+
forwardToAI: opts.forwardToAI,
|
|
1470
1502
|
}
|
|
1471
|
-
}
|
|
1472
|
-
return {
|
|
1473
|
-
content:
|
|
1474
|
-
'─ Simplify ─\n\nRunning cleanup review — 4 passes: reuse, simplification, efficiency, abstraction level...',
|
|
1475
|
-
injectMessage:
|
|
1476
|
-
'use the self-review skill to review these uncommitted changes. Focus on 4 cleanup passes: 1) Reuse — find duplicated logic, replace with existing helpers; 2) Simplification — flatten nesting, remove redundant state and dead code; 3) Efficiency — fix repeated object creation, unnecessary I/O, memory issues; 4) Abstraction Level — ensure code sits at the right architectural layer. Apply equivalent transformations only — do NOT change logic or fix bugs.',
|
|
1477
|
-
}
|
|
1478
|
-
} catch {
|
|
1479
|
-
return { content: '─ Simplify ─\n\nCould not detect changes. Are you in a git repository?' }
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
const verifyCmd: CommandHandler = async () => {
|
|
1484
|
-
try {
|
|
1485
|
-
const { execSync } = await import('node:child_process')
|
|
1486
|
-
const diff = execSync('git diff --stat', { encoding: 'utf-8', timeout: 5000 }).trim()
|
|
1487
|
-
if (!diff) {
|
|
1503
|
+
} catch {
|
|
1488
1504
|
return {
|
|
1489
|
-
content:
|
|
1490
|
-
'─ Verify ─\n\nNo uncommitted changes to verify.\n\nMake changes first, then run /verify for runtime verification.',
|
|
1505
|
+
content: `─ ${opts.label} ─\n\nCould not detect changes. Are you in a git repository?`,
|
|
1491
1506
|
}
|
|
1492
1507
|
}
|
|
1493
|
-
return {
|
|
1494
|
-
content:
|
|
1495
|
-
'─ Verify ─\n\nRunning runtime verification — observing actual execution behavior (not tests, not typecheck)...',
|
|
1496
|
-
injectMessage:
|
|
1497
|
-
'verify these uncommitted changes through runtime observation only. For each change: 1) Find the user-facing surface (CLI command, API endpoint, UI interaction); 2) Drive the changed code to execute; 3) Push boundaries — pass null, repeated values, wrong types, interrupt mid-flow (Ctrl-C), resize window; 4) Report verdict per change: PASS (works as expected), FAIL (does not work or breaks something), BLOCKED (cannot reach observable state), SKIP (no runtime surface, e.g. pure documentation). Do NOT run the test suite — observe real execution behavior only.',
|
|
1498
|
-
}
|
|
1499
|
-
} catch {
|
|
1500
|
-
return { content: '─ Verify ─\n\nCould not detect changes. Are you in a git repository?' }
|
|
1501
1508
|
}
|
|
1502
1509
|
}
|
|
1503
1510
|
|
|
1504
|
-
const
|
|
1511
|
+
const codeReviewCmd = gitDiffBridgeCmd({
|
|
1512
|
+
label: 'Code Review',
|
|
1513
|
+
noChangesHint:
|
|
1514
|
+
'No uncommitted changes to review.\n\nTo review a specific file: /code-review path/to/file.ts',
|
|
1515
|
+
runningMsg:
|
|
1516
|
+
'Reviewing uncommitted changes with the code-review skill (7 dimensions: correctness, security, performance, code quality, architecture, testing, language-specific)...',
|
|
1517
|
+
forwardToAI:
|
|
1518
|
+
'use the code-review skill to review all uncommitted changes. Check all 7 dimensions: correctness, security, performance, code quality, architecture & design, testing, and language-specific issues.',
|
|
1519
|
+
})
|
|
1520
|
+
|
|
1521
|
+
const simplifyCmd = gitDiffBridgeCmd({
|
|
1522
|
+
label: 'Simplify',
|
|
1523
|
+
noChangesHint:
|
|
1524
|
+
'No uncommitted changes to simplify.\n\nMake changes first, then run /simplify for cleanup review.',
|
|
1525
|
+
runningMsg:
|
|
1526
|
+
'Running cleanup review — 4 passes: reuse, simplification, efficiency, abstraction level...',
|
|
1527
|
+
forwardToAI:
|
|
1528
|
+
'use the self-review skill to review these uncommitted changes. Focus on 4 cleanup passes: 1) Reuse — find duplicated logic, replace with existing helpers; 2) Simplification — flatten nesting, remove redundant state and dead code; 3) Efficiency — fix repeated object creation, unnecessary I/O, memory issues; 4) Abstraction Level — ensure code sits at the right architectural layer. Apply equivalent transformations only — do NOT change logic or fix bugs.',
|
|
1529
|
+
})
|
|
1530
|
+
|
|
1531
|
+
const verifyCmd = gitDiffBridgeCmd({
|
|
1532
|
+
label: 'Verify',
|
|
1533
|
+
noChangesHint:
|
|
1534
|
+
'No uncommitted changes to verify.\n\nMake changes first, then run /verify for runtime verification.',
|
|
1535
|
+
runningMsg:
|
|
1536
|
+
'Running runtime verification — observing actual execution behavior (not tests, not typecheck)...',
|
|
1537
|
+
forwardToAI:
|
|
1538
|
+
'verify these uncommitted changes through runtime observation only. For each change: 1) Find the user-facing surface (CLI command, API endpoint, UI interaction); 2) Drive the changed code to execute; 3) Push boundaries — pass null, repeated values, wrong types, interrupt mid-flow (Ctrl-C), resize window; 4) Report verdict per change: PASS (works as expected), FAIL (does not work or breaks something), BLOCKED (cannot reach observable state), SKIP (no runtime surface, e.g. pure documentation). Do NOT run the test suite — observe real execution behavior only.',
|
|
1539
|
+
})
|
|
1540
|
+
|
|
1541
|
+
const designCmd: CommandHandler = (_ctx, args) => {
|
|
1505
1542
|
const topic = args.join(' ') || 'the current task'
|
|
1506
1543
|
return {
|
|
1507
1544
|
content: `─ Design ─\n\nStarting architectural design session for: ${topic}\n\nExploring approaches, trade-offs, component breakdown, data flow...`,
|
|
1508
|
-
|
|
1545
|
+
forwardToAI: `help me design the architecture for ${topic}. Explore 2-3 approaches with trade-offs, then present a design covering: component breakdown, data flow, interfaces between components, error handling strategy, and testing approach. Use the plan sub-agent if deeper analysis would help. Prefer simplicity — YAGNI.`,
|
|
1509
1546
|
}
|
|
1510
1547
|
}
|
|
1511
1548
|
|
|
@@ -3590,7 +3627,17 @@ const registry = new Map<string, CommandHandler>()
|
|
|
3590
3627
|
|
|
3591
3628
|
// Session
|
|
3592
3629
|
registry.set('/help', helpCmd)
|
|
3593
|
-
|
|
3630
|
+
const pickCmd: CommandHandler = (ctx) => ({
|
|
3631
|
+
content: `── Model Picker ──
|
|
3632
|
+
|
|
3633
|
+
Use ↑↓ to navigate, Enter to select, Esc to close.
|
|
3634
|
+
|
|
3635
|
+
Current: ${ctx.providerId} / ${ctx.modelId}
|
|
3636
|
+
Available: ${ctx.config.providers.filter((p) => p.status === 'active').length} providers, ${ctx.config.providers.flatMap((p) => p.models.filter((m) => m.status === 'active')).length} models
|
|
3637
|
+
|
|
3638
|
+
Tip: Press Ctrl+P or type /pick from the chat input.`,
|
|
3639
|
+
})
|
|
3640
|
+
registry.set('/pick', pickCmd)
|
|
3594
3641
|
registry.set('/version', versionCmd)
|
|
3595
3642
|
registry.set('/clear', clearCmd)
|
|
3596
3643
|
registry.set('/exit', exitCmd)
|
|
@@ -3618,6 +3665,7 @@ registry.set('/providers', providersCmd)
|
|
|
3618
3665
|
registry.set('/config', configCmd)
|
|
3619
3666
|
registry.set('/fast', fastCmd)
|
|
3620
3667
|
registry.set('/effort', effortCmd)
|
|
3668
|
+
registry.set('/switch', switchCmd)
|
|
3621
3669
|
|
|
3622
3670
|
// Tools & Skills
|
|
3623
3671
|
registry.set('/tools', toolsCmd)
|
|
@@ -3769,8 +3817,8 @@ const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
3769
3817
|
'/plugin-disable': 'Disable an enabled plugin',
|
|
3770
3818
|
'/plan': 'Enter plan mode',
|
|
3771
3819
|
'/no-plan': 'Exit plan mode',
|
|
3772
|
-
'/tdd': '
|
|
3773
|
-
'/todos': 'Task management',
|
|
3820
|
+
'/tdd': 'Test-Driven Development workflow (RED → GREEN → REFACTOR)',
|
|
3821
|
+
'/todos': 'Task management (list/create tasks)',
|
|
3774
3822
|
'/tasks': 'Background tasks',
|
|
3775
3823
|
'/review': 'Code review workflow',
|
|
3776
3824
|
'/pr-comments': 'PR review summary',
|
|
@@ -3795,7 +3843,7 @@ const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
3795
3843
|
'/agents': 'Agent view dashboard',
|
|
3796
3844
|
'/bg': 'Run a background agent task',
|
|
3797
3845
|
'/artifact': 'Manage artifacts',
|
|
3798
|
-
'/schedule': 'View scheduled tasks',
|
|
3846
|
+
'/schedule': 'View scheduled tasks and cron jobs',
|
|
3799
3847
|
'/commit': 'Generate commit message and review staged changes',
|
|
3800
3848
|
'/push': 'Push the current branch',
|
|
3801
3849
|
'/pr': 'Create a pull request',
|