@jaimevalasek/aioson 1.5.1 → 1.6.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.
Files changed (131) hide show
  1. package/README.md +6 -0
  2. package/docs/design-previews/aurora-command-ui-website.html +884 -0
  3. package/docs/design-previews/aurora-command-ui.html +682 -0
  4. package/docs/design-previews/bold-editorial-ui-website.html +658 -0
  5. package/docs/design-previews/bold-editorial-ui.html +717 -0
  6. package/docs/design-previews/clean-saas-ui-website.html +1202 -0
  7. package/docs/design-previews/clean-saas-ui.html +549 -0
  8. package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
  9. package/docs/design-previews/cognitive-core-ui.html +463 -0
  10. package/docs/design-previews/glassmorphism-ui-website.html +572 -0
  11. package/docs/design-previews/glassmorphism-ui.html +886 -0
  12. package/docs/design-previews/index.html +699 -0
  13. package/docs/design-previews/interface-design-website.html +1187 -0
  14. package/docs/design-previews/interface-design.html +513 -0
  15. package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
  16. package/docs/design-previews/neo-brutalist-ui.html +797 -0
  17. package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
  18. package/docs/design-previews/premium-command-center-ui.html +552 -0
  19. package/docs/design-previews/warm-craft-ui-website.html +684 -0
  20. package/docs/design-previews/warm-craft-ui.html +739 -0
  21. package/docs/en/cli-reference.md +20 -9
  22. package/docs/pt/README.md +7 -0
  23. package/docs/pt/agent-sharding.md +132 -0
  24. package/docs/pt/agentes.md +8 -2
  25. package/docs/pt/busca-de-contexto.md +129 -0
  26. package/docs/pt/cache-de-contexto.md +156 -0
  27. package/docs/pt/comandos-cli.md +28 -0
  28. package/docs/pt/design-hybrid-forge.md +107 -0
  29. package/docs/pt/inicio-rapido.md +54 -3
  30. package/docs/pt/inteligencia-adaptativa.md +324 -0
  31. package/docs/pt/monitor-de-contexto.md +104 -0
  32. package/docs/pt/recuperacao-de-sessao.md +125 -0
  33. package/docs/pt/sandbox.md +125 -0
  34. package/docs/pt/skills.md +98 -6
  35. package/package.json +1 -1
  36. package/src/agent-loader.js +280 -0
  37. package/src/cli.js +94 -0
  38. package/src/commands/agent-loader.js +85 -0
  39. package/src/commands/context-cache.js +90 -0
  40. package/src/commands/context-monitor.js +92 -0
  41. package/src/commands/context-search.js +66 -0
  42. package/src/commands/design-hybrid-options.js +385 -0
  43. package/src/commands/health.js +214 -0
  44. package/src/commands/init.js +54 -13
  45. package/src/commands/install.js +52 -13
  46. package/src/commands/learning-evolve.js +355 -0
  47. package/src/commands/live.js +34 -0
  48. package/src/commands/recovery.js +43 -0
  49. package/src/commands/sandbox.js +37 -0
  50. package/src/commands/setup-context.js +22 -2
  51. package/src/commands/setup.js +178 -0
  52. package/src/commands/skill.js +79 -32
  53. package/src/commands/tool-registry-cmd.js +232 -0
  54. package/src/commands/update.js +7 -0
  55. package/src/constants.js +9 -0
  56. package/src/context-cache.js +159 -0
  57. package/src/context-search.js +326 -0
  58. package/src/design-variation-catalog.js +503 -0
  59. package/src/i18n/messages/en.js +32 -2
  60. package/src/i18n/messages/es.js +30 -2
  61. package/src/i18n/messages/fr.js +30 -2
  62. package/src/i18n/messages/pt-BR.js +32 -2
  63. package/src/install-animation.js +260 -0
  64. package/src/install-profile.js +143 -0
  65. package/src/install-wizard.js +474 -0
  66. package/src/installer.js +38 -10
  67. package/src/parser.js +7 -1
  68. package/src/recovery-context-session.js +154 -0
  69. package/src/runtime-store.js +97 -1
  70. package/src/sandbox.js +177 -0
  71. package/src/tool-executor.js +94 -0
  72. package/src/updater.js +11 -3
  73. package/template/.aioson/agents/analyst.md +58 -3
  74. package/template/.aioson/agents/architect.md +38 -0
  75. package/template/.aioson/agents/design-hybrid-forge.md +127 -0
  76. package/template/.aioson/agents/dev.md +103 -0
  77. package/template/.aioson/agents/deyvin.md +57 -0
  78. package/template/.aioson/agents/pm.md +58 -0
  79. package/template/.aioson/agents/product.md +28 -0
  80. package/template/.aioson/agents/qa.md +79 -0
  81. package/template/.aioson/agents/setup.md +65 -3
  82. package/template/.aioson/agents/sheldon.md +107 -6
  83. package/template/.aioson/agents/tester.md +156 -0
  84. package/template/.aioson/config.md +15 -0
  85. package/template/.aioson/context/forensics/.gitkeep +0 -0
  86. package/template/.aioson/context/seeds/seed-example.md +27 -0
  87. package/template/.aioson/context/user-profile.md +42 -0
  88. package/template/.aioson/locales/en/agents/setup.md +33 -1
  89. package/template/.aioson/locales/es/agents/setup.md +33 -1
  90. package/template/.aioson/locales/fr/agents/setup.md +33 -1
  91. package/template/.aioson/locales/pt-BR/agents/setup.md +33 -1
  92. package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
  93. package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
  94. package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
  95. package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
  96. package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
  97. package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
  98. package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
  99. package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
  100. package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
  101. package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
  102. package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
  103. package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
  104. package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
  105. package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
  106. package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
  107. package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
  108. package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
  109. package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
  110. package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
  111. package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
  112. package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
  113. package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
  114. package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
  115. package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -0
  116. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +45 -0
  117. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
  118. package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
  119. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
  120. package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
  121. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +66 -0
  122. package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
  123. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +144 -0
  124. package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
  125. package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
  126. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +291 -0
  127. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +117 -0
  128. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +188 -0
  129. package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -0
  130. package/template/AGENTS.md +23 -1
  131. package/template/CLAUDE.md +1 -0
package/src/cli.js CHANGED
@@ -5,6 +5,7 @@ const { parseArgv } = require('./parser');
5
5
  const { createTranslator, normalizeLocale } = require('./i18n');
6
6
  const { runInit } = require('./commands/init');
7
7
  const { runInstall } = require('./commands/install');
8
+ const { runSetup } = require('./commands/setup');
8
9
  const { runUpdate } = require('./commands/update');
9
10
  const { runInfo } = require('./commands/info');
10
11
  const { runDoctorCommand } = require('./commands/doctor');
@@ -108,11 +109,22 @@ const {
108
109
  runSkillList,
109
110
  runSkillRemove
110
111
  } = require('./commands/skill');
112
+ const { runDesignHybridOptions } = require('./commands/design-hybrid-options');
111
113
  const { runBackupLocal } = require('./commands/backup-local-cmd');
114
+ const { runRecoveryGenerate, runRecoveryShow } = require('./commands/recovery');
115
+ const { runContextMonitor } = require('./commands/context-monitor');
116
+ const { runContextSearch, runContextSearchIndex } = require('./commands/context-search');
117
+ const { runContextCacheList, runContextCacheSave, runContextCacheRestore, runContextCacheCleanup } = require('./commands/context-cache');
118
+ const { runSandboxExec } = require('./commands/sandbox');
119
+ const { runAgentLoad, runAgentShardIndex } = require('./commands/agent-loader');
120
+ const { runLearningEvolve, runLearningApply } = require('./commands/learning-evolve');
121
+ const { runToolRegistry } = require('./commands/tool-registry-cmd');
122
+ const { runHealth } = require('./commands/health');
112
123
 
113
124
  const JSON_SUPPORTED_COMMANDS = new Set([
114
125
  'init',
115
126
  'install',
127
+ 'setup',
116
128
  'update',
117
129
  'i18n:add',
118
130
  'i18n-add',
@@ -241,6 +253,21 @@ const JSON_SUPPORTED_COMMANDS = new Set([
241
253
  'learning:list',
242
254
  'learning:stats',
243
255
  'learning:promote',
256
+ 'learning:evolve',
257
+ 'learning-evolve',
258
+ 'learning:apply',
259
+ 'learning-apply',
260
+ 'tool:register',
261
+ 'tool-register',
262
+ 'tool:list',
263
+ 'tool-list',
264
+ 'tool:call',
265
+ 'tool-call',
266
+ 'tool:unregister',
267
+ 'tool-unregister',
268
+ 'tool:show',
269
+ 'tool-show',
270
+ 'health',
244
271
  'runtime:init',
245
272
  'runtime-init',
246
273
  'runtime:ingest',
@@ -308,6 +335,32 @@ const JSON_SUPPORTED_COMMANDS = new Set([
308
335
  'skill-list',
309
336
  'skill:remove',
310
337
  'skill-remove',
338
+ 'design-hybrid:options',
339
+ 'design-hybrid-options',
340
+ 'recovery:generate',
341
+ 'recovery-generate',
342
+ 'recovery:show',
343
+ 'recovery-show',
344
+ 'context:monitor',
345
+ 'context-monitor',
346
+ 'context:search',
347
+ 'context-search',
348
+ 'context:search:index',
349
+ 'context-search-index',
350
+ 'context:cache',
351
+ 'context-cache',
352
+ 'context:cache:save',
353
+ 'context-cache-save',
354
+ 'context:cache:restore',
355
+ 'context-cache-restore',
356
+ 'context:cache:cleanup',
357
+ 'context-cache-cleanup',
358
+ 'sandbox:exec',
359
+ 'sandbox-exec',
360
+ 'agent:load',
361
+ 'agent-load',
362
+ 'agent:shard:index',
363
+ 'agent-shard-index',
311
364
  'version',
312
365
  '--version',
313
366
  '-v'
@@ -354,6 +407,7 @@ function printHelp(t, logger) {
354
407
  logger.log(t('cli.usage'));
355
408
  logHelpLine(t, logger, 'cli.help_init');
356
409
  logHelpLine(t, logger, 'cli.help_install');
410
+ logHelpLine(t, logger, 'cli.help_setup');
357
411
  logHelpLine(t, logger, 'cli.help_update');
358
412
  logHelpLine(t, logger, 'cli.help_info');
359
413
  logHelpLine(t, logger, 'cli.help_doctor');
@@ -428,6 +482,7 @@ function printHelp(t, logger) {
428
482
  logHelpLine(t, logger, 'cli.help_skill_install');
429
483
  logHelpLine(t, logger, 'cli.help_skill_list');
430
484
  logHelpLine(t, logger, 'cli.help_skill_remove');
485
+ logHelpLine(t, logger, 'cli.help_design_hybrid_options');
431
486
  logHelpLine(t, logger, 'cli.help_cloud_import_squad');
432
487
  logHelpLine(t, logger, 'cli.help_cloud_import_genome');
433
488
  logHelpLine(t, logger, 'cli.help_cloud_publish_squad');
@@ -491,6 +546,10 @@ async function main() {
491
546
  result = await runInit({ args, options, logger: commandLogger, t });
492
547
  } else if (command === 'install') {
493
548
  result = await runInstall({ args, options, logger: commandLogger, t });
549
+ } else if (command === 'setup') {
550
+ result = await runSetup({ args, options, logger: commandLogger, t });
551
+ } else if (command === 'install') {
552
+ result = await runInstall({ args, options, logger: commandLogger, t });
494
553
  } else if (command === 'update') {
495
554
  result = await runUpdate({ args, options, logger: commandLogger, t });
496
555
  } else if (command === 'info') {
@@ -644,6 +703,10 @@ async function main() {
644
703
  } else if (command === 'squad:learning' || command === 'squad-learning') {
645
704
  const sub = args[1] || 'list';
646
705
  result = await runSquadLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
706
+ } else if (command === 'learning:evolve' || command === 'learning-evolve') {
707
+ result = await runLearningEvolve({ args, options, logger: commandLogger, t });
708
+ } else if (command === 'learning:apply' || command === 'learning-apply') {
709
+ result = await runLearningApply({ args, options, logger: commandLogger, t });
647
710
  } else if (command.startsWith('learning:') || command === 'learning') {
648
711
  const sub = command === 'learning' ? (args[1] || 'list') : command.split(':')[1];
649
712
  result = await runLearning({ args, options: { ...options, sub }, logger: commandLogger, t });
@@ -718,6 +781,8 @@ async function main() {
718
781
  result = await runSkillList({ args, options, logger: commandLogger, t });
719
782
  } else if (command === 'skill:remove' || command === 'skill-remove') {
720
783
  result = await runSkillRemove({ args, options, logger: commandLogger, t });
784
+ } else if (command === 'design-hybrid:options' || command === 'design-hybrid-options') {
785
+ result = await runDesignHybridOptions({ args, options, logger: commandLogger, t });
721
786
  } else if (command === 'cloud:import:squad' || command === 'cloud-import-squad') {
722
787
  result = await runCloudImportSquad({ args, options, logger: commandLogger, t });
723
788
  } else if (command === 'cloud:import:genome' || command === 'cloud-import-genome') {
@@ -726,6 +791,35 @@ async function main() {
726
791
  result = await runCloudPublishSquad({ args, options, logger: commandLogger, t });
727
792
  } else if (command === 'cloud:publish:genome' || command === 'cloud-publish-genome') {
728
793
  result = await runCloudPublishGenome({ args, options, logger: commandLogger, t });
794
+ } else if (command === 'recovery:generate' || command === 'recovery-generate') {
795
+ result = await runRecoveryGenerate({ args, options, logger: commandLogger, t });
796
+ } else if (command === 'recovery:show' || command === 'recovery-show') {
797
+ result = await runRecoveryShow({ args, options, logger: commandLogger, t });
798
+ } else if (command === 'context:monitor' || command === 'context-monitor') {
799
+ result = await runContextMonitor({ args, options, logger: commandLogger, t });
800
+ } else if (command === 'context:search' || command === 'context-search') {
801
+ result = await runContextSearch({ args, options, logger: commandLogger, t });
802
+ } else if (command === 'context:search:index' || command === 'context-search-index') {
803
+ result = await runContextSearchIndex({ args, options, logger: commandLogger, t });
804
+ } else if (command === 'context:cache' || command === 'context-cache') {
805
+ result = await runContextCacheList({ args, options, logger: commandLogger, t });
806
+ } else if (command === 'context:cache:save' || command === 'context-cache-save') {
807
+ result = await runContextCacheSave({ args, options, logger: commandLogger, t });
808
+ } else if (command === 'context:cache:restore' || command === 'context-cache-restore') {
809
+ result = await runContextCacheRestore({ args, options, logger: commandLogger, t });
810
+ } else if (command === 'context:cache:cleanup' || command === 'context-cache-cleanup') {
811
+ result = await runContextCacheCleanup({ args, options, logger: commandLogger, t });
812
+ } else if (command === 'sandbox:exec' || command === 'sandbox-exec') {
813
+ result = await runSandboxExec({ args, options, logger: commandLogger, t });
814
+ } else if (command === 'agent:load' || command === 'agent-load') {
815
+ result = await runAgentLoad({ args, options, logger: commandLogger, t });
816
+ } else if (command === 'agent:shard:index' || command === 'agent-shard-index') {
817
+ result = await runAgentShardIndex({ args, options, logger: commandLogger, t });
818
+ } else if (command.startsWith('tool:') || command.startsWith('tool-')) {
819
+ const sub = command.replace(/^tool[:-]/, '');
820
+ result = await runToolRegistry({ args, options: { ...options, sub }, logger: commandLogger, t });
821
+ } else if (command === 'health') {
822
+ result = await runHealth({ args, options, logger: commandLogger, t });
729
823
  } else {
730
824
  const message = t('cli.unknown_command', { command });
731
825
  if (jsonMode) {
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { AgentLoader } = require('../agent-loader');
5
+
6
+ async function runAgentLoad({ args, options, logger }) {
7
+ const agentId = args[0] || options.agent || '';
8
+ const goal = options.goal || '';
9
+ const cwd = path.resolve(process.cwd(), options.cwd || '.');
10
+ const agentsDir = path.join(cwd, options['agents-dir'] || '.aioson/agents');
11
+ const maxShards = Number(options['max-shards']) || 3;
12
+ const maxTokens = Number(options['max-tokens']) || 2000;
13
+
14
+ if (!agentId) {
15
+ logger.error('Usage: aioson agent:load <agent-id> --goal="..." [--cwd=.]');
16
+ return { ok: false, error: 'missing_agent' };
17
+ }
18
+
19
+ const loader = new AgentLoader();
20
+ await loader.open();
21
+
22
+ try {
23
+ // Index agents dir if needed
24
+ await loader.indexAgentsDir(agentsDir, { force: Boolean(options.force) });
25
+
26
+ // Load relevant shards
27
+ const result = await loader.loadRelevantShards(agentId, goal, { maxShards, maxTokens });
28
+
29
+ if (result.shards.length === 0) {
30
+ logger.log(`No shards found for agent: ${agentId}`);
31
+ logger.log(`Make sure the agents directory exists: ${agentsDir}`);
32
+ return { ok: true, agentId, shards: [], tokens: 0 };
33
+ }
34
+
35
+ if (options.json) {
36
+ return { ok: true, ...result };
37
+ }
38
+
39
+ logger.log(`\n Agent: ${agentId} (${result.shards.length}/${result.totalShards} shards, ${result.tokens} tokens)\n`);
40
+ for (const shard of result.shards) {
41
+ logger.log(` ## ${shard.heading} (${shard.tokens} tokens)`);
42
+ }
43
+ logger.log('');
44
+
45
+ if (options.print) {
46
+ logger.log('\n---\n');
47
+ logger.log(AgentLoader.buildContext(result.shards));
48
+ }
49
+
50
+ return { ok: true, ...result };
51
+ } finally {
52
+ loader.close();
53
+ }
54
+ }
55
+
56
+ async function runAgentShardIndex({ args, options, logger }) {
57
+ const cwd = path.resolve(process.cwd(), args[0] || '.');
58
+ const agentsDir = path.join(cwd, options['agents-dir'] || '.aioson/agents');
59
+ const force = Boolean(options.force);
60
+
61
+ logger.log(`Indexing agent shards from: ${agentsDir}`);
62
+
63
+ const loader = new AgentLoader();
64
+ await loader.open();
65
+
66
+ try {
67
+ const result = await loader.indexAgentsDir(agentsDir, { force });
68
+ const stats = loader.stats();
69
+
70
+ if (options.json) {
71
+ return { ok: true, ...result, stats };
72
+ }
73
+
74
+ logger.log(` Agents indexed: ${result.agents}`);
75
+ logger.log(` Total shards: ${result.totalShards}`);
76
+ logger.log(` Index total docs: ${stats.totalDocs}`);
77
+ logger.log('');
78
+
79
+ return { ok: true, ...result, stats };
80
+ } finally {
81
+ loader.close();
82
+ }
83
+ }
84
+
85
+ module.exports = { runAgentLoad, runAgentShardIndex };
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { saveContextShadow, listSessions, restoreContext, cleanup } = require('../context-cache');
5
+
6
+ async function runContextCacheList({ args, options, logger }) {
7
+ const cacheDir = options.cacheDir || undefined;
8
+ const sessions = await listSessions({ cacheDir });
9
+
10
+ if (options.json) {
11
+ return { ok: true, sessions };
12
+ }
13
+
14
+ if (sessions.length === 0) {
15
+ logger.log('No cached sessions found.');
16
+ return { ok: true, sessions: [] };
17
+ }
18
+
19
+ logger.log('\n Cached Context Sessions\n');
20
+ for (const s of sessions) {
21
+ const kb = Math.round(s.size / 1024);
22
+ const goal = s.metadata.goal ? ` — ${s.metadata.goal.slice(0, 50)}` : '';
23
+ logger.log(` ${s.sessionId} ${s.createdAt.slice(0, 16)} ${kb}KB${goal}`);
24
+ }
25
+ logger.log('');
26
+
27
+ return { ok: true, sessions };
28
+ }
29
+
30
+ async function runContextCacheSave({ args, options, logger }) {
31
+ const cwd = path.resolve(process.cwd(), args[0] || '.');
32
+ const content = options.content || '';
33
+
34
+ if (!content) {
35
+ logger.error('--content is required. Example: aioson context:cache:save . --content="..." --goal="..."');
36
+ return { ok: false, error: 'missing_content' };
37
+ }
38
+
39
+ const result = await saveContextShadow(content, {
40
+ goal: options.goal || '',
41
+ agent: options.agent || '',
42
+ projectDir: cwd
43
+ });
44
+
45
+ if (options.json) return result;
46
+
47
+ logger.log(`Context saved. Session ID: ${result.sessionId}`);
48
+ logger.log(`Path: ${result.path}`);
49
+ return result;
50
+ }
51
+
52
+ async function runContextCacheRestore({ args, options, logger }) {
53
+ const sessionId = options.session || args[0] || '';
54
+ const cacheDir = options.cacheDir || undefined;
55
+
56
+ if (!sessionId) {
57
+ logger.error('--session=<id> is required.');
58
+ return { ok: false, error: 'missing_session' };
59
+ }
60
+
61
+ const result = await restoreContext(sessionId, {
62
+ cacheDir,
63
+ query: options.query || undefined
64
+ });
65
+
66
+ if (!result.ok) {
67
+ logger.error(`Restore failed: ${result.error}`);
68
+ return result;
69
+ }
70
+
71
+ if (options.json) return result;
72
+
73
+ logger.log(result.content);
74
+ return result;
75
+ }
76
+
77
+ async function runContextCacheCleanup({ args, options, logger }) {
78
+ const cacheDir = options.cacheDir || undefined;
79
+ const maxAgeHours = Number(options['max-age']) || 24;
80
+ const maxAge = maxAgeHours * 60 * 60 * 1000;
81
+
82
+ const result = await cleanup({ cacheDir, maxAge });
83
+
84
+ if (options.json) return { ok: true, ...result };
85
+
86
+ logger.log(`Removed ${result.removed} expired session(s).`);
87
+ return { ok: true, ...result };
88
+ }
89
+
90
+ module.exports = { runContextCacheList, runContextCacheSave, runContextCacheRestore, runContextCacheCleanup };
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const {
5
+ getContextUsage,
6
+ computeWarningLevel,
7
+ THRESHOLDS
8
+ } = require('../squad-dashboard/context-monitor');
9
+
10
+ const BAR_WIDTH = 20;
11
+ const LEVEL_ICONS = { normal: ' ', warning: '⚠', critical: '!', overflow: 'X', unknown: '?' };
12
+
13
+ function renderBar(ratio, width) {
14
+ const clamped = Math.max(0, Math.min(1, ratio));
15
+ const filled = Math.round(clamped * width);
16
+ const bar = '█'.repeat(filled) + '░'.repeat(width - filled);
17
+ return `[${bar}] ${Math.round(clamped * 100)}%`;
18
+ }
19
+
20
+ function formatTokens(n) {
21
+ if (typeof n !== 'number') return '?';
22
+ return n.toLocaleString();
23
+ }
24
+
25
+ function renderAgent(slug, agent) {
26
+ const used = agent.totalUsed || 0;
27
+ const win = agent.windowSize || 0;
28
+ const ratio = win > 0 ? used / win : 0;
29
+ const level = agent.warningLevel || computeWarningLevel(used, win);
30
+ const icon = LEVEL_ICONS[level] || '?';
31
+ const bar = renderBar(ratio, BAR_WIDTH);
32
+ const line = ` ${icon} ${slug.padEnd(16)} ${bar} ${formatTokens(used)}/${formatTokens(win)}`;
33
+ if (level === 'warning' || level === 'critical' || level === 'overflow') {
34
+ return `${line} [${level.toUpperCase()}]`;
35
+ }
36
+ return line;
37
+ }
38
+
39
+ async function runContextMonitor({ args, options, logger }) {
40
+ const cwd = path.resolve(process.cwd(), args[0] || '.');
41
+ const squadSlug = options.squad || null;
42
+ const agentSlug = options.agent || null;
43
+
44
+ if (!squadSlug) {
45
+ logger.log('\n Context Monitor\n');
46
+ logger.log(' No squad specified. Use --squad=<slug> to monitor a squad.');
47
+ logger.log(' Example: aioson context:monitor . --squad=my-squad');
48
+ logger.log('');
49
+ return { ok: true, squads: [] };
50
+ }
51
+
52
+ const data = await getContextUsage(cwd, squadSlug, agentSlug || null);
53
+
54
+ if (!data) {
55
+ logger.log(`\n No context data found for squad: ${squadSlug}`);
56
+ logger.log(' The squad may not have started yet or context-monitor.json is missing.');
57
+ logger.log('');
58
+ return { ok: true, squadSlug, agents: {} };
59
+ }
60
+
61
+ if (options.json) {
62
+ return { ok: true, ...data };
63
+ }
64
+
65
+ logger.log(`\n Context Monitor — ${squadSlug}\n`);
66
+
67
+ if (agentSlug) {
68
+ // Single agent
69
+ const agent = data;
70
+ logger.log(renderAgent(agentSlug, agent));
71
+ } else {
72
+ const agents = data.agents || {};
73
+ if (Object.keys(agents).length === 0) {
74
+ logger.log(' No agents tracked yet.');
75
+ } else {
76
+ for (const [slug, agent] of Object.entries(agents)) {
77
+ logger.log(renderAgent(slug, agent));
78
+ }
79
+ }
80
+ }
81
+
82
+ logger.log('');
83
+ logger.log(` Thresholds: warning=${Math.round(THRESHOLDS.warning * 100)}% critical=${Math.round(THRESHOLDS.critical * 100)}%`);
84
+ if (data.updatedAt) {
85
+ logger.log(` Updated: ${data.updatedAt}`);
86
+ }
87
+ logger.log('');
88
+
89
+ return { ok: true, ...data };
90
+ }
91
+
92
+ module.exports = { runContextMonitor };
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { withIndex } = require('../context-search');
5
+
6
+ async function runContextSearch({ args, options, logger }) {
7
+ const query = args[0] || options.query || '';
8
+ const cwd = path.resolve(process.cwd(), options.cwd || '.');
9
+ const limit = Number(options.limit) || 10;
10
+
11
+ if (!query) {
12
+ logger.log('Usage: aioson context:search <query> [--limit=10] [--cwd=.]');
13
+ return { ok: false, error: 'missing_query' };
14
+ }
15
+
16
+ const results = await withIndex(async (idx) => {
17
+ return idx.search(query, { limit, projectDir: cwd });
18
+ });
19
+
20
+ if (options.json) {
21
+ return { ok: true, results };
22
+ }
23
+
24
+ if (results.length === 0) {
25
+ logger.log(`No results for: ${query}`);
26
+ return { ok: true, results: [] };
27
+ }
28
+
29
+ logger.log(`\n Search results for: "${query}"\n`);
30
+ for (let i = 0; i < results.length; i++) {
31
+ const r = results[i];
32
+ logger.log(` ${i + 1}. ${r.title}`);
33
+ logger.log(` ${r.relPath}`);
34
+ if (r.snippet) {
35
+ logger.log(` ${r.snippet.replace(/\n/g, ' ')}`);
36
+ }
37
+ logger.log('');
38
+ }
39
+
40
+ return { ok: true, results };
41
+ }
42
+
43
+ async function runContextSearchIndex({ args, options, logger }) {
44
+ const cwd = path.resolve(process.cwd(), args[0] || '.');
45
+ const force = Boolean(options.force);
46
+
47
+ logger.log(`Indexing: ${cwd} ...`);
48
+
49
+ const result = await withIndex(async (idx) => {
50
+ const r = await idx.indexDirectory(cwd, { force });
51
+ const stats = idx.stats();
52
+ return { ...r, stats };
53
+ });
54
+
55
+ if (options.json) {
56
+ return { ok: true, ...result };
57
+ }
58
+
59
+ logger.log(` Indexed: ${result.indexed} files`);
60
+ logger.log(` Skipped: ${result.skipped} files (already indexed)`);
61
+ logger.log(` Total in index: ${result.stats.totalDocs} docs`);
62
+
63
+ return { ok: true, ...result };
64
+ }
65
+
66
+ module.exports = { runContextSearch, runContextSearchIndex };