@miphamai/cli 0.7.6 → 0.7.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miphamai/cli",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "Mipham Code — Multi-model open-core intelligent coding terminal by MiphamAI",
5
5
  "keywords": [
6
6
  "ai",
package/src/ui/app.tsx CHANGED
@@ -175,9 +175,12 @@ export function App({
175
175
  return
176
176
  }
177
177
 
178
+ let injectMessage: string | undefined
179
+
178
180
  const handler = getCommand(command)
179
181
  if (handler) {
180
182
  const result = await handler(mkCtx(), args)
183
+ injectMessage = result.injectMessage
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
- // Unknown slash command or handler returned: proceed to normal AI processing
206
- return
208
+
209
+ // Bridge: if command set injectMessage, route to AI processing
210
+ if (injectMessage) {
211
+ input = injectMessage
212
+ // fall through to normal AI processing below
213
+ } else {
214
+ // Unknown slash command or handler returned: proceed to normal AI processing
215
+ return
216
+ }
207
217
  }
208
218
 
209
219
  // ── Normal message processing (AI chat) ──
@@ -40,6 +40,8 @@ export interface CommandResult {
40
40
  clearMessages?: boolean
41
41
  /** Content to copy to clipboard (handled by caller) */
42
42
  copyContent?: string
43
+ /** If set, inject this as a user message and route to AI processing (bridges slash commands → skills) */
44
+ injectMessage?: string
43
45
  }
44
46
 
45
47
  type CommandHandler = (
@@ -1088,6 +1090,18 @@ const branchCmd: CommandHandler = (ctx, args) => {
1088
1090
  }
1089
1091
  }
1090
1092
 
1093
+ /** Parse human-readable interval to seconds. Returns null if invalid. */
1094
+ function parseInterval(raw: string): number | null {
1095
+ const m = raw.trim().match(/^(\d+)\s*(s|sec|m|min|h|hr|hour)$/i)
1096
+ if (!m) return null
1097
+ const n = parseInt(m[1]!, 10)
1098
+ const unit = m[2]!.toLowerCase()
1099
+ if (unit === 's' || unit === 'sec') return n
1100
+ if (unit === 'm' || unit === 'min') return n * 60
1101
+ if (unit === 'h' || unit === 'hr' || unit === 'hour') return n * 3600
1102
+ return null
1103
+ }
1104
+
1091
1105
  const loopCmd: CommandHandler = async (_ctx, args) => {
1092
1106
  const sub = args[0]
1093
1107
 
@@ -1166,24 +1180,23 @@ const loopCmd: CommandHandler = async (_ctx, args) => {
1166
1180
  /loop 5m check the deploy status
1167
1181
  /loop init Create vault in current directory
1168
1182
  /loop init ~/my-project Create vault in specific directory
1169
-
1170
- Note: Continuous looping requires session persistence, coming in a future release.
1171
1183
  `,
1172
1184
  }
1173
1185
  }
1174
1186
 
1175
1187
  const interval = args[0]!
1176
1188
  const prompt = args.slice(1).join(' ')
1189
+ const seconds = parseInterval(interval)
1177
1190
 
1178
- return {
1179
- content: stripIndent`
1180
- ── Loop Configured ──
1181
- Interval: ${interval}
1182
- Prompt: "${prompt}"
1191
+ if (seconds === null) {
1192
+ return {
1193
+ content: `── Invalid Interval ──\n\n"${interval}" is not a recognised interval.\n\nUse formats like: 10s, 5m, 1h, 30min, 2hr`,
1194
+ }
1195
+ }
1183
1196
 
1184
- Loop scheduling infrastructure is being built.
1185
- For now, manually re-run: /loop ${interval} ${prompt}
1186
- `,
1197
+ return {
1198
+ 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
+ injectMessage: `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
1200
  }
1188
1201
  }
1189
1202
 
@@ -1191,14 +1204,15 @@ const scheduleCmd: CommandHandler = (_ctx) => ({
1191
1204
  content: stripIndent`
1192
1205
  ── Scheduled Tasks ──
1193
1206
 
1194
- No scheduled tasks configured.
1207
+ Active loops are managed via ScheduleWakeup (in-session) and
1208
+ CronCreate (durable, survives restarts).
1195
1209
 
1196
- Schedule infrastructure is being built. Coming features:
1197
- • Cron-based scheduling (CronCreate tool)
1198
- • One-shot and recurring tasks
1199
- • Durable persistence across sessions
1210
+ Use /loop <interval> <prompt> to start a recurring task.
1211
+ Use CronList to view all scheduled jobs.
1212
+ Use CronDelete <id> to cancel a durable job.
1200
1213
 
1201
- Use /loop for simple repetition in the current session.
1214
+ The ScheduleWakeup mechanism automatically re-schedules on
1215
+ each wake, creating a self-perpetuating loop within the session.
1202
1216
  `,
1203
1217
  })
1204
1218
 
@@ -1420,39 +1434,78 @@ const issueCmd: CommandHandler = async () => {
1420
1434
  // Code Quality Commands (Claude Code parity)
1421
1435
  // ═══════════════════════════════════════════════════════════════
1422
1436
 
1423
- const simplifyCmd: CommandHandler = async () => {
1437
+ // ═══════════════════════════════════════════════════════════════
1438
+ // Code Quality — bridge slash commands to skills (Claude Code parity)
1439
+ // ═══════════════════════════════════════════════════════════════
1440
+
1441
+ const codeReviewCmd: CommandHandler = async () => {
1424
1442
  try {
1425
1443
  const { execSync } = await import('node:child_process')
1426
1444
  const diff = execSync('git diff --stat', { encoding: 'utf-8', timeout: 5000 }).trim()
1427
- const changed = execSync('git diff --name-only', { encoding: 'utf-8', timeout: 3000 }).trim()
1445
+ if (!diff) {
1446
+ return {
1447
+ content:
1448
+ '─ Code Review ─\n\nNo uncommitted changes to review.\n\nTo review a specific file: /code-review path/to/file.ts',
1449
+ }
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
+ }
1428
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()
1429
1466
  if (!diff) {
1430
1467
  return {
1431
1468
  content:
1432
- '── Simplify ──\n\nNo uncommitted changes to review.\n\nRun /simplify after making changes to review for reuse, simplification, and quality improvements.',
1469
+ '─ Simplify ─\n\nNo uncommitted changes to simplify.\n\nMake changes first, then run /simplify for cleanup review.',
1433
1470
  }
1434
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
+ }
1435
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) {
1488
+ return {
1489
+ content:
1490
+ '─ Verify ─\n\nNo uncommitted changes to verify.\n\nMake changes first, then run /verify for runtime verification.',
1491
+ }
1492
+ }
1436
1493
  return {
1437
- content: [
1438
- '── Simplify Review ──',
1439
- '',
1440
- 'Changed files:',
1441
- diff,
1442
- '',
1443
- 'To run simplification review, type: "review these changes for simplification and quality"',
1444
- '',
1445
- 'This will check for:',
1446
- ' • Code reuse opportunities',
1447
- ' • Overly complex logic',
1448
- ' • Dead code removal',
1449
- ' • Style and consistency',
1450
- '',
1451
- `Files to review: ${changed.split('\n').length}`,
1452
- ].join('\n'),
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.',
1453
1498
  }
1454
1499
  } catch {
1455
- return { content: '── Simplify ──\n\nCould not detect changes. Are you in a git repository?' }
1500
+ return { content: '─ Verify ─\n\nCould not detect changes. Are you in a git repository?' }
1501
+ }
1502
+ }
1503
+
1504
+ const designCmd: CommandHandler = async (_ctx, args) => {
1505
+ const topic = args.join(' ') || 'the current task'
1506
+ return {
1507
+ content: `─ Design ─\n\nStarting architectural design session for: ${topic}\n\nExploring approaches, trade-offs, component breakdown, data flow...`,
1508
+ injectMessage: `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
1509
  }
1457
1510
  }
1458
1511
 
@@ -3495,8 +3548,11 @@ const commandsListCmd: CommandHandler = () => {
3495
3548
  '/push': 'Workflow',
3496
3549
  '/pr': 'Workflow',
3497
3550
  '/issue': 'Workflow',
3498
- '/simplify': 'Workflow',
3499
- '/lint': 'Workflow',
3551
+ '/code-review': 'Code Quality',
3552
+ '/simplify': 'Code Quality',
3553
+ '/verify': 'Code Quality',
3554
+ '/design': 'Code Quality',
3555
+ '/lint': 'Code Quality',
3500
3556
  '/files': 'Session & Identity',
3501
3557
  '/stats': 'Session & Identity',
3502
3558
  '/summary': 'Session & Identity',
@@ -3634,7 +3690,10 @@ registry.set('/pr', prCmd)
3634
3690
  registry.set('/issue', issueCmd)
3635
3691
 
3636
3692
  // Code Quality (Claude Code parity)
3693
+ registry.set('/code-review', codeReviewCmd)
3637
3694
  registry.set('/simplify', simplifyCmd)
3695
+ registry.set('/verify', verifyCmd)
3696
+ registry.set('/design', designCmd)
3638
3697
  registry.set('/lint', lintCmd)
3639
3698
 
3640
3699
  // Session Enhancement (Claude Code parity)
@@ -3741,7 +3800,10 @@ const COMMAND_DESCRIPTIONS: Record<string, string> = {
3741
3800
  '/push': 'Push the current branch',
3742
3801
  '/pr': 'Create a pull request',
3743
3802
  '/issue': 'File a GitHub issue',
3744
- '/simplify': 'Review code for reuse, simplification, and quality',
3803
+ '/code-review': 'Review code for bugs, security, performance (7 dimensions)',
3804
+ '/simplify': 'Cleanup-only review: reuse, simplification, efficiency, abstraction',
3805
+ '/verify': 'Runtime verification — observe actual execution, not tests',
3806
+ '/design': 'Start architectural design session — explore approaches and trade-offs',
3745
3807
  '/lint': 'Run linting on the project',
3746
3808
  '/files': 'List files in current working directory',
3747
3809
  '/stats': 'Show session usage statistics',
package/dist/mipham DELETED
Binary file