@miphamai/cli 0.50.0 â 0.51.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.
- package/bin/mipham.ts +1 -9
- package/package.json +1 -1
- package/skills/standard/web-access/references/cdp-api.md +2 -1
- package/skills/standard/web-access/scripts/cdp-proxy.mjs +75 -1
- package/skills/standard/web-access/scripts/check-deps.mjs +17 -2
- package/skills/standard/web-access/scripts/find-url.mjs +0 -0
- package/skills/standard/web-access/scripts/match-site.mjs +0 -0
- package/skills/standard/web-access.SKILL.md +10 -3
- package/src/commands/project.ts +1 -1
- package/src/config/defaults.ts +5 -0
- package/src/core/auto-memory.ts +3 -3
- package/src/core/constitution-loader.ts +0 -2
- package/src/core/context.ts +0 -1
- package/src/core/credential-masker/index.ts +1 -0
- package/src/core/credential-masker/matcher.ts +18 -7
- package/src/core/credential-masker/search.ts +73 -0
- package/src/core/credential-masker.ts +1 -0
- package/src/core/crsi-sandbox.ts +0 -1
- package/src/core/dream-engine.ts +0 -2
- package/src/core/memory/memory-loader.ts +3 -1
- package/src/core/permission-rules.ts +23 -12
- package/src/core/rules-loader.ts +8 -10
- package/src/daemon/database.ts +0 -1
- package/src/daemon/feishu/adapter.ts +2 -1
- package/src/daemon/index.ts +18 -8
- package/src/daemon/server.ts +53 -10
- package/src/daemon/session-manager.ts +5 -4
- package/src/daemon/telegram/adapter.ts +70 -0
- package/src/daemon/telegram/api.ts +45 -0
- package/src/daemon/telegram/env.ts +14 -0
- package/src/daemon/telegram/poller.ts +64 -0
- package/src/daemon/telegram/types.ts +10 -0
- package/src/i18n-core/locales/en-US.json +123 -0
- package/src/i18n-core/locales/zh-CN.json +123 -0
- package/src/index.tsx +6 -0
- package/src/shared/package-info.ts +1 -1
- package/src/shared/types.ts +2 -0
- package/src/skills/bundled-skill-assets.ts +5 -5
- package/src/skills/bundled-skills.ts +1 -1
- package/src/tools/agent/exit-plan.ts +1 -3
- package/src/tools/agent/memory.ts +2 -1
- package/src/tools/file/glob.ts +38 -23
- package/src/tools/file/grep.ts +86 -64
- package/src/tools/index.ts +5 -5
- package/src/ui/commands.ts +188 -119
- package/src/ui/config-wizard.tsx +1 -1
package/src/ui/commands.ts
CHANGED
|
@@ -1022,8 +1022,6 @@ const crsiHealthCmd: CommandHandler = async (ctx) => {
|
|
|
1022
1022
|
lines.push('', '### ðĄïļ SIS čŠå
įŦåįģŧįŧ', '')
|
|
1023
1023
|
if (db) {
|
|
1024
1024
|
const stats = db.getStats()
|
|
1025
|
-
const healthEmoji =
|
|
1026
|
-
stats.avgSuccessRate >= 0.8 ? 'ðĒ' : stats.avgSuccessRate >= 0.5 ? 'ðĄ' : 'ðī'
|
|
1027
1025
|
|
|
1028
1026
|
lines.push(`| ææ | åž |`)
|
|
1029
1027
|
lines.push(`|------|----|`)
|
|
@@ -1246,7 +1244,7 @@ const crsiCritiqueCmd: CommandHandler = (ctx, args) => {
|
|
|
1246
1244
|
const engine = ctx.engine
|
|
1247
1245
|
const sc = engine.getSelfCritique?.()
|
|
1248
1246
|
if (!sc) {
|
|
1249
|
-
return { content: '
|
|
1247
|
+
return { content: t('commands.crsi_critique.not_init') }
|
|
1250
1248
|
}
|
|
1251
1249
|
|
|
1252
1250
|
const sub = args[0]?.toLowerCase()
|
|
@@ -1256,42 +1254,44 @@ const crsiCritiqueCmd: CommandHandler = (ctx, args) => {
|
|
|
1256
1254
|
sc.setEnabled(true)
|
|
1257
1255
|
return {
|
|
1258
1256
|
content: [
|
|
1259
|
-
'
|
|
1257
|
+
t('commands.crsi_critique.on_title'),
|
|
1260
1258
|
'',
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1259
|
+
t('commands.crsi_critique.model', { model: config.model || 'auto (fastest available)' }),
|
|
1260
|
+
t('commands.crsi_critique.threshold', { pct: (config.threshold * 100).toFixed(0) }),
|
|
1261
|
+
t('commands.crsi_critique.target_tools', { tools: config.targetTools.join(', ') }),
|
|
1264
1262
|
'',
|
|
1265
|
-
'
|
|
1266
|
-
'
|
|
1263
|
+
t('commands.crsi_critique.on_desc1'),
|
|
1264
|
+
t('commands.crsi_critique.on_desc2'),
|
|
1267
1265
|
'',
|
|
1268
|
-
'
|
|
1266
|
+
t('commands.crsi_critique.on_hint'),
|
|
1269
1267
|
].join('\n'),
|
|
1270
1268
|
}
|
|
1271
1269
|
}
|
|
1272
1270
|
|
|
1273
1271
|
if (sub === 'off' || sub === 'disable') {
|
|
1274
1272
|
sc.setEnabled(false)
|
|
1275
|
-
return {
|
|
1276
|
-
content: '## ð Self-Critique: OFF\n\nTool calls will execute without pre-flight critique.',
|
|
1277
|
-
}
|
|
1273
|
+
return { content: t('commands.crsi_critique.off_title') }
|
|
1278
1274
|
}
|
|
1279
1275
|
|
|
1280
1276
|
// status (default)
|
|
1281
1277
|
const lines: string[] = [
|
|
1282
|
-
'
|
|
1278
|
+
t('commands.crsi_critique.status_title'),
|
|
1283
1279
|
'',
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1280
|
+
t('commands.crsi_critique.state', {
|
|
1281
|
+
state: config.enabled ? 'ðĒ Enabled' : 'âŦ Disabled',
|
|
1282
|
+
}),
|
|
1283
|
+
t('commands.crsi_critique.model', { model: config.model || 'auto (fastest available)' }),
|
|
1284
|
+
t('commands.crsi_critique.threshold_detail', { pct: (config.threshold * 100).toFixed(0) }),
|
|
1285
|
+
t('commands.crsi_critique.target_tools', {
|
|
1286
|
+
tools: config.targetTools.length > 0 ? config.targetTools.join(', ') : 'all',
|
|
1287
|
+
}),
|
|
1288
|
+
t('commands.crsi_critique.timeout', { ms: String(config.timeoutMs) }),
|
|
1289
1289
|
'',
|
|
1290
1290
|
'ââ',
|
|
1291
|
-
'
|
|
1292
|
-
'
|
|
1291
|
+
t('commands.crsi_critique.status_on_hint'),
|
|
1292
|
+
t('commands.crsi_critique.status_off_hint'),
|
|
1293
1293
|
'',
|
|
1294
|
-
'
|
|
1294
|
+
t('commands.crsi_critique.inspired'),
|
|
1295
1295
|
]
|
|
1296
1296
|
|
|
1297
1297
|
return { content: lines.join('\n') }
|
|
@@ -1306,7 +1306,7 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1306
1306
|
const engine = ctx.engine
|
|
1307
1307
|
const toolFilter = args[0]?.toLowerCase()
|
|
1308
1308
|
|
|
1309
|
-
const lines: string[] = ['
|
|
1309
|
+
const lines: string[] = [t('commands.crsi_interpret.title'), '']
|
|
1310
1310
|
|
|
1311
1311
|
// ââ Error Signature Analysis ââ
|
|
1312
1312
|
const db = engine.getErrorSignatureDB?.()
|
|
@@ -1318,23 +1318,34 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1318
1318
|
if (sigs.length === 0) {
|
|
1319
1319
|
lines.push(
|
|
1320
1320
|
toolFilter
|
|
1321
|
-
?
|
|
1322
|
-
: '
|
|
1321
|
+
? t('commands.crsi_interpret.no_sigs_for_tool', { tool: toolFilter })
|
|
1322
|
+
: t('commands.crsi_interpret.no_sigs'),
|
|
1323
1323
|
)
|
|
1324
1324
|
} else {
|
|
1325
|
-
lines.push(
|
|
1325
|
+
lines.push(
|
|
1326
|
+
t('commands.crsi_interpret.sigs_title', {
|
|
1327
|
+
tool: toolFilter ? ` â \`${toolFilter}\`` : '',
|
|
1328
|
+
}),
|
|
1329
|
+
'',
|
|
1330
|
+
)
|
|
1326
1331
|
for (const sig of sigs.slice(0, 15)) {
|
|
1327
1332
|
const bar =
|
|
1328
1333
|
'â'.repeat(Math.round(sig.successRate * 10)) +
|
|
1329
1334
|
'â'.repeat(10 - Math.round(sig.successRate * 10))
|
|
1330
1335
|
lines.push(`- **${sig.toolName}**: \`${sig.pattern.slice(0, 60)}\``)
|
|
1331
1336
|
lines.push(
|
|
1332
|
-
|
|
1337
|
+
t('commands.crsi_interpret.sig_success', {
|
|
1338
|
+
bar,
|
|
1339
|
+
pct: String(Math.round(sig.successRate * 100)),
|
|
1340
|
+
occurrences: String(sig.occurrences),
|
|
1341
|
+
strategy: sig.fixStrategy,
|
|
1342
|
+
}),
|
|
1333
1343
|
)
|
|
1334
|
-
lines.push(
|
|
1344
|
+
lines.push(t('commands.crsi_interpret.sig_fix', { fix: sig.fixAction.slice(0, 80) }))
|
|
1335
1345
|
lines.push('')
|
|
1336
1346
|
}
|
|
1337
|
-
if (sigs.length > 15)
|
|
1347
|
+
if (sigs.length > 15)
|
|
1348
|
+
lines.push(t('commands.crsi_interpret.sigs_more', { count: String(sigs.length - 15) }), '')
|
|
1338
1349
|
}
|
|
1339
1350
|
}
|
|
1340
1351
|
|
|
@@ -1343,8 +1354,8 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1343
1354
|
if (autoMemory) {
|
|
1344
1355
|
const count = autoMemory.sessionReflectionCount ?? 0
|
|
1345
1356
|
if (count > 0) {
|
|
1346
|
-
lines.push('
|
|
1347
|
-
lines.push(
|
|
1357
|
+
lines.push(t('commands.crsi_interpret.reflection_title'), '')
|
|
1358
|
+
lines.push(t('commands.crsi_interpret.reflections', { count: String(count) }))
|
|
1348
1359
|
lines.push('')
|
|
1349
1360
|
}
|
|
1350
1361
|
}
|
|
@@ -1353,10 +1364,16 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1353
1364
|
const usage = engine.getUsageTracker?.()
|
|
1354
1365
|
if (usage) {
|
|
1355
1366
|
const summary = usage.getSummary()
|
|
1356
|
-
lines.push('
|
|
1357
|
-
lines.push(
|
|
1358
|
-
|
|
1359
|
-
|
|
1367
|
+
lines.push(t('commands.crsi_interpret.usage_title'), '')
|
|
1368
|
+
lines.push(
|
|
1369
|
+
t('commands.crsi_interpret.api_in', { count: summary.apiInputTokens.toLocaleString() }),
|
|
1370
|
+
)
|
|
1371
|
+
lines.push(
|
|
1372
|
+
t('commands.crsi_interpret.api_out', { count: summary.apiOutputTokens.toLocaleString() }),
|
|
1373
|
+
)
|
|
1374
|
+
lines.push(
|
|
1375
|
+
t('commands.crsi_interpret.est_tokens', { count: summary.estimatedTokens.toLocaleString() }),
|
|
1376
|
+
)
|
|
1360
1377
|
lines.push('')
|
|
1361
1378
|
}
|
|
1362
1379
|
|
|
@@ -1368,9 +1385,9 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1368
1385
|
if (analysis.systemHealth) {
|
|
1369
1386
|
const h = analysis.systemHealth
|
|
1370
1387
|
const bar = 'â'.repeat(Math.round(h.score / 10)) + 'â'.repeat(10 - Math.round(h.score / 10))
|
|
1371
|
-
lines.push('
|
|
1372
|
-
lines.push(
|
|
1373
|
-
lines.push(
|
|
1388
|
+
lines.push(t('commands.crsi_interpret.health_title'), '')
|
|
1389
|
+
lines.push(t('commands.crsi_interpret.overall', { bar, score: String(h.score) }))
|
|
1390
|
+
lines.push(t('commands.crsi_interpret.assessment', { assessment: h.assessment }))
|
|
1374
1391
|
if (h.components) {
|
|
1375
1392
|
lines.push('')
|
|
1376
1393
|
for (const [comp, score] of Object.entries(h.components)) {
|
|
@@ -1394,20 +1411,25 @@ const crsiInterpretCmd: CommandHandler = (ctx, args) => {
|
|
|
1394
1411
|
const blocks = c.principles.filter((p) => p.enforce === 'block').length
|
|
1395
1412
|
const warns = c.principles.filter((p) => p.enforce === 'warn').length
|
|
1396
1413
|
const autos = c.principles.filter((p) => p.enforce === 'auto').length
|
|
1397
|
-
lines.push('
|
|
1414
|
+
lines.push(t('commands.crsi_interpret.constitution_title'), '')
|
|
1398
1415
|
lines.push(
|
|
1399
|
-
|
|
1416
|
+
t('commands.crsi_interpret.principles', {
|
|
1417
|
+
total: String(c.principles.length),
|
|
1418
|
+
block: String(blocks),
|
|
1419
|
+
warn: String(warns),
|
|
1420
|
+
auto: String(autos),
|
|
1421
|
+
}),
|
|
1400
1422
|
)
|
|
1401
|
-
lines.push(
|
|
1423
|
+
lines.push(t('commands.crsi_interpret.version', { version: c.version }))
|
|
1402
1424
|
lines.push('')
|
|
1403
1425
|
}
|
|
1404
1426
|
|
|
1405
1427
|
if (lines.length <= 2) {
|
|
1406
|
-
lines.push('
|
|
1428
|
+
lines.push(t('commands.crsi_interpret.empty'))
|
|
1407
1429
|
}
|
|
1408
1430
|
|
|
1409
1431
|
lines.push('ââ')
|
|
1410
|
-
lines.push('
|
|
1432
|
+
lines.push(t('commands.crsi_interpret.filter_hint'))
|
|
1411
1433
|
|
|
1412
1434
|
return { content: lines.join('\n') }
|
|
1413
1435
|
}
|
|
@@ -1424,7 +1446,7 @@ const crsiRedTeamCmd: CommandHandler = async (ctx) => {
|
|
|
1424
1446
|
const preflight = engine.getPreFlightChecker?.()
|
|
1425
1447
|
|
|
1426
1448
|
if (!constitution || !preflight) {
|
|
1427
|
-
return { content: '
|
|
1449
|
+
return { content: t('commands.crsi_red_team.not_init') }
|
|
1428
1450
|
}
|
|
1429
1451
|
|
|
1430
1452
|
const { RedTeam: RT } = await import('../../src/core/red-team.js')
|
|
@@ -1432,21 +1454,21 @@ const crsiRedTeamCmd: CommandHandler = async (ctx) => {
|
|
|
1432
1454
|
const report = redTeam.run(constitution, preflight)
|
|
1433
1455
|
|
|
1434
1456
|
const lines: string[] = [
|
|
1435
|
-
'
|
|
1457
|
+
t('commands.crsi_red_team.title'),
|
|
1436
1458
|
'',
|
|
1437
|
-
|
|
1459
|
+
t('commands.crsi_red_team.score', { score: String(report.score) }),
|
|
1438
1460
|
'',
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1461
|
+
t('commands.crsi_red_team.metric'),
|
|
1462
|
+
t('commands.crsi_red_team.metric_sep'),
|
|
1463
|
+
t('commands.crsi_red_team.total_attacks', { count: String(report.total) }),
|
|
1464
|
+
t('commands.crsi_red_team.blocked', { count: String(report.blocked) }),
|
|
1465
|
+
t('commands.crsi_red_team.passed_through', { count: String(report.passedThrough) }),
|
|
1466
|
+
t('commands.crsi_red_team.false_positives', { count: String(report.falsePositives) }),
|
|
1445
1467
|
'',
|
|
1446
1468
|
]
|
|
1447
1469
|
|
|
1448
1470
|
// Per-principle breakdown
|
|
1449
|
-
lines.push('
|
|
1471
|
+
lines.push(t('commands.crsi_red_team.by_principle'), '')
|
|
1450
1472
|
for (const [pid, stats] of Object.entries(report.byPrinciple)) {
|
|
1451
1473
|
const pct = stats.total > 0 ? Math.round((stats.blocked / stats.total) * 100) : 100
|
|
1452
1474
|
const bar = 'â'.repeat(Math.round(pct / 10)) + 'â'.repeat(10 - Math.round(pct / 10))
|
|
@@ -1458,11 +1480,14 @@ const crsiRedTeamCmd: CommandHandler = async (ctx) => {
|
|
|
1458
1480
|
// Detail: passed-through attacks
|
|
1459
1481
|
const gaps = report.results.filter((r) => r.attack.shouldBlock && !r.blocked)
|
|
1460
1482
|
if (gaps.length > 0) {
|
|
1461
|
-
lines.push('
|
|
1483
|
+
lines.push(t('commands.crsi_red_team.gaps_title'), '')
|
|
1462
1484
|
for (const g of gaps) {
|
|
1463
1485
|
lines.push(`- **${g.attack.principleId}**: ${g.attack.description}`)
|
|
1464
1486
|
lines.push(
|
|
1465
|
-
|
|
1487
|
+
t('commands.crsi_red_team.gap_tool', {
|
|
1488
|
+
tool: g.attack.toolName,
|
|
1489
|
+
params: JSON.stringify(g.attack.params).slice(0, 80),
|
|
1490
|
+
}),
|
|
1466
1491
|
)
|
|
1467
1492
|
}
|
|
1468
1493
|
lines.push('')
|
|
@@ -1471,21 +1496,25 @@ const crsiRedTeamCmd: CommandHandler = async (ctx) => {
|
|
|
1471
1496
|
// Detail: caught attacks
|
|
1472
1497
|
const caught = report.results.filter((r) => r.blocked)
|
|
1473
1498
|
if (caught.length > 0) {
|
|
1474
|
-
lines.push('
|
|
1499
|
+
lines.push(t('commands.crsi_red_team.blocked_title'), '')
|
|
1475
1500
|
for (const c of caught) {
|
|
1476
|
-
lines.push(
|
|
1501
|
+
lines.push(
|
|
1502
|
+
t('commands.crsi_red_team.caught_by', {
|
|
1503
|
+
principle: c.attack.principleId,
|
|
1504
|
+
desc: c.attack.description,
|
|
1505
|
+
caught: c.caughtBy ?? 'unknown',
|
|
1506
|
+
}),
|
|
1507
|
+
)
|
|
1477
1508
|
}
|
|
1478
1509
|
lines.push('')
|
|
1479
1510
|
}
|
|
1480
1511
|
|
|
1481
1512
|
if (report.score === 100) {
|
|
1482
|
-
lines.push('
|
|
1513
|
+
lines.push(t('commands.crsi_red_team.all_blocked'))
|
|
1483
1514
|
} else if (report.score >= 80) {
|
|
1484
|
-
lines.push(
|
|
1485
|
-
'â ïļ Good coverage. Review the gaps above and add audit patterns to `ai-guardrails.yml`.',
|
|
1486
|
-
)
|
|
1515
|
+
lines.push(t('commands.crsi_red_team.good_coverage'))
|
|
1487
1516
|
} else {
|
|
1488
|
-
lines.push('
|
|
1517
|
+
lines.push(t('commands.crsi_red_team.critical'))
|
|
1489
1518
|
}
|
|
1490
1519
|
|
|
1491
1520
|
return { content: lines.join('\n') }
|
|
@@ -1502,45 +1531,61 @@ const dreamCmd: CommandHandler = async (ctx, args) => {
|
|
|
1502
1531
|
|
|
1503
1532
|
const engine = ctx.engine.getDreamEngine?.()
|
|
1504
1533
|
if (!engine) {
|
|
1505
|
-
return { content: '
|
|
1534
|
+
return { content: t('commands.dream.not_init') }
|
|
1506
1535
|
}
|
|
1507
1536
|
|
|
1508
1537
|
if (status) {
|
|
1509
1538
|
const history = engine.getDreamHistory()
|
|
1510
1539
|
if (history.length === 0) {
|
|
1511
|
-
return { content: '
|
|
1540
|
+
return { content: t('commands.dream.no_history') }
|
|
1512
1541
|
}
|
|
1513
|
-
const lines: string[] = ['
|
|
1542
|
+
const lines: string[] = [t('commands.dream.history_title'), '']
|
|
1514
1543
|
for (const entry of history.slice(0, 5)) {
|
|
1515
1544
|
const ts = new Date(entry.timestamp).toLocaleString('zh-CN')
|
|
1516
1545
|
const total = entry.actions.length
|
|
1517
1546
|
const applied = entry.actions.filter((a) => a.autoApplied).length
|
|
1518
1547
|
const flagged = entry.actions.filter((a) => !a.autoApplied).length
|
|
1519
|
-
lines.push(
|
|
1548
|
+
lines.push(
|
|
1549
|
+
t('commands.dream.history_entry', {
|
|
1550
|
+
time: ts,
|
|
1551
|
+
total: String(total),
|
|
1552
|
+
applied: String(applied),
|
|
1553
|
+
flagged: String(flagged),
|
|
1554
|
+
}),
|
|
1555
|
+
)
|
|
1520
1556
|
}
|
|
1521
1557
|
return { content: lines.join('\n') }
|
|
1522
1558
|
}
|
|
1523
1559
|
|
|
1524
1560
|
const report = engine.dream({ aggressive })
|
|
1525
1561
|
const lines: string[] = [
|
|
1526
|
-
'
|
|
1562
|
+
t('commands.dream.done_title'),
|
|
1527
1563
|
'',
|
|
1528
|
-
|
|
1529
|
-
|
|
1564
|
+
t('commands.dream.integrate', {
|
|
1565
|
+
before: String(report.beforeCount),
|
|
1566
|
+
after: String(report.afterCount),
|
|
1567
|
+
}),
|
|
1568
|
+
...(report.phases.deduplicated > 0
|
|
1569
|
+
? [t('commands.dream.dedup', { count: String(report.phases.deduplicated) })]
|
|
1570
|
+
: []),
|
|
1530
1571
|
...(report.phases.contradictionsFound > 0
|
|
1531
|
-
? [
|
|
1572
|
+
? [t('commands.dream.contradiction', { count: String(report.phases.contradictionsFound) })]
|
|
1573
|
+
: []),
|
|
1574
|
+
...(report.phases.merged > 0
|
|
1575
|
+
? [t('commands.dream.merge', { count: String(report.phases.merged) })]
|
|
1532
1576
|
: []),
|
|
1533
|
-
...(report.phases.merged > 0 ? [`- ååđķ: ${report.phases.merged} įŧ`] : []),
|
|
1534
1577
|
...(report.phases.solidified > 0
|
|
1535
|
-
? [
|
|
1578
|
+
? [t('commands.dream.solidify', { count: String(report.phases.solidified) })]
|
|
1579
|
+
: []),
|
|
1580
|
+
...(report.phases.pruned > 0
|
|
1581
|
+
? [t('commands.dream.prune', { count: String(report.phases.pruned) })]
|
|
1536
1582
|
: []),
|
|
1537
|
-
...(report.phases.pruned > 0 ? [`- æļ
įčŋæ: ${report.phases.pruned} æĄ`] : []),
|
|
1538
1583
|
'',
|
|
1539
1584
|
]
|
|
1540
1585
|
|
|
1541
1586
|
const flagged = report.actions.filter((a) => !a.autoApplied)
|
|
1542
1587
|
if (flagged.length > 0 && !aggressive) {
|
|
1543
|
-
lines.push(
|
|
1588
|
+
lines.push(t('commands.dream.review_hint', { count: String(flagged.length) }))
|
|
1544
1589
|
lines.push('')
|
|
1545
1590
|
for (const action of flagged) {
|
|
1546
1591
|
lines.push(`- [ ] **${action.type}**: ${action.description}`)
|
|
@@ -1548,7 +1593,7 @@ const dreamCmd: CommandHandler = async (ctx, args) => {
|
|
|
1548
1593
|
}
|
|
1549
1594
|
|
|
1550
1595
|
if (report.actions.length === 0) {
|
|
1551
|
-
lines.push('
|
|
1596
|
+
lines.push(t('commands.dream.clean'))
|
|
1552
1597
|
}
|
|
1553
1598
|
|
|
1554
1599
|
return { content: lines.join('\n') }
|
|
@@ -1563,7 +1608,7 @@ const constitutionCmd: CommandHandler = (ctx, args) => {
|
|
|
1563
1608
|
const engine = ctx.engine
|
|
1564
1609
|
const constitution = engine.getConstitutionLoader?.()
|
|
1565
1610
|
if (!constitution) {
|
|
1566
|
-
return { content: '
|
|
1611
|
+
return { content: t('commands.constitution.not_init') }
|
|
1567
1612
|
}
|
|
1568
1613
|
|
|
1569
1614
|
const subCmd = args[0]?.toLowerCase()
|
|
@@ -1573,11 +1618,11 @@ const constitutionCmd: CommandHandler = (ctx, args) => {
|
|
|
1573
1618
|
const c = constitution.reload()
|
|
1574
1619
|
return {
|
|
1575
1620
|
content: [
|
|
1576
|
-
'
|
|
1621
|
+
t('commands.constitution.reload_title'),
|
|
1577
1622
|
'',
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1623
|
+
t('commands.constitution.version', { version: c.version }),
|
|
1624
|
+
t('commands.constitution.principles', { count: String(c.principles.length) }),
|
|
1625
|
+
t('commands.constitution.path', { path: constitution.getPath() }),
|
|
1581
1626
|
'',
|
|
1582
1627
|
c.principles.map((p) => `- **${p.id}** [${p.enforce}]: ${p.text}`).join('\n'),
|
|
1583
1628
|
].join('\n'),
|
|
@@ -1587,9 +1632,13 @@ const constitutionCmd: CommandHandler = (ctx, args) => {
|
|
|
1587
1632
|
// /constitution view (default)
|
|
1588
1633
|
const c = constitution.load()
|
|
1589
1634
|
const lines: string[] = [
|
|
1590
|
-
'
|
|
1635
|
+
t('commands.constitution.view_title'),
|
|
1591
1636
|
'',
|
|
1592
|
-
|
|
1637
|
+
t('commands.constitution.view_summary', {
|
|
1638
|
+
version: c.version,
|
|
1639
|
+
count: String(c.principles.length),
|
|
1640
|
+
path: constitution.getPath(),
|
|
1641
|
+
}),
|
|
1593
1642
|
'',
|
|
1594
1643
|
'---',
|
|
1595
1644
|
'',
|
|
@@ -1601,20 +1650,18 @@ const constitutionCmd: CommandHandler = (ctx, args) => {
|
|
|
1601
1650
|
lines.push('')
|
|
1602
1651
|
lines.push(p.text)
|
|
1603
1652
|
if (p.rationale) lines.push(` *${p.rationale}*`)
|
|
1604
|
-
if (p.scope) lines.push(
|
|
1605
|
-
if (p.tools) lines.push(
|
|
1653
|
+
if (p.scope) lines.push(t('commands.constitution.scope', { scope: p.scope }))
|
|
1654
|
+
if (p.tools) lines.push(t('commands.constitution.tools', { tools: p.tools.join(', ') }))
|
|
1606
1655
|
lines.push('')
|
|
1607
1656
|
}
|
|
1608
1657
|
|
|
1609
1658
|
lines.push('---')
|
|
1610
1659
|
lines.push('')
|
|
1611
|
-
lines.push('
|
|
1612
|
-
lines.push('
|
|
1613
|
-
lines.push('
|
|
1660
|
+
lines.push(t('commands.constitution.reload_hint'))
|
|
1661
|
+
lines.push(t('commands.constitution.edit_hint'))
|
|
1662
|
+
lines.push(t('commands.constitution.reset_hint'))
|
|
1614
1663
|
lines.push('')
|
|
1615
|
-
lines.push(
|
|
1616
|
-
'*Inspired by Anthropic Constitutional AI. Mipham enforces these principles at runtime â auditable on every action.*',
|
|
1617
|
-
)
|
|
1664
|
+
lines.push(t('commands.constitution.inspired'))
|
|
1618
1665
|
|
|
1619
1666
|
return { content: lines.join('\n') }
|
|
1620
1667
|
}
|
|
@@ -1627,25 +1674,32 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1627
1674
|
const t = resolveT(ctx)
|
|
1628
1675
|
const engine = ctx.engine
|
|
1629
1676
|
const lines: string[] = [
|
|
1630
|
-
'
|
|
1677
|
+
t('commands.bug_report.title'),
|
|
1631
1678
|
'',
|
|
1632
|
-
'
|
|
1679
|
+
t('commands.bug_report.hint'),
|
|
1633
1680
|
'',
|
|
1634
1681
|
'---',
|
|
1635
1682
|
'',
|
|
1636
1683
|
]
|
|
1637
1684
|
|
|
1638
1685
|
// ââ Version & Runtime ââ
|
|
1639
|
-
lines.push('
|
|
1640
|
-
lines.push(
|
|
1641
|
-
lines.push(
|
|
1642
|
-
lines.push(
|
|
1643
|
-
lines.push(
|
|
1686
|
+
lines.push(t('commands.bug_report.env_title'), '')
|
|
1687
|
+
lines.push(t('commands.bug_report.mipham', { version: ctx.version }))
|
|
1688
|
+
lines.push(t('commands.bug_report.session', { id: ctx.sessionId }))
|
|
1689
|
+
lines.push(t('commands.bug_report.node', { version: process.version }))
|
|
1690
|
+
lines.push(t('commands.bug_report.platform', { platform: process.platform, arch: process.arch }))
|
|
1644
1691
|
lines.push(
|
|
1645
|
-
|
|
1692
|
+
t('commands.bug_report.os', {
|
|
1693
|
+
os:
|
|
1694
|
+
process.platform === 'darwin'
|
|
1695
|
+
? 'macOS'
|
|
1696
|
+
: process.platform === 'linux'
|
|
1697
|
+
? 'Linux'
|
|
1698
|
+
: 'Windows',
|
|
1699
|
+
}),
|
|
1646
1700
|
)
|
|
1647
|
-
lines.push(
|
|
1648
|
-
lines.push(
|
|
1701
|
+
lines.push(t('commands.bug_report.provider', { provider: ctx.providerId }))
|
|
1702
|
+
lines.push(t('commands.bug_report.model', { model: ctx.modelId }))
|
|
1649
1703
|
lines.push('')
|
|
1650
1704
|
|
|
1651
1705
|
// ââ SIS errors ââ
|
|
@@ -1654,10 +1708,16 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1654
1708
|
if (db) {
|
|
1655
1709
|
const active = db.getActive()
|
|
1656
1710
|
if (active.length > 0) {
|
|
1657
|
-
lines.push('
|
|
1711
|
+
lines.push(t('commands.bug_report.sigs_title'), '')
|
|
1658
1712
|
for (const sig of active.slice(0, 10)) {
|
|
1659
1713
|
lines.push(
|
|
1660
|
-
|
|
1714
|
+
t('commands.bug_report.sig_entry', {
|
|
1715
|
+
id: sig.id,
|
|
1716
|
+
pattern: sig.pattern,
|
|
1717
|
+
category: sig.category,
|
|
1718
|
+
occurrences: String(sig.occurrences),
|
|
1719
|
+
pct: (sig.successRate * 100).toFixed(0),
|
|
1720
|
+
}),
|
|
1661
1721
|
)
|
|
1662
1722
|
}
|
|
1663
1723
|
lines.push('')
|
|
@@ -1674,10 +1734,14 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1674
1734
|
const health = hookEngine.getHookHealth()
|
|
1675
1735
|
const disabled = health.filter((h) => h.health.disabled)
|
|
1676
1736
|
if (disabled.length > 0) {
|
|
1677
|
-
lines.push('
|
|
1737
|
+
lines.push(t('commands.bug_report.disabled_hooks'), '')
|
|
1678
1738
|
for (const entry of disabled) {
|
|
1679
1739
|
lines.push(
|
|
1680
|
-
|
|
1740
|
+
t('commands.bug_report.hook_entry', {
|
|
1741
|
+
key: entry.key,
|
|
1742
|
+
failures: String(entry.health.failures),
|
|
1743
|
+
time: new Date(entry.health.disabledAt).toISOString(),
|
|
1744
|
+
}),
|
|
1681
1745
|
)
|
|
1682
1746
|
}
|
|
1683
1747
|
lines.push('')
|
|
@@ -1694,10 +1758,15 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1694
1758
|
const history = dreamEngine.getDreamHistory()
|
|
1695
1759
|
if (history.length > 0) {
|
|
1696
1760
|
const last = history[0]!
|
|
1697
|
-
lines.push('
|
|
1698
|
-
lines.push(
|
|
1761
|
+
lines.push(t('commands.bug_report.last_dream'), '')
|
|
1762
|
+
lines.push(t('commands.bug_report.ran_at', { time: last.timestamp }))
|
|
1699
1763
|
lines.push(
|
|
1700
|
-
|
|
1764
|
+
t('commands.bug_report.actions', {
|
|
1765
|
+
total: String(last.actions.length),
|
|
1766
|
+
applied: String(
|
|
1767
|
+
last.actions.filter((a: { autoApplied: boolean }) => a.autoApplied).length,
|
|
1768
|
+
),
|
|
1769
|
+
}),
|
|
1701
1770
|
)
|
|
1702
1771
|
lines.push('')
|
|
1703
1772
|
}
|
|
@@ -1707,17 +1776,17 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1707
1776
|
}
|
|
1708
1777
|
|
|
1709
1778
|
// ââ Steps to reproduce (template) ââ
|
|
1710
|
-
lines.push('
|
|
1779
|
+
lines.push(t('commands.bug_report.steps_title'), '')
|
|
1711
1780
|
lines.push('1. ')
|
|
1712
1781
|
lines.push('2. ')
|
|
1713
1782
|
lines.push('3. ')
|
|
1714
1783
|
lines.push('')
|
|
1715
|
-
lines.push('
|
|
1784
|
+
lines.push(t('commands.bug_report.expected'), '')
|
|
1716
1785
|
lines.push('')
|
|
1717
|
-
lines.push('
|
|
1786
|
+
lines.push(t('commands.bug_report.actual'), '')
|
|
1718
1787
|
lines.push('')
|
|
1719
1788
|
lines.push('---')
|
|
1720
|
-
lines.push(
|
|
1789
|
+
lines.push(t('commands.bug_report.generated', { version: ctx.version }))
|
|
1721
1790
|
|
|
1722
1791
|
return { content: lines.join('\n'), copyContent: lines.join('\n') }
|
|
1723
1792
|
}
|
|
@@ -1730,7 +1799,7 @@ const bugReportCmd: CommandHandler = async (ctx) => {
|
|
|
1730
1799
|
|
|
1731
1800
|
const changelogCmd: CommandHandler = async (ctx) => {
|
|
1732
1801
|
const t = resolveT(ctx)
|
|
1733
|
-
const lines: string[] = ['
|
|
1802
|
+
const lines: string[] = [t('commands.changelog.title'), '']
|
|
1734
1803
|
|
|
1735
1804
|
try {
|
|
1736
1805
|
const { execSync } = await import('node:child_process')
|
|
@@ -1741,11 +1810,11 @@ const changelogCmd: CommandHandler = async (ctx) => {
|
|
|
1741
1810
|
.slice(0, 15)
|
|
1742
1811
|
|
|
1743
1812
|
if (tags.length === 0) {
|
|
1744
|
-
lines.push('
|
|
1813
|
+
lines.push(t('commands.changelog.no_tags'))
|
|
1745
1814
|
return { content: lines.join('\n') }
|
|
1746
1815
|
}
|
|
1747
1816
|
|
|
1748
|
-
lines.push(
|
|
1817
|
+
lines.push(t('commands.changelog.current', { version: ctx.version }), '')
|
|
1749
1818
|
|
|
1750
1819
|
for (let i = 0; i < tags.length; i++) {
|
|
1751
1820
|
const tag = tags[i]!
|
|
@@ -1761,25 +1830,25 @@ const changelogCmd: CommandHandler = async (ctx) => {
|
|
|
1761
1830
|
.filter(Boolean)
|
|
1762
1831
|
|
|
1763
1832
|
const isCurrent = tag === `v${ctx.version}`
|
|
1764
|
-
lines.push(`### ${tag}${isCurrent ? '
|
|
1833
|
+
lines.push(`### ${tag}${isCurrent ? t('commands.changelog.current_marker') : ''}`, '')
|
|
1765
1834
|
if (log.length > 0) {
|
|
1766
1835
|
for (const entry of log) {
|
|
1767
1836
|
lines.push(`- ${entry}`)
|
|
1768
1837
|
}
|
|
1769
1838
|
} else {
|
|
1770
|
-
lines.push(
|
|
1839
|
+
lines.push(t('commands.changelog.release_only'))
|
|
1771
1840
|
}
|
|
1772
1841
|
lines.push('')
|
|
1773
1842
|
} catch {
|
|
1774
|
-
lines.push(`### ${tag}`, '', '
|
|
1843
|
+
lines.push(`### ${tag}`, '', t('commands.changelog.details_unavailable'), '')
|
|
1775
1844
|
}
|
|
1776
1845
|
}
|
|
1777
1846
|
} catch {
|
|
1778
|
-
lines.push('
|
|
1847
|
+
lines.push(t('commands.changelog.no_git'))
|
|
1779
1848
|
}
|
|
1780
1849
|
|
|
1781
1850
|
lines.push('---')
|
|
1782
|
-
lines.push(
|
|
1851
|
+
lines.push(t('commands.changelog.full_history'))
|
|
1783
1852
|
|
|
1784
1853
|
return { content: lines.join('\n') }
|
|
1785
1854
|
}
|
package/src/ui/config-wizard.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import { Box, Text, useInput } from 'ink'
|
|
|
13
13
|
import { useI18n } from '../i18n-context'
|
|
14
14
|
import TextInput from 'ink-text-input'
|
|
15
15
|
import { DEFAULT_PROVIDERS, OLLAMA_PRESET_MODELS } from '../shared/constants'
|
|
16
|
-
import type {
|
|
16
|
+
import type { ModelInfo } from '../shared/types'
|
|
17
17
|
import { mkdirSync, writeFileSync } from 'node:fs'
|
|
18
18
|
import { join } from 'node:path'
|
|
19
19
|
import { homedir } from 'node:os'
|