@monoes/monomindcli 1.11.13 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/generated/channel-intelligence-director.md +87 -0
- package/.claude/agents/generated/chief-growth-officer.md +88 -0
- package/.claude/agents/generated/content-seo-strategist.md +90 -0
- package/.claude/agents/generated/developer-community-strategist.md +91 -0
- package/.claude/agents/generated/outreach-partnership-strategist.md +90 -0
- package/.claude/agents/generated/social-media-strategist.md +91 -0
- package/.claude/agents/generated/video-visual-strategist.md +90 -0
- package/.claude/commands/mastermind/master.md +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +13 -4
- package/.claude/helpers/control-start.cjs +5 -0
- package/.claude/helpers/event-logger.cjs +114 -0
- package/.claude/helpers/handlers/adr-draft-handler.cjs +19 -5
- package/.claude/helpers/handlers/agent-start-handler.cjs +13 -4
- package/.claude/helpers/handlers/compact-handler.cjs +2 -0
- package/.claude/helpers/handlers/edit-handler.cjs +1 -1
- package/.claude/helpers/handlers/gates-handler.cjs +3 -0
- package/.claude/helpers/handlers/graph-status-handler.cjs +14 -8
- package/.claude/helpers/handlers/loops-status-handler.cjs +5 -2
- package/.claude/helpers/handlers/route-handler.cjs +13 -6
- package/.claude/helpers/handlers/session-handler.cjs +11 -4
- package/.claude/helpers/handlers/session-restore-handler.cjs +21 -11
- package/.claude/helpers/handlers/task-handler.cjs +13 -5
- package/.claude/helpers/intelligence.cjs +7 -2
- package/.claude/helpers/loop-tracker.cjs +15 -3
- package/.claude/helpers/memory.cjs +6 -1
- package/.claude/helpers/router.cjs +5 -2
- package/.claude/helpers/session.cjs +2 -0
- package/.claude/helpers/statusline.cjs +10 -2
- package/.claude/helpers/utils/micro-agents.cjs +20 -4
- package/.claude/skills/mastermind/_protocol.md +25 -15
- package/.claude/skills/mastermind/architect.md +3 -3
- package/.claude/skills/mastermind/autodev.md +4 -2
- package/.claude/skills/mastermind/idea.md +10 -0
- package/.claude/skills/mastermind/ops.md +3 -3
- package/.claude/skills/mastermind/runorg.md +153 -86
- package/dist/src/agents/registry-builder.d.ts.map +1 -1
- package/dist/src/agents/registry-builder.js +2 -0
- package/dist/src/agents/registry-builder.js.map +1 -1
- package/dist/src/autopilot-state.d.ts.map +1 -1
- package/dist/src/autopilot-state.js +10 -5
- package/dist/src/autopilot-state.js.map +1 -1
- package/dist/src/benchmarks/benchmark-runner.d.ts.map +1 -1
- package/dist/src/benchmarks/benchmark-runner.js +13 -0
- package/dist/src/benchmarks/benchmark-runner.js.map +1 -1
- package/dist/src/benchmarks/metric-evaluators.d.ts.map +1 -1
- package/dist/src/benchmarks/metric-evaluators.js +20 -9
- package/dist/src/benchmarks/metric-evaluators.js.map +1 -1
- package/dist/src/browser/actions.d.ts.map +1 -1
- package/dist/src/browser/actions.js +10 -3
- package/dist/src/browser/actions.js.map +1 -1
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +12 -2
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/cdp.d.ts.map +1 -1
- package/dist/src/browser/cdp.js +21 -3
- package/dist/src/browser/cdp.js.map +1 -1
- package/dist/src/browser/har.d.ts.map +1 -1
- package/dist/src/browser/har.js +27 -5
- package/dist/src/browser/har.js.map +1 -1
- package/dist/src/commands/agent.d.ts.map +1 -1
- package/dist/src/commands/agent.js +11 -8
- package/dist/src/commands/agent.js.map +1 -1
- package/dist/src/commands/analyze.d.ts.map +1 -1
- package/dist/src/commands/analyze.js +36 -21
- package/dist/src/commands/analyze.js.map +1 -1
- package/dist/src/commands/autopilot.d.ts.map +1 -1
- package/dist/src/commands/autopilot.js +12 -4
- package/dist/src/commands/autopilot.js.map +1 -1
- package/dist/src/commands/benchmark.d.ts.map +1 -1
- package/dist/src/commands/benchmark.js +51 -8
- package/dist/src/commands/benchmark.js.map +1 -1
- package/dist/src/commands/browse.d.ts.map +1 -1
- package/dist/src/commands/browse.js +5 -2
- package/dist/src/commands/browse.js.map +1 -1
- package/dist/src/commands/claims.d.ts.map +1 -1
- package/dist/src/commands/claims.js +29 -11
- package/dist/src/commands/claims.js.map +1 -1
- package/dist/src/commands/cleanup.d.ts.map +1 -1
- package/dist/src/commands/cleanup.js +25 -5
- package/dist/src/commands/cleanup.js.map +1 -1
- package/dist/src/commands/config.d.ts.map +1 -1
- package/dist/src/commands/config.js +15 -7
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/daemon.d.ts.map +1 -1
- package/dist/src/commands/daemon.js +6 -0
- package/dist/src/commands/daemon.js.map +1 -1
- package/dist/src/commands/deployment.d.ts.map +1 -1
- package/dist/src/commands/deployment.js +34 -19
- package/dist/src/commands/deployment.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +97 -20
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/guidance.d.ts.map +1 -1
- package/dist/src/commands/guidance.js +15 -2
- package/dist/src/commands/guidance.js.map +1 -1
- package/dist/src/commands/hive-mind.d.ts.map +1 -1
- package/dist/src/commands/hive-mind.js +37 -14
- package/dist/src/commands/hive-mind.js.map +1 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +42 -25
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +9 -4
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/issues.d.ts.map +1 -1
- package/dist/src/commands/issues.js +29 -26
- package/dist/src/commands/issues.js.map +1 -1
- package/dist/src/commands/mcp.d.ts.map +1 -1
- package/dist/src/commands/mcp.js +11 -5
- package/dist/src/commands/mcp.js.map +1 -1
- package/dist/src/commands/memory.d.ts.map +1 -1
- package/dist/src/commands/memory.js +10 -0
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/migrate.js +5 -5
- package/dist/src/commands/migrate.js.map +1 -1
- package/dist/src/commands/monograph.d.ts.map +1 -1
- package/dist/src/commands/monograph.js +18 -5
- package/dist/src/commands/monograph.js.map +1 -1
- package/dist/src/commands/monovector/backup.d.ts.map +1 -1
- package/dist/src/commands/monovector/backup.js +8 -2
- package/dist/src/commands/monovector/backup.js.map +1 -1
- package/dist/src/commands/monovector/benchmark.d.ts.map +1 -1
- package/dist/src/commands/monovector/benchmark.js +20 -7
- package/dist/src/commands/monovector/benchmark.js.map +1 -1
- package/dist/src/commands/monovector/import.d.ts.map +1 -1
- package/dist/src/commands/monovector/import.js +15 -0
- package/dist/src/commands/monovector/import.js.map +1 -1
- package/dist/src/commands/monovector/migrate.d.ts.map +1 -1
- package/dist/src/commands/monovector/migrate.js +4 -1
- package/dist/src/commands/monovector/migrate.js.map +1 -1
- package/dist/src/commands/monovector/optimize.d.ts.map +1 -1
- package/dist/src/commands/monovector/optimize.js +11 -0
- package/dist/src/commands/monovector/optimize.js.map +1 -1
- package/dist/src/commands/monovector/setup.d.ts.map +1 -1
- package/dist/src/commands/monovector/setup.js +11 -1
- package/dist/src/commands/monovector/setup.js.map +1 -1
- package/dist/src/commands/neural.js +1 -1
- package/dist/src/commands/neural.js.map +1 -1
- package/dist/src/commands/performance.d.ts.map +1 -1
- package/dist/src/commands/performance.js +20 -7
- package/dist/src/commands/performance.js.map +1 -1
- package/dist/src/commands/platforms.d.ts.map +1 -1
- package/dist/src/commands/platforms.js +90 -8
- package/dist/src/commands/platforms.js.map +1 -1
- package/dist/src/commands/plugins.d.ts.map +1 -1
- package/dist/src/commands/plugins.js +12 -5
- package/dist/src/commands/plugins.js.map +1 -1
- package/dist/src/commands/process.d.ts.map +1 -1
- package/dist/src/commands/process.js +33 -10
- package/dist/src/commands/process.js.map +1 -1
- package/dist/src/commands/progress.d.ts.map +1 -1
- package/dist/src/commands/progress.js +5 -3
- package/dist/src/commands/progress.js.map +1 -1
- package/dist/src/commands/providers.js +5 -5
- package/dist/src/commands/providers.js.map +1 -1
- package/dist/src/commands/replay.d.ts.map +1 -1
- package/dist/src/commands/replay.js +8 -2
- package/dist/src/commands/replay.js.map +1 -1
- package/dist/src/commands/route.d.ts.map +1 -1
- package/dist/src/commands/route.js +27 -7
- package/dist/src/commands/route.js.map +1 -1
- package/dist/src/commands/security.d.ts.map +1 -1
- package/dist/src/commands/security.js +4 -0
- package/dist/src/commands/security.js.map +1 -1
- package/dist/src/commands/session.d.ts.map +1 -1
- package/dist/src/commands/session.js +12 -1
- package/dist/src/commands/session.js.map +1 -1
- package/dist/src/commands/start.d.ts.map +1 -1
- package/dist/src/commands/start.js +11 -4
- package/dist/src/commands/start.js.map +1 -1
- package/dist/src/commands/status.d.ts.map +1 -1
- package/dist/src/commands/status.js +7 -4
- package/dist/src/commands/status.js.map +1 -1
- package/dist/src/commands/swarm.d.ts.map +1 -1
- package/dist/src/commands/swarm.js +27 -13
- package/dist/src/commands/swarm.js.map +1 -1
- package/dist/src/commands/task.d.ts.map +1 -1
- package/dist/src/commands/task.js +26 -11
- package/dist/src/commands/task.js.map +1 -1
- package/dist/src/commands/tokens.d.ts.map +1 -1
- package/dist/src/commands/tokens.js +7 -2
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/transfer-store.d.ts.map +1 -1
- package/dist/src/commands/transfer-store.js +36 -22
- package/dist/src/commands/transfer-store.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +15 -3
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/workflow.d.ts.map +1 -1
- package/dist/src/commands/workflow.js +39 -6
- package/dist/src/commands/workflow.js.map +1 -1
- package/dist/src/consensus/audit-writer.d.ts.map +1 -1
- package/dist/src/consensus/audit-writer.js +18 -7
- package/dist/src/consensus/audit-writer.js.map +1 -1
- package/dist/src/consensus/vote-signer.d.ts.map +1 -1
- package/dist/src/consensus/vote-signer.js +25 -8
- package/dist/src/consensus/vote-signer.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +14 -11
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/shared-instructions-generator.d.ts.map +1 -1
- package/dist/src/init/shared-instructions-generator.js +20 -4
- package/dist/src/init/shared-instructions-generator.js.map +1 -1
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +36 -15
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/mcp-tools/a2a-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/a2a-tools.js +98 -13
- package/dist/src/mcp-tools/a2a-tools.js.map +1 -1
- package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/agent-tools.js +16 -3
- package/dist/src/mcp-tools/agent-tools.js.map +1 -1
- package/dist/src/mcp-tools/analyze-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/analyze-tools.js +80 -17
- package/dist/src/mcp-tools/analyze-tools.js.map +1 -1
- package/dist/src/mcp-tools/browser-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/browser-tools.js +84 -22
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/claims-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/claims-tools.js +35 -7
- package/dist/src/mcp-tools/claims-tools.js.map +1 -1
- package/dist/src/mcp-tools/config-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/config-tools.js +82 -17
- package/dist/src/mcp-tools/config-tools.js.map +1 -1
- package/dist/src/mcp-tools/coordination-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/coordination-tools.js +37 -4
- package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
- package/dist/src/mcp-tools/daa-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/daa-tools.js +49 -7
- package/dist/src/mcp-tools/daa-tools.js.map +1 -1
- package/dist/src/mcp-tools/embeddings-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/embeddings-tools.js +45 -18
- package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
- package/dist/src/mcp-tools/github-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/github-tools.js +75 -25
- package/dist/src/mcp-tools/github-tools.js.map +1 -1
- package/dist/src/mcp-tools/guidance-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/guidance-tools.js +32 -10
- package/dist/src/mcp-tools/guidance-tools.js.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.js +91 -20
- package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +188 -29
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/memory-tools.js +25 -7
- package/dist/src/mcp-tools/memory-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph-compat.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-compat.js +11 -2
- package/dist/src/mcp-tools/monograph-compat.js.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.js +148 -26
- package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
- package/dist/src/mcp-tools/neural-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/neural-tools.js +44 -9
- package/dist/src/mcp-tools/neural-tools.js.map +1 -1
- package/dist/src/mcp-tools/performance-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/performance-tools.js +45 -10
- package/dist/src/mcp-tools/performance-tools.js.map +1 -1
- package/dist/src/mcp-tools/progress-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/progress-tools.js +7 -4
- package/dist/src/mcp-tools/progress-tools.js.map +1 -1
- package/dist/src/mcp-tools/request-tracker.d.ts.map +1 -1
- package/dist/src/mcp-tools/request-tracker.js +15 -1
- package/dist/src/mcp-tools/request-tracker.js.map +1 -1
- package/dist/src/mcp-tools/security-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/security-tools.js +61 -9
- package/dist/src/mcp-tools/security-tools.js.map +1 -1
- package/dist/src/mcp-tools/session-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/session-tools.js +45 -14
- package/dist/src/mcp-tools/session-tools.js.map +1 -1
- package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/swarm-tools.js +15 -3
- package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
- package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/system-tools.js +14 -7
- package/dist/src/mcp-tools/system-tools.js.map +1 -1
- package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/task-tools.js +52 -10
- package/dist/src/mcp-tools/task-tools.js.map +1 -1
- package/dist/src/mcp-tools/terminal-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/terminal-tools.js +40 -6
- package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
- package/dist/src/mcp-tools/transfer-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/transfer-tools.js +37 -4
- package/dist/src/mcp-tools/transfer-tools.js.map +1 -1
- package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/workflow-tools.js +29 -6
- package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
- package/dist/src/memory/ewc-consolidation.d.ts.map +1 -1
- package/dist/src/memory/ewc-consolidation.js +26 -10
- package/dist/src/memory/ewc-consolidation.js.map +1 -1
- package/dist/src/memory/intelligence.d.ts.map +1 -1
- package/dist/src/memory/intelligence.js +80 -19
- package/dist/src/memory/intelligence.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +21 -2
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +67 -3
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/memory/sona-optimizer.d.ts.map +1 -1
- package/dist/src/memory/sona-optimizer.js +14 -4
- package/dist/src/memory/sona-optimizer.js.map +1 -1
- package/dist/src/monovector/command-outcomes.d.ts.map +1 -1
- package/dist/src/monovector/command-outcomes.js +43 -7
- package/dist/src/monovector/command-outcomes.js.map +1 -1
- package/dist/src/monovector/coverage-router.d.ts.map +1 -1
- package/dist/src/monovector/coverage-router.js +8 -4
- package/dist/src/monovector/coverage-router.js.map +1 -1
- package/dist/src/monovector/coverage-tools.d.ts.map +1 -1
- package/dist/src/monovector/coverage-tools.js +6 -3
- package/dist/src/monovector/coverage-tools.js.map +1 -1
- package/dist/src/monovector/diff-classifier.d.ts.map +1 -1
- package/dist/src/monovector/diff-classifier.js +13 -0
- package/dist/src/monovector/diff-classifier.js.map +1 -1
- package/dist/src/monovector/route-outcomes.d.ts +2 -1
- package/dist/src/monovector/route-outcomes.d.ts.map +1 -1
- package/dist/src/monovector/route-outcomes.js +46 -4
- package/dist/src/monovector/route-outcomes.js.map +1 -1
- package/dist/src/plugins/manager.d.ts.map +1 -1
- package/dist/src/plugins/manager.js +8 -3
- package/dist/src/plugins/manager.js.map +1 -1
- package/dist/src/plugins/store/discovery.d.ts.map +1 -1
- package/dist/src/plugins/store/discovery.js +46 -2
- package/dist/src/plugins/store/discovery.js.map +1 -1
- package/dist/src/plugins/store/search.d.ts.map +1 -1
- package/dist/src/plugins/store/search.js +5 -4
- package/dist/src/plugins/store/search.js.map +1 -1
- package/dist/src/production/circuit-breaker.d.ts.map +1 -1
- package/dist/src/production/circuit-breaker.js +17 -3
- package/dist/src/production/circuit-breaker.js.map +1 -1
- package/dist/src/production/error-handler.d.ts.map +1 -1
- package/dist/src/production/error-handler.js +3 -0
- package/dist/src/production/error-handler.js.map +1 -1
- package/dist/src/production/monitoring.d.ts.map +1 -1
- package/dist/src/production/monitoring.js +20 -3
- package/dist/src/production/monitoring.js.map +1 -1
- package/dist/src/production/rate-limiter.d.ts.map +1 -1
- package/dist/src/production/rate-limiter.js +13 -4
- package/dist/src/production/rate-limiter.js.map +1 -1
- package/dist/src/production/retry.d.ts.map +1 -1
- package/dist/src/production/retry.js +17 -9
- package/dist/src/production/retry.js.map +1 -1
- package/dist/src/routing/embed-worker.js +6 -2
- package/dist/src/routing/embed-worker.js.map +1 -1
- package/dist/src/routing/embedder.d.ts.map +1 -1
- package/dist/src/routing/embedder.js +0 -0
- package/dist/src/routing/embedder.js.map +1 -1
- package/dist/src/routing/llm-caller.d.ts.map +1 -1
- package/dist/src/routing/llm-caller.js +13 -2
- package/dist/src/routing/llm-caller.js.map +1 -1
- package/dist/src/routing/route-layer-factory.d.ts.map +1 -1
- package/dist/src/routing/route-layer-factory.js +18 -3
- package/dist/src/routing/route-layer-factory.js.map +1 -1
- package/dist/src/services/claim-service.d.ts +1 -0
- package/dist/src/services/claim-service.d.ts.map +1 -1
- package/dist/src/services/claim-service.js +8 -0
- package/dist/src/services/claim-service.js.map +1 -1
- package/dist/src/services/config-file-manager.d.ts.map +1 -1
- package/dist/src/services/config-file-manager.js +14 -2
- package/dist/src/services/config-file-manager.js.map +1 -1
- package/dist/src/services/headless-worker-executor.d.ts.map +1 -1
- package/dist/src/services/headless-worker-executor.js +18 -2
- package/dist/src/services/headless-worker-executor.js.map +1 -1
- package/dist/src/services/worker-daemon.d.ts.map +1 -1
- package/dist/src/services/worker-daemon.js +53 -12
- package/dist/src/services/worker-daemon.js.map +1 -1
- package/dist/src/transfer/anonymization/index.d.ts +0 -3
- package/dist/src/transfer/anonymization/index.d.ts.map +1 -1
- package/dist/src/transfer/anonymization/index.js +16 -1
- package/dist/src/transfer/anonymization/index.js.map +1 -1
- package/dist/src/transfer/export.d.ts.map +1 -1
- package/dist/src/transfer/export.js +8 -0
- package/dist/src/transfer/export.js.map +1 -1
- package/dist/src/transfer/ipfs/upload.d.ts.map +1 -1
- package/dist/src/transfer/ipfs/upload.js +33 -3
- package/dist/src/transfer/ipfs/upload.js.map +1 -1
- package/dist/src/transfer/serialization/cfp.d.ts.map +1 -1
- package/dist/src/transfer/serialization/cfp.js +9 -3
- package/dist/src/transfer/serialization/cfp.js.map +1 -1
- package/dist/src/transfer/storage/gcs.d.ts.map +1 -1
- package/dist/src/transfer/storage/gcs.js +37 -3
- package/dist/src/transfer/storage/gcs.js.map +1 -1
- package/dist/src/transfer/store/discovery.d.ts.map +1 -1
- package/dist/src/transfer/store/discovery.js +45 -3
- package/dist/src/transfer/store/discovery.js.map +1 -1
- package/dist/src/transfer/store/download.d.ts.map +1 -1
- package/dist/src/transfer/store/download.js +5 -0
- package/dist/src/transfer/store/download.js.map +1 -1
- package/dist/src/transfer/store/publish.d.ts.map +1 -1
- package/dist/src/transfer/store/publish.js +13 -1
- package/dist/src/transfer/store/publish.js.map +1 -1
- package/dist/src/transfer/store/registry.d.ts +8 -0
- package/dist/src/transfer/store/registry.d.ts.map +1 -1
- package/dist/src/transfer/store/registry.js +30 -5
- package/dist/src/transfer/store/registry.js.map +1 -1
- package/dist/src/transfer/store/search.d.ts.map +1 -1
- package/dist/src/transfer/store/search.js +20 -5
- package/dist/src/transfer/store/search.js.map +1 -1
- package/dist/src/ui/collector.mjs +39 -5
- package/dist/src/ui/dashboard.html +926 -1268
- package/dist/src/ui/orgs.html +722 -12
- package/dist/src/ui/server.mjs +573 -134
- package/dist/src/update/checker.d.ts.map +1 -1
- package/dist/src/update/checker.js +59 -7
- package/dist/src/update/checker.js.map +1 -1
- package/dist/src/update/executor.d.ts.map +1 -1
- package/dist/src/update/executor.js +50 -3
- package/dist/src/update/executor.js.map +1 -1
- package/dist/src/update/index.d.ts.map +1 -1
- package/dist/src/update/index.js +18 -1
- package/dist/src/update/index.js.map +1 -1
- package/dist/src/update/rate-limiter.d.ts +6 -0
- package/dist/src/update/rate-limiter.d.ts.map +1 -1
- package/dist/src/update/rate-limiter.js +79 -7
- package/dist/src/update/rate-limiter.js.map +1 -1
- package/dist/src/update/validator.d.ts.map +1 -1
- package/dist/src/update/validator.js +52 -1
- package/dist/src/update/validator.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -3
- package/dist/src/ui/data/mastermind-events.jsonl +0 -59
package/dist/src/ui/orgs.html
CHANGED
|
@@ -285,6 +285,43 @@ html, body {
|
|
|
285
285
|
.meta-cell-label { font-size: 8px; letter-spacing: 2px; color: var(--dim); margin-bottom: 4px; }
|
|
286
286
|
.meta-cell-value { font-size: 11px; color: var(--text); }
|
|
287
287
|
|
|
288
|
+
/* ── Live status strip ─────────────────────────────────────────── */
|
|
289
|
+
#live-strip {
|
|
290
|
+
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
|
|
291
|
+
background: oklch(8% 0.01 186); border: 1px solid var(--border);
|
|
292
|
+
border-radius: 4px; padding: 8px 12px; font-size: 10px; color: var(--dim);
|
|
293
|
+
letter-spacing: 0.5px;
|
|
294
|
+
}
|
|
295
|
+
#ls-state { display: flex; align-items: center; gap: 5px; }
|
|
296
|
+
.ls-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dim); flex-shrink: 0; }
|
|
297
|
+
.ls-dot.running { background: oklch(65% 0.20 150); }
|
|
298
|
+
@media (prefers-reduced-motion: no-preference) { .ls-dot.running { animation: ls-pulse 2s ease-in-out infinite; } }
|
|
299
|
+
@keyframes ls-pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
|
|
300
|
+
#ls-label { font-size: 9px; letter-spacing: 2px; }
|
|
301
|
+
.ls-metric { font-size: 10px; color: var(--muted); }
|
|
302
|
+
.ls-sparkline-wrap { display: flex; align-items: flex-end; gap: 1px; height: 20px; margin-left: auto; }
|
|
303
|
+
.ls-bar { width: 6px; border-radius: 1px; background: oklch(62% 0.20 186 / 0.4); min-height: 2px; }
|
|
304
|
+
.ls-bar.active { background: oklch(62% 0.20 186 / 0.8); }
|
|
305
|
+
#clf-wrap {
|
|
306
|
+
background: oklch(8% 0.01 186); border: 1px solid var(--border);
|
|
307
|
+
border-radius: 4px; overflow: hidden;
|
|
308
|
+
}
|
|
309
|
+
#clf-header {
|
|
310
|
+
font-size: 8px; letter-spacing: 3px; color: var(--dim); padding: 6px 12px;
|
|
311
|
+
border-bottom: 1px solid var(--border);
|
|
312
|
+
}
|
|
313
|
+
#clf-rows { min-height: 48px; max-height: 160px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--teal-dim) transparent; }
|
|
314
|
+
.clf-row {
|
|
315
|
+
display: grid; grid-template-columns: 80px 70px 1fr;
|
|
316
|
+
gap: 8px; padding: 5px 12px;
|
|
317
|
+
font-size: 10px; border-bottom: 1px solid oklch(100% 0 0 / 0.03);
|
|
318
|
+
}
|
|
319
|
+
.clf-row.new { animation: clf-fadein 0.3s ease; }
|
|
320
|
+
@keyframes clf-fadein { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
|
|
321
|
+
.clf-time { color: var(--dim); font-variant-numeric: tabular-nums; }
|
|
322
|
+
.clf-type { color: var(--accent); }
|
|
323
|
+
.clf-msg { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
324
|
+
|
|
288
325
|
/* ── Roles list ─────────────────────────────────────────────────── */
|
|
289
326
|
#roles-pane { padding: 20px; }
|
|
290
327
|
|
|
@@ -364,6 +401,116 @@ html, body {
|
|
|
364
401
|
.hc-value.amber { color: var(--amber); }
|
|
365
402
|
.hc-value.red { color: var(--red); }
|
|
366
403
|
|
|
404
|
+
/* ── Chat tab ───────────────────────────────────────────────────── */
|
|
405
|
+
#chat-pane {
|
|
406
|
+
display: flex; flex-direction: column; height: 100%;
|
|
407
|
+
overflow: hidden;
|
|
408
|
+
}
|
|
409
|
+
#chat-session-bar {
|
|
410
|
+
display: flex; align-items: center; gap: 8px;
|
|
411
|
+
padding: 10px 20px 8px;
|
|
412
|
+
border-bottom: 1px solid var(--border);
|
|
413
|
+
flex-shrink: 0; flex-wrap: wrap;
|
|
414
|
+
}
|
|
415
|
+
#chat-sess-label { font-size: 8px; letter-spacing: 2px; color: var(--dim); }
|
|
416
|
+
#chat-sess-select {
|
|
417
|
+
background: var(--bg-panel); color: var(--muted);
|
|
418
|
+
border: 1px solid var(--border); border-radius: 3px;
|
|
419
|
+
font-size: 9px; font-family: var(--mono); letter-spacing: 0.5px;
|
|
420
|
+
padding: 3px 6px; cursor: pointer; max-width: 260px;
|
|
421
|
+
}
|
|
422
|
+
#chat-sess-select:focus { outline: none; border-color: var(--teal-dim); }
|
|
423
|
+
#chat-live-dot {
|
|
424
|
+
width: 5px; height: 5px; border-radius: 50%;
|
|
425
|
+
background: var(--dim); margin-left: auto; flex-shrink: 0;
|
|
426
|
+
transition: background 0.4s;
|
|
427
|
+
}
|
|
428
|
+
#chat-live-dot.on { background: var(--green); animation: livepulse 2.2s ease-in-out infinite; }
|
|
429
|
+
#chat-live-label { font-size: 8px; color: var(--dim); }
|
|
430
|
+
|
|
431
|
+
#chat-feed-wrap {
|
|
432
|
+
flex: 1; overflow-y: auto; padding: 12px 20px;
|
|
433
|
+
display: flex; flex-direction: column; gap: 5px;
|
|
434
|
+
scrollbar-width: thin;
|
|
435
|
+
scrollbar-color: var(--teal-dim) transparent;
|
|
436
|
+
}
|
|
437
|
+
#chat-feed-wrap::-webkit-scrollbar { width: 4px; }
|
|
438
|
+
#chat-feed-wrap::-webkit-scrollbar-thumb { background: var(--teal-dim); border-radius: 2px; }
|
|
439
|
+
|
|
440
|
+
#chat-feed-empty {
|
|
441
|
+
font-size: 10px; color: var(--dim); text-align: center;
|
|
442
|
+
padding: 30px 0; line-height: 2;
|
|
443
|
+
}
|
|
444
|
+
#chat-agent-bar {
|
|
445
|
+
display: flex; align-items: center; gap: 6px;
|
|
446
|
+
padding: 6px 20px 7px;
|
|
447
|
+
border-bottom: 1px solid var(--border);
|
|
448
|
+
flex-shrink: 0; flex-wrap: wrap;
|
|
449
|
+
}
|
|
450
|
+
#chat-agent-label { font-size: 8px; letter-spacing: 2px; color: var(--dim); flex-shrink: 0; }
|
|
451
|
+
.chat-agent-pill {
|
|
452
|
+
font-size: 8px; padding: 2px 8px; border-radius: 10px;
|
|
453
|
+
border: 1px solid var(--border); color: var(--muted);
|
|
454
|
+
background: transparent; cursor: pointer; letter-spacing: 0.3px;
|
|
455
|
+
font-family: var(--mono); transition: border-color 0.15s, color 0.15s;
|
|
456
|
+
}
|
|
457
|
+
.chat-agent-pill:hover { border-color: var(--teal-dim); color: var(--text); }
|
|
458
|
+
.chat-agent-pill.active { border-color: var(--teal); color: var(--teal); background: oklch(62% 0.20 186 / 0.07); }
|
|
459
|
+
|
|
460
|
+
.cmsg { display: flex; flex-direction: column; max-width: 92%; }
|
|
461
|
+
.cmsg.csys { align-self: center; max-width: 100%; }
|
|
462
|
+
.cmsg.cagent { align-self: flex-start; }
|
|
463
|
+
.cmsg.cic { align-self: flex-start; }
|
|
464
|
+
|
|
465
|
+
@keyframes cmsg-in { from{opacity:0;transform:translateY(3px)} to{opacity:1;transform:none} }
|
|
466
|
+
.cmsg.new { animation: cmsg-in 0.18s ease-out; }
|
|
467
|
+
|
|
468
|
+
.cmsg.csys .cbubble {
|
|
469
|
+
background: oklch(10% 0.008 186);
|
|
470
|
+
border: 1px solid var(--border);
|
|
471
|
+
border-radius: 6px; padding: 4px 12px;
|
|
472
|
+
font-size: 9px; color: var(--dim); letter-spacing: 0.3px;
|
|
473
|
+
text-align: center;
|
|
474
|
+
}
|
|
475
|
+
.cmsg.cagent .cbubble {
|
|
476
|
+
background: oklch(11% 0.016 186);
|
|
477
|
+
border: 1px solid var(--teal-dim);
|
|
478
|
+
border-radius: 2px 8px 8px 8px;
|
|
479
|
+
padding: 7px 11px;
|
|
480
|
+
color: oklch(70% 0.010 186);
|
|
481
|
+
font-size: 11px; line-height: 1.6;
|
|
482
|
+
word-break: break-word; white-space: pre-wrap;
|
|
483
|
+
}
|
|
484
|
+
.cmsg.cic .cbubble {
|
|
485
|
+
background: oklch(10% 0.013 295);
|
|
486
|
+
border: 1px solid oklch(68% 0.18 295 / 0.22);
|
|
487
|
+
border-radius: 2px 8px 8px 8px;
|
|
488
|
+
padding: 7px 11px;
|
|
489
|
+
color: oklch(68% 0.010 295);
|
|
490
|
+
font-size: 11px; line-height: 1.6;
|
|
491
|
+
word-break: break-word; white-space: pre-wrap;
|
|
492
|
+
}
|
|
493
|
+
.cmsg-meta {
|
|
494
|
+
display: flex; align-items: center; gap: 5px;
|
|
495
|
+
margin-bottom: 3px; flex-wrap: wrap;
|
|
496
|
+
}
|
|
497
|
+
.cmsg.csys .cmsg-meta { display: none; }
|
|
498
|
+
.ctag {
|
|
499
|
+
font-size: 8px; padding: 1px 6px; border-radius: 10px;
|
|
500
|
+
border: 1px solid var(--teal-dim); color: var(--teal);
|
|
501
|
+
letter-spacing: 0.4px; flex-shrink: 0;
|
|
502
|
+
}
|
|
503
|
+
.ctag.sender { border-color: oklch(68% 0.18 295 / 0.35); color: oklch(68% 0.14 295); }
|
|
504
|
+
.ctag.receiver{ border-color: oklch(78% 0.18 80 / 0.35); color: var(--amber); }
|
|
505
|
+
.cic-arrow { font-size: 9px; color: var(--dim); }
|
|
506
|
+
.cts { font-size: 8px; color: var(--dim); margin-left: auto; }
|
|
507
|
+
.cevtype {
|
|
508
|
+
font-size: 7px; padding: 1px 4px; border-radius: 2px;
|
|
509
|
+
background: oklch(62% 0.20 186 / 0.07);
|
|
510
|
+
border: 1px solid var(--border); color: var(--dim);
|
|
511
|
+
letter-spacing: 0.3px;
|
|
512
|
+
}
|
|
513
|
+
|
|
367
514
|
/* ── Communication edges (SVG in chart) ─────────────────────────── */
|
|
368
515
|
.oc-edge { stroke: var(--teal); stroke-opacity: 0.25; stroke-width: 1; fill: none; }
|
|
369
516
|
.oc-edge.command { stroke: var(--teal); stroke-opacity: 0.4; }
|
|
@@ -397,8 +544,8 @@ html, body {
|
|
|
397
544
|
|
|
398
545
|
/* Arrow markers are inline in the SVG */
|
|
399
546
|
|
|
400
|
-
/* ── Copy
|
|
401
|
-
.oi-copy-btn {
|
|
547
|
+
/* ── Copy / Export / Import buttons on org items ────────────────── */
|
|
548
|
+
.oi-copy-btn, .oi-export-btn, .oi-import-btn {
|
|
402
549
|
display: none;
|
|
403
550
|
flex-shrink: 0;
|
|
404
551
|
background: none;
|
|
@@ -414,14 +561,49 @@ html, body {
|
|
|
414
561
|
line-height: 1.4;
|
|
415
562
|
white-space: nowrap;
|
|
416
563
|
}
|
|
417
|
-
.org-item:hover .oi-copy-btn
|
|
564
|
+
.org-item:hover .oi-copy-btn,
|
|
565
|
+
.org-item:hover .oi-export-btn,
|
|
566
|
+
.org-item:hover .oi-import-btn { display: inline-block; }
|
|
418
567
|
.oi-copy-btn:hover {
|
|
419
568
|
color: var(--teal);
|
|
420
569
|
border-color: var(--teal-dim);
|
|
421
570
|
background: var(--teal-glow);
|
|
422
571
|
}
|
|
572
|
+
.oi-export-btn:hover {
|
|
573
|
+
color: var(--green, #4ade80);
|
|
574
|
+
border-color: oklch(60% 0.15 145 / 0.4);
|
|
575
|
+
background: oklch(60% 0.15 145 / 0.08);
|
|
576
|
+
}
|
|
577
|
+
.oi-import-btn:hover {
|
|
578
|
+
color: var(--amber, #facc15);
|
|
579
|
+
border-color: oklch(70% 0.15 85 / 0.4);
|
|
580
|
+
background: oklch(70% 0.15 85 / 0.08);
|
|
581
|
+
}
|
|
423
582
|
|
|
424
583
|
/* ── Copy modal ─────────────────────────────────────────────────── */
|
|
584
|
+
#copy-project-list {
|
|
585
|
+
max-height: 180px;
|
|
586
|
+
overflow-y: auto;
|
|
587
|
+
border: 1px solid var(--border-hi);
|
|
588
|
+
border-radius: 4px;
|
|
589
|
+
margin: 4px 0 10px;
|
|
590
|
+
background: oklch(6% 0.008 186);
|
|
591
|
+
}
|
|
592
|
+
.copy-proj-row {
|
|
593
|
+
padding: 7px 10px;
|
|
594
|
+
font-size: 12px;
|
|
595
|
+
font-family: var(--mono);
|
|
596
|
+
color: var(--text-md);
|
|
597
|
+
cursor: pointer;
|
|
598
|
+
border-bottom: 1px solid var(--border);
|
|
599
|
+
white-space: nowrap;
|
|
600
|
+
overflow: hidden;
|
|
601
|
+
text-overflow: ellipsis;
|
|
602
|
+
}
|
|
603
|
+
.copy-proj-row:last-child { border-bottom: none; }
|
|
604
|
+
.copy-proj-row:hover { background: var(--bg-hover); color: var(--text-hi); }
|
|
605
|
+
.copy-proj-row.selected { background: color-mix(in srgb, var(--teal) 15%, transparent); color: var(--teal); border-left: 2px solid var(--teal); padding-left: 8px; }
|
|
606
|
+
.copy-proj-loading { padding: 10px; font-size: 11px; color: var(--dim); text-align: center; }
|
|
425
607
|
#copy-modal-overlay {
|
|
426
608
|
display: none;
|
|
427
609
|
position: fixed; inset: 0;
|
|
@@ -571,6 +753,7 @@ html, body {
|
|
|
571
753
|
<button class="tab-btn" onclick="switchTab('roles')">ROLES</button>
|
|
572
754
|
<button class="tab-btn" onclick="switchTab('activity')">ACTIVITY</button>
|
|
573
755
|
<button class="tab-btn" onclick="switchTab('health')">HEALTH</button>
|
|
756
|
+
<button class="tab-btn" onclick="switchTab('chat')">CHAT</button>
|
|
574
757
|
</div>
|
|
575
758
|
|
|
576
759
|
<div id="main-body">
|
|
@@ -618,6 +801,23 @@ html, body {
|
|
|
618
801
|
</svg>
|
|
619
802
|
</div>
|
|
620
803
|
|
|
804
|
+
<!-- Live status strip -->
|
|
805
|
+
<div id="live-strip">
|
|
806
|
+
<div id="ls-state">
|
|
807
|
+
<span id="ls-dot" class="ls-dot"></span>
|
|
808
|
+
<span id="ls-label">IDLE</span>
|
|
809
|
+
</div>
|
|
810
|
+
<div id="ls-uptime" class="ls-metric" title="Uptime">—</div>
|
|
811
|
+
<div id="ls-last" class="ls-metric" title="Last event">—</div>
|
|
812
|
+
<div id="ls-epm" class="ls-metric" title="Events / 5 min">—</div>
|
|
813
|
+
<div id="ls-sparkline" class="ls-sparkline-wrap"></div>
|
|
814
|
+
</div>
|
|
815
|
+
<!-- Live event feed -->
|
|
816
|
+
<div id="clf-wrap">
|
|
817
|
+
<div id="clf-header">LIVE EVENTS</div>
|
|
818
|
+
<div id="clf-rows"></div>
|
|
819
|
+
</div>
|
|
820
|
+
|
|
621
821
|
<!-- Legend -->
|
|
622
822
|
<div style="display:flex; gap:16px; flex-wrap:wrap; padding:0 2px;">
|
|
623
823
|
<div style="display:flex; align-items:center; gap:5px; font-size:8px; color:var(--dim);">
|
|
@@ -662,6 +862,26 @@ html, body {
|
|
|
662
862
|
</div>
|
|
663
863
|
</div>
|
|
664
864
|
|
|
865
|
+
<!-- Chat tab -->
|
|
866
|
+
<div class="tab-pane" id="tab-chat">
|
|
867
|
+
<div id="chat-pane">
|
|
868
|
+
<div id="chat-session-bar">
|
|
869
|
+
<span id="chat-sess-label">SESSION</span>
|
|
870
|
+
<select id="chat-sess-select" onchange="selectChatSession(this.value)">
|
|
871
|
+
<option value="">— select a session —</option>
|
|
872
|
+
</select>
|
|
873
|
+
<div id="chat-live-dot"></div>
|
|
874
|
+
<span id="chat-live-label">OFFLINE</span>
|
|
875
|
+
</div>
|
|
876
|
+
<div id="chat-agent-bar" style="display:none">
|
|
877
|
+
<span id="chat-agent-label">AGENT</span>
|
|
878
|
+
</div>
|
|
879
|
+
<div id="chat-feed-wrap">
|
|
880
|
+
<div id="chat-feed-empty">Select a session above to see agent communications.</div>
|
|
881
|
+
</div>
|
|
882
|
+
</div>
|
|
883
|
+
</div>
|
|
884
|
+
|
|
665
885
|
</div><!-- end main-body -->
|
|
666
886
|
</div><!-- end org-detail -->
|
|
667
887
|
</div><!-- end main -->
|
|
@@ -672,12 +892,14 @@ html, body {
|
|
|
672
892
|
<div id="copy-modal">
|
|
673
893
|
<div id="copy-modal-title">COPY ORG TO PROJECT</div>
|
|
674
894
|
<div id="copy-modal-org">—</div>
|
|
675
|
-
<div class="copy-modal-label">DESTINATION PROJECT
|
|
895
|
+
<div class="copy-modal-label">SELECT DESTINATION PROJECT</div>
|
|
896
|
+
<div id="copy-project-list"><div class="copy-proj-loading">Loading projects…</div></div>
|
|
897
|
+
<div class="copy-modal-label" style="margin-top:4px">OR ENTER PATH MANUALLY</div>
|
|
676
898
|
<input id="copy-dest-input" type="text" placeholder="/absolute/path/to/project"
|
|
677
|
-
onkeydown="if(event.key==='Enter')executeCopy(); if(event.key==='Escape')closeCopyModal()"
|
|
899
|
+
onkeydown="if(event.key==='Enter')executeCopy(); if(event.key==='Escape')closeCopyModal()"
|
|
900
|
+
oninput="document.querySelectorAll('.copy-proj-row').forEach(r=>r.classList.remove('selected'))">
|
|
678
901
|
<div id="copy-modal-hint">
|
|
679
|
-
|
|
680
|
-
<span style="color:var(--muted)"><destination>/.monomind/orgs/<name>.json</span>
|
|
902
|
+
Writes to <span style="color:var(--teal)"><destination>/.monomind/orgs/<name>.json</span>
|
|
681
903
|
</div>
|
|
682
904
|
<div id="copy-modal-status"></div>
|
|
683
905
|
<div class="copy-modal-actions">
|
|
@@ -742,12 +964,14 @@ window.switchTab = function(tab) {
|
|
|
742
964
|
(tab === 'chart' && b.textContent === 'ORG CHART') ||
|
|
743
965
|
(tab === 'roles' && b.textContent === 'ROLES') ||
|
|
744
966
|
(tab === 'activity' && b.textContent === 'ACTIVITY') ||
|
|
745
|
-
(tab === 'health' && b.textContent === 'HEALTH')
|
|
967
|
+
(tab === 'health' && b.textContent === 'HEALTH') ||
|
|
968
|
+
(tab === 'chat' && b.textContent === 'CHAT'));
|
|
746
969
|
});
|
|
747
970
|
document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
|
|
748
971
|
const pane = document.getElementById('tab-' + tab);
|
|
749
972
|
if (pane) pane.classList.add('active');
|
|
750
|
-
if (
|
|
973
|
+
if (tab === 'chat') renderChatTab();
|
|
974
|
+
else if (orgDetailData) renderTab(tab);
|
|
751
975
|
};
|
|
752
976
|
|
|
753
977
|
// ── Render all orgs in sidebar ────────────────────────────────────
|
|
@@ -795,6 +1019,8 @@ function renderSidebar() {
|
|
|
795
1019
|
<div class="oi-name">${esc(org.name)}</div>
|
|
796
1020
|
<span class="oi-badge ${org.running ? 'running' : 'idle'}">${org.running ? 'LIVE' : 'IDLE'}</span>
|
|
797
1021
|
<button class="oi-copy-btn" title="Copy org to another project">COPY</button>
|
|
1022
|
+
<button class="oi-export-btn" title="Export org as JSON file">EXPORT</button>
|
|
1023
|
+
<button class="oi-import-btn" title="Import org from JSON file">IMPORT</button>
|
|
798
1024
|
</div>
|
|
799
1025
|
${goalText ? `<div class="oi-goal">${esc(goalText)}</div>` : ''}
|
|
800
1026
|
<div class="oi-meta">
|
|
@@ -806,6 +1032,14 @@ function renderSidebar() {
|
|
|
806
1032
|
e.stopPropagation();
|
|
807
1033
|
openCopyModal(org.name);
|
|
808
1034
|
});
|
|
1035
|
+
item.querySelector('.oi-export-btn').addEventListener('click', e => {
|
|
1036
|
+
e.stopPropagation();
|
|
1037
|
+
exportOrg(org.name);
|
|
1038
|
+
});
|
|
1039
|
+
item.querySelector('.oi-import-btn').addEventListener('click', e => {
|
|
1040
|
+
e.stopPropagation();
|
|
1041
|
+
triggerImportOrg(org.name);
|
|
1042
|
+
});
|
|
809
1043
|
item.addEventListener('click', () => selectOrg(org.name));
|
|
810
1044
|
list.appendChild(item);
|
|
811
1045
|
});
|
|
@@ -814,6 +1048,9 @@ function renderSidebar() {
|
|
|
814
1048
|
// ── Select and load an org ────────────────────────────────────────
|
|
815
1049
|
async function selectOrg(name) {
|
|
816
1050
|
selectedOrg = name;
|
|
1051
|
+
chatCurrentId = null; // reset chat session when org changes
|
|
1052
|
+
orgRunStartMs = null;
|
|
1053
|
+
if (lsUptimeTimer) { clearInterval(lsUptimeTimer); lsUptimeTimer = null; }
|
|
817
1054
|
|
|
818
1055
|
// Update sidebar active state
|
|
819
1056
|
document.querySelectorAll('.org-item').forEach(el => {
|
|
@@ -879,7 +1116,7 @@ function updateHeader(listOrg, data) {
|
|
|
879
1116
|
// ── Tab renderers ─────────────────────────────────────────────────
|
|
880
1117
|
function renderTab(tab) {
|
|
881
1118
|
if (!orgDetailData) return;
|
|
882
|
-
if (tab === 'chart') renderChart();
|
|
1119
|
+
if (tab === 'chart') { renderChart(); initLiveStrip(); }
|
|
883
1120
|
else if (tab === 'roles') renderRoles();
|
|
884
1121
|
else if (tab === 'activity') renderActivity();
|
|
885
1122
|
else if (tab === 'health') renderHealth();
|
|
@@ -1215,6 +1452,18 @@ function renderHealth() {
|
|
|
1215
1452
|
<div class="hc-value ${health.tasks_pending > 5 ? 'amber' : ''}">${health.tasks_pending}</div>
|
|
1216
1453
|
<div class="hc-sub">pending</div>
|
|
1217
1454
|
</div>` : ''}
|
|
1455
|
+
${health?.run_success_rate_7d !== null && health?.run_success_rate_7d !== undefined ? `
|
|
1456
|
+
<div class="health-cell">
|
|
1457
|
+
<div class="hc-label">SUCCESS</div>
|
|
1458
|
+
<div class="hc-value ${health.run_success_rate_7d >= 80 ? 'green' : health.run_success_rate_7d >= 50 ? 'amber' : 'red'}">${health.run_success_rate_7d}%</div>
|
|
1459
|
+
<div class="hc-sub">7d rate (${health.total_runs_7d || 0} runs)</div>
|
|
1460
|
+
</div>` : ''}
|
|
1461
|
+
${health?.budget_used_pct !== null && health?.budget_used_pct !== undefined ? `
|
|
1462
|
+
<div class="health-cell">
|
|
1463
|
+
<div class="hc-label">BUDGET</div>
|
|
1464
|
+
<div class="hc-value ${health.budget_used_pct > 90 ? 'red' : health.budget_used_pct > 70 ? 'amber' : ''}">${health.budget_used_pct}%</div>
|
|
1465
|
+
<div class="hc-sub">tokens used</div>
|
|
1466
|
+
</div>` : ''}
|
|
1218
1467
|
`;
|
|
1219
1468
|
|
|
1220
1469
|
if (health?.errors && health.errors.length) {
|
|
@@ -1237,6 +1486,281 @@ function renderHealth() {
|
|
|
1237
1486
|
}
|
|
1238
1487
|
}
|
|
1239
1488
|
|
|
1489
|
+
// ── CHAT TAB ──────────────────────────────────────────────────────
|
|
1490
|
+
let chatSessions = []; // all sessions from /api/mastermind/sessions
|
|
1491
|
+
let chatCurrentId = null; // currently viewed session id
|
|
1492
|
+
let chatCurrentAgent = 'all'; // 'all' or an agent/role name
|
|
1493
|
+
let chatScrollLocked = false;
|
|
1494
|
+
let mmSse = null;
|
|
1495
|
+
|
|
1496
|
+
async function loadChatSessions() {
|
|
1497
|
+
try {
|
|
1498
|
+
const r = await fetch('/api/mastermind/sessions');
|
|
1499
|
+
if (!r.ok) return;
|
|
1500
|
+
chatSessions = await r.json();
|
|
1501
|
+
populateChatSelect();
|
|
1502
|
+
} catch(_) {}
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
function orgSessionMatch(s) {
|
|
1506
|
+
if (!selectedOrg) return true;
|
|
1507
|
+
const orgLc = selectedOrg.toLowerCase();
|
|
1508
|
+
const prompt = (s.prompt || '').toLowerCase();
|
|
1509
|
+
if (prompt.includes('running org: ' + orgLc) || prompt.includes('org: ' + orgLc)) return true;
|
|
1510
|
+
// Also check events for an org field
|
|
1511
|
+
return (s.events || []).some(ev => (ev.org || '').toLowerCase() === orgLc);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
function populateChatSelect() {
|
|
1515
|
+
const sel = document.getElementById('chat-sess-select');
|
|
1516
|
+
if (!sel) return;
|
|
1517
|
+
const prev = chatCurrentId || sel.value;
|
|
1518
|
+
|
|
1519
|
+
// Filter to sessions for this org; fall back to all if none match
|
|
1520
|
+
const orgSessions = chatSessions.filter(orgSessionMatch);
|
|
1521
|
+
const list = orgSessions.length ? orgSessions : chatSessions;
|
|
1522
|
+
const isFiltered = orgSessions.length > 0 && orgSessions.length < chatSessions.length;
|
|
1523
|
+
|
|
1524
|
+
const placeholder = isFiltered
|
|
1525
|
+
? `— ${orgSessions.length} session${orgSessions.length !== 1 ? 's' : ''} for ${selectedOrg} —`
|
|
1526
|
+
: '— select a session —';
|
|
1527
|
+
sel.innerHTML = `<option value="">${placeholder}</option>`;
|
|
1528
|
+
|
|
1529
|
+
list.forEach(s => {
|
|
1530
|
+
const d = new Date(s.ts);
|
|
1531
|
+
const ts = d.toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'});
|
|
1532
|
+
const date = d.toLocaleDateString([],{month:'short',day:'numeric'});
|
|
1533
|
+
const prompt = (s.prompt || '').replace(/^running org:\s*/i, '').slice(0, 40);
|
|
1534
|
+
const label = `${date} ${ts} ${prompt}${prompt.length >= 40 ? '…' : ''} [${s.status || '?'}]`;
|
|
1535
|
+
const opt = document.createElement('option');
|
|
1536
|
+
opt.value = s.id;
|
|
1537
|
+
opt.textContent = label;
|
|
1538
|
+
if (s.id === prev) opt.selected = true;
|
|
1539
|
+
sel.appendChild(opt);
|
|
1540
|
+
});
|
|
1541
|
+
|
|
1542
|
+
// Auto-select most recent running session for this org
|
|
1543
|
+
if (!chatCurrentId) {
|
|
1544
|
+
const running = list.find(s => s.status === 'running');
|
|
1545
|
+
if (running) { sel.value = running.id; selectChatSession(running.id); }
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
window.selectChatSession = function(id) {
|
|
1550
|
+
chatCurrentId = id;
|
|
1551
|
+
chatCurrentAgent = 'all';
|
|
1552
|
+
const feed = document.getElementById('chat-feed-wrap');
|
|
1553
|
+
const empty = document.getElementById('chat-feed-empty');
|
|
1554
|
+
const bar = document.getElementById('chat-agent-bar');
|
|
1555
|
+
if (!id) {
|
|
1556
|
+
feed.querySelectorAll('.cmsg').forEach(e=>e.remove());
|
|
1557
|
+
if (empty) empty.style.display = 'block';
|
|
1558
|
+
if (bar) bar.style.display = 'none';
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1561
|
+
const sess = chatSessions.find(s => s.id === id);
|
|
1562
|
+
if (!sess) return;
|
|
1563
|
+
feed.querySelectorAll('.cmsg').forEach(e=>e.remove());
|
|
1564
|
+
if (empty) empty.style.display = 'none';
|
|
1565
|
+
populateChatAgentBar(sess.events || []);
|
|
1566
|
+
(sess.events || []).forEach(ev => appendChatEvent(ev, false));
|
|
1567
|
+
chatScrollFeed();
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
function chatAgentMatchesFilter(ev) {
|
|
1571
|
+
if (chatCurrentAgent === 'all') return true;
|
|
1572
|
+
return ev.agent === chatCurrentAgent || ev.from === chatCurrentAgent || ev.to === chatCurrentAgent;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
function populateChatAgentBar(events) {
|
|
1576
|
+
const bar = document.getElementById('chat-agent-bar');
|
|
1577
|
+
if (!bar) return;
|
|
1578
|
+
const agentSet = new Set();
|
|
1579
|
+
(events || []).forEach(ev => {
|
|
1580
|
+
if (ev.agent) agentSet.add(ev.agent);
|
|
1581
|
+
if (ev.from && ev.from !== '?') agentSet.add(ev.from);
|
|
1582
|
+
if (ev.to && ev.to !== '?') agentSet.add(ev.to);
|
|
1583
|
+
});
|
|
1584
|
+
// Add org roles even if not yet seen in events
|
|
1585
|
+
if (orgDetailData && Array.isArray(orgDetailData.roles)) {
|
|
1586
|
+
orgDetailData.roles.forEach(r => {
|
|
1587
|
+
const n = typeof r === 'string' ? r : (r.role || r.name || r.id || '');
|
|
1588
|
+
if (n) agentSet.add(n);
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
const agents = [...agentSet].sort();
|
|
1592
|
+
if (!agents.length) { bar.style.display = 'none'; return; }
|
|
1593
|
+
bar.style.display = 'flex';
|
|
1594
|
+
bar.innerHTML = '<span id="chat-agent-label">AGENT</span>';
|
|
1595
|
+
['all', ...agents].forEach(name => {
|
|
1596
|
+
const pill = document.createElement('button');
|
|
1597
|
+
pill.className = 'chat-agent-pill' + (chatCurrentAgent === name ? ' active' : '');
|
|
1598
|
+
pill.textContent = name === 'all' ? 'ALL' : name;
|
|
1599
|
+
pill.dataset.agent = name;
|
|
1600
|
+
pill.onclick = () => selectChatAgent(name);
|
|
1601
|
+
bar.appendChild(pill);
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
window.selectChatAgent = function(name) {
|
|
1606
|
+
chatCurrentAgent = name;
|
|
1607
|
+
document.querySelectorAll('#chat-agent-bar .chat-agent-pill').forEach(p => {
|
|
1608
|
+
p.classList.toggle('active', p.dataset.agent === name);
|
|
1609
|
+
});
|
|
1610
|
+
const feed = document.getElementById('chat-feed-wrap');
|
|
1611
|
+
const empty = document.getElementById('chat-feed-empty');
|
|
1612
|
+
const sess = chatSessions.find(s => s.id === chatCurrentId);
|
|
1613
|
+
feed.querySelectorAll('.cmsg').forEach(e => e.remove());
|
|
1614
|
+
if (!sess) return;
|
|
1615
|
+
const visible = (sess.events || []).filter(ev => chatAgentMatchesFilter(ev));
|
|
1616
|
+
if (!visible.length) {
|
|
1617
|
+
if (empty) { empty.style.display = 'block'; empty.textContent = name === 'all' ? 'No events.' : `No events for "${name}"`; }
|
|
1618
|
+
} else {
|
|
1619
|
+
if (empty) empty.style.display = 'none';
|
|
1620
|
+
visible.forEach(ev => appendChatEvent(ev, false));
|
|
1621
|
+
}
|
|
1622
|
+
chatScrollFeed();
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
function appendChatEvent(ev, animate) {
|
|
1626
|
+
if (!chatAgentMatchesFilter(ev)) return;
|
|
1627
|
+
const feed = document.getElementById('chat-feed-wrap');
|
|
1628
|
+
const empty = document.getElementById('chat-feed-empty');
|
|
1629
|
+
if (!feed) return;
|
|
1630
|
+
if (empty) empty.style.display = 'none';
|
|
1631
|
+
const ts = new Date(ev.ts || Date.now()).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit'});
|
|
1632
|
+
const DCOLS = {build:'#60a5fa',idea:'#fbbf24',marketing:'#f472b6',review:'#34d399',research:'#a78bfa',content:'#fb923c',release:'#22d3ee',sales:'#f87171',ops:'#4ade80',finance:'#fde68a',orgs:'#c084fc'};
|
|
1633
|
+
const dc = d => DCOLS[d] || 'oklch(62% 0.20 186)';
|
|
1634
|
+
let el = null;
|
|
1635
|
+
|
|
1636
|
+
if (ev.type === 'session:start') {
|
|
1637
|
+
el = mkSys(`🔵 Session started${ev.prompt ? ': ' + esc(ev.prompt.slice(0,80)) : ''}`, ts);
|
|
1638
|
+
} else if (ev.type === 'session:complete') {
|
|
1639
|
+
el = mkSys(`🏁 Session complete — ${esc((ev.domains||[]).join(', ') || 'done')}`, ts);
|
|
1640
|
+
} else if (ev.type === 'domain:dispatch') {
|
|
1641
|
+
el = mkSys(`<span style="color:${dc(ev.domain)}">⚙ [${esc((ev.domain||'').toUpperCase())}]</span> ${esc(ev.cmd||'dispatched')}`, ts);
|
|
1642
|
+
} else if (ev.type === 'domain:complete') {
|
|
1643
|
+
const arts = (ev.artifacts||[]).length ? ` · ${ev.artifacts.length} artifact${ev.artifacts.length!==1?'s':''}` : '';
|
|
1644
|
+
el = mkSys(`<span style="color:${dc(ev.domain)}">✓ [${esc((ev.domain||'').toUpperCase())}]</span> ${esc(ev.status||'done')}${arts}`, ts);
|
|
1645
|
+
} else if (ev.type === 'agent:spawn') {
|
|
1646
|
+
const col = dc(ev.domain);
|
|
1647
|
+
el = mkAgent(ev.agent||'agent', `spawned: ${esc(ev.task||'task')}`, ts, col, 'spawn');
|
|
1648
|
+
} else if (ev.type === 'agent:message') {
|
|
1649
|
+
el = mkAgent(ev.agent||'agent', esc(ev.text||''), ts, dc(ev.domain), null);
|
|
1650
|
+
} else if (ev.type === 'intercom') {
|
|
1651
|
+
el = mkIntercom(ev.from, ev.to, esc(ev.msg||''), ts);
|
|
1652
|
+
} else if (ev.type === 'loop:start') {
|
|
1653
|
+
el = mkSys(`🔁 Loop: ${esc(ev.command||'')} (${ev.repeat||'?'} runs)`, ts);
|
|
1654
|
+
} else if (ev.type === 'loop:complete') {
|
|
1655
|
+
el = mkSys(`🔁 Loop done: ${esc(ev.command||'')} — ${ev.ranReps||'?'} run(s)`, ts);
|
|
1656
|
+
} else {
|
|
1657
|
+
el = mkSys(`<span style="opacity:0.4">${esc(ev.type)}${ev.domain?' ['+esc(ev.domain)+']':''}</span>`, ts);
|
|
1658
|
+
}
|
|
1659
|
+
if (!el) return;
|
|
1660
|
+
if (animate) el.classList.add('new');
|
|
1661
|
+
feed.appendChild(el);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
function mkSys(html, ts) {
|
|
1665
|
+
const el = document.createElement('div');
|
|
1666
|
+
el.className = 'cmsg csys';
|
|
1667
|
+
el.innerHTML = `<div class="cbubble">${html} <span style="color:var(--dim);margin-left:8px">${ts}</span></div>`;
|
|
1668
|
+
return el;
|
|
1669
|
+
}
|
|
1670
|
+
function mkAgent(name, text, ts, color, typeTag) {
|
|
1671
|
+
const el = document.createElement('div');
|
|
1672
|
+
el.className = 'cmsg cagent';
|
|
1673
|
+
const tagStyle = color ? `style="border-color:${color}44;color:${color}"` : '';
|
|
1674
|
+
const ttag = typeTag ? `<span class="cevtype">${esc(typeTag)}</span>` : '';
|
|
1675
|
+
el.innerHTML = `<div class="cmsg-meta"><span class="ctag" ${tagStyle}>${esc(name)}</span>${ttag}<span class="cts">${ts}</span></div><div class="cbubble">${text}</div>`;
|
|
1676
|
+
return el;
|
|
1677
|
+
}
|
|
1678
|
+
function mkIntercom(from, to, text, ts) {
|
|
1679
|
+
const el = document.createElement('div');
|
|
1680
|
+
el.className = 'cmsg cic';
|
|
1681
|
+
el.innerHTML = `<div class="cmsg-meta"><span class="ctag sender">${esc(from||'?')}</span><span class="cic-arrow">→</span><span class="ctag receiver">${esc(to||'?')}</span><span class="cevtype">intercom</span><span class="cts">${ts}</span></div><div class="cbubble">${text}</div>`;
|
|
1682
|
+
return el;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
function chatScrollFeed() {
|
|
1686
|
+
const feed = document.getElementById('chat-feed-wrap');
|
|
1687
|
+
if (feed && !chatScrollLocked) feed.scrollTop = feed.scrollHeight;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
function renderChatTab() {
|
|
1691
|
+
if (chatSessions.length) {
|
|
1692
|
+
populateChatSelect(); // re-filter immediately with current selectedOrg
|
|
1693
|
+
}
|
|
1694
|
+
loadChatSessions(); // then refresh from server
|
|
1695
|
+
connectMmSSE();
|
|
1696
|
+
const feed = document.getElementById('chat-feed-wrap');
|
|
1697
|
+
if (feed) {
|
|
1698
|
+
feed.addEventListener('scroll', () => {
|
|
1699
|
+
chatScrollLocked = feed.scrollHeight - feed.scrollTop - feed.clientHeight > 80;
|
|
1700
|
+
}, { passive: true });
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
function connectMmSSE() {
|
|
1705
|
+
if (mmSse) return; // already connected
|
|
1706
|
+
mmSse = new EventSource('/api/mastermind-stream');
|
|
1707
|
+
mmSse.onopen = () => {
|
|
1708
|
+
const dot = document.getElementById('chat-live-dot');
|
|
1709
|
+
const lbl = document.getElementById('chat-live-label');
|
|
1710
|
+
if (dot) dot.classList.add('on');
|
|
1711
|
+
if (lbl) lbl.textContent = 'LIVE';
|
|
1712
|
+
};
|
|
1713
|
+
mmSse.onmessage = e => {
|
|
1714
|
+
try {
|
|
1715
|
+
const ev = JSON.parse(e.data);
|
|
1716
|
+
handleMmEvent(ev);
|
|
1717
|
+
} catch(_) {}
|
|
1718
|
+
};
|
|
1719
|
+
mmSse.onerror = () => {
|
|
1720
|
+
const dot = document.getElementById('chat-live-dot');
|
|
1721
|
+
const lbl = document.getElementById('chat-live-label');
|
|
1722
|
+
if (dot) dot.classList.remove('on');
|
|
1723
|
+
if (lbl) lbl.textContent = 'RECONNECTING';
|
|
1724
|
+
mmSse = null;
|
|
1725
|
+
setTimeout(connectMmSSE, 4000);
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
function handleMmEvent(ev) {
|
|
1730
|
+
// Update in-memory sessions list
|
|
1731
|
+
if (ev.type === 'session:start') {
|
|
1732
|
+
const existing = chatSessions.find(s => s.id === ev.session);
|
|
1733
|
+
if (!existing) {
|
|
1734
|
+
chatSessions.unshift({ id: ev.session, ts: ev.ts||Date.now(), prompt: ev.prompt||'', status:'running', domains:[], events:[ev] });
|
|
1735
|
+
}
|
|
1736
|
+
populateChatSelect();
|
|
1737
|
+
// Auto-select if chat tab is active, nothing selected, and session matches this org
|
|
1738
|
+
if (currentTab === 'chat' && !chatCurrentId) {
|
|
1739
|
+
const newSess = chatSessions.find(s => s.id === ev.session);
|
|
1740
|
+
if (newSess && orgSessionMatch(newSess)) {
|
|
1741
|
+
const sel = document.getElementById('chat-sess-select');
|
|
1742
|
+
if (sel) { sel.value = ev.session; selectChatSession(ev.session); }
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
const sess = chatSessions.find(s => s.id === ev.session);
|
|
1748
|
+
if (sess) {
|
|
1749
|
+
(sess.events = sess.events || []).push(ev);
|
|
1750
|
+
if (ev.type === 'domain:dispatch' && ev.domain && !sess.domains.includes(ev.domain)) sess.domains.push(ev.domain);
|
|
1751
|
+
if (ev.type === 'session:complete') { sess.status = ev.status || 'complete'; sess.endTs = ev.ts; populateChatSelect(); }
|
|
1752
|
+
// If this is the currently-viewed session and chat tab is visible, append bubble
|
|
1753
|
+
if (currentTab === 'chat' && chatCurrentId === ev.session) {
|
|
1754
|
+
const hasNewAgent = (ev.agent && !document.querySelector(`[data-agent="${CSS.escape(ev.agent)}"]`))
|
|
1755
|
+
|| (ev.from && !document.querySelector(`[data-agent="${CSS.escape(ev.from)}"]`))
|
|
1756
|
+
|| (ev.to && !document.querySelector(`[data-agent="${CSS.escape(ev.to)}"]`));
|
|
1757
|
+
if (hasNewAgent) populateChatAgentBar(sess.events);
|
|
1758
|
+
appendChatEvent(ev, true);
|
|
1759
|
+
chatScrollFeed();
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1240
1764
|
// ── Stop org action ────────────────────────────────────────────────
|
|
1241
1765
|
window.stopCurrentOrg = async function() {
|
|
1242
1766
|
if (!selectedOrg) return;
|
|
@@ -1248,18 +1772,20 @@ window.stopCurrentOrg = async function() {
|
|
|
1248
1772
|
|
|
1249
1773
|
// ── SSE org events ────────────────────────────────────────────────
|
|
1250
1774
|
const orgEventLog = {};
|
|
1775
|
+
let orgRunStartMs = null;
|
|
1776
|
+
let lsUptimeTimer = null;
|
|
1251
1777
|
|
|
1252
1778
|
let evtSource = null;
|
|
1253
1779
|
function connectSSE() {
|
|
1254
1780
|
if (evtSource) evtSource.close();
|
|
1255
|
-
evtSource = new EventSource('/api/
|
|
1781
|
+
evtSource = new EventSource('/api/mastermind-stream');
|
|
1256
1782
|
evtSource.onmessage = e => {
|
|
1257
1783
|
try {
|
|
1258
1784
|
const ev = JSON.parse(e.data);
|
|
1259
1785
|
if (ev && typeof ev.org === 'string' && ev.type && ev.type.startsWith('org:')) {
|
|
1260
1786
|
const name = ev.org;
|
|
1261
1787
|
if (!orgEventLog[name]) orgEventLog[name] = [];
|
|
1262
|
-
orgEventLog[name].push(ev);
|
|
1788
|
+
orgEventLog[name].push({ ...ev, _ts: Date.now() });
|
|
1263
1789
|
if (orgEventLog[name].length > 50) orgEventLog[name].shift();
|
|
1264
1790
|
|
|
1265
1791
|
// Refresh if this org is selected
|
|
@@ -1270,6 +1796,13 @@ function connectSSE() {
|
|
|
1270
1796
|
if (ev.type === 'org:start' || ev.type === 'org:stop') {
|
|
1271
1797
|
setTimeout(loadOrgs, 400);
|
|
1272
1798
|
}
|
|
1799
|
+
// Update live strip for selected org on chart tab
|
|
1800
|
+
if (name === selectedOrg && currentTab === 'chart') {
|
|
1801
|
+
if (ev.type === 'org:start') orgRunStartMs = Date.now();
|
|
1802
|
+
if (ev.type === 'org:stop') orgRunStartMs = null;
|
|
1803
|
+
appendLiveFeedRow(ev, true);
|
|
1804
|
+
updateLiveStrip();
|
|
1805
|
+
}
|
|
1273
1806
|
}
|
|
1274
1807
|
} catch (_) {}
|
|
1275
1808
|
};
|
|
@@ -1278,6 +1811,102 @@ function connectSSE() {
|
|
|
1278
1811
|
};
|
|
1279
1812
|
}
|
|
1280
1813
|
|
|
1814
|
+
function updateLiveStrip() {
|
|
1815
|
+
const events = orgEventLog[selectedOrg] || [];
|
|
1816
|
+
const running = orgRunStartMs !== null;
|
|
1817
|
+
const dot = document.getElementById('ls-dot');
|
|
1818
|
+
const label = document.getElementById('ls-label');
|
|
1819
|
+
if (!dot || !label) return;
|
|
1820
|
+
dot.className = 'ls-dot' + (running ? ' running' : '');
|
|
1821
|
+
label.textContent = running ? 'RUNNING' : 'IDLE';
|
|
1822
|
+
|
|
1823
|
+
// Uptime
|
|
1824
|
+
const uptimeEl = document.getElementById('ls-uptime');
|
|
1825
|
+
if (uptimeEl) {
|
|
1826
|
+
if (running && orgRunStartMs) {
|
|
1827
|
+
const s = Math.floor((Date.now() - orgRunStartMs) / 1000);
|
|
1828
|
+
const h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), sec = s % 60;
|
|
1829
|
+
uptimeEl.textContent = h ? `up ${h}h ${m}m` : m ? `up ${m}m ${sec}s` : `up ${sec}s`;
|
|
1830
|
+
} else {
|
|
1831
|
+
uptimeEl.textContent = '—';
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
// Last event
|
|
1836
|
+
const lastEl = document.getElementById('ls-last');
|
|
1837
|
+
if (lastEl && events.length) {
|
|
1838
|
+
const last = events[events.length - 1];
|
|
1839
|
+
const ago = Math.round((Date.now() - (last._ts || Date.now())) / 1000);
|
|
1840
|
+
lastEl.textContent = ago < 5 ? 'just now' : ago < 60 ? ago + 's ago' : Math.floor(ago/60) + 'm ago';
|
|
1841
|
+
} else if (lastEl) {
|
|
1842
|
+
lastEl.textContent = '—';
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
// Events per 5 min
|
|
1846
|
+
const now = Date.now();
|
|
1847
|
+
const epmEl = document.getElementById('ls-epm');
|
|
1848
|
+
if (epmEl) {
|
|
1849
|
+
const recent = events.filter(ev => ev._ts && now - ev._ts < 5 * 60 * 1000).length;
|
|
1850
|
+
epmEl.textContent = recent + ' / 5m';
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// 12-bar sparkline (25s buckets)
|
|
1854
|
+
renderLiveSparkline(events);
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
function renderLiveSparkline(events) {
|
|
1858
|
+
const wrap = document.getElementById('ls-sparkline');
|
|
1859
|
+
if (!wrap) return;
|
|
1860
|
+
const now = Date.now();
|
|
1861
|
+
const buckets = Array.from({ length: 12 }, (_, i) => {
|
|
1862
|
+
const start = now - (12 - i) * 25000;
|
|
1863
|
+
return events.filter(ev => ev._ts && ev._ts >= start && ev._ts < start + 25000).length;
|
|
1864
|
+
});
|
|
1865
|
+
const max = Math.max(1, ...buckets);
|
|
1866
|
+
wrap.innerHTML = buckets.map((count, i) => {
|
|
1867
|
+
const h = Math.max(2, Math.round(count / max * 18));
|
|
1868
|
+
return `<div class="ls-bar${i === 11 ? ' active' : ''}" style="height:${h}px" title="${count} events"></div>`;
|
|
1869
|
+
}).join('');
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
function appendLiveFeedRow(ev, isNew) {
|
|
1873
|
+
const rows = document.getElementById('clf-rows');
|
|
1874
|
+
if (!rows) return;
|
|
1875
|
+
const time = new Date().toLocaleTimeString('en', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
1876
|
+
const type = (ev.type || '').replace('org:', '');
|
|
1877
|
+
const msg = ev.message || ev.msg || ev.agent || ev.role || ev.status || '';
|
|
1878
|
+
const row = document.createElement('div');
|
|
1879
|
+
row.className = 'clf-row' + (isNew ? ' new' : '');
|
|
1880
|
+
row.title = msg;
|
|
1881
|
+
row.innerHTML = `<span class="clf-time">${time}</span><span class="clf-type">${type}</span><span class="clf-msg">${msg}</span>`;
|
|
1882
|
+
rows.appendChild(row);
|
|
1883
|
+
if (rows.children.length > 30) rows.removeChild(rows.firstChild);
|
|
1884
|
+
rows.scrollTop = rows.scrollHeight;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
function initLiveStrip() {
|
|
1888
|
+
orgRunStartMs = null;
|
|
1889
|
+
const rows = document.getElementById('clf-rows');
|
|
1890
|
+
if (rows) rows.innerHTML = '';
|
|
1891
|
+
const events = orgEventLog[selectedOrg] || [];
|
|
1892
|
+
// Seed from existing event history
|
|
1893
|
+
events.forEach(ev => appendLiveFeedRow(ev, false));
|
|
1894
|
+
// Detect running state from list data
|
|
1895
|
+
const listOrg = allOrgs.find(o => o.name === selectedOrg);
|
|
1896
|
+
if (listOrg && listOrg.running && !orgRunStartMs) {
|
|
1897
|
+
const acts = orgDetailData._activity || [];
|
|
1898
|
+
const startEv = acts.slice().reverse().find(e => e.type === 'org:start' || e.type === 'org:create');
|
|
1899
|
+
if (startEv && startEv.ts) orgRunStartMs = startEv.ts;
|
|
1900
|
+
else if (listOrg.running_since) orgRunStartMs = listOrg.running_since;
|
|
1901
|
+
else orgRunStartMs = Date.now(); // fallback
|
|
1902
|
+
} else if (listOrg && !listOrg.running) {
|
|
1903
|
+
orgRunStartMs = null;
|
|
1904
|
+
}
|
|
1905
|
+
updateLiveStrip();
|
|
1906
|
+
if (lsUptimeTimer) clearInterval(lsUptimeTimer);
|
|
1907
|
+
lsUptimeTimer = setInterval(updateLiveStrip, 1000);
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1281
1910
|
// ── Data loading ──────────────────────────────────────────────────
|
|
1282
1911
|
async function loadOrgs() {
|
|
1283
1912
|
try {
|
|
@@ -1307,9 +1936,30 @@ window.openCopyModal = function(name) {
|
|
|
1307
1936
|
document.getElementById('copy-modal-status').className = '';
|
|
1308
1937
|
document.getElementById('copy-confirm-btn').disabled = false;
|
|
1309
1938
|
document.getElementById('copy-modal-overlay').classList.add('open');
|
|
1939
|
+
// Load project list
|
|
1940
|
+
const listEl = document.getElementById('copy-project-list');
|
|
1941
|
+
listEl.innerHTML = '<div class="copy-proj-loading">Loading projects…</div>';
|
|
1942
|
+
fetch('/api/projects').then(r => r.json()).then(data => {
|
|
1943
|
+
const projects = data?.projects || [];
|
|
1944
|
+
if (!projects.length) { listEl.innerHTML = '<div class="copy-proj-loading">No other projects found</div>'; return; }
|
|
1945
|
+
listEl.innerHTML = projects.map(p => {
|
|
1946
|
+
const label = p.name || p.slug || p.path?.split('/').pop() || p.path;
|
|
1947
|
+
const isCurrentDir = p.path === (window._orgDir || '');
|
|
1948
|
+
return `<div class="copy-proj-row${isCurrentDir ? ' selected' : ''}" title="${p.path}" onclick="selectCopyProject('${p.path.replace(/'/g,"\\'")}', this)">
|
|
1949
|
+
<span style="color:var(--text-hi)">${label}</span>
|
|
1950
|
+
<span style="color:var(--dim);font-size:10px;margin-left:6px">${p.path.replace(/\/Users\/[^/]+\//, '~/')}</span>
|
|
1951
|
+
</div>`;
|
|
1952
|
+
}).join('');
|
|
1953
|
+
}).catch(() => { listEl.innerHTML = '<div class="copy-proj-loading">Could not load projects</div>'; });
|
|
1310
1954
|
setTimeout(() => document.getElementById('copy-dest-input').focus(), 60);
|
|
1311
1955
|
};
|
|
1312
1956
|
|
|
1957
|
+
window.selectCopyProject = function(path, el) {
|
|
1958
|
+
document.querySelectorAll('.copy-proj-row').forEach(r => r.classList.remove('selected'));
|
|
1959
|
+
el.classList.add('selected');
|
|
1960
|
+
document.getElementById('copy-dest-input').value = path;
|
|
1961
|
+
};
|
|
1962
|
+
|
|
1313
1963
|
window.closeCopyModal = function() {
|
|
1314
1964
|
document.getElementById('copy-modal-overlay').classList.remove('open');
|
|
1315
1965
|
copyTargetOrg = null;
|
|
@@ -1351,6 +2001,66 @@ window.executeCopy = async function() {
|
|
|
1351
2001
|
}
|
|
1352
2002
|
};
|
|
1353
2003
|
|
|
2004
|
+
// ── Export org ────────────────────────────────────────────────────
|
|
2005
|
+
window.exportOrg = async function(name) {
|
|
2006
|
+
try {
|
|
2007
|
+
const r = await fetch(`/api/orgs/${encodeURIComponent(name)}`);
|
|
2008
|
+
if (!r.ok) throw new Error(r.statusText);
|
|
2009
|
+
const blob = await r.blob();
|
|
2010
|
+
const a = document.createElement('a');
|
|
2011
|
+
a.href = URL.createObjectURL(blob);
|
|
2012
|
+
a.download = `${name}.json`;
|
|
2013
|
+
a.click();
|
|
2014
|
+
setTimeout(() => URL.revokeObjectURL(a.href), 5000);
|
|
2015
|
+
} catch(e) {
|
|
2016
|
+
alert('EXPORT FAILED: ' + e.message);
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
// ── Import org ────────────────────────────────────────────────────
|
|
2021
|
+
let importTargetOrg = null;
|
|
2022
|
+
|
|
2023
|
+
window.triggerImportOrg = function(name) {
|
|
2024
|
+
importTargetOrg = name;
|
|
2025
|
+
let inp = document.getElementById('oi-import-file-input');
|
|
2026
|
+
if (!inp) {
|
|
2027
|
+
inp = document.createElement('input');
|
|
2028
|
+
inp.type = 'file';
|
|
2029
|
+
inp.accept = '.json,application/json';
|
|
2030
|
+
inp.id = 'oi-import-file-input';
|
|
2031
|
+
inp.style.display = 'none';
|
|
2032
|
+
document.body.appendChild(inp);
|
|
2033
|
+
inp.addEventListener('change', handleImportFile);
|
|
2034
|
+
}
|
|
2035
|
+
inp.value = '';
|
|
2036
|
+
inp.click();
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
async function handleImportFile(e) {
|
|
2040
|
+
const file = e.target.files[0];
|
|
2041
|
+
if (!file || !importTargetOrg) return;
|
|
2042
|
+
try {
|
|
2043
|
+
const text = await file.text();
|
|
2044
|
+
let data;
|
|
2045
|
+
try { data = JSON.parse(text); } catch(_) { alert('IMPORT FAILED: invalid JSON'); return; }
|
|
2046
|
+
const r = await fetch(`/api/orgs/${encodeURIComponent(importTargetOrg)}/import`, {
|
|
2047
|
+
method: 'POST',
|
|
2048
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2049
|
+
body: JSON.stringify(data),
|
|
2050
|
+
});
|
|
2051
|
+
const result = await r.json();
|
|
2052
|
+
if (r.ok && result.ok) {
|
|
2053
|
+
loadOrgs();
|
|
2054
|
+
} else {
|
|
2055
|
+
alert('IMPORT FAILED: ' + (result.error || r.statusText));
|
|
2056
|
+
}
|
|
2057
|
+
} catch(e) {
|
|
2058
|
+
alert('IMPORT FAILED: ' + e.message);
|
|
2059
|
+
} finally {
|
|
2060
|
+
importTargetOrg = null;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1354
2064
|
// ── Bootstrap ─────────────────────────────────────────────────────
|
|
1355
2065
|
connectSSE();
|
|
1356
2066
|
loadOrgs();
|