@jaimevalasek/aioson 1.4.0 → 1.5.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.
- package/CHANGELOG.md +31 -1
- package/LICENSE +661 -21
- package/README.md +3 -1
- package/docs/en/squad-dashboard.md +372 -0
- package/docs/openclaw-bridge.md +308 -0
- package/docs/pt/agentes.md +124 -10
- package/docs/pt/cenarios.md +46 -2
- package/docs/pt/comandos-cli.md +60 -1
- package/docs/pt/inicio-rapido.md +18 -2
- package/docs/pt/squad-dashboard.md +373 -0
- package/docs/testing/genome-2.0-matrix.md +5 -5
- package/docs/testing/genome-2.0-rollout.md +9 -9
- package/package.json +2 -2
- package/src/backup-local.js +74 -0
- package/src/cli.js +98 -0
- package/src/commands/backup-local-cmd.js +25 -0
- package/src/commands/runtime.js +242 -0
- package/src/commands/setup-context.js +7 -2
- package/src/commands/squad-daemon.js +209 -0
- package/src/commands/squad-dashboard.js +39 -0
- package/src/commands/squad-deploy.js +64 -0
- package/src/commands/squad-doctor.js +52 -0
- package/src/commands/squad-mcp.js +270 -0
- package/src/commands/squad-processes.js +56 -0
- package/src/commands/squad-recovery.js +42 -0
- package/src/commands/squad-roi.js +291 -0
- package/src/commands/squad-score.js +250 -0
- package/src/commands/squad-status.js +37 -1
- package/src/commands/squad-validate.js +62 -1
- package/src/commands/squad-webhook.js +160 -0
- package/src/commands/squad-worker.js +191 -0
- package/src/commands/squad-worktrees.js +75 -0
- package/src/commands/web-map.js +70 -0
- package/src/commands/web-scrape.js +71 -0
- package/src/constants.js +8 -0
- package/src/context-writer.js +45 -1
- package/src/i18n/messages/en.js +127 -1
- package/src/i18n/messages/es.js +117 -0
- package/src/i18n/messages/fr.js +117 -0
- package/src/i18n/messages/pt-BR.js +126 -1
- package/src/lib/webhook-server.js +328 -0
- package/src/mcp-connectors/registry.js +602 -0
- package/src/runtime-store.js +259 -2
- package/src/squad/external-session.js +180 -0
- package/src/squad/inter-squad.js +74 -0
- package/src/squad/recovery-context.js +201 -0
- package/src/squad/worktree-manager.js +114 -0
- package/src/squad-daemon.js +490 -0
- package/src/squad-dashboard/api.js +223 -0
- package/src/squad-dashboard/attachment-handler.js +93 -0
- package/src/squad-dashboard/context-monitor.js +157 -0
- package/src/squad-dashboard/execution-logs.js +115 -0
- package/src/squad-dashboard/hunk-review.js +209 -0
- package/src/squad-dashboard/metrics.js +133 -0
- package/src/squad-dashboard/process-monitor.js +125 -0
- package/src/squad-dashboard/renderer.js +858 -0
- package/src/squad-dashboard/server.js +232 -0
- package/src/squad-dashboard/styles.js +525 -0
- package/src/squad-dashboard/token-tracker.js +99 -0
- package/src/web.js +284 -0
- package/src/worker-runner.js +339 -0
- package/template/.aioson/agents/analyst.md +4 -0
- package/template/.aioson/agents/architect.md +4 -0
- package/template/.aioson/agents/dev.md +120 -11
- package/template/.aioson/agents/deyvin.md +8 -0
- package/template/.aioson/agents/neo.md +152 -0
- package/template/.aioson/agents/orache.md +17 -0
- package/template/.aioson/agents/orchestrator.md +26 -0
- package/template/.aioson/agents/product.md +60 -12
- package/template/.aioson/agents/qa.md +1 -0
- package/template/.aioson/agents/setup.md +63 -19
- package/template/.aioson/agents/sheldon.md +603 -0
- package/template/.aioson/agents/squad.md +191 -0
- package/template/.aioson/agents/tester.md +254 -0
- package/template/.aioson/agents/ux-ui.md +12 -0
- package/template/.aioson/config.md +6 -0
- package/template/.aioson/locales/en/agents/analyst.md +8 -0
- package/template/.aioson/locales/en/agents/architect.md +8 -0
- package/template/.aioson/locales/en/agents/dev.md +66 -7
- package/template/.aioson/locales/en/agents/deyvin.md +8 -0
- package/template/.aioson/locales/en/agents/neo.md +8 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/en/agents/qa.md +49 -0
- package/template/.aioson/locales/en/agents/setup.md +2 -1
- package/template/.aioson/locales/en/agents/sheldon.md +340 -0
- package/template/.aioson/locales/en/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/es/agents/analyst.md +8 -0
- package/template/.aioson/locales/es/agents/architect.md +8 -0
- package/template/.aioson/locales/es/agents/dev.md +66 -7
- package/template/.aioson/locales/es/agents/deyvin.md +8 -0
- package/template/.aioson/locales/es/agents/neo.md +48 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/es/agents/qa.md +26 -0
- package/template/.aioson/locales/es/agents/setup.md +2 -1
- package/template/.aioson/locales/es/agents/sheldon.md +192 -0
- package/template/.aioson/locales/es/agents/squad.md +63 -0
- package/template/.aioson/locales/es/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/fr/agents/analyst.md +8 -0
- package/template/.aioson/locales/fr/agents/architect.md +8 -0
- package/template/.aioson/locales/fr/agents/dev.md +66 -7
- package/template/.aioson/locales/fr/agents/deyvin.md +8 -0
- package/template/.aioson/locales/fr/agents/neo.md +48 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/fr/agents/qa.md +26 -0
- package/template/.aioson/locales/fr/agents/setup.md +2 -1
- package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
- package/template/.aioson/locales/fr/agents/squad.md +63 -0
- package/template/.aioson/locales/fr/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/pt-BR/agents/analyst.md +19 -0
- package/template/.aioson/locales/pt-BR/agents/architect.md +19 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +75 -12
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +8 -0
- package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/pt-BR/agents/product.md +8 -3
- package/template/.aioson/locales/pt-BR/agents/qa.md +60 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +2 -1
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
- package/template/.aioson/locales/pt-BR/agents/squad.md +105 -0
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +8 -0
- package/template/.aioson/schemas/squad-blueprint.schema.json +21 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +178 -1
- package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +55 -9
- package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +1 -1
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +100 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +43 -9
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +40 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +99 -12
- package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
- package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
- package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
- package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
- package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
- package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
- package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
- package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
- package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
- package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
- package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
- package/template/.aioson/skills/squad/formats/catalog.json +15 -0
- package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
- package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
- package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
- package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
- package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
- package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
- package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
- package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
- package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
- package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
- package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
- package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
- package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
- package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
- package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
- package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
- package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
- package/template/.aioson/skills/static/debugging-protocol.md +42 -0
- package/template/.aioson/skills/static/git-worktrees.md +36 -0
- package/template/.aioson/tasks/implementation-plan.md +19 -0
- package/template/.aioson/tasks/squad-design.md +28 -0
- package/template/.aioson/tasks/squad-profile.md +48 -0
- package/template/.aioson/tasks/squad-review.md +61 -0
- package/template/.aioson/tasks/squad-task-decompose.md +66 -0
- package/template/.claude/commands/aioson/agent/neo.md +5 -0
- package/template/.claude/commands/aioson/agent/tester.md +5 -0
- package/template/.gemini/GEMINI.md +1 -0
- package/template/.gemini/commands/aios-neo.toml +4 -0
- package/template/.gemini/commands/aios-tester.toml +6 -0
- package/template/AGENTS.md +3 -0
- package/template/CLAUDE.md +5 -2
- package/template/OPENCODE.md +2 -0
package/src/cli.js
CHANGED
|
@@ -32,6 +32,8 @@ const { runQaInit } = require('./commands/qa-init');
|
|
|
32
32
|
const { runQaRun } = require('./commands/qa-run');
|
|
33
33
|
const { runQaScan } = require('./commands/qa-scan');
|
|
34
34
|
const { runQaReport } = require('./commands/qa-report');
|
|
35
|
+
const { runWebMap } = require('./commands/web-map');
|
|
36
|
+
const { runWebScrape } = require('./commands/web-scrape');
|
|
35
37
|
const { runScanProject } = require('./commands/scan-project');
|
|
36
38
|
const { runConfig } = require('./commands/config');
|
|
37
39
|
const { runGenomeDoctor } = require('./commands/genome-doctor');
|
|
@@ -48,6 +50,17 @@ const { runImplementationPlan } = require('./commands/implementation-plan');
|
|
|
48
50
|
const { runSquadPlan } = require('./commands/squad-plan');
|
|
49
51
|
const { runSquadLearning } = require('./commands/squad-learning');
|
|
50
52
|
const { runLearning } = require('./commands/learning');
|
|
53
|
+
const { runSquadDashboard } = require('./commands/squad-dashboard');
|
|
54
|
+
const { runSquadWorker } = require('./commands/squad-worker');
|
|
55
|
+
const { runSquadDaemon } = require('./commands/squad-daemon');
|
|
56
|
+
const { runSquadMcp } = require('./commands/squad-mcp');
|
|
57
|
+
const { runSquadRoi } = require('./commands/squad-roi');
|
|
58
|
+
const { runSquadScore } = require('./commands/squad-score');
|
|
59
|
+
const { runSquadProcesses } = require('./commands/squad-processes');
|
|
60
|
+
const { runSquadWorktrees, runSquadMerge } = require('./commands/squad-worktrees');
|
|
61
|
+
const { runSquadRecovery } = require('./commands/squad-recovery');
|
|
62
|
+
const { runSquadDeploy } = require('./commands/squad-deploy');
|
|
63
|
+
const { runSquadWebhook } = require('./commands/squad-webhook');
|
|
51
64
|
const {
|
|
52
65
|
runRuntimeInit,
|
|
53
66
|
runRuntimeIngest,
|
|
@@ -60,6 +73,8 @@ const {
|
|
|
60
73
|
runRuntimeFail,
|
|
61
74
|
runRuntimeStatus,
|
|
62
75
|
runRuntimeLog,
|
|
76
|
+
runAgentDone,
|
|
77
|
+
runAgentRecover,
|
|
63
78
|
runRuntimeSessionStart,
|
|
64
79
|
runRuntimeSessionLog,
|
|
65
80
|
runRuntimeSessionFinish,
|
|
@@ -93,6 +108,7 @@ const {
|
|
|
93
108
|
runSkillList,
|
|
94
109
|
runSkillRemove
|
|
95
110
|
} = require('./commands/skill');
|
|
111
|
+
const { runBackupLocal } = require('./commands/backup-local-cmd');
|
|
96
112
|
|
|
97
113
|
const JSON_SUPPORTED_COMMANDS = new Set([
|
|
98
114
|
'init',
|
|
@@ -159,6 +175,10 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
159
175
|
'qa-scan',
|
|
160
176
|
'qa:report',
|
|
161
177
|
'qa-report',
|
|
178
|
+
'web:map',
|
|
179
|
+
'web-map',
|
|
180
|
+
'web:scrape',
|
|
181
|
+
'web-scrape',
|
|
162
182
|
'scan:project',
|
|
163
183
|
'scan-project',
|
|
164
184
|
'config',
|
|
@@ -182,6 +202,31 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
182
202
|
'squad-agent-create',
|
|
183
203
|
'squad:investigate',
|
|
184
204
|
'squad-investigate',
|
|
205
|
+
'squad:dashboard',
|
|
206
|
+
'squad-dashboard',
|
|
207
|
+
'squad:worker',
|
|
208
|
+
'squad-worker',
|
|
209
|
+
'squad:daemon',
|
|
210
|
+
'squad-daemon',
|
|
211
|
+
'squad:mcp',
|
|
212
|
+
'squad-mcp',
|
|
213
|
+
'squad:mcp:call',
|
|
214
|
+
'squad:roi',
|
|
215
|
+
'squad-roi',
|
|
216
|
+
'squad:score',
|
|
217
|
+
'squad-score',
|
|
218
|
+
'squad:processes',
|
|
219
|
+
'squad-processes',
|
|
220
|
+
'squad:worktrees',
|
|
221
|
+
'squad-worktrees',
|
|
222
|
+
'squad:merge',
|
|
223
|
+
'squad-merge',
|
|
224
|
+
'squad:recovery',
|
|
225
|
+
'squad-recovery',
|
|
226
|
+
'squad:deploy',
|
|
227
|
+
'squad-deploy',
|
|
228
|
+
'squad:webhook',
|
|
229
|
+
'squad-webhook',
|
|
185
230
|
'plan:show',
|
|
186
231
|
'plan:status',
|
|
187
232
|
'plan:checkpoint',
|
|
@@ -218,6 +263,10 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
218
263
|
'runtime-status',
|
|
219
264
|
'runtime:log',
|
|
220
265
|
'runtime-log',
|
|
266
|
+
'agent:done',
|
|
267
|
+
'agent-done',
|
|
268
|
+
'agent:recover',
|
|
269
|
+
'agent-recover',
|
|
221
270
|
'runtime:session:start',
|
|
222
271
|
'runtime-session-start',
|
|
223
272
|
'runtime:session:log',
|
|
@@ -333,6 +382,8 @@ function printHelp(t, logger) {
|
|
|
333
382
|
logHelpLine(t, logger, 'cli.help_qa_run');
|
|
334
383
|
logHelpLine(t, logger, 'cli.help_qa_scan');
|
|
335
384
|
logHelpLine(t, logger, 'cli.help_qa_report');
|
|
385
|
+
logHelpLine(t, logger, 'cli.help_web_map');
|
|
386
|
+
logHelpLine(t, logger, 'cli.help_web_scrape');
|
|
336
387
|
logHelpLine(t, logger, 'cli.help_scan_project');
|
|
337
388
|
logHelpLine(t, logger, 'cli.help_config');
|
|
338
389
|
logHelpLine(t, logger, 'cli.help_genome_doctor');
|
|
@@ -345,6 +396,12 @@ function printHelp(t, logger) {
|
|
|
345
396
|
logHelpLine(t, logger, 'cli.help_squad_pipeline');
|
|
346
397
|
logHelpLine(t, logger, 'cli.help_squad_agent_create');
|
|
347
398
|
logHelpLine(t, logger, 'cli.help_squad_investigate');
|
|
399
|
+
logHelpLine(t, logger, 'cli.help_squad_dashboard');
|
|
400
|
+
logHelpLine(t, logger, 'cli.help_squad_worker');
|
|
401
|
+
logHelpLine(t, logger, 'cli.help_squad_daemon');
|
|
402
|
+
logHelpLine(t, logger, 'cli.help_squad_mcp');
|
|
403
|
+
logHelpLine(t, logger, 'cli.help_squad_roi');
|
|
404
|
+
logHelpLine(t, logger, 'cli.help_squad_score');
|
|
348
405
|
logHelpLine(t, logger, 'cli.help_squad_learning');
|
|
349
406
|
logHelpLine(t, logger, 'cli.help_learning');
|
|
350
407
|
logHelpLine(t, logger, 'cli.help_runtime_init');
|
|
@@ -523,6 +580,10 @@ async function main() {
|
|
|
523
580
|
result = await runQaScan({ args, options, logger: commandLogger, t });
|
|
524
581
|
} else if (command === 'qa:report' || command === 'qa-report') {
|
|
525
582
|
result = await runQaReport({ args, options, logger: commandLogger, t });
|
|
583
|
+
} else if (command === 'web:map' || command === 'web-map') {
|
|
584
|
+
result = await runWebMap({ args, options, logger: commandLogger, t });
|
|
585
|
+
} else if (command === 'web:scrape' || command === 'web-scrape') {
|
|
586
|
+
result = await runWebScrape({ args, options, logger: commandLogger, t });
|
|
526
587
|
} else if (command === 'scan:project' || command === 'scan-project') {
|
|
527
588
|
result = await runScanProject({ args, options, logger: commandLogger, t });
|
|
528
589
|
} else if (command === 'config') {
|
|
@@ -547,6 +608,37 @@ async function main() {
|
|
|
547
608
|
result = await runSquadAgentCreate({ args, options, logger: commandLogger, t });
|
|
548
609
|
} else if (command === 'squad:investigate' || command === 'squad-investigate') {
|
|
549
610
|
result = await runSquadInvestigate({ args, options, logger: commandLogger, t });
|
|
611
|
+
} else if (command === 'squad:dashboard' || command === 'squad-dashboard') {
|
|
612
|
+
result = await runSquadDashboard({ args, options, logger: commandLogger, t });
|
|
613
|
+
} else if (command === 'squad:worker' || command === 'squad-worker') {
|
|
614
|
+
const sub = options.sub || 'list';
|
|
615
|
+
result = await runSquadWorker({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
616
|
+
} else if (command === 'squad:daemon' || command === 'squad-daemon') {
|
|
617
|
+
const sub = options.sub || 'status';
|
|
618
|
+
result = await runSquadDaemon({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
619
|
+
} else if (command === 'squad:mcp:call') {
|
|
620
|
+
result = await runSquadMcp({ args, options: { ...options, sub: 'call' }, logger: commandLogger, t });
|
|
621
|
+
} else if (command === 'squad:mcp' || command === 'squad-mcp') {
|
|
622
|
+
const sub = options.sub || 'status';
|
|
623
|
+
result = await runSquadMcp({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
624
|
+
} else if (command === 'squad:roi' || command === 'squad-roi') {
|
|
625
|
+
const sub = options.sub || 'report';
|
|
626
|
+
result = await runSquadRoi({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
627
|
+
} else if (command === 'squad:score' || command === 'squad-score') {
|
|
628
|
+
result = await runSquadScore({ args, options, logger: commandLogger, translator: t });
|
|
629
|
+
} else if (command === 'squad:processes' || command === 'squad-processes') {
|
|
630
|
+
result = await runSquadProcesses({ args, options, logger: commandLogger, t });
|
|
631
|
+
} else if (command === 'squad:worktrees' || command === 'squad-worktrees') {
|
|
632
|
+
result = await runSquadWorktrees({ args, options, logger: commandLogger, t });
|
|
633
|
+
} else if (command === 'squad:merge' || command === 'squad-merge') {
|
|
634
|
+
result = await runSquadMerge({ args, options, logger: commandLogger, t });
|
|
635
|
+
} else if (command === 'squad:recovery' || command === 'squad-recovery') {
|
|
636
|
+
result = await runSquadRecovery({ args, options, logger: commandLogger, t });
|
|
637
|
+
} else if (command === 'squad:deploy' || command === 'squad-deploy') {
|
|
638
|
+
result = await runSquadDeploy({ args, options, logger: commandLogger, t });
|
|
639
|
+
} else if (command === 'squad:webhook' || command === 'squad-webhook') {
|
|
640
|
+
const sub = options.sub || 'start';
|
|
641
|
+
result = await runSquadWebhook({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
550
642
|
} else if (command === 'squad:plan' || command === 'squad-plan') {
|
|
551
643
|
result = await runSquadPlan({ args, options, logger: commandLogger, t });
|
|
552
644
|
} else if (command === 'squad:learning' || command === 'squad-learning') {
|
|
@@ -580,6 +672,10 @@ async function main() {
|
|
|
580
672
|
result = await runRuntimeStatus({ args, options, logger: commandLogger, t });
|
|
581
673
|
} else if (command === 'runtime:log' || command === 'runtime-log') {
|
|
582
674
|
result = await runRuntimeLog({ args, options, logger: commandLogger, t });
|
|
675
|
+
} else if (command === 'agent:done' || command === 'agent-done') {
|
|
676
|
+
result = await runAgentDone({ args, options, logger: commandLogger, t });
|
|
677
|
+
} else if (command === 'agent:recover' || command === 'agent-recover') {
|
|
678
|
+
result = await runAgentRecover({ args, options, logger: commandLogger, t });
|
|
583
679
|
} else if (command === 'runtime:session:start' || command === 'runtime-session-start') {
|
|
584
680
|
result = await runRuntimeSessionStart({ args, options, logger: commandLogger, t });
|
|
585
681
|
} else if (command === 'runtime:session:log' || command === 'runtime-session-log') {
|
|
@@ -614,6 +710,8 @@ async function main() {
|
|
|
614
710
|
result = await runRuntimeBackup({ args, options, logger: commandLogger, t });
|
|
615
711
|
} else if (command === 'runtime:restore' || command === 'runtime-restore') {
|
|
616
712
|
result = await runRuntimeRestore({ args, options, logger: commandLogger, t });
|
|
713
|
+
} else if (command === 'backup:local' || command === 'backup-local') {
|
|
714
|
+
result = await runBackupLocal({ args, options, logger: commandLogger, t });
|
|
617
715
|
} else if (command === 'skill:install' || command === 'skill-install') {
|
|
618
716
|
result = await runSkillInstall({ args, options, logger: commandLogger, t });
|
|
619
717
|
} else if (command === 'skill:list' || command === 'skill-list') {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { backupAiosonDocs } = require('../backup-local');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* aioson backup:local [.]
|
|
8
|
+
*
|
|
9
|
+
* Manually backs up all .md files from .aioson/context/ and .aioson/plans/
|
|
10
|
+
* to ~/.aioson/backups/{project}/{timestamp}/
|
|
11
|
+
*/
|
|
12
|
+
async function runBackupLocal({ args, options, logger }) {
|
|
13
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
14
|
+
const result = await backupAiosonDocs(targetDir);
|
|
15
|
+
|
|
16
|
+
if (result.count === 0) {
|
|
17
|
+
logger.log('backup:local — nothing to back up (no .md files found in .aioson/context/ or .aioson/plans/)');
|
|
18
|
+
return { ok: true, count: 0, backupPath: null };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
logger.log(`backup:local — ${result.count} file(s) backed up → ${result.backupPath}`);
|
|
22
|
+
return { ok: true, count: result.count, backupPath: result.backupPath };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { runBackupLocal };
|
package/src/commands/runtime.js
CHANGED
|
@@ -20,6 +20,7 @@ const {
|
|
|
20
20
|
} = require('../runtime-store');
|
|
21
21
|
const { runAutoDelivery } = require('../delivery-runner');
|
|
22
22
|
const { writeHandoff, buildRuntimeLogHandoff } = require('../session-handoff');
|
|
23
|
+
const { backupAiosonDocs, isDocCreatingAgent } = require('../backup-local');
|
|
23
24
|
|
|
24
25
|
const ALLOWED_LAYOUTS = new Set(['document', 'tabs', 'accordion', 'stack', 'mixed']);
|
|
25
26
|
const DEFAULT_TEXT_FIELDS = ['content', 'text', 'body', 'lyrics', 'markdown'];
|
|
@@ -1159,6 +1160,80 @@ async function runRuntimeLog({ args, options = {}, logger, t }) {
|
|
|
1159
1160
|
}
|
|
1160
1161
|
|
|
1161
1162
|
|
|
1163
|
+
/**
|
|
1164
|
+
* aioson agent:done . --agent=<name> --summary="..." [--title="..."] [--status=completed|failed]
|
|
1165
|
+
*
|
|
1166
|
+
* Safe self-registration for official agents invoked directly (not via workflow:next or live:start).
|
|
1167
|
+
* - If an active live session exists for the agent: appends a completion event without closing the session.
|
|
1168
|
+
* - If no session exists: creates a standalone task+run and immediately marks it completed.
|
|
1169
|
+
*
|
|
1170
|
+
* Intended to be called ONCE at the very end of an agent session, after delivering the main artifact.
|
|
1171
|
+
*/
|
|
1172
|
+
async function runAgentDone({ args, options = {}, logger, t }) {
|
|
1173
|
+
const targetDir = resolveTargetDir(args);
|
|
1174
|
+
const agentName = String(options.agent || '').trim();
|
|
1175
|
+
if (!agentName) {
|
|
1176
|
+
throw new Error('--agent is required');
|
|
1177
|
+
}
|
|
1178
|
+
const normalizedAgent = agentName.startsWith('@') ? agentName : `@${agentName}`;
|
|
1179
|
+
const summary = String(options.summary || options.message || `${normalizedAgent} session completed`).trim();
|
|
1180
|
+
const title = options.title ? String(options.title).trim() : null;
|
|
1181
|
+
const status = options.status || 'completed';
|
|
1182
|
+
|
|
1183
|
+
const { db, dbPath, runtimeDir } = await openRuntimeDb(targetDir);
|
|
1184
|
+
|
|
1185
|
+
try {
|
|
1186
|
+
const session = await readAgentSession(runtimeDir, normalizedAgent);
|
|
1187
|
+
const hasActiveSession = session && !session.finished && session.runKey;
|
|
1188
|
+
|
|
1189
|
+
if (hasActiveSession) {
|
|
1190
|
+
// Live or tracked session is already open — only append a completion note.
|
|
1191
|
+
// Do NOT close the session: live:handoff or live:close owns the lifecycle.
|
|
1192
|
+
appendRunEvent(db, {
|
|
1193
|
+
runKey: session.runKey,
|
|
1194
|
+
eventType: 'agent_done',
|
|
1195
|
+
phase: 'live',
|
|
1196
|
+
status: 'running',
|
|
1197
|
+
message: summary
|
|
1198
|
+
});
|
|
1199
|
+
|
|
1200
|
+
if (!options.json) {
|
|
1201
|
+
logger.log(`agent:done — ${normalizedAgent} | live session active, event logged | run: ${session.runKey} (${dbPath})`);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
if (isDocCreatingAgent(normalizedAgent)) {
|
|
1205
|
+
backupAiosonDocs(targetDir).catch(() => {});
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
return { ok: true, targetDir, dbPath, agent: normalizedAgent, mode: 'live_event', runKey: session.runKey };
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// No active session — create a standalone task+run and immediately complete it.
|
|
1212
|
+
const { runKey, taskKey } = await logAgentEvent(db, runtimeDir, {
|
|
1213
|
+
agentName: normalizedAgent,
|
|
1214
|
+
message: summary,
|
|
1215
|
+
type: 'completed',
|
|
1216
|
+
taskTitle: title || normalizedAgent,
|
|
1217
|
+
finish: true,
|
|
1218
|
+
status,
|
|
1219
|
+
summary
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
if (!options.json) {
|
|
1223
|
+
logger.log(`agent:done — ${normalizedAgent} | task: ${taskKey} | run: ${runKey} (${dbPath})`);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
if (isDocCreatingAgent(normalizedAgent)) {
|
|
1227
|
+
backupAiosonDocs(targetDir).catch(() => {});
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
return { ok: true, targetDir, dbPath, agent: normalizedAgent, mode: 'standalone', runKey, taskKey };
|
|
1231
|
+
} finally {
|
|
1232
|
+
db.close();
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
|
|
1162
1237
|
async function runRuntimeSessionStart({ args, options = {}, logger, t }) {
|
|
1163
1238
|
const targetDir = resolveTargetDir(args);
|
|
1164
1239
|
const { db, dbPath, runtimeDir } = await openRuntimeDb(targetDir);
|
|
@@ -1683,6 +1758,171 @@ function parseFrontmatter(content) {
|
|
|
1683
1758
|
return result;
|
|
1684
1759
|
}
|
|
1685
1760
|
|
|
1761
|
+
/**
|
|
1762
|
+
* Parses a duration string like "24h", "30m", "7d" into milliseconds.
|
|
1763
|
+
* Falls back to treating the raw value as hours.
|
|
1764
|
+
*/
|
|
1765
|
+
function parseDurationMs(value, defaultHours = 24) {
|
|
1766
|
+
const text = String(value || '').trim().toLowerCase();
|
|
1767
|
+
if (!text) return defaultHours * 60 * 60 * 1000;
|
|
1768
|
+
|
|
1769
|
+
const match = text.match(/^(\d+(?:\.\d+)?)\s*([hmd]?)$/);
|
|
1770
|
+
if (!match) return defaultHours * 60 * 60 * 1000;
|
|
1771
|
+
|
|
1772
|
+
const n = parseFloat(match[1]);
|
|
1773
|
+
const unit = match[2] || 'h';
|
|
1774
|
+
if (unit === 'd') return n * 24 * 60 * 60 * 1000;
|
|
1775
|
+
if (unit === 'm') return n * 60 * 1000;
|
|
1776
|
+
return n * 60 * 60 * 1000; // hours (default)
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
/**
|
|
1780
|
+
* aioson agent:recover [targetDir] [--older-than=<duration>] [--dry-run]
|
|
1781
|
+
*
|
|
1782
|
+
* Detects and closes agent sessions that were abandoned (Claude Code closed before
|
|
1783
|
+
* agent:done was called, or live:start session was never closed).
|
|
1784
|
+
*
|
|
1785
|
+
* Sources checked:
|
|
1786
|
+
* 1. Session files in .aioson/.sessions/ with finished=false older than threshold.
|
|
1787
|
+
* 2. agent_runs rows with status='running'/'queued' and started_at older than threshold
|
|
1788
|
+
* that have no corresponding live session file (orphaned DB records).
|
|
1789
|
+
*
|
|
1790
|
+
* --older-than Duration threshold. Accepts: 24h (default), 8h, 30m, 7d.
|
|
1791
|
+
* --dry-run Report what would be recovered without making any changes.
|
|
1792
|
+
* --json Output JSON result.
|
|
1793
|
+
*/
|
|
1794
|
+
async function runAgentRecover({ args, options = {}, logger }) {
|
|
1795
|
+
const targetDir = resolveTargetDir(args);
|
|
1796
|
+
const dryRun = Boolean(options['dry-run'] || options.dryRun);
|
|
1797
|
+
const olderThanMs = parseDurationMs(options['older-than'] || options.olderThan, 24);
|
|
1798
|
+
const cutoffMs = Date.now() - olderThanMs;
|
|
1799
|
+
const cutoffIso = new Date(cutoffMs).toISOString();
|
|
1800
|
+
const now = new Date().toISOString();
|
|
1801
|
+
|
|
1802
|
+
const { db, dbPath, runtimeDir } = await openRuntimeDb(targetDir);
|
|
1803
|
+
|
|
1804
|
+
const recovered = [];
|
|
1805
|
+
const skipped = [];
|
|
1806
|
+
|
|
1807
|
+
try {
|
|
1808
|
+
// ── 1. Scan session files ─────────────────────────────────────────────────
|
|
1809
|
+
const sessionsDir = path.join(runtimeDir, '.sessions');
|
|
1810
|
+
let sessionFiles = [];
|
|
1811
|
+
try {
|
|
1812
|
+
const entries = await fs.readdir(sessionsDir);
|
|
1813
|
+
sessionFiles = entries.filter((f) => f.endsWith('.json'));
|
|
1814
|
+
} catch {
|
|
1815
|
+
// .sessions dir may not exist — that's fine
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
for (const file of sessionFiles) {
|
|
1819
|
+
const filePath = path.join(sessionsDir, file);
|
|
1820
|
+
let session;
|
|
1821
|
+
try {
|
|
1822
|
+
session = JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
1823
|
+
} catch {
|
|
1824
|
+
continue;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
if (session.finished) continue;
|
|
1828
|
+
|
|
1829
|
+
const startedAt = session.startedAt ? new Date(session.startedAt).getTime() : 0;
|
|
1830
|
+
if (startedAt > cutoffMs) {
|
|
1831
|
+
skipped.push({ source: 'session_file', file, reason: 'within_threshold', startedAt: session.startedAt });
|
|
1832
|
+
continue;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
const agentName = file.replace(/\.json$/, '');
|
|
1836
|
+
const runKey = session.runKey || null;
|
|
1837
|
+
const taskKey = session.taskKey || null;
|
|
1838
|
+
|
|
1839
|
+
if (!dryRun) {
|
|
1840
|
+
// Mark run as abandoned
|
|
1841
|
+
if (runKey) {
|
|
1842
|
+
const runRow = db.prepare('SELECT run_key, status FROM agent_runs WHERE run_key = ?').get(runKey);
|
|
1843
|
+
if (runRow && (runRow.status === 'running' || runRow.status === 'queued')) {
|
|
1844
|
+
db.prepare(`
|
|
1845
|
+
UPDATE agent_runs
|
|
1846
|
+
SET status = 'abandoned', summary = 'Recovered: session abandoned without close', updated_at = ?, finished_at = ?
|
|
1847
|
+
WHERE run_key = ?
|
|
1848
|
+
`).run(now, now, runKey);
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
// Mark task as abandoned
|
|
1852
|
+
if (taskKey) {
|
|
1853
|
+
const taskRow = db.prepare('SELECT task_key, status FROM tasks WHERE task_key = ?').get(taskKey);
|
|
1854
|
+
if (taskRow && (taskRow.status === 'running' || taskRow.status === 'queued')) {
|
|
1855
|
+
db.prepare(`
|
|
1856
|
+
UPDATE tasks
|
|
1857
|
+
SET status = 'abandoned', updated_at = ?, finished_at = ?
|
|
1858
|
+
WHERE task_key = ?
|
|
1859
|
+
`).run(now, now, taskKey);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
// Remove session file
|
|
1863
|
+
try { await fs.unlink(filePath); } catch { /* noop */ }
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
recovered.push({ source: 'session_file', agent: agentName, runKey, taskKey, startedAt: session.startedAt });
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
// ── 2. Scan DB for orphaned running runs (no session file) ────────────────
|
|
1870
|
+
const orphanedRuns = db.prepare(`
|
|
1871
|
+
SELECT run_key, task_key, agent_name, started_at
|
|
1872
|
+
FROM agent_runs
|
|
1873
|
+
WHERE status IN ('running', 'queued')
|
|
1874
|
+
AND source = 'direct'
|
|
1875
|
+
AND started_at < ?
|
|
1876
|
+
`).all(cutoffIso);
|
|
1877
|
+
|
|
1878
|
+
for (const run of orphanedRuns) {
|
|
1879
|
+
// Skip if already recovered via session file
|
|
1880
|
+
if (recovered.some((r) => r.runKey === run.run_key)) continue;
|
|
1881
|
+
|
|
1882
|
+
if (!dryRun) {
|
|
1883
|
+
db.prepare(`
|
|
1884
|
+
UPDATE agent_runs
|
|
1885
|
+
SET status = 'abandoned', summary = 'Recovered: orphaned run with no session file', updated_at = ?, finished_at = ?
|
|
1886
|
+
WHERE run_key = ?
|
|
1887
|
+
`).run(now, now, run.run_key);
|
|
1888
|
+
|
|
1889
|
+
if (run.task_key) {
|
|
1890
|
+
const taskRow = db.prepare('SELECT task_key, status FROM tasks WHERE task_key = ?').get(run.task_key);
|
|
1891
|
+
if (taskRow && (taskRow.status === 'running' || taskRow.status === 'queued')) {
|
|
1892
|
+
db.prepare(`
|
|
1893
|
+
UPDATE tasks
|
|
1894
|
+
SET status = 'abandoned', updated_at = ?, finished_at = ?
|
|
1895
|
+
WHERE task_key = ?
|
|
1896
|
+
`).run(now, now, run.task_key);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
recovered.push({ source: 'orphaned_run', agent: run.agent_name, runKey: run.run_key, taskKey: run.task_key, startedAt: run.started_at });
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
// ── Output ────────────────────────────────────────────────────────────────
|
|
1905
|
+
const olderThanLabel = options['older-than'] || options.olderThan || '24h';
|
|
1906
|
+
if (recovered.length === 0) {
|
|
1907
|
+
logger.log(`agent:recover — no abandoned sessions found older than ${olderThanLabel} (${dbPath})`);
|
|
1908
|
+
} else {
|
|
1909
|
+
const verb = dryRun ? '[dry-run] would recover' : 'recovered';
|
|
1910
|
+
logger.log(`agent:recover — ${verb} ${recovered.length} abandoned session(s) older than ${olderThanLabel} (${dbPath})`);
|
|
1911
|
+
for (const r of recovered) {
|
|
1912
|
+
logger.log(` ${r.agent} started: ${r.startedAt || '?'} run: ${r.runKey || '—'} [${r.source}]`);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
if (skipped.length > 0) {
|
|
1916
|
+
logger.log(` skipped ${skipped.length} session(s) within threshold.`);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
return { ok: true, targetDir, dbPath, dryRun, cutoff: cutoffIso, recovered, skipped };
|
|
1920
|
+
} finally {
|
|
1921
|
+
db.close();
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
|
|
1686
1926
|
/**
|
|
1687
1927
|
* aioson runtime:prune [targetDir] --older-than=<days>
|
|
1688
1928
|
*
|
|
@@ -1767,6 +2007,8 @@ module.exports = {
|
|
|
1767
2007
|
runRuntimeFail,
|
|
1768
2008
|
runRuntimeStatus,
|
|
1769
2009
|
runRuntimeLog,
|
|
2010
|
+
runAgentDone,
|
|
2011
|
+
runAgentRecover,
|
|
1770
2012
|
runRuntimeSessionStart,
|
|
1771
2013
|
runRuntimeSessionLog,
|
|
1772
2014
|
runRuntimeSessionFinish,
|
|
@@ -8,7 +8,8 @@ const {
|
|
|
8
8
|
calculateClassification,
|
|
9
9
|
normalizeBoolean,
|
|
10
10
|
renderProjectContext,
|
|
11
|
-
writeProjectContext
|
|
11
|
+
writeProjectContext,
|
|
12
|
+
renderSquadApiSection
|
|
12
13
|
} = require('../context-writer');
|
|
13
14
|
const { applyAgentLocale } = require('../locales');
|
|
14
15
|
const { openRuntimeDb, logAgentEvent } = require('../runtime-store');
|
|
@@ -208,6 +209,7 @@ function applyExplicitOverrides(data, options, detectedInstalled) {
|
|
|
208
209
|
const langValue = options.language ?? options.lang;
|
|
209
210
|
if (langValue !== undefined) output.conversationLanguage = String(langValue);
|
|
210
211
|
if (hasOption(options, 'design-skill')) output.designSkill = String(options['design-skill']);
|
|
212
|
+
if (hasOption(options, 'test-runner')) output.testRunner = String(options['test-runner']);
|
|
211
213
|
if (hasOption(options, 'web3-enabled')) {
|
|
212
214
|
output.web3Enabled = normalizeBoolean(options['web3-enabled'], output.web3Enabled);
|
|
213
215
|
}
|
|
@@ -469,6 +471,7 @@ async function runSetupContext({ args, options, logger, t }) {
|
|
|
469
471
|
frameworkInstalled: detectedInstalled,
|
|
470
472
|
conversationLanguage: 'en',
|
|
471
473
|
designSkill: '',
|
|
474
|
+
testRunner: '',
|
|
472
475
|
web3Enabled: inferredWeb3Enabled,
|
|
473
476
|
web3Networks: inferredWeb3Enabled ? inferWeb3Network(detectedFramework) : '',
|
|
474
477
|
contractFramework: inferredWeb3Enabled ? detectedFramework : '',
|
|
@@ -616,7 +619,9 @@ async function runSetupContext({ args, options, logger, t }) {
|
|
|
616
619
|
}
|
|
617
620
|
|
|
618
621
|
const content = renderProjectContext(data);
|
|
619
|
-
const
|
|
622
|
+
const squadApiSection = await renderSquadApiSection(targetDir);
|
|
623
|
+
const fullContent = squadApiSection ? content + '\n' + squadApiSection + '\n' : content;
|
|
624
|
+
const filePath = await writeProjectContext(targetDir, fullContent);
|
|
620
625
|
const localeApplyResult = await applyAgentLocale(targetDir, data.conversationLanguage, {
|
|
621
626
|
dryRun: false
|
|
622
627
|
});
|