@miphamai/cli 0.7.6 → 0.7.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/ui/app.tsx +12 -2
- package/src/ui/commands.ts +101 -49
- package/dist/mipham +0 -0
package/package.json
CHANGED
package/src/ui/app.tsx
CHANGED
|
@@ -175,9 +175,12 @@ export function App({
|
|
|
175
175
|
return
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
let forwardToAI: string | undefined
|
|
179
|
+
|
|
178
180
|
const handler = getCommand(command)
|
|
179
181
|
if (handler) {
|
|
180
182
|
const result = await handler(mkCtx(), args)
|
|
183
|
+
forwardToAI = result.forwardToAI
|
|
181
184
|
setMessages((prev) => [
|
|
182
185
|
...prev,
|
|
183
186
|
{ role: 'user', content: input },
|
|
@@ -202,8 +205,15 @@ export function App({
|
|
|
202
205
|
}
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
|
|
209
|
+
// Bridge: if command set forwardToAI, route the message to AI processing
|
|
210
|
+
if (forwardToAI) {
|
|
211
|
+
input = forwardToAI
|
|
212
|
+
// fall through to normal AI processing below
|
|
213
|
+
} else {
|
|
214
|
+
// No handler matched or handler didn't request AI routing — stop here
|
|
215
|
+
return
|
|
216
|
+
}
|
|
207
217
|
}
|
|
208
218
|
|
|
209
219
|
// ── Normal message processing (AI chat) ──
|
package/src/ui/commands.ts
CHANGED
|
@@ -40,6 +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, 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
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
type CommandHandler = (
|
|
@@ -1088,6 +1091,18 @@ const branchCmd: CommandHandler = (ctx, args) => {
|
|
|
1088
1091
|
}
|
|
1089
1092
|
}
|
|
1090
1093
|
|
|
1094
|
+
/** Parse human-readable interval to seconds. Returns null if invalid. */
|
|
1095
|
+
function parseInterval(raw: string): number | null {
|
|
1096
|
+
const m = raw.trim().match(/^(\d+)\s*(s|sec|m|min|h|hr|hour)$/i)
|
|
1097
|
+
if (!m) return null
|
|
1098
|
+
const n = parseInt(m[1]!, 10)
|
|
1099
|
+
const unit = m[2]!.toLowerCase()
|
|
1100
|
+
if (unit === 's' || unit === 'sec') return n
|
|
1101
|
+
if (unit === 'm' || unit === 'min') return n * 60
|
|
1102
|
+
if (unit === 'h' || unit === 'hr' || unit === 'hour') return n * 3600
|
|
1103
|
+
return null
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1091
1106
|
const loopCmd: CommandHandler = async (_ctx, args) => {
|
|
1092
1107
|
const sub = args[0]
|
|
1093
1108
|
|
|
@@ -1166,24 +1181,23 @@ const loopCmd: CommandHandler = async (_ctx, args) => {
|
|
|
1166
1181
|
/loop 5m check the deploy status
|
|
1167
1182
|
/loop init Create vault in current directory
|
|
1168
1183
|
/loop init ~/my-project Create vault in specific directory
|
|
1169
|
-
|
|
1170
|
-
Note: Continuous looping requires session persistence, coming in a future release.
|
|
1171
1184
|
`,
|
|
1172
1185
|
}
|
|
1173
1186
|
}
|
|
1174
1187
|
|
|
1175
1188
|
const interval = args[0]!
|
|
1176
1189
|
const prompt = args.slice(1).join(' ')
|
|
1190
|
+
const seconds = parseInterval(interval)
|
|
1177
1191
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1192
|
+
if (seconds === null) {
|
|
1193
|
+
return {
|
|
1194
|
+
content: `── Invalid Interval ──\n\n"${interval}" is not a recognised interval.\n\nUse formats like: 10s, 5m, 1h, 30min, 2hr`,
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1183
1197
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
`,
|
|
1198
|
+
return {
|
|
1199
|
+
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.`,
|
|
1200
|
+
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."`,
|
|
1187
1201
|
}
|
|
1188
1202
|
}
|
|
1189
1203
|
|
|
@@ -1191,14 +1205,15 @@ const scheduleCmd: CommandHandler = (_ctx) => ({
|
|
|
1191
1205
|
content: stripIndent`
|
|
1192
1206
|
── Scheduled Tasks ──
|
|
1193
1207
|
|
|
1194
|
-
|
|
1208
|
+
Active loops are managed via ScheduleWakeup (in-session) and
|
|
1209
|
+
CronCreate (durable, survives restarts).
|
|
1195
1210
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
• Durable persistence across sessions
|
|
1211
|
+
Use /loop <interval> <prompt> to start a recurring task.
|
|
1212
|
+
Use CronList to view all scheduled jobs.
|
|
1213
|
+
Use CronDelete <id> to cancel a durable job.
|
|
1200
1214
|
|
|
1201
|
-
|
|
1215
|
+
The ScheduleWakeup mechanism automatically re-schedules on
|
|
1216
|
+
each wake, creating a self-perpetuating loop within the session.
|
|
1202
1217
|
`,
|
|
1203
1218
|
})
|
|
1204
1219
|
|
|
@@ -1417,42 +1432,70 @@ const issueCmd: CommandHandler = async () => {
|
|
|
1417
1432
|
}
|
|
1418
1433
|
|
|
1419
1434
|
// ═══════════════════════════════════════════════════════════════
|
|
1420
|
-
// Code Quality
|
|
1435
|
+
// Code Quality — bridge slash commands to skills (Claude Code parity)
|
|
1421
1436
|
// ═══════════════════════════════════════════════════════════════
|
|
1422
1437
|
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1438
|
+
/** Factory for git-diff-based commands that bridge to AI skills via forwardToAI. */
|
|
1439
|
+
function gitDiffBridgeCmd(opts: {
|
|
1440
|
+
label: string
|
|
1441
|
+
noChangesHint: string
|
|
1442
|
+
runningMsg: string
|
|
1443
|
+
forwardToAI: string
|
|
1444
|
+
}): CommandHandler {
|
|
1445
|
+
return async () => {
|
|
1446
|
+
try {
|
|
1447
|
+
const { execSync } = await import('node:child_process')
|
|
1448
|
+
const diff = execSync('git diff --stat', { encoding: 'utf-8', timeout: 5000 }).trim()
|
|
1449
|
+
if (!diff) {
|
|
1450
|
+
return { content: `─ ${opts.label} ─\n\n${opts.noChangesHint}` }
|
|
1451
|
+
}
|
|
1430
1452
|
return {
|
|
1431
|
-
content:
|
|
1432
|
-
|
|
1453
|
+
content: `─ ${opts.label} ─\n\n${opts.runningMsg}\n\nChanged files:\n${diff}`,
|
|
1454
|
+
forwardToAI: opts.forwardToAI,
|
|
1455
|
+
}
|
|
1456
|
+
} catch {
|
|
1457
|
+
return {
|
|
1458
|
+
content: `─ ${opts.label} ─\n\nCould not detect changes. Are you in a git repository?`,
|
|
1433
1459
|
}
|
|
1434
1460
|
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1435
1463
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1464
|
+
const codeReviewCmd = gitDiffBridgeCmd({
|
|
1465
|
+
label: 'Code Review',
|
|
1466
|
+
noChangesHint:
|
|
1467
|
+
'No uncommitted changes to review.\n\nTo review a specific file: /code-review path/to/file.ts',
|
|
1468
|
+
runningMsg:
|
|
1469
|
+
'Reviewing uncommitted changes with the code-review skill (7 dimensions: correctness, security, performance, code quality, architecture, testing, language-specific)...',
|
|
1470
|
+
forwardToAI:
|
|
1471
|
+
'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.',
|
|
1472
|
+
})
|
|
1473
|
+
|
|
1474
|
+
const simplifyCmd = gitDiffBridgeCmd({
|
|
1475
|
+
label: 'Simplify',
|
|
1476
|
+
noChangesHint:
|
|
1477
|
+
'No uncommitted changes to simplify.\n\nMake changes first, then run /simplify for cleanup review.',
|
|
1478
|
+
runningMsg:
|
|
1479
|
+
'Running cleanup review — 4 passes: reuse, simplification, efficiency, abstraction level...',
|
|
1480
|
+
forwardToAI:
|
|
1481
|
+
'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.',
|
|
1482
|
+
})
|
|
1483
|
+
|
|
1484
|
+
const verifyCmd = gitDiffBridgeCmd({
|
|
1485
|
+
label: 'Verify',
|
|
1486
|
+
noChangesHint:
|
|
1487
|
+
'No uncommitted changes to verify.\n\nMake changes first, then run /verify for runtime verification.',
|
|
1488
|
+
runningMsg:
|
|
1489
|
+
'Running runtime verification — observing actual execution behavior (not tests, not typecheck)...',
|
|
1490
|
+
forwardToAI:
|
|
1491
|
+
'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.',
|
|
1492
|
+
})
|
|
1493
|
+
|
|
1494
|
+
const designCmd: CommandHandler = (_ctx, args) => {
|
|
1495
|
+
const topic = args.join(' ') || 'the current task'
|
|
1496
|
+
return {
|
|
1497
|
+
content: `─ Design ─\n\nStarting architectural design session for: ${topic}\n\nExploring approaches, trade-offs, component breakdown, data flow...`,
|
|
1498
|
+
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.`,
|
|
1456
1499
|
}
|
|
1457
1500
|
}
|
|
1458
1501
|
|
|
@@ -3495,8 +3538,11 @@ const commandsListCmd: CommandHandler = () => {
|
|
|
3495
3538
|
'/push': 'Workflow',
|
|
3496
3539
|
'/pr': 'Workflow',
|
|
3497
3540
|
'/issue': 'Workflow',
|
|
3498
|
-
'/
|
|
3499
|
-
'/
|
|
3541
|
+
'/code-review': 'Code Quality',
|
|
3542
|
+
'/simplify': 'Code Quality',
|
|
3543
|
+
'/verify': 'Code Quality',
|
|
3544
|
+
'/design': 'Code Quality',
|
|
3545
|
+
'/lint': 'Code Quality',
|
|
3500
3546
|
'/files': 'Session & Identity',
|
|
3501
3547
|
'/stats': 'Session & Identity',
|
|
3502
3548
|
'/summary': 'Session & Identity',
|
|
@@ -3634,7 +3680,10 @@ registry.set('/pr', prCmd)
|
|
|
3634
3680
|
registry.set('/issue', issueCmd)
|
|
3635
3681
|
|
|
3636
3682
|
// Code Quality (Claude Code parity)
|
|
3683
|
+
registry.set('/code-review', codeReviewCmd)
|
|
3637
3684
|
registry.set('/simplify', simplifyCmd)
|
|
3685
|
+
registry.set('/verify', verifyCmd)
|
|
3686
|
+
registry.set('/design', designCmd)
|
|
3638
3687
|
registry.set('/lint', lintCmd)
|
|
3639
3688
|
|
|
3640
3689
|
// Session Enhancement (Claude Code parity)
|
|
@@ -3741,7 +3790,10 @@ const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
3741
3790
|
'/push': 'Push the current branch',
|
|
3742
3791
|
'/pr': 'Create a pull request',
|
|
3743
3792
|
'/issue': 'File a GitHub issue',
|
|
3744
|
-
'/
|
|
3793
|
+
'/code-review': 'Review code for bugs, security, performance (7 dimensions)',
|
|
3794
|
+
'/simplify': 'Cleanup-only review: reuse, simplification, efficiency, abstraction',
|
|
3795
|
+
'/verify': 'Runtime verification — observe actual execution, not tests',
|
|
3796
|
+
'/design': 'Start architectural design session — explore approaches and trade-offs',
|
|
3745
3797
|
'/lint': 'Run linting on the project',
|
|
3746
3798
|
'/files': 'List files in current working directory',
|
|
3747
3799
|
'/stats': 'Show session usage statistics',
|
package/dist/mipham
DELETED
|
Binary file
|