opc-agent 4.2.13 โ†’ 5.0.0-rc.1

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 (207) hide show
  1. package/.opc/memory.db +0 -0
  2. package/.opc/schedules.json +784 -0
  3. package/.opc/voice-tmp/tts-1776835848670.mp3 +0 -0
  4. package/.opc/voice-tmp/tts-1776835873696.mp3 +0 -0
  5. package/README.md +125 -141
  6. package/README.zh-CN.md +75 -160
  7. package/TASK.md +34 -0
  8. package/data/brain.db/deepbrain.sqlite +0 -0
  9. package/dist/channels/api.d.ts +14 -0
  10. package/dist/channels/api.d.ts.map +1 -0
  11. package/dist/channels/api.js +58 -0
  12. package/dist/channels/api.js.map +1 -0
  13. package/dist/channels/voice.d.ts +21 -0
  14. package/dist/channels/voice.d.ts.map +1 -1
  15. package/dist/channels/voice.js +31 -1
  16. package/dist/channels/voice.js.map +1 -1
  17. package/dist/cli/chat.d.ts.map +1 -1
  18. package/dist/cli/chat.js +104 -0
  19. package/dist/cli/chat.js.map +1 -1
  20. package/dist/cli/setup.d.ts +1 -1
  21. package/dist/cli/setup.d.ts.map +1 -1
  22. package/dist/cli/setup.js +263 -33
  23. package/dist/cli/setup.js.map +1 -1
  24. package/dist/cli.js +201 -116
  25. package/dist/cli.js.map +1 -1
  26. package/dist/core/agent-loop.d.ts +3 -0
  27. package/dist/core/agent-loop.d.ts.map +1 -0
  28. package/dist/core/agent-loop.js +51 -0
  29. package/dist/core/agent-loop.js.map +1 -0
  30. package/dist/core/context-assembler.d.ts +12 -0
  31. package/dist/core/context-assembler.d.ts.map +1 -0
  32. package/dist/core/context-assembler.js +81 -0
  33. package/dist/core/context-assembler.js.map +1 -0
  34. package/dist/core/guardrails.d.ts +16 -0
  35. package/dist/core/guardrails.d.ts.map +1 -0
  36. package/dist/core/guardrails.js +62 -0
  37. package/dist/core/guardrails.js.map +1 -0
  38. package/dist/core/index.d.ts +1 -0
  39. package/dist/core/index.d.ts.map +1 -0
  40. package/dist/core/index.js +3 -0
  41. package/dist/core/index.js.map +1 -0
  42. package/dist/core/iteration-budget.d.ts +12 -0
  43. package/dist/core/iteration-budget.d.ts.map +1 -0
  44. package/dist/core/iteration-budget.js +26 -0
  45. package/dist/core/iteration-budget.js.map +1 -0
  46. package/dist/core/runtime.js +1 -1
  47. package/dist/core/runtime.js.map +1 -1
  48. package/dist/core/types.d.ts +412 -0
  49. package/dist/core/types.d.ts.map +1 -1
  50. package/dist/deepbrain/embedding.d.ts +7 -0
  51. package/dist/deepbrain/embedding.d.ts.map +1 -0
  52. package/dist/deepbrain/embedding.js +108 -0
  53. package/dist/deepbrain/embedding.js.map +1 -0
  54. package/dist/deepbrain/index.d.ts +8 -0
  55. package/dist/deepbrain/index.d.ts.map +1 -0
  56. package/dist/deepbrain/index.js +19 -0
  57. package/dist/deepbrain/index.js.map +1 -0
  58. package/dist/deepbrain/migrate.d.ts +2 -0
  59. package/dist/deepbrain/migrate.d.ts.map +1 -0
  60. package/dist/deepbrain/migrate.js +139 -0
  61. package/dist/deepbrain/migrate.js.map +1 -0
  62. package/dist/deepbrain/provider.d.ts +13 -0
  63. package/dist/deepbrain/provider.d.ts.map +1 -0
  64. package/dist/deepbrain/provider.js +85 -0
  65. package/dist/deepbrain/provider.js.map +1 -0
  66. package/dist/deepbrain/recall.d.ts +9 -0
  67. package/dist/deepbrain/recall.d.ts.map +1 -0
  68. package/dist/deepbrain/recall.js +48 -0
  69. package/dist/deepbrain/recall.js.map +1 -0
  70. package/dist/deepbrain/store.d.ts +36 -0
  71. package/dist/deepbrain/store.d.ts.map +1 -0
  72. package/dist/deepbrain/store.js +342 -0
  73. package/dist/deepbrain/store.js.map +1 -0
  74. package/dist/deepbrain/workspace-files.d.ts +5 -0
  75. package/dist/deepbrain/workspace-files.d.ts.map +1 -0
  76. package/dist/deepbrain/workspace-files.js +159 -0
  77. package/dist/deepbrain/workspace-files.js.map +1 -0
  78. package/dist/evolution/index.d.ts +1 -0
  79. package/dist/evolution/index.d.ts.map +1 -0
  80. package/dist/evolution/index.js +3 -0
  81. package/dist/evolution/index.js.map +1 -0
  82. package/dist/evolution/l1-experience.d.ts +11 -0
  83. package/dist/evolution/l1-experience.d.ts.map +1 -0
  84. package/dist/evolution/l1-experience.js +185 -0
  85. package/dist/evolution/l1-experience.js.map +1 -0
  86. package/dist/evolution/l2-consolidation.d.ts +4 -0
  87. package/dist/evolution/l2-consolidation.d.ts.map +1 -0
  88. package/dist/evolution/l2-consolidation.js +106 -0
  89. package/dist/evolution/l2-consolidation.js.map +1 -0
  90. package/dist/evolution/l2-memskill.d.ts +12 -0
  91. package/dist/evolution/l2-memskill.d.ts.map +1 -0
  92. package/dist/evolution/l2-memskill.js +57 -0
  93. package/dist/evolution/l2-memskill.js.map +1 -0
  94. package/dist/evolution/l3-skill-discover.d.ts +4 -0
  95. package/dist/evolution/l3-skill-discover.d.ts.map +1 -0
  96. package/dist/evolution/l3-skill-discover.js +139 -0
  97. package/dist/evolution/l3-skill-discover.js.map +1 -0
  98. package/dist/evolution/l3-skill-verify.d.ts +12 -0
  99. package/dist/evolution/l3-skill-verify.d.ts.map +1 -0
  100. package/dist/evolution/l3-skill-verify.js +122 -0
  101. package/dist/evolution/l3-skill-verify.js.map +1 -0
  102. package/dist/evolution/l4-desensitize.d.ts +7 -0
  103. package/dist/evolution/l4-desensitize.d.ts.map +1 -0
  104. package/dist/evolution/l4-desensitize.js +30 -0
  105. package/dist/evolution/l4-desensitize.js.map +1 -0
  106. package/dist/evolution/l4-group-evolve.d.ts +8 -0
  107. package/dist/evolution/l4-group-evolve.d.ts.map +1 -0
  108. package/dist/evolution/l4-group-evolve.js +15 -0
  109. package/dist/evolution/l4-group-evolve.js.map +1 -0
  110. package/dist/evolution/maturity-scorer.d.ts +11 -0
  111. package/dist/evolution/maturity-scorer.d.ts.map +1 -0
  112. package/dist/evolution/maturity-scorer.js +21 -0
  113. package/dist/evolution/maturity-scorer.js.map +1 -0
  114. package/dist/index.d.ts +7 -1
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +33 -5
  117. package/dist/index.js.map +1 -1
  118. package/dist/providers/agentkits.d.ts +20 -0
  119. package/dist/providers/agentkits.d.ts.map +1 -0
  120. package/dist/providers/agentkits.js +173 -0
  121. package/dist/providers/agentkits.js.map +1 -0
  122. package/dist/providers/model-provider.d.ts +16 -0
  123. package/dist/providers/model-provider.d.ts.map +1 -0
  124. package/dist/providers/model-provider.js +13 -0
  125. package/dist/providers/model-provider.js.map +1 -0
  126. package/dist/providers/model-recommender.d.ts +15 -0
  127. package/dist/providers/model-recommender.d.ts.map +1 -0
  128. package/dist/providers/model-recommender.js +71 -0
  129. package/dist/providers/model-recommender.js.map +1 -0
  130. package/dist/providers/ollama.d.ts +22 -0
  131. package/dist/providers/ollama.d.ts.map +1 -0
  132. package/dist/providers/ollama.js +176 -0
  133. package/dist/providers/ollama.js.map +1 -0
  134. package/dist/providers/openai-compat.d.ts +23 -0
  135. package/dist/providers/openai-compat.d.ts.map +1 -0
  136. package/dist/providers/openai-compat.js +184 -0
  137. package/dist/providers/openai-compat.js.map +1 -0
  138. package/dist/providers/router.d.ts +11 -0
  139. package/dist/providers/router.d.ts.map +1 -0
  140. package/dist/providers/router.js +48 -0
  141. package/dist/providers/router.js.map +1 -0
  142. package/dist/scheduler/cron.d.ts +19 -0
  143. package/dist/scheduler/cron.d.ts.map +1 -0
  144. package/dist/scheduler/cron.js +64 -0
  145. package/dist/scheduler/cron.js.map +1 -0
  146. package/dist/schema/oad.d.ts +72 -72
  147. package/dist/skills/loader.d.ts +16 -0
  148. package/dist/skills/loader.d.ts.map +1 -0
  149. package/dist/skills/loader.js +114 -0
  150. package/dist/skills/loader.js.map +1 -0
  151. package/dist/skills/matcher.d.ts +18 -0
  152. package/dist/skills/matcher.d.ts.map +1 -0
  153. package/dist/skills/matcher.js +70 -0
  154. package/dist/skills/matcher.js.map +1 -0
  155. package/dist/studio/agent-pool.d.ts +17 -0
  156. package/dist/studio/agent-pool.d.ts.map +1 -0
  157. package/dist/studio/agent-pool.js +35 -0
  158. package/dist/studio/agent-pool.js.map +1 -0
  159. package/dist/studio/assistant-tools.d.ts +4 -0
  160. package/dist/studio/assistant-tools.d.ts.map +1 -0
  161. package/dist/studio/assistant-tools.js +36 -0
  162. package/dist/studio/assistant-tools.js.map +1 -0
  163. package/dist/studio/index.d.ts +1 -0
  164. package/dist/studio/index.d.ts.map +1 -0
  165. package/dist/studio/index.js +3 -0
  166. package/dist/studio/index.js.map +1 -0
  167. package/dist/studio/server.d.ts +3 -0
  168. package/dist/studio/server.d.ts.map +1 -1
  169. package/dist/studio/server.js +156 -24
  170. package/dist/studio/server.js.map +1 -1
  171. package/dist/templates/index.d.ts +1 -0
  172. package/dist/templates/index.d.ts.map +1 -0
  173. package/dist/templates/index.js +3 -0
  174. package/dist/templates/index.js.map +1 -0
  175. package/dist/templates/roles/index.d.ts +4 -0
  176. package/dist/templates/roles/index.d.ts.map +1 -0
  177. package/dist/templates/roles/index.js +46 -0
  178. package/dist/templates/roles/index.js.map +1 -0
  179. package/dist/templates/template-provider.d.ts +16 -0
  180. package/dist/templates/template-provider.d.ts.map +1 -0
  181. package/dist/templates/template-provider.js +60 -0
  182. package/dist/templates/template-provider.js.map +1 -0
  183. package/dist/tools/builtin/definitions.d.ts +7 -0
  184. package/dist/tools/builtin/definitions.d.ts.map +1 -0
  185. package/dist/tools/builtin/definitions.js +60 -0
  186. package/dist/tools/builtin/definitions.js.map +1 -0
  187. package/dist/tools/execute-code.d.ts +20 -0
  188. package/dist/tools/execute-code.d.ts.map +1 -0
  189. package/dist/tools/execute-code.js +92 -0
  190. package/dist/tools/execute-code.js.map +1 -0
  191. package/dist/tools/hooks.d.ts +47 -0
  192. package/dist/tools/hooks.d.ts.map +1 -0
  193. package/dist/tools/hooks.js +69 -0
  194. package/dist/tools/hooks.js.map +1 -0
  195. package/dist/tools/index.d.ts +9 -0
  196. package/dist/tools/index.d.ts.map +1 -0
  197. package/dist/tools/index.js +16 -0
  198. package/dist/tools/index.js.map +1 -0
  199. package/dist/tools/permission.d.ts +20 -0
  200. package/dist/tools/permission.d.ts.map +1 -0
  201. package/dist/tools/permission.js +35 -0
  202. package/dist/tools/permission.js.map +1 -0
  203. package/dist/tools/registry.d.ts +25 -0
  204. package/dist/tools/registry.d.ts.map +1 -0
  205. package/dist/tools/registry.js +42 -0
  206. package/dist/tools/registry.js.map +1 -0
  207. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -244,6 +244,10 @@ spec:
244
244
  // CONTEXT.md
245
245
  const readmeContent = roleData.files['README.md'] || '';
246
246
  fs.writeFileSync(path.join(dir, 'CONTEXT.md'), `# Project Context\n\n## Role: ${roleDisplayName}\n\n${readmeContent}\n`);
247
+ // .opc/ directory โ€” runtime state
248
+ fs.mkdirSync(path.join(dir, '.opc'), { recursive: true });
249
+ // DEEPBRAIN.md โ€” long-term memory seed
250
+ fs.writeFileSync(path.join(dir, 'DEEPBRAIN.md'), `# DeepBrain Memory\n\nThis file seeds the agent's long-term knowledge store.\n`);
247
251
  // data/brain-seed.md if available
248
252
  if (roleData.files['brain-seed.md']) {
249
253
  fs.writeFileSync(path.join(dir, 'data', 'brain-seed.md'), roleData.files['brain-seed.md']);
@@ -385,13 +389,30 @@ export class EchoSkill extends BaseSkill {
385
389
  const ollamaData = await ollamaRes.json();
386
390
  modelNames = (ollamaData.models || []).map((m) => m.name || m.model);
387
391
  ollamaRunning = true;
388
- if (opts.yes && modelNames.length > 0) {
389
- const rec = (0, model_recommender_1.recommendModels)(allModels, sys, modelNames);
390
- // --yes: prefer best installed recommended model
391
- const bestInstalled = rec.installed.length > 0 ? rec.installed[rec.installed.length - 1] : null;
392
- // Filter out embedding-only models (can't chat)
392
+ if (opts.yes) {
393
+ const yesRec = (0, model_recommender_1.recommendModels)(allModels, sys, modelNames);
394
+ const bestInstalled = yesRec.installed.length > 0 ? yesRec.installed[yesRec.installed.length - 1] : null;
393
395
  const chatModels = modelNames.filter(m => !m.includes('embed'));
394
- llmModel = bestInstalled ? bestInstalled.name : (chatModels[0] || 'qwen2.5:7b');
396
+ if (bestInstalled) {
397
+ llmModel = bestInstalled.name;
398
+ }
399
+ else if (chatModels.length > 0) {
400
+ llmModel = chatModels[0];
401
+ }
402
+ else {
403
+ // No suitable model installed โ€” auto-pull the recommended one
404
+ console.log(`\n ${icon.info} ็ณป็ปŸ: ${sys.totalRAM}GB RAM, ${sys.cpuCount} ๆ ธ CPU`);
405
+ console.log(` ${icon.info} ๆŽจ่ๆจกๅž‹ๆœชๅฎ‰่ฃ…๏ผŒๆญฃๅœจไธ‹่ฝฝ ${color.cyan(yesRec.best.name)} (${yesRec.best.size})...`);
406
+ await new Promise((resolve) => {
407
+ const child = (0, child_process_1.spawn)('ollama', ['pull', yesRec.best.name], { stdio: 'inherit' });
408
+ child.on('close', () => resolve());
409
+ child.on('error', () => {
410
+ console.log(` ${color.yellow('โš ๏ธ')} ไธ‹่ฝฝๅคฑ่ดฅ๏ผŒ็จๅŽๆ‰‹ๅŠจ่ฟ่กŒ: ollama pull ${yesRec.best.name}`);
411
+ resolve();
412
+ });
413
+ });
414
+ llmModel = yesRec.best.name;
415
+ }
395
416
  }
396
417
  }
397
418
  catch {
@@ -432,8 +453,14 @@ export class EchoSkill extends BaseSkill {
432
453
  if (chosen.startsWith('pull:')) {
433
454
  const pullModel = chosen.slice(5);
434
455
  console.log(`\n ${icon.info} ๆญฃๅœจไธ‹่ฝฝ ${color.cyan(pullModel)}...`);
435
- console.log(` ่ฟ่กŒ ${color.cyan(`ollama pull ${pullModel}`)} ไธ‹่ฝฝ`);
436
- console.log(` ไธ‹่ฝฝๅฎŒๆˆๅŽ่ฟ่กŒ ${color.cyan('opc run')} ๅฏๅŠจ\n`);
456
+ await new Promise((resolve) => {
457
+ const child = (0, child_process_1.spawn)('ollama', ['pull', pullModel], { stdio: 'inherit' });
458
+ child.on('close', () => resolve());
459
+ child.on('error', () => {
460
+ console.log(` ${color.yellow('โš ๏ธ')} ไธ‹่ฝฝๅคฑ่ดฅ๏ผŒ็จๅŽๆ‰‹ๅŠจ่ฟ่กŒ: ollama pull ${pullModel}`);
461
+ resolve();
462
+ });
463
+ });
437
464
  llmModel = pullModel;
438
465
  }
439
466
  else {
@@ -774,6 +801,18 @@ on startup to understand the project context.
774
801
  - Add domain knowledge here
775
802
  - Add FAQ items here
776
803
  - Add company policies here
804
+ `);
805
+ // .opc/ directory โ€” runtime state (brain DB, cache, etc.)
806
+ fs.mkdirSync(path.join(dir, '.opc'), { recursive: true });
807
+ // DEEPBRAIN.md โ€” long-term memory seed (compat with MEMORY.md)
808
+ fs.writeFileSync(path.join(dir, 'DEEPBRAIN.md'), `# DeepBrain Memory
809
+
810
+ This file seeds the agent's long-term knowledge store (DeepBrain).
811
+ Add knowledge entries below โ€” they will be loaded on first run.
812
+
813
+ ## Core Knowledge
814
+
815
+ <!-- Add domain knowledge, FAQs, policies, etc. here -->
777
816
  `);
778
817
  console.log(`\n${icon.success} Created agent project: ${color.bold(name + '/')}`);
779
818
  console.log(` ${icon.file} oad.yaml - Agent ้…็ฝฎ (${llmProvider}/${llmModel})`);
@@ -782,6 +821,8 @@ on startup to understand the project context.
782
821
  console.log(` ${icon.file} src/skills/echo.ts - Example skill`);
783
822
  console.log(` ${icon.file} SOUL.md - Agent personality`);
784
823
  console.log(` ${icon.file} CONTEXT.md - Project context`);
824
+ console.log(` ${icon.file} DEEPBRAIN.md - Long-term memory seed`);
825
+ console.log(` ${icon.file} .opc/ - Runtime state directory`);
785
826
  console.log(` ${icon.file} package.json - Dependencies`);
786
827
  console.log(` ${icon.file} tsconfig.json - TypeScript config`);
787
828
  console.log(` ${icon.file} .env.example - Environment template`);
@@ -840,6 +881,7 @@ program
840
881
  .description('Start agent with web server')
841
882
  .option('-f, --file <file>', 'OAD file', 'oad.yaml')
842
883
  .option('-p, --port <port>', 'Port override')
884
+ .option('-c, --channel <channel>', 'Extra channel to activate (e.g. telegram)')
843
885
  .action(async (opts) => {
844
886
  loadDotEnv();
845
887
  const runtime = new runtime_1.AgentRuntime();
@@ -847,6 +889,25 @@ program
847
889
  await runtime.initialize();
848
890
  await runtime.start();
849
891
  const agent = runtime.getAgent();
892
+ // Start extra channel requested via --channel flag
893
+ if (opts.channel === 'telegram') {
894
+ const cfg = runtime.getConfig();
895
+ const tgInConfig = cfg?.spec?.channels?.find((c) => c.type === 'telegram');
896
+ // Only start manually if NOT already handled by runtime (i.e. not in oad.yaml channels list)
897
+ if (!tgInConfig) {
898
+ const token = process.env.TELEGRAM_BOT_TOKEN ?? '';
899
+ if (!token) {
900
+ console.warn('[telegram] No token found. Set TELEGRAM_BOT_TOKEN or add telegram to oad.yaml channels. Skipping.');
901
+ }
902
+ else {
903
+ const { TelegramChannel } = require('./channels/telegram');
904
+ const tg = new TelegramChannel({ token });
905
+ tg.onMessage((msg) => agent.handleMessage(msg));
906
+ await tg.start();
907
+ console.log(` ${color.dim('Telegram:')} bot polling started`);
908
+ }
909
+ }
910
+ }
850
911
  // Auto-start Studio on port 4000
851
912
  let studioUrl = '';
852
913
  try {
@@ -1532,65 +1593,89 @@ protocolCmd.command('disable')
1532
1593
  // ๐Ÿ”„ Migrate command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
1533
1594
  program
1534
1595
  .command('migrate')
1535
- .description('Migrate OAD to latest schema version')
1596
+ .description('Migrate project: MEMORY.md โ†’ DEEPBRAIN.md and OAD to latest schema')
1536
1597
  .option('-f, --file <file>', 'OAD file', 'oad.yaml')
1537
1598
  .option('--dry-run', 'Show changes without writing')
1599
+ .option('--schema-only', 'Only migrate OAD schema (skip MEMORY.md โ†’ DEEPBRAIN.md)')
1538
1600
  .action(async (opts) => {
1601
+ // Step 1: MEMORY.md โ†’ DEEPBRAIN.md migration
1602
+ if (!opts.schemaOnly) {
1603
+ console.log(`\n${icon.gear} ${color.bold('DeepBrain Migration')} (MEMORY.md โ†’ DEEPBRAIN.md)\n`);
1604
+ try {
1605
+ if (opts.dryRun) {
1606
+ const memExists = fs.existsSync(path.join(process.cwd(), 'MEMORY.md'));
1607
+ const soulExists = fs.existsSync(path.join(process.cwd(), 'SOUL.md'));
1608
+ const dbExists = fs.existsSync(path.join(process.cwd(), '.opc', 'brain.db'));
1609
+ console.log(` MEMORY.md: ${memExists ? color.cyan('found โ€” would migrate to DEEPBRAIN.md') : color.dim('not found')}`);
1610
+ console.log(` SOUL.md: ${soulExists ? color.cyan('found โ€” would migrate to EGO.md') : color.dim('not found')}`);
1611
+ console.log(` .opc/brain.db:${dbExists ? color.dim(' already exists') : color.cyan(' would create')}`);
1612
+ console.log(`\n ${icon.info} Dry run โ€” no changes.\n`);
1613
+ }
1614
+ else {
1615
+ const { migrate: deepbrainMigrate } = require('./deepbrain/migrate');
1616
+ await deepbrainMigrate(process.cwd());
1617
+ console.log(` ${icon.success} MEMORY.md โ†’ DEEPBRAIN.md migration complete.`);
1618
+ console.log(` ${icon.success} SOUL.md โ†’ EGO.md migration complete.`);
1619
+ console.log(` ${icon.success} Knowledge seeded into .opc/brain.db.\n`);
1620
+ }
1621
+ }
1622
+ catch (e) {
1623
+ console.log(` ${icon.warn} DeepBrain migration: ${e.message}\n`);
1624
+ }
1625
+ }
1626
+ // Step 2: OAD schema migration
1627
+ console.log(`${icon.gear} ${color.bold('OAD Schema Migration')}\n`);
1539
1628
  try {
1540
1629
  const raw = fs.readFileSync(opts.file, 'utf-8');
1541
1630
  const config = yaml.load(raw);
1542
1631
  let changed = false;
1543
- // Migration: add apiVersion if missing
1544
1632
  if (!config.apiVersion) {
1545
1633
  config.apiVersion = 'opc/v1';
1546
1634
  changed = true;
1547
1635
  }
1548
- // Migration: add kind if missing
1549
1636
  if (!config.kind) {
1550
1637
  config.kind = 'Agent';
1551
1638
  changed = true;
1552
1639
  }
1553
- // Migration: ensure metadata.version
1554
1640
  if (!config.metadata?.version) {
1555
1641
  if (!config.metadata)
1556
1642
  config.metadata = {};
1557
1643
  config.metadata.version = '1.0.0';
1558
1644
  changed = true;
1559
1645
  }
1560
- // Migration: ensure spec.channels is array
1561
1646
  if (config.spec?.channels && !Array.isArray(config.spec.channels)) {
1562
1647
  config.spec.channels = [config.spec.channels];
1563
1648
  changed = true;
1564
1649
  }
1565
- // Migration: ensure spec.skills is array
1566
1650
  if (config.spec?.skills && !Array.isArray(config.spec.skills)) {
1567
1651
  config.spec.skills = [config.spec.skills];
1568
1652
  changed = true;
1569
1653
  }
1570
- // Migration: old model format
1571
1654
  if (config.spec?.llm?.model && !config.spec?.model) {
1572
1655
  config.spec.model = config.spec.llm.model;
1573
1656
  delete config.spec.llm;
1574
1657
  changed = true;
1575
1658
  }
1576
1659
  if (!changed) {
1577
- console.log(`${icon.success} OAD is already up to date.`);
1578
- return;
1660
+ console.log(` ${icon.success} OAD is already up to date.\n`);
1579
1661
  }
1580
- if (opts.dryRun) {
1581
- console.log(`\n${icon.info} Would migrate:\n`);
1662
+ else if (opts.dryRun) {
1663
+ console.log(` ${icon.info} Would migrate:\n`);
1582
1664
  console.log(yaml.dump(config, { lineWidth: 120 }));
1583
1665
  }
1584
1666
  else {
1585
- // Backup
1586
1667
  fs.writeFileSync(opts.file + '.bak', raw);
1587
1668
  fs.writeFileSync(opts.file, yaml.dump(config, { lineWidth: 120 }));
1588
- console.log(`${icon.success} Migrated ${color.bold(opts.file)} (backup: ${opts.file}.bak)`);
1669
+ console.log(` ${icon.success} Migrated ${color.bold(opts.file)} (backup: ${opts.file}.bak)\n`);
1589
1670
  }
1590
1671
  }
1591
1672
  catch (err) {
1592
- console.error(`${icon.error} Migration failed:`, err instanceof Error ? err.message : err);
1593
- process.exit(1);
1673
+ if (err.code !== 'ENOENT') {
1674
+ console.error(` ${icon.error} OAD migration failed:`, err instanceof Error ? err.message : err);
1675
+ }
1676
+ else {
1677
+ console.log(` ${color.dim(`No OAD file found (${opts.file}) โ€” skipping schema migration.`)}\n`);
1678
+ }
1594
1679
  }
1595
1680
  });
1596
1681
  // โ”€โ”€ Brain command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@@ -1701,6 +1786,58 @@ brainCmd
1701
1786
  }
1702
1787
  console.log();
1703
1788
  });
1789
+ brainCmd
1790
+ .command('recall')
1791
+ .argument('<query>', 'Search query')
1792
+ .description('Query DeepBrain knowledge base')
1793
+ .option('--top-k <n>', 'Number of results', '5')
1794
+ .option('--layer <layer>', 'Filter by layer (l1/l2/l3/l4/workstation/job/industry)')
1795
+ .action(async (query, opts) => {
1796
+ console.log(`\n${icon.search} ${color.bold('DeepBrain Recall')} โ€” ${color.cyan(query)}\n`);
1797
+ try {
1798
+ const { DeepBrain } = require('./deepbrain/provider');
1799
+ const brain = new DeepBrain({ dbPath: path.join(process.cwd(), '.opc', 'brain.db'), embeddingProvider: 'none' });
1800
+ await brain.init();
1801
+ const result = await brain.recall({ query, topK: parseInt(opts.topK) || 5, layer: opts.layer });
1802
+ if (result.entries.length === 0) {
1803
+ console.log(` ${icon.info} No results found.\n`);
1804
+ return;
1805
+ }
1806
+ for (const entry of result.entries) {
1807
+ console.log(` ${color.cyan(`[${entry.layer}]`)} ${color.dim(entry.source)} โ€” maturity: ${entry.maturityScore.toFixed(2)}`);
1808
+ const preview = entry.content.length > 200 ? entry.content.slice(0, 200) + 'โ€ฆ' : entry.content;
1809
+ console.log(` ${preview}`);
1810
+ console.log();
1811
+ }
1812
+ console.log(` ${color.dim(`${result.entries.length} result(s) in ${result.elapsedMs}ms`)}\n`);
1813
+ }
1814
+ catch (e) {
1815
+ console.log(` ${icon.warn} ${e.message}\n`);
1816
+ }
1817
+ });
1818
+ brainCmd
1819
+ .command('stats')
1820
+ .description('Show DeepBrain knowledge base statistics')
1821
+ .action(async () => {
1822
+ console.log(`\n${icon.gear} ${color.bold('DeepBrain Stats')}\n`);
1823
+ try {
1824
+ const { DeepBrain } = require('./deepbrain/provider');
1825
+ const brain = new DeepBrain({ dbPath: path.join(process.cwd(), '.opc', 'brain.db'), embeddingProvider: 'none' });
1826
+ await brain.init();
1827
+ const stats = await brain.getStats();
1828
+ console.log(` ${color.cyan('Total Entries'.padEnd(18))} ${stats.totalEntries}`);
1829
+ const layers = stats.entriesByLayer;
1830
+ for (const [layer, count] of Object.entries(layers)) {
1831
+ console.log(` ${color.cyan(layer.padEnd(18))} ${count}`);
1832
+ }
1833
+ console.log(` ${color.cyan('Avg Maturity'.padEnd(18))} ${(stats.avgMaturityScore ?? 0).toFixed(3)}`);
1834
+ console.log(` ${color.cyan('Last Evolution'.padEnd(18))} ${stats.lastEvolution ?? 'never'}`);
1835
+ console.log();
1836
+ }
1837
+ catch (e) {
1838
+ console.log(` ${icon.warn} ${e.message}\n`);
1839
+ }
1840
+ });
1704
1841
  // โ”€โ”€ Logs command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
1705
1842
  program
1706
1843
  .command('logs')
@@ -2049,65 +2186,16 @@ program
2049
2186
  .option('--port <port>', 'Port to listen on', '4000')
2050
2187
  .option('--no-open', 'Do not open browser automatically')
2051
2188
  .action(async (opts) => {
2189
+ process.on('uncaughtException', (err) => {
2190
+ console.error('[Studio] Uncaught exception:', err.message);
2191
+ });
2192
+ process.on('unhandledRejection', (err) => {
2193
+ console.error('[Studio] Unhandled rejection:', err?.message || err);
2194
+ });
2052
2195
  const { StudioServer } = require('./studio/server');
2053
- const net = require('net');
2054
2196
  const port = parseInt(opts.port, 10);
2055
- const checkPort = (p) => new Promise((resolve) => {
2056
- const sock = new net.Socket();
2057
- sock.setTimeout(400);
2058
- sock.once('connect', () => { sock.destroy(); resolve(true); });
2059
- sock.once('error', () => { sock.destroy(); resolve(false); });
2060
- sock.once('timeout', () => { sock.destroy(); resolve(false); });
2061
- sock.connect(p, 'localhost');
2062
- });
2063
- const server = new StudioServer({ port, agentDir: process.cwd() });
2197
+ const server = new StudioServer({ port, agentDir: process.cwd(), openBrowser: opts.open !== false });
2064
2198
  await server.start();
2065
- // Try to start sub-module UI servers with graceful fallback
2066
- const subModules = [
2067
- { name: 'DeepBrain', icon: '๐Ÿง ', pkg: 'deepbrain', port: 4001, serveMethod: 'serveUI' },
2068
- { name: 'AgentKits', icon: '๐Ÿ“Š', pkg: 'agentkits', port: 4002, serveMethod: 'serveUI' },
2069
- { name: 'Workstation', icon: '๐Ÿ‘ค', pkg: 'agent-workstation', port: 4003, serveMethod: 'serveUI' },
2070
- ];
2071
- const moduleStatuses = [];
2072
- for (const mod of subModules) {
2073
- try {
2074
- const already = await checkPort(mod.port);
2075
- if (already) {
2076
- moduleStatuses.push(` ${icon.success} ${mod.icon} ${mod.name} already running on :${mod.port}`);
2077
- continue;
2078
- }
2079
- const modExports = await dynamicImport(mod.pkg);
2080
- if (typeof modExports[mod.serveMethod] === 'function') {
2081
- modExports[mod.serveMethod]({ port: mod.port });
2082
- await new Promise(r => setTimeout(r, 600));
2083
- const started = await checkPort(mod.port);
2084
- moduleStatuses.push(started
2085
- ? ` ${icon.success} ${mod.icon} ${mod.name} started on :${mod.port}`
2086
- : ` ${icon.warn} ${mod.icon} ${mod.name} failed to start`);
2087
- }
2088
- else {
2089
- moduleStatuses.push(` ${icon.success} ${mod.icon} ${mod.name} installed`);
2090
- }
2091
- }
2092
- catch {
2093
- moduleStatuses.push(` ${color.dim('โ—‹')} ${mod.icon} ${mod.name} not installed (npm i ${mod.pkg})`);
2094
- }
2095
- }
2096
- if (moduleStatuses.length > 0) {
2097
- console.log('\nModules:');
2098
- moduleStatuses.forEach(s => console.log(s));
2099
- }
2100
- const url = `http://localhost:${port}`;
2101
- console.log(`\n${icon.success} OPC Studio ready โ†’ ${color.cyan(url)}`);
2102
- if (opts.open !== false) {
2103
- try {
2104
- const { exec } = require('child_process');
2105
- const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start ""' : 'xdg-open';
2106
- exec(`${openCmd} ${url}`);
2107
- }
2108
- catch { }
2109
- }
2110
- console.log(color.dim('Press Ctrl+C to stop'));
2111
2199
  });
2112
2200
  program
2113
2201
  .command('doctor')
@@ -2316,43 +2404,6 @@ program
2316
2404
  }
2317
2405
  console.log();
2318
2406
  });
2319
- // โ”€โ”€ Search command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2320
- program
2321
- .command('memory-search <query>')
2322
- .description('Search conversation history (requires SQLite memory)')
2323
- .option('-n, --limit <n>', 'Max results', '10')
2324
- .option('--json', 'Output as JSON')
2325
- .action(async (query, opts) => {
2326
- try {
2327
- const { SQLiteStore } = await Promise.resolve().then(() => __importStar(require('./memory/sqlite-store')));
2328
- const store = new SQLiteStore();
2329
- const results = await store.search(query, parseInt(opts.limit, 10));
2330
- const stats = await store.stats();
2331
- if (opts.json) {
2332
- console.log(JSON.stringify({ query, results, stats }, null, 2));
2333
- await store.close();
2334
- return;
2335
- }
2336
- console.log(`\n๐Ÿ” ๆœ็ดข: "${query}" (${results.length} ๆก็ป“ๆžœ, ๅ…ฑ ${stats.totalMessages} ๆกๆถˆๆฏ)\n`);
2337
- if (results.length === 0) {
2338
- console.log(' ๆœชๆ‰พๅˆฐๅŒน้…็ป“ๆžœใ€‚\n');
2339
- await store.close();
2340
- return;
2341
- }
2342
- for (const msg of results) {
2343
- const time = new Date(msg.timestamp).toLocaleString();
2344
- const role = msg.role === 'user' ? '๐Ÿ‘ค' : '๐Ÿค–';
2345
- const preview = msg.content.length > 120 ? msg.content.slice(0, 120) + '...' : msg.content;
2346
- console.log(` ${role} [${time}] ${preview}`);
2347
- }
2348
- console.log(`\n ๐Ÿ’พ ๆ•ฐๆฎๅบ“: ${stats.dbSizeKB}KB, ${stats.sessions} ไธชไผš่ฏ\n`);
2349
- await store.close();
2350
- }
2351
- catch (err) {
2352
- console.error(`${icon.error} ๆœ็ดขๅคฑ่ดฅ: ${err instanceof Error ? err.message : err}`);
2353
- console.log(' ๆ็คบ: ้œ€่ฆ sql.js ๆ”ฏๆŒใ€‚่ฟ่กŒ: npm install sql.js');
2354
- }
2355
- });
2356
2407
  // โ”€โ”€ Keys command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2357
2408
  const keys_1 = require("./security/keys");
2358
2409
  const approval_1 = require("./security/approval");
@@ -2661,6 +2712,40 @@ mcpCmd
2661
2712
  await server.serveStdio();
2662
2713
  }
2663
2714
  });
2715
+ // โ”€โ”€ Memory Search command โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2716
+ program
2717
+ .command('memory-search')
2718
+ .argument('<query>', 'Search query')
2719
+ .description('Search agent memory (DeepBrain knowledge base)')
2720
+ .option('--top-k <n>', 'Number of results', '5')
2721
+ .option('--json', 'Output as JSON')
2722
+ .action(async (query, opts) => {
2723
+ try {
2724
+ const { DeepBrain } = require('./deepbrain/provider');
2725
+ const brain = new DeepBrain({ dbPath: path.join(process.cwd(), '.opc', 'brain.db'), embeddingProvider: 'none' });
2726
+ await brain.init();
2727
+ const result = await brain.recall({ query, topK: parseInt(opts.topK) || 5 });
2728
+ if (opts.json) {
2729
+ console.log(JSON.stringify(result, null, 2));
2730
+ return;
2731
+ }
2732
+ console.log(`\n${icon.search} ${color.bold('Memory Search')} โ€” ${color.cyan(query)}\n`);
2733
+ if (result.entries.length === 0) {
2734
+ console.log(` ${icon.info} No results found.\n`);
2735
+ return;
2736
+ }
2737
+ for (const entry of result.entries) {
2738
+ console.log(` ${color.cyan(`[${entry.layer}]`)} ${color.dim(entry.source)}`);
2739
+ const preview = entry.content.length > 200 ? entry.content.slice(0, 200) + 'โ€ฆ' : entry.content;
2740
+ console.log(` ${preview}\n`);
2741
+ }
2742
+ console.log(` ${color.dim(`${result.entries.length} result(s) in ${result.elapsedMs}ms`)}\n`);
2743
+ }
2744
+ catch (e) {
2745
+ console.error(`${icon.error} Memory search failed: ${e.message}`);
2746
+ process.exit(1);
2747
+ }
2748
+ });
2664
2749
  // โ”€โ”€ Parse CLI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2665
2750
  program.parse();
2666
2751
  //# sourceMappingURL=cli.js.map