@bolloon/bolloon-agent 0.3.35 → 0.3.37

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.
Files changed (48) hide show
  1. package/dist/agents/pi-sdk-tools.js +2 -1
  2. package/dist/cli/ink-app.js +44 -1
  3. package/dist/cli/mention-data.js +23 -0
  4. package/dist/cli-entry.js +113 -6
  5. package/dist/electron/config.js +9 -14
  6. package/dist/electron/dialogs.js +16 -53
  7. package/dist/electron/first-run.js +24 -65
  8. package/dist/electron/ipc.js +10 -14
  9. package/dist/electron/logger.js +7 -44
  10. package/dist/electron/main.js +42 -45
  11. package/dist/electron/menu.js +13 -18
  12. package/dist/electron/paths.js +12 -54
  13. package/dist/electron/server.js +18 -57
  14. package/dist/electron/tray.js +15 -53
  15. package/dist/electron/window.js +22 -61
  16. package/dist/electron-build/electron/config.js +21 -0
  17. package/dist/electron-build/electron/config.js.map +1 -0
  18. package/dist/electron-build/electron/dialogs.js +108 -0
  19. package/dist/electron-build/electron/dialogs.js.map +1 -0
  20. package/dist/electron-build/electron/first-run.js +170 -0
  21. package/dist/electron-build/electron/first-run.js.map +1 -0
  22. package/dist/electron-build/electron/ipc.js +20 -0
  23. package/dist/electron-build/electron/ipc.js.map +1 -0
  24. package/dist/electron-build/electron/logger.js +114 -0
  25. package/dist/electron-build/electron/logger.js.map +1 -0
  26. package/dist/electron-build/electron/main.js +79 -0
  27. package/dist/electron-build/electron/main.js.map +1 -0
  28. package/dist/electron-build/electron/menu.js +145 -0
  29. package/dist/electron-build/electron/menu.js.map +1 -0
  30. package/dist/electron-build/electron/paths.js +75 -0
  31. package/dist/electron-build/electron/paths.js.map +1 -0
  32. package/dist/electron-build/electron/server.js +119 -0
  33. package/dist/electron-build/electron/server.js.map +1 -0
  34. package/dist/electron-build/electron/tray.js +111 -0
  35. package/dist/electron-build/electron/tray.js.map +1 -0
  36. package/dist/electron-build/electron/window.js +111 -0
  37. package/dist/electron-build/electron/window.js.map +1 -0
  38. package/dist/electron-build/electron-preload.js +32 -0
  39. package/dist/electron-build/electron-preload.js.map +1 -0
  40. package/dist/electron-build/electron.js +8 -0
  41. package/dist/electron-build/electron.js.map +1 -0
  42. package/dist/electron-build/utils/auto-update.js +598 -0
  43. package/dist/electron-build/utils/auto-update.js.map +1 -0
  44. package/dist/electron-preload.js +16 -19
  45. package/dist/electron.js +1 -4
  46. package/dist/index.js +426 -0
  47. package/dist/utils/auto-update.js +12 -51
  48. package/package.json +5 -4
package/dist/electron.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
1
  /**
4
2
  * Electron 入口 shim — 真正逻辑在 src/electron/main.ts
5
3
  * (保留 src/electron.ts 平铺入口, 不动 package.json 的 dist/electron.js 解析)
6
4
  */
7
- require("./electron/main");
8
- //# sourceMappingURL=electron.js.map
5
+ import './electron/main';
package/dist/index.js CHANGED
@@ -581,12 +581,438 @@ async function processInput(input, comm) {
581
581
  appendLine(`${C_WARN}[队列 ${pendingQueue.length}]${RESET} 已入队, 执行完当前后自动运行`);
582
582
  return;
583
583
  }
584
+ // ==================== 2026-08-06: 系统命令组 (/model /now /ipfs /memory ...) ====================
585
+ const cmd = trimmed.toLowerCase();
586
+ // /model /login — 模型供应商选择器 (ink 交互渲染, 复用 MentionPopup)
587
+ if (cmd === '/model' || cmd === '/login') {
588
+ try {
589
+ const { llmConfigStore, PROVIDER_INFO } = await import('./llm/config-store.js');
590
+ await llmConfigStore.initialize();
591
+ const config = await llmConfigStore.getConfig();
592
+ const items = Object.entries(config.providers).map(([name, p]) => ({
593
+ kind: 'command',
594
+ label: name,
595
+ hint: `${String(PROVIDER_INFO[name]?.name || '').padEnd(14)} ${p.apiKey ? '🔑' : p.requiresApiKey ? '⚠ 无key' : ''} ${p.model || ''}`,
596
+ insert: name,
597
+ }));
598
+ globalThis.__inkOpenPicker?.(items, '选择模型供应商 (↑↓ 选择 · Enter 确认 · Esc 取消)', async (it) => {
599
+ try {
600
+ await llmConfigStore.setActiveProvider(it.label);
601
+ const active = await llmConfigStore.getActiveProvider();
602
+ appendLine(`${C_OK}✓ 已切换到 ${it.label} (${String(PROVIDER_INFO[it.label]?.name || '')})${RESET}`);
603
+ appendLine(`${C_DIM} 当前模型: ${config.providers[it.label]?.model || '默认'}${RESET}`);
604
+ }
605
+ catch (e) {
606
+ appendLine(`${C_ERROR}✗ 切换失败: ${String(e.message || e).slice(0, 150)}${RESET}`);
607
+ }
608
+ });
609
+ }
610
+ catch (e) {
611
+ appendLine(`${C_ERROR}/model 失败: ${String(e.message || e).slice(0, 150)}${RESET}`);
612
+ }
613
+ return;
614
+ }
615
+ // /logout — 显示当前供应商 (减法: 登出 = 查看当前, 切换走 /model)
616
+ if (cmd === '/logout') {
617
+ try {
618
+ const { llmConfigStore, PROVIDER_INFO } = await import('./llm/config-store.js');
619
+ await llmConfigStore.initialize();
620
+ const active = await llmConfigStore.getActiveProvider();
621
+ const cfg = await llmConfigStore.getActiveProviderConfig();
622
+ appendLine(`${C_DIM}当前供应商:${RESET} ${C_ACCENT}${active}${RESET} (${String(PROVIDER_INFO[active]?.name || '')})`);
623
+ appendLine(`${C_DIM} 模型: ${cfg?.model || '默认'}${RESET}`);
624
+ appendLine(`${C_DIM} 切换: /model 打开选择器${RESET}`);
625
+ }
626
+ catch { /* 静默 */ }
627
+ return;
628
+ }
629
+ // /now — 当前状态总览
630
+ if (cmd === '/now') {
631
+ try {
632
+ const cm = require('./bootstrap/context-manager.js').getContextManager();
633
+ const usage = cm.getUsage();
634
+ appendLine(`${C_ACCENT}● 当前状态${RESET}`);
635
+ appendLine(` ${C_DIM}智能体:${RESET} ${cliAgentName} ${cliActiveChannelId ? `(${C_DIM}ch:${cliActiveChannelId.slice(0, 12)}${RESET})` : ''}`);
636
+ appendLine(` ${C_DIM}运行:${RESET} ${fmtDuration(Date.now() - cliStartTime)}`);
637
+ appendLine(` ${C_DIM}上下文:${RESET} ${(usage.usedTokens / 1000).toFixed(0)}k / ${(usage.maxTokens / 1000).toFixed(0)}k tokens (${Math.round(usage.pct * 100)}%)${usage.stage === 'warning' ? ` ${C_WARN}⚠ 即将压缩${RESET}` : ''}`);
638
+ const a = await getAgent();
639
+ appendLine(` ${C_DIM}消息:${RESET} ${a.messageHistory?.length ?? 0} 条`);
640
+ }
641
+ catch { /* 静默 */ }
642
+ return;
643
+ }
644
+ // /tools — 可用工具列表
645
+ if (cmd === '/tools') {
646
+ try {
647
+ const a = await getAgent();
648
+ const defs = (a.getToolDefinitions?.() ?? []);
649
+ const names = Array.isArray(defs) ? defs.map((d) => d.name || d.function?.name).filter(Boolean) : Object.keys(defs || {});
650
+ appendLine(`${C_ACCENT}可用工具 (${names.length}):${RESET}`);
651
+ for (const n of names.slice(0, 40))
652
+ appendLine(` ${C_DIM}·${RESET} ${n}`);
653
+ if (names.length > 40)
654
+ appendLine(` ${C_DIM}... 共 ${names.length} 个${RESET}`);
655
+ }
656
+ catch { /* 静默 */ }
657
+ return;
658
+ }
659
+ // /session — 当前会话信息
660
+ if (cmd === '/session') {
661
+ try {
662
+ const a = await getAgent();
663
+ const h = a.messageHistory ?? [];
664
+ appendLine(`${C_ACCENT}会话:${RESET}`);
665
+ appendLine(` ${C_DIM}channel:${RESET} ${a.currentChannelId || '—'}`);
666
+ appendLine(` ${C_DIM}agent:${RESET} ${a.currentAgentId || '—'}`);
667
+ appendLine(` ${C_DIM}消息:${RESET} ${h.length} 条 (${h.length > 15 ? `${h.length - 15} 条已压缩` : '窗口内'})`);
668
+ }
669
+ catch { /* 静默 */ }
670
+ return;
671
+ }
672
+ // /memory — 记忆摘要 (memory-compressor 落盘文件)
673
+ if (cmd === '/memory') {
674
+ try {
675
+ const { getMemoryDir } = await import('./bootstrap/memory-compressor.js');
676
+ const { readdir, readFile } = await import('fs/promises');
677
+ const { join } = await import('path');
678
+ const dir = getMemoryDir(cliAgentName === 'bolloon' ? 'agent' : cliAgentName);
679
+ const files = (await readdir(join(dir, 'sessions')).catch(() => [])).filter((f) => f.endsWith('.summary.md'));
680
+ appendLine(`${C_ACCENT}记忆摘要 (${files.length} 个 session):${RESET}`);
681
+ for (const f of files.slice(-5)) {
682
+ try {
683
+ const raw = await readFile(join(dir, 'sessions', f), 'utf-8');
684
+ const tail = raw.trim().split('\n').slice(-6).join(' ').slice(0, 180);
685
+ appendLine(` ${C_DIM}·${RESET} ${f.replace('.summary.md', '').slice(-30)}`);
686
+ appendLine(` ${C_DIM}${tail}${RESET}`);
687
+ }
688
+ catch { /* 跳过 */ }
689
+ }
690
+ }
691
+ catch { /* 静默 */ }
692
+ return;
693
+ }
694
+ // /resume — 恢复: 最近记忆摘要 + 进行中计划
695
+ if (cmd === '/resume' || cmd.startsWith('/resume ')) {
696
+ try {
697
+ const { getMemoryDir, getSessionSummaryPath } = await import('./bootstrap/memory-compressor.js');
698
+ const { readFile, readdir } = await import('fs/promises');
699
+ const { join } = await import('path');
700
+ const dir = getMemoryDir(cliAgentName === 'bolloon' ? 'agent' : cliAgentName);
701
+ const files = (await readdir(join(dir, 'sessions')).catch(() => [])).filter((f) => f.endsWith('.summary.md'));
702
+ appendLine(`${C_ACCENT}↻ 恢复上下文:${RESET}`);
703
+ if (files.length > 0) {
704
+ const f = files[files.length - 1];
705
+ const raw = await readFile(join(dir, 'sessions', f), 'utf-8');
706
+ const block = raw.trim().split('\n').slice(-12).join('\n').slice(-1200);
707
+ appendLine(` ${C_DIM}最近记忆 (${f.slice(0, 24)}...):${RESET}`);
708
+ for (const line of block.split('\n').slice(-8))
709
+ appendLine(` ${C_DIM}${line.slice(0, 100)}${RESET}`);
710
+ }
711
+ else {
712
+ appendLine(` ${C_DIM}暂无记忆摘要${RESET}`);
713
+ }
714
+ const { listActivePlans } = await import('./agents/plan-store.js');
715
+ const plans = await listActivePlans();
716
+ if (plans.length > 0) {
717
+ appendLine(` ${C_DIM}进行中计划 (${plans.length}):${RESET}`);
718
+ for (const p of plans.slice(0, 3))
719
+ appendLine(` ${C_ACCENT}·${RESET} ${p.goal || p.planId} ${C_DIM}${p.status || ''}${RESET}`);
720
+ }
721
+ }
722
+ catch { /* 静默 */ }
723
+ return;
724
+ }
725
+ // /goal — 进行中的目标/计划
726
+ if (cmd === '/goal') {
727
+ try {
728
+ const { listActivePlans, planToContext } = await import('./agents/plan-store.js');
729
+ const plans = await listActivePlans();
730
+ appendLine(`${C_ACCENT}目标 (${plans.length} 个进行中):${RESET}`);
731
+ if (plans.length === 0) {
732
+ appendLine(` ${C_DIM}无进行中计划 — 可用 /plan 创建${RESET}`);
733
+ }
734
+ for (const p of plans.slice(0, 5)) {
735
+ appendLine(` ${C_ACCENT}●${RESET} ${p.goal || p.planId} ${C_DIM}[${p.status || 'active'}]${RESET}`);
736
+ const steps = Array.isArray(p.steps) ? p.steps : [];
737
+ const done = steps.filter((s) => s.done || s.status === 'done').length;
738
+ if (steps.length > 0)
739
+ appendLine(` ${C_DIM}${done}/${steps.length} 步完成${RESET}`);
740
+ }
741
+ }
742
+ catch { /* 静默 */ }
743
+ return;
744
+ }
745
+ // /skill — 技能候选 (skill-writer 落盘)
746
+ if (cmd === '/skill') {
747
+ try {
748
+ const { listSkillCandidates } = await import('./agents/skill-writer.js');
749
+ const cands = await listSkillCandidates();
750
+ appendLine(`${C_ACCENT}技能候选 (${cands.length}):${RESET}`);
751
+ if (cands.length === 0) {
752
+ appendLine(` ${C_DIM}无候选 — 连续成功工具调用 ≥2 自动生成${RESET}`);
753
+ }
754
+ for (const c of cands.slice(0, 8)) {
755
+ appendLine(` ${C_DIM}·${RESET} ${c.name || '?'} ${C_DIM}(${c.source || ''})${RESET}`);
756
+ }
757
+ }
758
+ catch { /* 静默 */ }
759
+ return;
760
+ }
761
+ // /mcp — MCP 插件/工具列表
762
+ if (cmd === '/mcp') {
763
+ try {
764
+ const { readFile } = await import('fs/promises');
765
+ const { join } = await import('path');
766
+ let servers = {};
767
+ try {
768
+ servers = JSON.parse(await readFile(join(process.env.HOME || '/tmp', '.mcp.json'), 'utf-8')).mcpServers || {};
769
+ }
770
+ catch { /* 无 */ }
771
+ appendLine(`${C_ACCENT}MCP 服务器 (${Object.keys(servers).length}):${RESET}`);
772
+ if (Object.keys(servers).length === 0) {
773
+ appendLine(` ${C_DIM}无 (~/.mcp.json 未配置)${RESET}`);
774
+ }
775
+ for (const [name, s] of Object.entries(servers)) {
776
+ const cmdStr = s?.command || '';
777
+ appendLine(` ${C_DIM}·${RESET} ${name} ${C_DIM}(${String(cmdStr).slice(0, 40)})${RESET}`);
778
+ }
779
+ }
780
+ catch { /* 静默 */ }
781
+ return;
782
+ }
783
+ // /agent — 当前智能体身份
784
+ if (cmd === '/agent') {
785
+ try {
786
+ const a = await getAgent();
787
+ appendLine(`${C_ACCENT}智能体:${RESET}`);
788
+ appendLine(` ${C_DIM}名称:${RESET} ${cliAgentName}`);
789
+ appendLine(` ${C_DIM}agentId:${RESET} ${a.currentAgentId || '—'}`);
790
+ appendLine(` ${C_DIM}channel:${RESET} ${cliActiveChannelId || '—'}`);
791
+ }
792
+ catch { /* 静默 */ }
793
+ return;
794
+ }
795
+ // /did — DID 身份
796
+ if (cmd === '/did') {
797
+ try {
798
+ const { loadOrCreateAgentIdentity } = await import('./agents/agent-identity.js');
799
+ const identity = loadOrCreateAgentIdentity(cliAgentName === 'bolloon' ? 'default-agent' : cliAgentName);
800
+ appendLine(`${C_ACCENT}DID 身份:${RESET}`);
801
+ appendLine(` ${C_DIM}did:${RESET} ${identity.did}`);
802
+ appendLine(` ${C_DIM}publicKey:${RESET} ${identity.publicKey?.slice(0, 32) || '—'}...`);
803
+ appendLine(` ${C_DIM}发布:${RESET} 可用 publish_did 工具发布到 IPFS+IPNS`);
804
+ }
805
+ catch (e) {
806
+ appendLine(`${C_ERROR}/did 失败: ${String(e.message || e).slice(0, 120)}${RESET}`);
807
+ }
808
+ return;
809
+ }
810
+ // /ipfs — Kubo 状态
811
+ if (cmd === '/ipfs') {
812
+ try {
813
+ const { kuboApi } = await import('./agents/pi-sdk-tools.js');
814
+ const id = await kuboApi('/api/v0/id');
815
+ const peers = await kuboApi('/api/v0/swarm/peers');
816
+ const pins = await kuboApi('/api/v0/pin/ls?type=recursive');
817
+ appendLine(`${C_ACCENT}IPFS (Kubo):${RESET}`);
818
+ appendLine(` ${C_DIM}节点:${RESET} ${String(id.ID || '').slice(0, 24)}...`);
819
+ appendLine(` ${C_DIM}版本:${RESET} ${id.AgentVersion || ''}`);
820
+ appendLine(` ${C_DIM}peers:${RESET} ${peers?.Peers?.length ?? 0}`);
821
+ appendLine(` ${C_DIM}pins:${RESET} ${pins?.Keys ? Object.keys(pins.Keys).length : 0}`);
822
+ }
823
+ catch (e) {
824
+ appendLine(`${C_ERROR}/ipfs 失败: ${String(e.message || e).slice(0, 120)}${RESET}`);
825
+ }
826
+ return;
827
+ }
828
+ // /ipns — IPNS 状态 (keys + self 解析)
829
+ if (cmd === '/ipns') {
830
+ try {
831
+ const { kuboApi } = await import('./agents/pi-sdk-tools.js');
832
+ const keys = await kuboApi('/api/v0/key/list');
833
+ const keyList = keys?.Keys || [];
834
+ appendLine(`${C_ACCENT}IPNS keys (${keyList.length}):${RESET}`);
835
+ for (const k of keyList.slice(0, 10)) {
836
+ appendLine(` ${C_DIM}·${RESET} ${k.Name} ${C_DIM}${String(k.Id).slice(0, 20)}...${RESET}`);
837
+ }
838
+ try {
839
+ const r = await kuboApi('/api/v0/name/resolve?arg=ui-deploy&recursive=true&nocache=true', undefined, 15000);
840
+ appendLine(` ${C_DIM}ui-deploy →${RESET} ${r.Path || ''}`);
841
+ }
842
+ catch { /* 无 ui-deploy */ }
843
+ }
844
+ catch (e) {
845
+ appendLine(`${C_ERROR}/ipns 失败: ${String(e.message || e).slice(0, 120)}${RESET}`);
846
+ }
847
+ return;
848
+ }
849
+ // /wallet — 钱包状态
850
+ if (cmd === '/wallet') {
851
+ try {
852
+ const { readFile } = await import('fs/promises');
853
+ const { join } = await import('path');
854
+ let wallets = [];
855
+ try {
856
+ wallets = JSON.parse(await readFile(join(process.env.HOME || '/tmp', '.bolloon', 'wallets.json'), 'utf-8'));
857
+ }
858
+ catch { /* 无 */ }
859
+ appendLine(`${C_ACCENT}钱包 (${Array.isArray(wallets) ? wallets.length : 0}):${RESET}`);
860
+ if (!Array.isArray(wallets) || wallets.length === 0) {
861
+ appendLine(` ${C_DIM}无 — 可用 wallet_create 工具创建 EVM 钱包${RESET}`);
862
+ }
863
+ for (const w of (Array.isArray(wallets) ? wallets : []).slice(0, 5)) {
864
+ appendLine(` ${C_DIM}·${RESET} ${w.name || w.address?.slice(0, 12) || '?'} ${C_DIM}${String(w.address || '').slice(0, 16)}...${RESET}`);
865
+ }
866
+ }
867
+ catch { /* 静默 */ }
868
+ return;
869
+ }
870
+ // /email — 邮件配置状态
871
+ if (cmd === '/email') {
872
+ try {
873
+ const { readFile } = await import('fs/promises');
874
+ const { join } = await import('path');
875
+ let cfg = null;
876
+ try {
877
+ cfg = JSON.parse(await readFile(join(process.env.HOME || '/tmp', '.bolloon', 'smtp.json'), 'utf-8'));
878
+ }
879
+ catch { /* 无 */ }
880
+ appendLine(`${C_ACCENT}邮件 (SMTP):${RESET}`);
881
+ if (!cfg) {
882
+ appendLine(` ${C_DIM}未配置 smtp.json — 发件人: 天墟星剑 <2844169590@qq.com>${RESET}`);
883
+ }
884
+ else {
885
+ appendLine(` ${C_DIM}host:${RESET} ${cfg.host || 'smtp.qq.com'}`);
886
+ appendLine(` ${C_DIM}发件人:${RESET} ${cfg.from || cfg.user || '—'}`);
887
+ }
888
+ }
889
+ catch { /* 静默 */ }
890
+ return;
891
+ }
892
+ // /loop — 当前循环状态 (消息数 + token 估算)
893
+ if (cmd === '/loop') {
894
+ try {
895
+ const a = await getAgent();
896
+ const h = a.messageHistory ?? [];
897
+ let tokens = 0;
898
+ try {
899
+ const { estimateTokens } = require('./context-compaction/index.js');
900
+ tokens = estimateTokens(h);
901
+ }
902
+ catch {
903
+ tokens = Math.round(JSON.stringify(h).length / 4);
904
+ }
905
+ appendLine(`${C_ACCENT}Loop 状态:${RESET}`);
906
+ appendLine(` ${C_DIM}消息:${RESET} ${h.length} 条 (窗口 15, ${Math.max(0, h.length - 15)} 条早期压缩)`);
907
+ appendLine(` ${C_DIM}token:${RESET} ${(tokens / 1000).toFixed(1)}k / 1M (${((tokens / 1_000_000) * 100).toFixed(2)}%)`);
908
+ }
909
+ catch { /* 静默 */ }
910
+ return;
911
+ }
912
+ // /judgement — 判断力列表
913
+ if (cmd === '/judgement' || cmd === '/judgments') {
914
+ try {
915
+ const { loadAllJudgments } = await import('./pi-ecosystem-judgment/human-value-store.js');
916
+ const all = await loadAllJudgments().catch(() => []);
917
+ appendLine(`${C_ACCENT}判断力 (${all.length} 条):${RESET}`);
918
+ for (const j of all.slice(0, 8)) {
919
+ appendLine(` ${C_DIM}·${RESET} ${String(j.decision || '').slice(0, 70)}`);
920
+ }
921
+ }
922
+ catch { /* 静默 */ }
923
+ return;
924
+ }
925
+ // /insight — Context OS 08-Insights 资产
926
+ if (cmd === '/insight') {
927
+ try {
928
+ const { readContextAssets, readAssetBody } = await import('./bootstrap/context-os.js');
929
+ const listings = await readContextAssets('08-Insights');
930
+ const files = listings[0]?.files || [];
931
+ appendLine(`${C_ACCENT}洞察 (${files.length} 篇):${RESET}`);
932
+ if (files.length === 0) {
933
+ appendLine(` ${C_DIM}无 — 价值点路由自动沉淀 insight 到 08-Insights${RESET}`);
934
+ }
935
+ for (const f of files.slice(0, 6)) {
936
+ const body = await readAssetBody('08-Insights', f.file).catch(() => null);
937
+ const firstLine = (body?.body || '').split('\n').filter(l => l.trim() && !l.startsWith('---')).slice(0, 2).join(' ').slice(0, 90);
938
+ appendLine(` ${C_ACCENT}·${RESET} ${f.title} ${C_DIM}${firstLine ? '— ' + firstLine : ''}${RESET}`);
939
+ }
940
+ }
941
+ catch { /* 静默 */ }
942
+ return;
943
+ }
944
+ // /wiki — wiki 状态
945
+ if (cmd === '/wiki') {
946
+ try {
947
+ const { readFile } = await import('fs/promises');
948
+ const { join } = await import('path');
949
+ const root = process.cwd();
950
+ const statusPath = join(root, 'docs', 'wiki', 'current-status.md');
951
+ const raw = await readFile(statusPath, 'utf-8');
952
+ const title = raw.match(/^title:\s*(.+)$/m)?.[1] || 'current-status';
953
+ const confirmed = raw.match(/^last_confirmed:\s*(.+)$/m)?.[1] || '?';
954
+ const supported = (raw.match(/\|\|+/g) || []).length;
955
+ appendLine(`${C_ACCENT}Wiki:${RESET} ${title}`);
956
+ appendLine(` ${C_DIM}last_confirmed:${RESET} ${confirmed}`);
957
+ appendLine(` ${C_DIM}已支持条目:${RESET} ${supported}`);
958
+ appendLine(` ${C_DIM}位置:${RESET} docs/wiki/ (wiki-first 范式)`);
959
+ }
960
+ catch { /* 静默 */ }
961
+ return;
962
+ }
963
+ // /dream — 随机灵感 (从 Insights + Knowledge 资产随机取一条)
964
+ if (cmd === '/dream') {
965
+ try {
966
+ const { readContextAssets, readAssetBody } = await import('./bootstrap/context-os.js');
967
+ const layers = ['08-Insights', '07-Knowledge', '12-Analysis'];
968
+ const pool = [];
969
+ for (const layer of layers) {
970
+ const listings = await readContextAssets(layer);
971
+ for (const f of (listings[0]?.files || []).slice(0, 5)) {
972
+ const body = await readAssetBody(layer, f.file).catch(() => null);
973
+ const lines = (body?.body || '').split('\n').filter(l => l.trim() && !l.startsWith('---') && !l.startsWith('#') && !l.startsWith('>') && !l.startsWith('未来'));
974
+ if (lines[0])
975
+ pool.push(lines[0].trim().slice(0, 100));
976
+ }
977
+ }
978
+ if (pool.length === 0) {
979
+ appendLine(`${C_DIM}🌙 梦境空空 — 多对话让记忆沉淀出洞察后, /dream 就有素材了${RESET}`);
980
+ }
981
+ else {
982
+ const pick = pool[Math.floor(Math.random() * pool.length)];
983
+ appendLine(`${C_DIM}🌙 ${pick}${RESET}`);
984
+ }
985
+ }
986
+ catch { /* 静默 */ }
987
+ return;
988
+ }
584
989
  if (trimmed.toLowerCase() === '/help' || trimmed === 'help') {
585
990
  appendLine(`${C_DIM}命令:${RESET}`);
586
991
  appendLine(` ${C_ACCENT}!<cmd>${RESET} 执行终端命令 ${C_DIM}如 !ls -la${RESET}`);
587
992
  appendLine(` ${C_ACCENT}/queue${RESET} 切换队列模式 ${C_DIM}输入排队, 当前结束后自动执行${RESET}`);
588
993
  appendLine(` ${C_ACCENT}/dequeue${RESET} 出队一条`);
589
994
  appendLine(` ${C_ACCENT}/channel [名字|id|序号]${RESET} 切换当前智能体 ${C_DIM}无参列出所有; 支持名字/ID/序号三种解析${RESET}`);
995
+ appendLine(` ${C_ACCENT}/model${RESET} / ${C_ACCENT}/login${RESET} 模型供应商选择器 ${C_DIM}↑↓ 选择 · Enter 确认 · Esc 取消${RESET}`);
996
+ appendLine(` ${C_ACCENT}/logout${RESET} 查看当前供应商`);
997
+ appendLine(` ${C_ACCENT}/now${RESET} 当前状态总览 ${C_DIM}智能体/运行时间/上下文 tokens/消息数${RESET}`);
998
+ appendLine(` ${C_ACCENT}/session${RESET} 当前会话信息 ${C_DIM}channel/agent/消息窗口${RESET}`);
999
+ appendLine(` ${C_ACCENT}/loop${RESET} 循环状态 ${C_DIM}消息数 + token 估算${RESET}`);
1000
+ appendLine(` ${C_ACCENT}/memory${RESET} 记忆摘要 ${C_DIM}memory-compressor 落盘摘要${RESET}`);
1001
+ appendLine(` ${C_ACCENT}/resume${RESET} 恢复上下文 ${C_DIM}最近记忆 + 进行中计划${RESET}`);
1002
+ appendLine(` ${C_ACCENT}/goal${RESET} 进行中目标 ${C_DIM}plan-store active plans${RESET}`);
1003
+ appendLine(` ${C_ACCENT}/tools${RESET} 可用工具列表`);
1004
+ appendLine(` ${C_ACCENT}/skill${RESET} 技能候选 ${C_DIM}skill-writer 沉淀候选${RESET}`);
1005
+ appendLine(` ${C_ACCENT}/mcp${RESET} MCP 服务器列表`);
1006
+ appendLine(` ${C_ACCENT}/agent${RESET} 当前智能体身份`);
1007
+ appendLine(` ${C_ACCENT}/did${RESET} DID 身份`);
1008
+ appendLine(` ${C_ACCENT}/ipfs${RESET} Kubo 状态 ${C_DIM}节点/peers/pins${RESET}`);
1009
+ appendLine(` ${C_ACCENT}/ipns${RESET} IPNS keys + resolve`);
1010
+ appendLine(` ${C_ACCENT}/wallet${RESET} 钱包状态`);
1011
+ appendLine(` ${C_ACCENT}/email${RESET} 邮件配置`);
1012
+ appendLine(` ${C_ACCENT}/judgement${RESET} 判断力列表`);
1013
+ appendLine(` ${C_ACCENT}/insight${RESET} Context OS 洞察 (08-Insights)`);
1014
+ appendLine(` ${C_ACCENT}/wiki${RESET} wiki 状态`);
1015
+ appendLine(` ${C_ACCENT}/dream${RESET} 随机灵感`);
590
1016
  appendLine(` ${C_ACCENT}@名字${RESET} @ 命中智能体 ${C_DIM}弹出窗选择后发送给智能体${RESET}`);
591
1017
  appendLine(` ${C_ACCENT}/名字${RESET} / 命中命令/技能/插件 ${C_DIM}输入 / 自动弹出${RESET}`);
592
1018
  appendLine(` ${C_ACCENT}#路径${RESET} # 命中文件 ${C_DIM}输入 # 自动弹出文件列表${RESET}`);
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * npm 自动更新检查器
4
3
  *
@@ -14,48 +13,11 @@
14
13
  * 开发态下若 cwd 的 package.json 就是本包则回退到 cwd,不受任意工作目录影响。
15
14
  * - 检查频率受节流缓存约束(默认 24h 一次),不会每次启动都打 npm。
16
15
  */
17
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
- if (k2 === undefined) k2 = k;
19
- var desc = Object.getOwnPropertyDescriptor(m, k);
20
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
- desc = { enumerable: true, get: function() { return m[k]; } };
22
- }
23
- Object.defineProperty(o, k2, desc);
24
- }) : (function(o, m, k, k2) {
25
- if (k2 === undefined) k2 = k;
26
- o[k2] = m[k];
27
- }));
28
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
- Object.defineProperty(o, "default", { enumerable: true, value: v });
30
- }) : function(o, v) {
31
- o["default"] = v;
32
- });
33
- var __importStar = (this && this.__importStar) || (function () {
34
- var ownKeys = function(o) {
35
- ownKeys = Object.getOwnPropertyNames || function (o) {
36
- var ar = [];
37
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
- return ar;
39
- };
40
- return ownKeys(o);
41
- };
42
- return function (mod) {
43
- if (mod && mod.__esModule) return mod;
44
- var result = {};
45
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
- __setModuleDefault(result, mod);
47
- return result;
48
- };
49
- })();
50
- Object.defineProperty(exports, "__esModule", { value: true });
51
- exports.checkAndUpdate = checkAndUpdate;
52
- exports.checkForUpdates = checkForUpdates;
53
- exports.performUpdate = performUpdate;
54
- const child_process_1 = require("child_process");
55
- const fs = __importStar(require("fs"));
56
- const path = __importStar(require("path"));
57
- const https = __importStar(require("https"));
58
- const http = __importStar(require("http"));
16
+ import { execSync } from 'child_process';
17
+ import * as fs from 'fs';
18
+ import * as path from 'path';
19
+ import * as https from 'https';
20
+ import * as http from 'http';
59
21
  // ANSI 颜色
60
22
  const RESET = '\x1b[0m';
61
23
  const BOLD = '\x1b[1m';
@@ -113,7 +75,7 @@ function getGlobalBolloonDir() {
113
75
  const candidates = [];
114
76
  // 1. npm root -g(最可靠)
115
77
  try {
116
- const npmRoot = (0, child_process_1.execSync)('npm root -g', { encoding: 'utf-8', timeout: 8000 }).trim();
78
+ const npmRoot = execSync('npm root -g', { encoding: 'utf-8', timeout: 8000 }).trim();
117
79
  if (npmRoot)
118
80
  candidates.push(path.join(npmRoot, '@bolloon', 'bolloon-agent'));
119
81
  }
@@ -122,7 +84,7 @@ function getGlobalBolloonDir() {
122
84
  }
123
85
  // 2. npm prefix -g
124
86
  try {
125
- const npmPrefix = (0, child_process_1.execSync)('npm prefix -g', { encoding: 'utf-8', timeout: 8000 }).trim();
87
+ const npmPrefix = execSync('npm prefix -g', { encoding: 'utf-8', timeout: 8000 }).trim();
126
88
  if (npmPrefix)
127
89
  candidates.push(path.join(npmPrefix, 'lib', 'node_modules', '@bolloon', 'bolloon-agent'));
128
90
  }
@@ -280,7 +242,7 @@ async function checkBolloonUpdates() {
280
242
  */
281
243
  function checkNpmOutdated() {
282
244
  try {
283
- const output = (0, child_process_1.execSync)('npm outdated --json', {
245
+ const output = execSync('npm outdated --json', {
284
246
  encoding: 'utf-8',
285
247
  timeout: 30000,
286
248
  maxBuffer: 10 * 1024 * 1024,
@@ -344,7 +306,7 @@ async function updatePackagesWithVersion(packagesWithVersion) {
344
306
  const args = ['npm', 'install', '-g', ...packagesWithVersion];
345
307
  notify(`\n${CYAN}📦 正在更新包...${RESET}\n`, RESET);
346
308
  try {
347
- (0, child_process_1.execSync)(args.join(' '), {
309
+ execSync(args.join(' '), {
348
310
  encoding: 'utf-8',
349
311
  timeout: 300000,
350
312
  stdio: 'inherit',
@@ -462,7 +424,7 @@ function resolveAutoUpdatePolicy() {
462
424
  * 例如 Electron 用 app.relaunch(),Node 用 detached 重新 spawn)。
463
425
  * 若未提供或 autoRestart=false,则仅提示用户手动重启。
464
426
  */
465
- async function checkAndUpdate(opts = {}) {
427
+ export async function checkAndUpdate(opts = {}) {
466
428
  const policy = resolveAutoUpdatePolicy();
467
429
  if (policy.blocked) {
468
430
  return { hasUpdate: false, info: null, updated: false, message: '跳过更新检查(已显式禁用)' };
@@ -566,13 +528,13 @@ async function checkAndUpdate(opts = {}) {
566
528
  /**
567
529
  * 仅检查更新,不自动安装
568
530
  */
569
- async function checkForUpdates() {
531
+ export async function checkForUpdates() {
570
532
  return await checkBolloonUpdates();
571
533
  }
572
534
  /**
573
535
  * 手动触发更新
574
536
  */
575
- async function performUpdate(packages) {
537
+ export async function performUpdate(packages) {
576
538
  return await updatePackages(packages);
577
539
  }
578
540
  // CLI 入口
@@ -595,4 +557,3 @@ if (process.argv[1]?.includes('auto-update')) {
595
557
  }
596
558
  })();
597
559
  }
598
- //# sourceMappingURL=auto-update.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.3.35",
3
+ "version": "0.3.37",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",
@@ -35,7 +35,7 @@
35
35
  "dev": "tsx -r dotenv/config src/index.ts",
36
36
  "dev:web": "npm run build:web && tsx -r dotenv/config src/index.ts --web",
37
37
  "dev:electron": "npm run build:electron && npm run electron:start",
38
- "electron:start": "NODE_ENV=development electron dist/electron.js",
38
+ "electron:start": "NODE_ENV=development electron dist/electron-build/electron.js",
39
39
  "electron:dev": "concurrently \"npm run dev:web\" \"npm run electron:start\"",
40
40
  "electron:build": "npm run build:electron && electron-builder",
41
41
  "electron:pack": "electron-builder --dir",
@@ -133,7 +133,8 @@
133
133
  "files": [
134
134
  "dist/**/*",
135
135
  "bin/**/*",
136
- "package.json"
136
+ "package.json",
137
+ "dist/electron-build/**/*"
137
138
  ],
138
139
  "npmRebuild": false,
139
140
  "buildDependenciesFromSource": false,
@@ -147,7 +148,7 @@
147
148
  }
148
149
  ],
149
150
  "extraMetadata": {
150
- "main": "dist/electron.js",
151
+ "main": "dist/electron-build/electron.js",
151
152
  "type": "commonjs"
152
153
  },
153
154
  "win": {