botmux 2.85.1 → 2.87.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/README.en.md +26 -0
- package/README.md +26 -0
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +12 -1
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/pty-backend.d.ts.map +1 -1
- package/dist/adapters/backend/pty-backend.js +4 -1
- package/dist/adapters/backend/pty-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +22 -9
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +9 -0
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/backend/types.js.map +1 -1
- package/dist/adapters/backend/zellij-backend.js +1 -1
- package/dist/adapters/backend/zellij-backend.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +8 -5
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +2 -1
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +25 -3
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/bot-registry.d.ts +10 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +6 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +362 -16
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +215 -5
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/cost-calculator.d.ts.map +1 -1
- package/dist/core/cost-calculator.js +7 -106
- package/dist/core/cost-calculator.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +285 -2
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/maintenance.d.ts +18 -0
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +58 -30
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/per-bot-env.d.ts +38 -0
- package/dist/core/per-bot-env.d.ts.map +1 -0
- package/dist/core/per-bot-env.js +79 -0
- package/dist/core/per-bot-env.js.map +1 -0
- package/dist/core/role-resolver.d.ts +1 -0
- package/dist/core/role-resolver.d.ts.map +1 -1
- package/dist/core/role-resolver.js +14 -0
- package/dist/core/role-resolver.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +70 -6
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/skills/discovery.d.ts +7 -0
- package/dist/core/skills/discovery.d.ts.map +1 -1
- package/dist/core/skills/discovery.js +51 -0
- package/dist/core/skills/discovery.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +5 -2
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/update-check.d.ts +67 -0
- package/dist/core/update-check.d.ts.map +1 -0
- package/dist/core/update-check.js +159 -0
- package/dist/core/update-check.js.map +1 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +4 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +29 -6
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +1 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +1 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/skill-install-request.d.ts +10 -0
- package/dist/dashboard/skill-install-request.d.ts.map +1 -1
- package/dist/dashboard/skill-install-request.js +17 -0
- package/dist/dashboard/skill-install-request.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +43 -4
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +178 -1
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/groups.d.ts +2 -0
- package/dist/dashboard/web/groups.d.ts.map +1 -1
- package/dist/dashboard/web/groups.js +419 -3
- package/dist/dashboard/web/groups.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +745 -3
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/insights.d.ts +2 -0
- package/dist/dashboard/web/insights.d.ts.map +1 -0
- package/dist/dashboard/web/insights.js +1523 -0
- package/dist/dashboard/web/insights.js.map +1 -0
- package/dist/dashboard/web/role-profile-match.d.ts +31 -0
- package/dist/dashboard/web/role-profile-match.d.ts.map +1 -0
- package/dist/dashboard/web/role-profile-match.js +58 -0
- package/dist/dashboard/web/role-profile-match.js.map +1 -0
- package/dist/dashboard/web/roles.d.ts +1 -0
- package/dist/dashboard/web/roles.d.ts.map +1 -1
- package/dist/dashboard/web/roles.js +520 -27
- package/dist/dashboard/web/roles.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +84 -0
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings.d.ts.map +1 -1
- package/dist/dashboard/web/settings.js +289 -0
- package/dist/dashboard/web/settings.js.map +1 -1
- package/dist/dashboard/web/skills.d.ts.map +1 -1
- package/dist/dashboard/web/skills.js +183 -10
- package/dist/dashboard/web/skills.js.map +1 -1
- package/dist/dashboard/web/whiteboards.d.ts +2 -0
- package/dist/dashboard/web/whiteboards.d.ts.map +1 -0
- package/dist/dashboard/web/whiteboards.js +267 -0
- package/dist/dashboard/web/whiteboards.js.map +1 -0
- package/dist/dashboard-web/app.js +1406 -833
- package/dist/dashboard-web/index.html +3 -1
- package/dist/dashboard-web/style.css +1382 -30
- package/dist/dashboard.js +474 -6
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +6 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +12 -0
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +34 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +34 -1
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +7 -3
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/services/bot-config-store.d.ts.map +1 -1
- package/dist/services/bot-config-store.js +19 -0
- package/dist/services/bot-config-store.js.map +1 -1
- package/dist/services/group-creator.d.ts +6 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +54 -5
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/insight/antigravity-span-reader.d.ts +3 -0
- package/dist/services/insight/antigravity-span-reader.d.ts.map +1 -0
- package/dist/services/insight/antigravity-span-reader.js +249 -0
- package/dist/services/insight/antigravity-span-reader.js.map +1 -0
- package/dist/services/insight/classify.d.ts +7 -0
- package/dist/services/insight/classify.d.ts.map +1 -0
- package/dist/services/insight/classify.js +46 -0
- package/dist/services/insight/classify.js.map +1 -0
- package/dist/services/insight/claude-span-reader.d.ts +3 -0
- package/dist/services/insight/claude-span-reader.d.ts.map +1 -0
- package/dist/services/insight/claude-span-reader.js +257 -0
- package/dist/services/insight/claude-span-reader.js.map +1 -0
- package/dist/services/insight/codex-span-reader.d.ts +3 -0
- package/dist/services/insight/codex-span-reader.d.ts.map +1 -0
- package/dist/services/insight/codex-span-reader.js +290 -0
- package/dist/services/insight/codex-span-reader.js.map +1 -0
- package/dist/services/insight/intent.d.ts +5 -0
- package/dist/services/insight/intent.d.ts.map +1 -0
- package/dist/services/insight/intent.js +145 -0
- package/dist/services/insight/intent.js.map +1 -0
- package/dist/services/insight/jsonl.d.ts +10 -0
- package/dist/services/insight/jsonl.d.ts.map +1 -0
- package/dist/services/insight/jsonl.js +36 -0
- package/dist/services/insight/jsonl.js.map +1 -0
- package/dist/services/insight/prompt.d.ts +3 -0
- package/dist/services/insight/prompt.d.ts.map +1 -0
- package/dist/services/insight/prompt.js +99 -0
- package/dist/services/insight/prompt.js.map +1 -0
- package/dist/services/insight/redact.d.ts +4 -0
- package/dist/services/insight/redact.d.ts.map +1 -0
- package/dist/services/insight/redact.js +67 -0
- package/dist/services/insight/redact.js.map +1 -0
- package/dist/services/insight/report.d.ts +29 -0
- package/dist/services/insight/report.d.ts.map +1 -0
- package/dist/services/insight/report.js +1126 -0
- package/dist/services/insight/report.js.map +1 -0
- package/dist/services/insight/safe-detail.d.ts +5 -0
- package/dist/services/insight/safe-detail.d.ts.map +1 -0
- package/dist/services/insight/safe-detail.js +59 -0
- package/dist/services/insight/safe-detail.js.map +1 -0
- package/dist/services/insight/scrub.d.ts +22 -0
- package/dist/services/insight/scrub.d.ts.map +1 -0
- package/dist/services/insight/scrub.js +70 -0
- package/dist/services/insight/scrub.js.map +1 -0
- package/dist/services/insight/types.d.ts +394 -0
- package/dist/services/insight/types.d.ts.map +1 -0
- package/dist/services/insight/types.js +2 -0
- package/dist/services/insight/types.js.map +1 -0
- package/dist/services/resumable-session-discovery.d.ts.map +1 -1
- package/dist/services/resumable-session-discovery.js +21 -4
- package/dist/services/resumable-session-discovery.js.map +1 -1
- package/dist/services/role-profile-store.d.ts +25 -0
- package/dist/services/role-profile-store.d.ts.map +1 -0
- package/dist/services/role-profile-store.js +171 -0
- package/dist/services/role-profile-store.js.map +1 -0
- package/dist/services/skill-registry-store.d.ts +1 -0
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +32 -0
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/transcript-resolver.d.ts +26 -0
- package/dist/services/transcript-resolver.d.ts.map +1 -0
- package/dist/services/transcript-resolver.js +111 -0
- package/dist/services/transcript-resolver.js.map +1 -0
- package/dist/services/whiteboard-store.d.ts +67 -0
- package/dist/services/whiteboard-store.d.ts.map +1 -0
- package/dist/services/whiteboard-store.js +450 -0
- package/dist/services/whiteboard-store.js.map +1 -0
- package/dist/setup/bot-config-editor.d.ts +8 -0
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +9 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +118 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/install-diagnostics.d.ts +52 -0
- package/dist/utils/install-diagnostics.d.ts.map +1 -0
- package/dist/utils/install-diagnostics.js +155 -0
- package/dist/utils/install-diagnostics.js.map +1 -0
- package/dist/utils/install-info.d.ts +4 -0
- package/dist/utils/install-info.d.ts.map +1 -1
- package/dist/utils/install-info.js +6 -0
- package/dist/utils/install-info.js.map +1 -1
- package/dist/worker.js +12 -0
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../src/core/command-handler.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAoF,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjJ,OAAO,EAA8D,KAAK,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACtI,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../src/core/command-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,9 +40,11 @@ import { ttadkConfigModelChoices } from '../setup/cli-selection.js';
|
|
|
40
40
|
import { publishAttentionPatch, announcePendingRepoSession } from './session-activity.js';
|
|
41
41
|
import { setCardMode } from '../services/card-mode-store.js';
|
|
42
42
|
import { canOperate } from '../im/lark/event-dispatcher.js';
|
|
43
|
+
import { buildSafeInsightReport } from '../services/insight/report.js';
|
|
43
44
|
import { invalidWorkingDirs } from '../utils/working-dir.js';
|
|
44
|
-
import { writeRoleFile, deleteRoleFile, resolveRole, resolveTeamRoleFile, writeTeamRoleFile, deleteTeamRoleFile } from './role-resolver.js';
|
|
45
|
+
import { writeRoleFile, deleteRoleFile, resolveRole, resolveRoleFile, resolveTeamRoleFile, writeTeamRoleFile, deleteTeamRoleFile } from './role-resolver.js';
|
|
45
46
|
import { getBotCapability, setBotCapability, clearBotCapability } from '../services/bot-profile-store.js';
|
|
47
|
+
import { deleteRoleProfileEntry, deleteRoleProfileIfEmpty, isValidRoleProfileId, listRoleProfileEntries, listRoleProfiles, MAX_ROLE_PROFILE_ENTRY_BYTES, readRoleProfileEntry, writeRoleProfileEntry, } from '../services/role-profile-store.js';
|
|
46
48
|
import { sessionKey, sessionAnchorId } from './types.js';
|
|
47
49
|
import { t, localeForBot } from '../i18n/index.js';
|
|
48
50
|
import { runSkillsImCommand } from './skills/im-command.js';
|
|
@@ -292,6 +294,139 @@ async function handleRoleCommand(args, rootId, chatId, larkAppId, senderId, deps
|
|
|
292
294
|
const trimmed = args.trim();
|
|
293
295
|
const loc = localeForBot(larkAppId);
|
|
294
296
|
const dataDir = config.session.dataDir;
|
|
297
|
+
// /role profile [...] — reusable suites of per-bot chat roles. Profiles are
|
|
298
|
+
// not a runtime role layer; applying one materializes this bot's entry into
|
|
299
|
+
// the current chat role.
|
|
300
|
+
const profileMatch = trimmed.match(/^profile\b([\s\S]*)$/);
|
|
301
|
+
if (profileMatch) {
|
|
302
|
+
const profileArgs = profileMatch[1].trim();
|
|
303
|
+
const subMatch = profileArgs.match(/^(\S+)(?:\s+([\s\S]*))?$/);
|
|
304
|
+
const sub = (subMatch?.[1] ?? '').toLowerCase();
|
|
305
|
+
const subBody = subMatch?.[2]?.trim() ?? '';
|
|
306
|
+
if (!sub || sub === 'help') {
|
|
307
|
+
await sessionReply(rootId, t('role.profile.help', undefined, loc));
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (sub === 'list' || sub === 'ls') {
|
|
311
|
+
const profiles = listRoleProfiles(dataDir);
|
|
312
|
+
if (profiles.length === 0) {
|
|
313
|
+
await sessionReply(rootId, t('role.profile.list_empty', undefined, loc));
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const lines = profiles.map(p => {
|
|
317
|
+
const hasEntry = readRoleProfileEntry(dataDir, p.profileId, larkAppId) !== null;
|
|
318
|
+
const status = hasEntry
|
|
319
|
+
? t('role.profile.current_configured', undefined, loc)
|
|
320
|
+
: t('role.profile.current_missing', undefined, loc);
|
|
321
|
+
return `• ${p.profileId} — ${p.entryCount} ${t('role.profile.entries', undefined, loc)}; ${status}`;
|
|
322
|
+
});
|
|
323
|
+
await sessionReply(rootId, `${t('role.profile.list_header', undefined, loc)}\n${lines.join('\n')}`);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const [profileId = '', ...afterProfile] = subBody.split(/\s+/);
|
|
327
|
+
if (!profileId || !isValidRoleProfileId(profileId)) {
|
|
328
|
+
await sessionReply(rootId, t('role.profile.invalid', undefined, loc));
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (sub === 'show') {
|
|
332
|
+
const showAll = afterProfile.includes('--all');
|
|
333
|
+
if (showAll) {
|
|
334
|
+
const entries = listRoleProfileEntries(dataDir, profileId);
|
|
335
|
+
if (entries.length === 0) {
|
|
336
|
+
await sessionReply(rootId, t('role.profile.no_entries', { profile: profileId }, loc));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const body = entries.map(entry => `### ${entry.larkAppId}\n${t('role.byte_count', { bytes: entry.byteLength, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}\n\`\`\`markdown\n${entry.content}\n\`\`\``).join('\n\n');
|
|
340
|
+
await sessionReply(rootId, `${t('role.profile.show_all_header', { profile: profileId }, loc)}\n${body}`);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const content = readRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
344
|
+
if (content === null) {
|
|
345
|
+
await sessionReply(rootId, t('role.profile.entry_empty', { profile: profileId }, loc));
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
await sessionReply(rootId, `${t('role.profile.entry_current', { profile: profileId }, loc)}\n\`\`\`markdown\n${content}\n\`\`\`\n${t('role.byte_count', { bytes: Buffer.byteLength(content, 'utf-8'), max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}`);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (sub === 'set') {
|
|
352
|
+
const content = subBody.slice(profileId.length).trim();
|
|
353
|
+
if (!content) {
|
|
354
|
+
await sessionReply(rootId, t('role.profile.set_empty', undefined, loc));
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
writeRoleProfileEntry(dataDir, profileId, larkAppId, content);
|
|
358
|
+
await sessionReply(rootId, t('role.profile.entry_saved', {
|
|
359
|
+
profile: profileId,
|
|
360
|
+
bytes: Math.min(Buffer.byteLength(content.trim(), 'utf-8'), MAX_ROLE_PROFILE_ENTRY_BYTES),
|
|
361
|
+
max: MAX_ROLE_PROFILE_ENTRY_BYTES,
|
|
362
|
+
}, loc));
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (sub === 'save') {
|
|
366
|
+
const { content, source } = resolveRole(larkAppId, chatId);
|
|
367
|
+
if (!content) {
|
|
368
|
+
await sessionReply(rootId, t('role.profile.save_no_effective', { profile: profileId }, loc));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
writeRoleProfileEntry(dataDir, profileId, larkAppId, content);
|
|
372
|
+
await sessionReply(rootId, t('role.profile.saved_effective', {
|
|
373
|
+
profile: profileId,
|
|
374
|
+
source,
|
|
375
|
+
bytes: Buffer.byteLength(content, 'utf-8'),
|
|
376
|
+
max: MAX_ROLE_PROFILE_ENTRY_BYTES,
|
|
377
|
+
}, loc));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (sub === 'delete' || sub === 'del' || sub === 'rm' || sub === '删除') {
|
|
381
|
+
const existed = deleteRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
382
|
+
deleteRoleProfileIfEmpty(dataDir, profileId);
|
|
383
|
+
await sessionReply(rootId, existed
|
|
384
|
+
? t('role.profile.entry_deleted', { profile: profileId }, loc)
|
|
385
|
+
: t('role.profile.entry_nothing', { profile: profileId }, loc));
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (sub === 'apply') {
|
|
389
|
+
const flags = new Set(afterProfile);
|
|
390
|
+
const preview = flags.has('--preview');
|
|
391
|
+
const force = flags.has('--force');
|
|
392
|
+
const quiet = flags.has('--quiet');
|
|
393
|
+
const content = readRoleProfileEntry(dataDir, profileId, larkAppId);
|
|
394
|
+
if (content === null) {
|
|
395
|
+
await sessionReply(rootId, t('role.profile.apply_missing', { profile: profileId }, loc));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const existing = resolveRoleFile(larkAppId, chatId);
|
|
399
|
+
const bytes = Buffer.byteLength(content, 'utf-8');
|
|
400
|
+
if (preview) {
|
|
401
|
+
const overwriteLine = existing && !force
|
|
402
|
+
? `\n${t('role.profile.apply_would_refuse', undefined, loc)}`
|
|
403
|
+
: '';
|
|
404
|
+
await sessionReply(rootId, `${t('role.profile.apply_preview', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc)}${overwriteLine}\n\`\`\`markdown\n${content}\n\`\`\``);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (existing && !force) {
|
|
408
|
+
// An empty entry would *clear* the chat role, not overwrite it — phrase
|
|
409
|
+
// the --force refusal accordingly so the intent is not misread.
|
|
410
|
+
const refusedKey = content ? 'role.profile.apply_refused' : 'role.profile.apply_refused_clear';
|
|
411
|
+
await sessionReply(rootId, t(refusedKey, { profile: profileId }, loc));
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (!content) {
|
|
415
|
+
deleteRoleFile(larkAppId, chatId);
|
|
416
|
+
if (!quiet) {
|
|
417
|
+
await sessionReply(rootId, t('role.profile.applied', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc));
|
|
418
|
+
}
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
writeRoleFile(larkAppId, chatId, content);
|
|
422
|
+
if (!quiet) {
|
|
423
|
+
await sessionReply(rootId, t('role.profile.applied', { profile: profileId, bytes, max: MAX_ROLE_PROFILE_ENTRY_BYTES }, loc));
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
await sessionReply(rootId, t('role.profile.help', undefined, loc));
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
295
430
|
// /role team [...] — manage the team-level (per-bot, cross-chat) role
|
|
296
431
|
const teamMatch = trimmed.match(/^team\b([\s\S]*)$/);
|
|
297
432
|
if (teamMatch) {
|
|
@@ -886,6 +1021,38 @@ export async function handleTermLinkCommand(rootId, larkAppId, chatId, senderOpe
|
|
|
886
1021
|
}
|
|
887
1022
|
// channel === 'ephemeral': the visible-to-you card IS the response; no extra msg.
|
|
888
1023
|
}
|
|
1024
|
+
/** Format a SafeInsightReport into a compact owner-facing summary for the
|
|
1025
|
+
* `/insight` command. Spans are never rendered here — the dashboard Insight tab
|
|
1026
|
+
* owns span detail; the chat card stays a one-glance summary (aggregate + the
|
|
1027
|
+
* severity-sorted rule suggestions, top first). */
|
|
1028
|
+
function formatInsightCard(report, loc) {
|
|
1029
|
+
if (report.status === 'unsupported_cli')
|
|
1030
|
+
return t('cmd.insight.unsupported', undefined, loc);
|
|
1031
|
+
if (report.status === 'transcript_missing')
|
|
1032
|
+
return t('cmd.insight.no_transcript', undefined, loc);
|
|
1033
|
+
if (report.status !== 'ok')
|
|
1034
|
+
return t('cmd.insight.parse_error', undefined, loc);
|
|
1035
|
+
const a = report.agg;
|
|
1036
|
+
if (a.totalSpans === 0)
|
|
1037
|
+
return t('cmd.insight.no_spans', undefined, loc);
|
|
1038
|
+
const icon = (s) => (s === 'bad' ? '🔴' : s === 'warn' ? '🟡' : 'ℹ️');
|
|
1039
|
+
const header = t('cmd.insight.header', undefined, loc);
|
|
1040
|
+
const lines = [report.meta.asOf ? `${header} · ${report.meta.asOf}` : header];
|
|
1041
|
+
lines.push(t('cmd.insight.metrics_line', {
|
|
1042
|
+
total: String(a.totalSpans),
|
|
1043
|
+
failed: String(a.failedSpans),
|
|
1044
|
+
slow: String(a.slowSpans),
|
|
1045
|
+
rw: a.readWriteRatio === null ? '—' : String(a.readWriteRatio),
|
|
1046
|
+
compactions: String(a.compactions),
|
|
1047
|
+
}, loc));
|
|
1048
|
+
lines.push('', `${t('cmd.insight.suggestions_label', undefined, loc)}:`);
|
|
1049
|
+
for (const s of report.suggestions) {
|
|
1050
|
+
lines.push(`${icon(s.severity)} ${s.title} — ${s.action}`);
|
|
1051
|
+
if (s.evidence.length)
|
|
1052
|
+
lines.push(` · ${s.evidence.join(';')}`);
|
|
1053
|
+
}
|
|
1054
|
+
return lines.join('\n');
|
|
1055
|
+
}
|
|
889
1056
|
export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
890
1057
|
const { activeSessions, getActiveCount, lastRepoScan } = deps;
|
|
891
1058
|
// Command replies carry the triggering messageId as the turnId so a shared
|
|
@@ -919,6 +1086,28 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
919
1086
|
}
|
|
920
1087
|
break;
|
|
921
1088
|
}
|
|
1089
|
+
case '/insight': {
|
|
1090
|
+
if (!ds) {
|
|
1091
|
+
await sessionReply(rootId, t('cmd.no_active_session', undefined, loc));
|
|
1092
|
+
break;
|
|
1093
|
+
}
|
|
1094
|
+
// owner-only:与 /card /term 同一 operator 门(开放模式下 owner 通过;
|
|
1095
|
+
// 仅对话授权的 grantee 不算 operator)。无权限直接不回内容。
|
|
1096
|
+
if (!canOperate(larkAppId, ds.chatId, message.senderId)) {
|
|
1097
|
+
await sessionReply(rootId, t('cmd.insight.operator_only', undefined, loc));
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1100
|
+
// 卡片只取 summary(聚合 + 规则建议);span 明细留给 dashboard Insight tab。
|
|
1101
|
+
// buildSafeInsightReport 同步、只读、自带 fail-closed 脱敏,raw 永不进结构。
|
|
1102
|
+
const report = buildSafeInsightReport({
|
|
1103
|
+
cliId: ds.session.cliId ?? 'unknown',
|
|
1104
|
+
sessionId: ds.session.sessionId,
|
|
1105
|
+
cliSessionId: ds.session.cliSessionId,
|
|
1106
|
+
cwd: ds.session.workingDir,
|
|
1107
|
+
}, { detail: 'summary' });
|
|
1108
|
+
await sessionReply(rootId, formatInsightCard(report, loc));
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
922
1111
|
case '/land': {
|
|
923
1112
|
// 把沙盒会话副本里 agent 的改动落回真实仓库。owner 审阅 diff 卡后点「应用到磁盘」。
|
|
924
1113
|
// agent 在沙盒里无感(以为改的就是真文件),所以只能由 owner 在此手动触发。
|
|
@@ -1062,8 +1251,9 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1062
1251
|
// dropped: wrap them now (full prompt-building context lives here)
|
|
1063
1252
|
// and stash for delivery right after the raw input on prompt_ready.
|
|
1064
1253
|
if (hasBufferedInput) {
|
|
1065
|
-
const { buildNewTopicPrompt, getAvailableBots } = await import('./session-manager.js');
|
|
1066
|
-
|
|
1254
|
+
const { buildNewTopicPrompt, ensureSessionWhiteboard, getAvailableBots } = await import('./session-manager.js');
|
|
1255
|
+
ensureSessionWhiteboard(ds);
|
|
1256
|
+
const followUpPrompt = buildNewTopicPrompt(pendingPrompt, ds.session.sessionId, botCfg.cliId, botCfg.cliPathOverride, ds.pendingAttachments, ds.pendingMentions, await getAvailableBots(ds.larkAppId, ds.chatId), ds.pendingFollowUps, { name: selfBot.botName, openId: selfBot.botOpenId }, loc, ds.pendingSender, { larkAppId, chatId: ds.chatId, whiteboardId: ds.session.whiteboardId });
|
|
1067
1257
|
ds.pendingFollowUpInput = {
|
|
1068
1258
|
userPrompt: pendingPrompt || (ds.pendingFollowUps?.join('\n\n') ?? ''),
|
|
1069
1259
|
cliInput: followUpPrompt,
|
|
@@ -1073,8 +1263,9 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1073
1263
|
forkWorker(ds, '', false);
|
|
1074
1264
|
}
|
|
1075
1265
|
else if (hasBufferedInput) {
|
|
1076
|
-
const { buildNewTopicPrompt, getAvailableBots } = await import('./session-manager.js');
|
|
1077
|
-
|
|
1266
|
+
const { buildNewTopicPrompt, ensureSessionWhiteboard, getAvailableBots } = await import('./session-manager.js');
|
|
1267
|
+
ensureSessionWhiteboard(ds);
|
|
1268
|
+
const prompt = buildNewTopicPrompt(pendingPrompt, ds.session.sessionId, botCfg.cliId, botCfg.cliPathOverride, ds.pendingAttachments, ds.pendingMentions, await getAvailableBots(ds.larkAppId, ds.chatId), ds.pendingFollowUps, { name: selfBot.botName, openId: selfBot.botOpenId }, loc, ds.pendingSender, { larkAppId, chatId: ds.chatId, whiteboardId: ds.session.whiteboardId });
|
|
1078
1269
|
// Last-line defence: prompt prep awaited above — if anything
|
|
1079
1270
|
// replaced OR closed the session in that window (`/close` deletes
|
|
1080
1271
|
// the active-map entry without touching sessionId), forking now
|
|
@@ -1811,6 +2002,16 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1811
2002
|
if (m.name)
|
|
1812
2003
|
rawArgs = rawArgs.split(`@${m.name}`).join(' ');
|
|
1813
2004
|
}
|
|
2005
|
+
let roleProfileId;
|
|
2006
|
+
const roleProfileArg = rawArgs.match(/(?:^|\s)--role-profile(?:=|\s+)(\S+)/);
|
|
2007
|
+
if (roleProfileArg) {
|
|
2008
|
+
if (!isValidRoleProfileId(roleProfileArg[1])) {
|
|
2009
|
+
await sessionReply(rootId, t('role.profile.invalid', undefined, loc));
|
|
2010
|
+
break;
|
|
2011
|
+
}
|
|
2012
|
+
roleProfileId = roleProfileArg[1];
|
|
2013
|
+
rawArgs = rawArgs.replace(roleProfileArg[0], ' ');
|
|
2014
|
+
}
|
|
1814
2015
|
const firstLine = rawArgs.split(/\r?\n/).map(s => s.trim()).find(Boolean) ?? '';
|
|
1815
2016
|
const MAX_NAME = 50; // Lark group names cap around 60; leave headroom for '…'
|
|
1816
2017
|
let groupName;
|
|
@@ -1834,6 +2035,7 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1834
2035
|
userOpenIds: [senderOpenId],
|
|
1835
2036
|
transferOwnerTo: senderOpenId,
|
|
1836
2037
|
notifyOwnerOpenId: senderOpenId,
|
|
2038
|
+
roleProfileId,
|
|
1837
2039
|
});
|
|
1838
2040
|
// Prefer the shareable join link (others can click to *join*); fall
|
|
1839
2041
|
// back to the member-only applink URL when Lark's link API failed.
|
|
@@ -1866,6 +2068,14 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1866
2068
|
if (result.invalidBotIds.length > 0) {
|
|
1867
2069
|
hints.push(t('cmd.group.warn_bots_rejected', { bots: result.invalidBotIds.map(nameOf).join('、') }, loc));
|
|
1868
2070
|
}
|
|
2071
|
+
if (roleProfileId) {
|
|
2072
|
+
if (result.roleProfileBootstrapError) {
|
|
2073
|
+
hints.push(t('cmd.group.role_profile_bootstrap_failed', { profile: roleProfileId, reason: result.roleProfileBootstrapError ?? 'unknown' }, loc));
|
|
2074
|
+
}
|
|
2075
|
+
else {
|
|
2076
|
+
hints.push(t('cmd.group.role_profile_bootstrap_sent', { profile: roleProfileId }, loc));
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
1869
2079
|
const hintsText = hints.length > 0 ? '\n' + hints.join('\n') : '';
|
|
1870
2080
|
await sessionReply(rootId, t('cmd.group.created', { name: groupName, link, hints: hintsText }, loc));
|
|
1871
2081
|
logger.info(`[${logTag}] /group created chat=${result.chatId} name="${groupName}" bots=[${larkAppIdsForGroup.join(',')}] invitee=${senderOpenId}`);
|