@monoes/monomindcli 2.8.3 → 2.9.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/.claude/helpers/auto-memory-hook.mjs +0 -0
- package/.claude/helpers/handlers/route-handler.cjs +12 -0
- package/.claude/helpers/handlers/session-restore-handler.cjs +28 -7
- package/.claude/helpers/hook-handler.cjs +0 -0
- package/.claude/helpers/utils/micro-agents.cjs +22 -0
- package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +11 -6
- package/.claude/skills/monodesign/scripts/live-inject.mjs +20 -7
- package/.claude/skills/monodesign/scripts/live-server.mjs +38 -2
- package/LICENSE +191 -0
- package/README.md +8 -6
- package/dist/src/browser/dashboard/server.d.ts +5 -0
- package/dist/src/browser/dashboard/server.d.ts.map +1 -1
- package/dist/src/browser/dashboard/server.js +59 -4
- package/dist/src/browser/dashboard/server.js.map +1 -1
- package/dist/src/browser/dashboard/ui.html +18 -8
- package/dist/src/browser/workflow/store.d.ts.map +1 -1
- package/dist/src/browser/workflow/store.js +3 -2
- package/dist/src/browser/workflow/store.js.map +1 -1
- package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
- package/dist/src/capabilities/cap-documents.js +14 -9
- package/dist/src/capabilities/cap-documents.js.map +1 -1
- package/dist/src/commands/design-palette.d.ts +5 -0
- package/dist/src/commands/design-palette.d.ts.map +1 -1
- package/dist/src/commands/design-palette.js +8 -5
- package/dist/src/commands/design-palette.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +22 -18
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/download-embeddings.d.ts +8 -0
- package/dist/src/commands/download-embeddings.d.ts.map +1 -0
- package/dist/src/commands/download-embeddings.js +34 -0
- package/dist/src/commands/download-embeddings.js.map +1 -0
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +14 -0
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +4 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/init-wizard.js +1 -1
- package/dist/src/commands/init-wizard.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +48 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/monograph.d.ts.map +1 -1
- package/dist/src/commands/monograph.js +35 -1
- package/dist/src/commands/monograph.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts +10 -0
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +195 -31
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org.d.ts +1 -0
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +139 -3
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/commands/route.d.ts +1 -9
- package/dist/src/commands/route.d.ts.map +1 -1
- package/dist/src/commands/route.js +42 -65
- package/dist/src/commands/route.js.map +1 -1
- package/dist/src/commands/security-cve.d.ts.map +1 -1
- package/dist/src/commands/security-cve.js +2 -1
- package/dist/src/commands/security-cve.js.map +1 -1
- package/dist/src/index.d.ts +0 -10
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -15
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/copy-assets.d.ts +17 -0
- package/dist/src/init/copy-assets.d.ts.map +1 -0
- package/dist/src/init/copy-assets.js +271 -0
- package/dist/src/init/copy-assets.js.map +1 -0
- package/dist/src/init/executor.d.ts +2 -30
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +56 -2493
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/geminimd-generator.js +2 -2
- package/dist/src/init/helpers-generator.d.ts.map +1 -1
- package/dist/src/init/helpers-generator.js +9 -0
- package/dist/src/init/helpers-generator.js.map +1 -1
- package/dist/src/init/kimi-generator.js +3 -3
- package/dist/src/init/kimi-generator.js.map +1 -1
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +0 -4
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/init/shared.d.ts +112 -0
- package/dist/src/init/shared.d.ts.map +1 -0
- package/dist/src/init/shared.js +475 -0
- package/dist/src/init/shared.js.map +1 -0
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +37 -0
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/init/types.d.ts +1 -1
- package/dist/src/init/types.d.ts.map +1 -1
- package/dist/src/init/upgrade.d.ts +34 -0
- package/dist/src/init/upgrade.d.ts.map +1 -0
- package/dist/src/init/upgrade.js +477 -0
- package/dist/src/init/upgrade.js.map +1 -0
- package/dist/src/init/write-antigravity.d.ts +13 -0
- package/dist/src/init/write-antigravity.d.ts.map +1 -0
- package/dist/src/init/write-antigravity.js +117 -0
- package/dist/src/init/write-antigravity.js.map +1 -0
- package/dist/src/init/write-capabilities.d.ts +9 -0
- package/dist/src/init/write-capabilities.d.ts.map +1 -0
- package/dist/src/init/write-capabilities.js +392 -0
- package/dist/src/init/write-capabilities.js.map +1 -0
- package/dist/src/init/write-claude.d.ts +25 -0
- package/dist/src/init/write-claude.d.ts.map +1 -0
- package/dist/src/init/write-claude.js +279 -0
- package/dist/src/init/write-claude.js.map +1 -0
- package/dist/src/init/write-kimicode.d.ts +19 -0
- package/dist/src/init/write-kimicode.d.ts.map +1 -0
- package/dist/src/init/write-kimicode.js +223 -0
- package/dist/src/init/write-kimicode.js.map +1 -0
- package/dist/src/init/write-opencode.d.ts +14 -0
- package/dist/src/init/write-opencode.d.ts.map +1 -0
- package/dist/src/init/write-opencode.js +130 -0
- package/dist/src/init/write-opencode.js.map +1 -0
- package/dist/src/init/write-runtime-config.d.ts +14 -0
- package/dist/src/init/write-runtime-config.d.ts.map +1 -0
- package/dist/src/init/write-runtime-config.js +214 -0
- package/dist/src/init/write-runtime-config.js.map +1 -0
- package/dist/src/init/write-sample-org.d.ts +9 -0
- package/dist/src/init/write-sample-org.d.ts.map +1 -0
- package/dist/src/init/write-sample-org.js +39 -0
- package/dist/src/init/write-sample-org.js.map +1 -0
- package/dist/src/knowledge/eval/golden-set.js +1 -1
- package/dist/src/knowledge/eval/golden-set.js.map +1 -1
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +7 -3
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-tools/analyze-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/analyze-tools.js +2 -25
- package/dist/src/mcp-tools/analyze-tools.js.map +1 -1
- package/dist/src/mcp-tools/auto-install.d.ts.map +1 -1
- package/dist/src/mcp-tools/auto-install.js +2 -1
- package/dist/src/mcp-tools/auto-install.js.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.js +26 -0
- package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
- package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/memory-tools.js +2 -37
- package/dist/src/mcp-tools/memory-tools.js.map +1 -1
- package/dist/src/mcp-tools/monodesign-tools.d.ts +19 -0
- package/dist/src/mcp-tools/monodesign-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monodesign-tools.js +233 -0
- package/dist/src/mcp-tools/monodesign-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/agent-history-tools.d.ts +5 -0
- package/dist/src/mcp-tools/monograph/agent-history-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/agent-history-tools.js +177 -0
- package/dist/src/mcp-tools/monograph/agent-history-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/build-tools.d.ts +9 -0
- package/dist/src/mcp-tools/monograph/build-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/build-tools.js +299 -0
- package/dist/src/mcp-tools/monograph/build-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/group-tools.d.ts +10 -0
- package/dist/src/mcp-tools/monograph/group-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/group-tools.js +225 -0
- package/dist/src/mcp-tools/monograph/group-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/health-tools.d.ts +6 -0
- package/dist/src/mcp-tools/monograph/health-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/health-tools.js +113 -0
- package/dist/src/mcp-tools/monograph/health-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/impact-tools.d.ts +9 -0
- package/dist/src/mcp-tools/monograph/impact-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/impact-tools.js +532 -0
- package/dist/src/mcp-tools/monograph/impact-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/index.d.ts +10 -0
- package/dist/src/mcp-tools/monograph/index.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/index.js +73 -0
- package/dist/src/mcp-tools/monograph/index.js.map +1 -0
- package/dist/src/mcp-tools/monograph/query-tools.d.ts +11 -0
- package/dist/src/mcp-tools/monograph/query-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/query-tools.js +500 -0
- package/dist/src/mcp-tools/monograph/query-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph/shared.d.ts +64 -0
- package/dist/src/mcp-tools/monograph/shared.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/shared.js +215 -0
- package/dist/src/mcp-tools/monograph/shared.js.map +1 -0
- package/dist/src/mcp-tools/monograph/visualize-tools.d.ts +10 -0
- package/dist/src/mcp-tools/monograph/visualize-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monograph/visualize-tools.js +382 -0
- package/dist/src/mcp-tools/monograph/visualize-tools.js.map +1 -0
- package/dist/src/mcp-tools/monograph-tools.d.ts +4 -23
- package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.js +4 -2439
- package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
- package/dist/src/mcp-tools/monomind-tools.d.ts +8 -0
- package/dist/src/mcp-tools/monomind-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monomind-tools.js +13 -1
- package/dist/src/mcp-tools/monomind-tools.js.map +1 -1
- package/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts.map +1 -1
- package/dist/src/mcp-tools/quality/security-compliance/detect-secrets.js +31 -2
- package/dist/src/mcp-tools/quality/security-compliance/detect-secrets.js.map +1 -1
- package/dist/src/mcp-tools/terminal-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/terminal-tools.js +31 -1
- package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
- package/dist/src/mcp-tools/types.d.ts +8 -27
- package/dist/src/mcp-tools/types.d.ts.map +1 -1
- package/dist/src/mcp-tools/types.js +9 -91
- package/dist/src/mcp-tools/types.js.map +1 -1
- package/dist/src/memory/file-permissions.d.ts +15 -0
- package/dist/src/memory/file-permissions.d.ts.map +1 -0
- package/dist/src/memory/file-permissions.js +25 -0
- package/dist/src/memory/file-permissions.js.map +1 -0
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +94 -34
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-crud.d.ts.map +1 -1
- package/dist/src/memory/memory-crud.js +298 -275
- package/dist/src/memory/memory-crud.js.map +1 -1
- package/dist/src/memory/memory-initializer.d.ts +2 -4
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +53 -76
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/memory/memory-migrations.d.ts +1 -14
- package/dist/src/memory/memory-migrations.d.ts.map +1 -1
- package/dist/src/memory/memory-migrations.js +52 -105
- package/dist/src/memory/memory-migrations.js.map +1 -1
- package/dist/src/memory/sona-optimizer.d.ts +1 -1
- package/dist/src/memory/sona-optimizer.js +1 -1
- package/dist/src/monovector/index.d.ts +16 -19
- package/dist/src/monovector/index.d.ts.map +1 -1
- package/dist/src/monovector/index.js +50 -8
- package/dist/src/monovector/index.js.map +1 -1
- package/dist/src/orgrt/approvals.d.ts +16 -0
- package/dist/src/orgrt/approvals.d.ts.map +1 -0
- package/dist/src/orgrt/approvals.js +72 -0
- package/dist/src/orgrt/approvals.js.map +1 -0
- package/dist/src/orgrt/bus.d.ts.map +1 -1
- package/dist/src/orgrt/bus.js +21 -0
- package/dist/src/orgrt/bus.js.map +1 -1
- package/dist/src/orgrt/checkpoint-ops.d.ts +19 -0
- package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -0
- package/dist/src/orgrt/checkpoint-ops.js +219 -0
- package/dist/src/orgrt/checkpoint-ops.js.map +1 -0
- package/dist/src/orgrt/checkpoint.d.ts +33 -1
- package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
- package/dist/src/orgrt/checkpoint.js +50 -6
- package/dist/src/orgrt/checkpoint.js.map +1 -1
- package/dist/src/orgrt/cross-org.d.ts +32 -0
- package/dist/src/orgrt/cross-org.d.ts.map +1 -0
- package/dist/src/orgrt/cross-org.js +256 -0
- package/dist/src/orgrt/cross-org.js.map +1 -0
- package/dist/src/orgrt/daemon.d.ts +131 -157
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +356 -966
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +33 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -0
- package/dist/src/orgrt/decisions.js +169 -0
- package/dist/src/orgrt/decisions.js.map +1 -0
- package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/kimicode-runner.js +5 -1
- package/dist/src/orgrt/kimicode-runner.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +10 -2
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/org-memory.d.ts +45 -0
- package/dist/src/orgrt/org-memory.d.ts.map +1 -0
- package/dist/src/orgrt/org-memory.js +220 -0
- package/dist/src/orgrt/org-memory.js.map +1 -0
- package/dist/src/orgrt/policy.d.ts +4 -0
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +13 -1
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/prechecks.d.ts +15 -0
- package/dist/src/orgrt/prechecks.d.ts.map +1 -0
- package/dist/src/orgrt/prechecks.js +21 -0
- package/dist/src/orgrt/prechecks.js.map +1 -0
- package/dist/src/orgrt/questions.d.ts +39 -0
- package/dist/src/orgrt/questions.d.ts.map +1 -0
- package/dist/src/orgrt/questions.js +135 -0
- package/dist/src/orgrt/questions.js.map +1 -0
- package/dist/src/orgrt/remote.d.ts +25 -0
- package/dist/src/orgrt/remote.d.ts.map +1 -0
- package/dist/src/orgrt/remote.js +73 -0
- package/dist/src/orgrt/remote.js.map +1 -0
- package/dist/src/orgrt/scheduler-integration.d.ts +19 -0
- package/dist/src/orgrt/scheduler-integration.d.ts.map +1 -0
- package/dist/src/orgrt/scheduler-integration.js +90 -0
- package/dist/src/orgrt/scheduler-integration.js.map +1 -0
- package/dist/src/orgrt/server.d.ts.map +1 -1
- package/dist/src/orgrt/server.js +70 -2
- package/dist/src/orgrt/server.js.map +1 -1
- package/dist/src/orgrt/session.d.ts +30 -1
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +184 -53
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/state-detector.d.ts +19 -0
- package/dist/src/orgrt/state-detector.d.ts.map +1 -0
- package/dist/src/orgrt/state-detector.js +59 -0
- package/dist/src/orgrt/state-detector.js.map +1 -0
- package/dist/src/orgrt/task-dag.d.ts +27 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -0
- package/dist/src/orgrt/task-dag.js +100 -0
- package/dist/src/orgrt/task-dag.js.map +1 -0
- package/dist/src/orgrt/tool-fence.d.ts +7 -4
- package/dist/src/orgrt/tool-fence.d.ts.map +1 -1
- package/dist/src/orgrt/tool-fence.js +47 -6
- package/dist/src/orgrt/tool-fence.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +57 -2
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +34 -3
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/routing/model-download.d.ts +49 -0
- package/dist/src/routing/model-download.d.ts.map +1 -0
- package/dist/src/routing/model-download.js +106 -0
- package/dist/src/routing/model-download.js.map +1 -0
- package/dist/src/services/crash-reporter.d.ts +5 -0
- package/dist/src/services/crash-reporter.d.ts.map +1 -1
- package/dist/src/services/crash-reporter.js +49 -0
- package/dist/src/services/crash-reporter.js.map +1 -1
- package/dist/src/transfer/anonymization/index.d.ts +18 -15
- package/dist/src/transfer/anonymization/index.d.ts.map +1 -1
- package/dist/src/transfer/anonymization/index.js +7 -119
- package/dist/src/transfer/anonymization/index.js.map +1 -1
- package/dist/src/ui/dashboard.html +606 -7
- package/dist/src/ui/orgs.html +7 -1
- package/dist/src/ui/routes-monograph.mjs +6 -0
- package/dist/src/ui/server.mjs +327 -7
- package/dist/src/update/checker.d.ts.map +1 -1
- package/dist/src/update/checker.js +2 -1
- 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 +7 -3
- package/dist/src/update/executor.js.map +1 -1
- package/dist/src/update/index.d.ts +0 -1
- package/dist/src/update/index.d.ts.map +1 -1
- package/dist/src/update/index.js +5 -24
- package/dist/src/update/index.js.map +1 -1
- package/dist/src/utils/db-mutex.d.ts +11 -0
- package/dist/src/utils/db-mutex.d.ts.map +1 -0
- package/dist/src/utils/db-mutex.js +23 -0
- package/dist/src/utils/db-mutex.js.map +1 -0
- package/dist/src/utils/input-guards.d.ts +23 -0
- package/dist/src/utils/input-guards.d.ts.map +1 -1
- package/dist/src/utils/input-guards.js +72 -0
- package/dist/src/utils/input-guards.js.map +1 -1
- package/dist/src/utils/npm-command.d.ts +10 -0
- package/dist/src/utils/npm-command.d.ts.map +1 -0
- package/dist/src/utils/npm-command.js +12 -0
- package/dist/src/utils/npm-command.js.map +1 -0
- package/dist/src/utils/paths.d.ts +28 -0
- package/dist/src/utils/paths.d.ts.map +1 -0
- package/dist/src/utils/paths.js +108 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/scripts/download-embedding-model.mjs +97 -0
- package/scripts/publish.sh +0 -0
- package/scripts/sync-claude-assets.sh +0 -0
- package/dist/src/production/circuit-breaker.d.ts +0 -121
- package/dist/src/production/circuit-breaker.d.ts.map +0 -1
- package/dist/src/production/circuit-breaker.js +0 -262
- package/dist/src/production/circuit-breaker.js.map +0 -1
- package/dist/src/production/error-handler.d.ts +0 -119
- package/dist/src/production/error-handler.d.ts.map +0 -1
- package/dist/src/production/error-handler.js +0 -324
- package/dist/src/production/error-handler.js.map +0 -1
- package/dist/src/production/index.d.ts +0 -6
- package/dist/src/production/index.d.ts.map +0 -1
- package/dist/src/production/index.js +0 -6
- package/dist/src/production/index.js.map +0 -1
- package/dist/src/production/monitoring.d.ts +0 -181
- package/dist/src/production/monitoring.d.ts.map +0 -1
- package/dist/src/production/monitoring.js +0 -375
- package/dist/src/production/monitoring.js.map +0 -1
- package/dist/src/production/rate-limiter.d.ts +0 -125
- package/dist/src/production/rate-limiter.d.ts.map +0 -1
- package/dist/src/production/rate-limiter.js +0 -218
- package/dist/src/production/rate-limiter.js.map +0 -1
- package/dist/src/production/retry.d.ts +0 -48
- package/dist/src/production/retry.d.ts.map +0 -1
- package/dist/src/production/retry.js +0 -189
- package/dist/src/production/retry.js.map +0 -1
- package/dist/src/transfer/types.d.ts +0 -245
- package/dist/src/transfer/types.d.ts.map +0 -1
- package/dist/src/transfer/types.js +0 -6
- package/dist/src/transfer/types.js.map +0 -1
|
@@ -1522,6 +1522,56 @@ select.pb-cfg-inp { padding: 4px 7px; cursor: pointer; }
|
|
|
1522
1522
|
.mm-skill-name { font-family: var(--mono); font-size: 12px; color: oklch(65% 0.16 295); flex-shrink: 0; }
|
|
1523
1523
|
.mm-skill-desc { font-size: 12px; color: var(--text-lo); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1524
1524
|
.mm-skill-item:hover .mm-skill-name { color: oklch(75% 0.16 295); }
|
|
1525
|
+
|
|
1526
|
+
/* ── Global Documents view + markdown viewer ─────────────────────────────── */
|
|
1527
|
+
.gd-row { transition: background 0.1s, border-color 0.1s; }
|
|
1528
|
+
.gd-row:hover { background: var(--surface-hi); }
|
|
1529
|
+
.gd-row.active { background: var(--surface-hi); }
|
|
1530
|
+
|
|
1531
|
+
/* Markdown document typography — readable, scoped, doesn't inherit app chrome */
|
|
1532
|
+
.gd-doc { color: var(--text); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; font-size: 14px; line-height: 1.7; }
|
|
1533
|
+
.gd-md { max-width: 760px; }
|
|
1534
|
+
.gd-md h1 { font-size: 28px; font-weight: 700; margin: 32px 0 12px; line-height: 1.2; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
|
|
1535
|
+
.gd-md h2 { font-size: 22px; font-weight: 700; margin: 28px 0 10px; line-height: 1.3; }
|
|
1536
|
+
.gd-md h3 { font-size: 18px; font-weight: 600; margin: 22px 0 8px; }
|
|
1537
|
+
.gd-md h4 { font-size: 15px; font-weight: 600; margin: 18px 0 6px; color: var(--text-hi); }
|
|
1538
|
+
.gd-md h5 { font-size: 13px; font-weight: 600; margin: 16px 0 4px; color: var(--text); text-transform: uppercase; letter-spacing: 0.4px; }
|
|
1539
|
+
.gd-md h6 { font-size: 12px; font-weight: 500; margin: 14px 0 4px; color: var(--text-lo); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
1540
|
+
.gd-md p { margin: 10px 0; }
|
|
1541
|
+
.gd-md ul, .gd-md ol { margin: 10px 0; padding-left: 24px; }
|
|
1542
|
+
.gd-md ul { list-style: disc; }
|
|
1543
|
+
.gd-md ol { list-style: decimal; }
|
|
1544
|
+
.gd-md li { margin: 3px 0; }
|
|
1545
|
+
.gd-md li > ul, .gd-md li > ol { margin: 4px 0; }
|
|
1546
|
+
.gd-md ul.md-tasklist { list-style: none; padding-left: 8px; }
|
|
1547
|
+
.gd-md ul.md-tasklist li { display: flex; align-items: flex-start; gap: 8px; }
|
|
1548
|
+
.gd-md ul.md-tasklist li input[type="checkbox"] { margin-top: 4px; accent-color: var(--accent, #00D2AA); }
|
|
1549
|
+
.gd-md blockquote { margin: 12px 0; padding: 8px 16px; border-left: 3px solid var(--accent, #00D2AA); background: var(--surface); border-radius: 0 6px 6px 0; color: var(--text-lo); }
|
|
1550
|
+
.gd-md blockquote p { margin: 6px 0; }
|
|
1551
|
+
.gd-md hr { border: none; border-top: 1px solid var(--border); margin: 24px 0; }
|
|
1552
|
+
.gd-md strong { font-weight: 700; color: var(--text-hi); }
|
|
1553
|
+
.gd-md em { font-style: italic; }
|
|
1554
|
+
.gd-md del { text-decoration: line-through; color: var(--text-lo); }
|
|
1555
|
+
.gd-md code { font-family: var(--mono, 'SF Mono', Monaco, Menlo, Consolas, monospace); font-size: 0.88em; background: var(--surface-hi); color: var(--text-hi); padding: 1px 6px; border-radius: 4px; }
|
|
1556
|
+
.gd-md a { color: var(--accent, #00D2AA); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.1s; }
|
|
1557
|
+
.gd-md a:hover { border-bottom-color: currentColor; }
|
|
1558
|
+
.gd-md img { margin: 12px 0; box-shadow: 0 1px 4px rgba(0,0,0,0.1); }
|
|
1559
|
+
|
|
1560
|
+
/* Fenced code blocks */
|
|
1561
|
+
.gd-md .gd-code-block { margin: 14px 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--surface); }
|
|
1562
|
+
.gd-md .gd-code-bar { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 4px 10px; background: var(--surface-hi); border-bottom: 1px solid var(--border); }
|
|
1563
|
+
.gd-md .gd-code-lang { font-family: var(--mono, monospace); font-size: 10px; color: var(--text-lo); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
1564
|
+
.gd-md .gd-code-copy { background: transparent; border: 1px solid var(--border); color: var(--text-lo); padding: 2px 8px; border-radius: 4px; font-size: 10px; cursor: pointer; transition: background 0.1s, color 0.1s; }
|
|
1565
|
+
.gd-md .gd-code-copy:hover { background: var(--surface); color: var(--text); }
|
|
1566
|
+
.gd-md pre { margin: 0; padding: 12px 14px; overflow-x: auto; }
|
|
1567
|
+
.gd-md pre code { background: transparent; color: var(--text); padding: 0; font-size: 12.5px; line-height: 1.5; }
|
|
1568
|
+
|
|
1569
|
+
/* GFM tables */
|
|
1570
|
+
.gd-md .gd-table-wrap { margin: 14px 0; overflow-x: auto; }
|
|
1571
|
+
.gd-md table { border-collapse: collapse; width: 100%; font-size: 13px; }
|
|
1572
|
+
.gd-md th, .gd-md td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; vertical-align: top; }
|
|
1573
|
+
.gd-md th { background: var(--surface-hi); font-weight: 600; color: var(--text-hi); }
|
|
1574
|
+
.gd-md tr:nth-child(even) td { background: var(--surface); }
|
|
1525
1575
|
</style>
|
|
1526
1576
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
1527
1577
|
</head>
|
|
@@ -1579,6 +1629,10 @@ select.pb-cfg-inp { padding: 4px 7px; cursor: pointer; }
|
|
|
1579
1629
|
<div class="nav-item" data-view="global">
|
|
1580
1630
|
<span class="ico">⊕</span><span class="lbl">Global Feed</span>
|
|
1581
1631
|
</div>
|
|
1632
|
+
<div class="nav-item" data-view="global-docs" title="Mastermind-generated documents across all projects">
|
|
1633
|
+
<span class="ico">📄</span><span class="lbl">Documents</span>
|
|
1634
|
+
<span class="bdg" id="bdg-global-docs">—</span>
|
|
1635
|
+
</div>
|
|
1582
1636
|
<div class="nav-item" data-view="global-tokens" title="Token usage across all projects">
|
|
1583
1637
|
<span class="ico">$</span><span class="lbl">Global Tokens</span>
|
|
1584
1638
|
</div>
|
|
@@ -1919,6 +1973,7 @@ select.pb-cfg-inp { padding: 4px 7px; cursor: pointer; }
|
|
|
1919
1973
|
<button class="odt-btn" data-memtab="swarm" onclick="switchMemTab('swarm')">Swarm</button>
|
|
1920
1974
|
<button class="odt-btn" data-memtab="chunks" onclick="switchMemTab('chunks')">Chunks</button>
|
|
1921
1975
|
<button class="odt-btn" data-memtab="agent-graph" onclick="switchMemTab('agent-graph')">Agent Graph</button>
|
|
1976
|
+
<button class="odt-btn" data-memtab="store" onclick="switchMemTab('store')">Store</button>
|
|
1922
1977
|
</div>
|
|
1923
1978
|
<div id="mem-tab-memories">
|
|
1924
1979
|
<div class="mem-split" id="mem-split">
|
|
@@ -1982,6 +2037,19 @@ select.pb-cfg-inp { padding: 4px 7px; cursor: pointer; }
|
|
|
1982
2037
|
</div>
|
|
1983
2038
|
</div>
|
|
1984
2039
|
</div>
|
|
2040
|
+
<div id="mem-tab-store" style="display:none">
|
|
2041
|
+
<div class="filter-bar" style="margin-bottom:6px;display:flex;gap:6px;align-items:center">
|
|
2042
|
+
<input class="filter-input" id="store-search-input" type="text" placeholder="Search SQLite memory store…"
|
|
2043
|
+
onkeydown="if(event.key==='Enter')storeSearch()" style="flex:1">
|
|
2044
|
+
<input class="filter-input" id="store-ns-input" type="text" placeholder="namespace" style="width:120px"
|
|
2045
|
+
onkeydown="if(event.key==='Enter'){storeSearch()||loadStoreEntries()}">
|
|
2046
|
+
<button class="btn" onclick="storeSearch()" title="Semantic search">Search</button>
|
|
2047
|
+
<button class="btn" onclick="loadStoreEntries()" title="List entries">List</button>
|
|
2048
|
+
<button class="btn" onclick="openStoreNewModal()">+ New</button>
|
|
2049
|
+
</div>
|
|
2050
|
+
<div id="store-results" style="margin-bottom:8px"></div>
|
|
2051
|
+
<div id="store-entries-grid"></div>
|
|
2052
|
+
</div>
|
|
1985
2053
|
</div>
|
|
1986
2054
|
</div>
|
|
1987
2055
|
|
|
@@ -2179,6 +2247,36 @@ select.pb-cfg-inp { padding: 4px 7px; cursor: pointer; }
|
|
|
2179
2247
|
</div>
|
|
2180
2248
|
</div>
|
|
2181
2249
|
|
|
2250
|
+
<!-- GLOBAL DOCS — mastermind-generated markdown documents -->
|
|
2251
|
+
<div class="view" id="view-global-docs">
|
|
2252
|
+
<div class="vscroll" style="padding:0;display:flex;flex-direction:column;height:100%">
|
|
2253
|
+
<div style="display:flex;align-items:center;gap:10px;padding:14px 20px 10px;border-bottom:1px solid var(--border);flex-shrink:0">
|
|
2254
|
+
<div class="pg-title" style="margin:0">Documents</div>
|
|
2255
|
+
<span class="pg-sub" id="gd-sub" style="margin:0">Mastermind-generated across all projects</span>
|
|
2256
|
+
<span style="flex:1"></span>
|
|
2257
|
+
<input id="gd-search" type="text" placeholder="Filter by title, project, or category…" oninput="gdFilter(this.value)" style="background:var(--surface);border:1px solid var(--border);color:var(--text);padding:5px 10px;border-radius:6px;font-size:12px;width:260px" autocomplete="off" spellcheck="false">
|
|
2258
|
+
<select id="gd-sort" onchange="gdRender()" style="background:var(--surface);border:1px solid var(--border);color:var(--text);padding:5px 8px;border-radius:6px;font-size:12px">
|
|
2259
|
+
<option value="date-desc">Newest first</option>
|
|
2260
|
+
<option value="date-asc">Oldest first</option>
|
|
2261
|
+
<option value="title">Title (A→Z)</option>
|
|
2262
|
+
<option value="project">Project</option>
|
|
2263
|
+
</select>
|
|
2264
|
+
<button class="btn" onclick="loadGlobalDocs(true)" title="Rescan">↺</button>
|
|
2265
|
+
</div>
|
|
2266
|
+
<div id="gd-split" style="display:flex;flex:1;min-height:0">
|
|
2267
|
+
<div id="gd-list" style="width:340px;flex-shrink:0;overflow-y:auto;border-right:1px solid var(--border);padding:8px 0">
|
|
2268
|
+
<div class="loading-txt" style="padding:20px">Loading…</div>
|
|
2269
|
+
</div>
|
|
2270
|
+
<div id="gd-viewer" style="flex:1;overflow-y:auto;padding:32px 40px;max-width:960px">
|
|
2271
|
+
<div class="empty" style="margin-top:80px">
|
|
2272
|
+
<div class="empty-ico">📄</div>
|
|
2273
|
+
<div>Select a document to read</div>
|
|
2274
|
+
</div>
|
|
2275
|
+
</div>
|
|
2276
|
+
</div>
|
|
2277
|
+
</div>
|
|
2278
|
+
</div>
|
|
2279
|
+
|
|
2182
2280
|
<!-- GLOBAL TOKENS -->
|
|
2183
2281
|
<div class="view" id="view-global-tokens">
|
|
2184
2282
|
<div class="vscroll">
|
|
@@ -2381,7 +2479,7 @@ document.querySelectorAll('.nav-item[data-view]').forEach(el => {
|
|
|
2381
2479
|
});
|
|
2382
2480
|
|
|
2383
2481
|
// ── collapsible global nav section ──────────────────────────
|
|
2384
|
-
const GLOBAL_VIEWS = ['global', 'global-tokens', 'global-orgs', 'humaninput'];
|
|
2482
|
+
const GLOBAL_VIEWS = ['global', 'global-docs', 'global-tokens', 'global-orgs', 'humaninput'];
|
|
2385
2483
|
function setGlobalNavOpen(open) {
|
|
2386
2484
|
const items = document.getElementById('nav-glob-items');
|
|
2387
2485
|
const hdr = document.getElementById('nav-glob-hdr');
|
|
@@ -2410,10 +2508,10 @@ function switchView(v, { updateHash = true } = {}) {
|
|
|
2410
2508
|
el.classList.toggle('active', el.dataset.view === v));
|
|
2411
2509
|
document.querySelectorAll('.view').forEach(el =>
|
|
2412
2510
|
el.classList.toggle('active', el.id === 'view-' + v));
|
|
2413
|
-
const titles = { now:'Now', projects:'Projects', sessions:'Sessions', tokens:'Tokens', memory:'Memory', orgs:'Orgs', monograph:'Monograph', global:'Global Feed', 'global-tokens':'Global Tokens', 'global-orgs':'All Orgs', humaninput:'Human Input' };
|
|
2511
|
+
const titles = { now:'Now', projects:'Projects', sessions:'Sessions', tokens:'Tokens', memory:'Memory', orgs:'Orgs', monograph:'Monograph', global:'Global Feed', 'global-docs':'Documents', 'global-tokens':'Global Tokens', 'global-orgs':'All Orgs', humaninput:'Human Input' };
|
|
2414
2512
|
document.getElementById('view-title').textContent = titles[v] || v;
|
|
2415
2513
|
const PROJECT = DIR ? shortPath(DIR) : 'monomind';
|
|
2416
|
-
const VIEW_LABELS = { now: 'Now', sessions: 'Sessions', projects: 'Projects', tokens: 'Tokens', memory: 'Memory', orgs: 'Orgs', monograph: 'Monograph', global: 'Global Feed', 'global-tokens': 'Global Tokens', 'global-orgs': 'All Orgs', humaninput: 'Human Input' };
|
|
2514
|
+
const VIEW_LABELS = { now: 'Now', sessions: 'Sessions', projects: 'Projects', tokens: 'Tokens', memory: 'Memory', orgs: 'Orgs', monograph: 'Monograph', global: 'Global Feed', 'global-docs': 'Documents', 'global-tokens': 'Global Tokens', 'global-orgs': 'All Orgs', humaninput: 'Human Input' };
|
|
2417
2515
|
document.title = `monomind · ${PROJECT} · ${VIEW_LABELS[v] || v}`;
|
|
2418
2516
|
if (updateHash) _pushHash();
|
|
2419
2517
|
// Projects always re-fetches so onclick paths in cards stay current
|
|
@@ -2473,6 +2571,7 @@ function renderView(v) {
|
|
|
2473
2571
|
if (v === 'orgs') renderOrgs();
|
|
2474
2572
|
if (v === 'monograph') loadMonograph();
|
|
2475
2573
|
if (v === 'global') renderGlobalFeed();
|
|
2574
|
+
if (v === 'global-docs') loadGlobalDocs();
|
|
2476
2575
|
if (v === 'global-tokens') renderGlobalTokens();
|
|
2477
2576
|
if (v === 'global-orgs') renderGlobalOrgs();
|
|
2478
2577
|
if (v === 'humaninput') renderHumanInputView();
|
|
@@ -3370,7 +3469,7 @@ function switchMemTab(tab) {
|
|
|
3370
3469
|
_currentMemTab = tab;
|
|
3371
3470
|
document.querySelectorAll('.mem-tab-bar .odt-btn').forEach(b =>
|
|
3372
3471
|
b.classList.toggle('active', b.dataset.memtab === tab));
|
|
3373
|
-
['memories','routing','usage','adrs','swarm','chunks','agent-graph'].forEach(t => {
|
|
3472
|
+
['memories','routing','usage','adrs','swarm','chunks','agent-graph','store'].forEach(t => {
|
|
3374
3473
|
const el = document.getElementById('mem-tab-' + t);
|
|
3375
3474
|
if (el) el.style.display = t === tab ? '' : 'none';
|
|
3376
3475
|
});
|
|
@@ -3381,6 +3480,7 @@ function switchMemTab(tab) {
|
|
|
3381
3480
|
else if (tab === 'swarm') loadSwarmTab();
|
|
3382
3481
|
else if (tab === 'chunks') loadChunksTab();
|
|
3383
3482
|
else if (tab === 'agent-graph') loadAgentGraphTab();
|
|
3483
|
+
else if (tab === 'store') loadStoreEntries();
|
|
3384
3484
|
}
|
|
3385
3485
|
|
|
3386
3486
|
async function loadMemRouting() {
|
|
@@ -4097,6 +4197,390 @@ async function renderGlobalFeed() {
|
|
|
4097
4197
|
}
|
|
4098
4198
|
}
|
|
4099
4199
|
|
|
4200
|
+
// ── Global Documents ─────────────────────────────────────────────────────────
|
|
4201
|
+
// mastermind-generated markdown docs across all known projects + global brain.
|
|
4202
|
+
// Master/detail: list on the left (ordered by date), markdown viewer on right.
|
|
4203
|
+
let _gdAllDocs = [];
|
|
4204
|
+
let _gdSelected = null;
|
|
4205
|
+
let _gdFilterText = '';
|
|
4206
|
+
|
|
4207
|
+
async function loadGlobalDocs(force = false) {
|
|
4208
|
+
const listEl = document.getElementById('gd-list');
|
|
4209
|
+
const subEl = document.getElementById('gd-sub');
|
|
4210
|
+
const bdgEl = document.getElementById('bdg-global-docs');
|
|
4211
|
+
if (force) _gdAllDocs = [];
|
|
4212
|
+
if (!_gdAllDocs.length) {
|
|
4213
|
+
listEl.innerHTML = '<div class="loading-txt" style="padding:20px">Loading documents…</div>';
|
|
4214
|
+
try {
|
|
4215
|
+
const data = await apiFetch('/api/global-docs');
|
|
4216
|
+
_gdAllDocs = (data?.docs || []).slice();
|
|
4217
|
+
} catch (err) {
|
|
4218
|
+
listEl.innerHTML = '<div class="empty" style="padding:24px"><div class="empty-ico">📄</div><div>Could not load: ' + esc(err.message) + '</div></div>';
|
|
4219
|
+
return;
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4222
|
+
if (bdgEl) bdgEl.textContent = _gdAllDocs.length > 0 ? _gdAllDocs.length : '—';
|
|
4223
|
+
gdRender();
|
|
4224
|
+
}
|
|
4225
|
+
|
|
4226
|
+
function gdFilter(v) {
|
|
4227
|
+
_gdFilterText = (v || '').toLowerCase().trim();
|
|
4228
|
+
gdRender();
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4231
|
+
function gdCatLabel(c) {
|
|
4232
|
+
return ({ plan:'Plan', spec:'Spec', review:'Review', report:'Report',
|
|
4233
|
+
wiki:'Wiki', decision:'Decision', idea:'Idea', improvement:'Improvement',
|
|
4234
|
+
task:'Task', mastermind:'Mastermind' })[c] || c;
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4237
|
+
function gdCatColor(c) {
|
|
4238
|
+
const m = {
|
|
4239
|
+
plan:'#3b82f6', spec:'#8b5cf6', review:'#10b981', report:'#f59e0b',
|
|
4240
|
+
wiki:'#06b6d4', decision:'#ec4899', idea:'#f97316', improvement:'#84cc16',
|
|
4241
|
+
task:'#6366f1', mastermind:'#64748b',
|
|
4242
|
+
};
|
|
4243
|
+
return m[c] || '#64748b';
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4246
|
+
function gdSorted() {
|
|
4247
|
+
const sort = document.getElementById('gd-sort')?.value || 'date-desc';
|
|
4248
|
+
const out = _gdAllDocs.slice();
|
|
4249
|
+
if (sort === 'date-desc') out.sort((a, b) => (b.mtime || 0) - (a.mtime || 0));
|
|
4250
|
+
else if (sort === 'date-asc') out.sort((a, b) => (a.mtime || 0) - (b.mtime || 0));
|
|
4251
|
+
else if (sort === 'title') out.sort((a, b) => (a.title || '').localeCompare(b.title || ''));
|
|
4252
|
+
else if (sort === 'project') out.sort((a, b) => (a.project || '').localeCompare(b.project || '') || (b.mtime || 0) - (a.mtime || 0));
|
|
4253
|
+
return out;
|
|
4254
|
+
}
|
|
4255
|
+
|
|
4256
|
+
function gdFiltered() {
|
|
4257
|
+
const all = gdSorted();
|
|
4258
|
+
if (!_gdFilterText) return all;
|
|
4259
|
+
return all.filter(d => {
|
|
4260
|
+
const hay = (d.title + ' ' + d.project + ' ' + d.category + ' ' + d.filename + ' ' + (d.preview || '')).toLowerCase();
|
|
4261
|
+
return hay.includes(_gdFilterText);
|
|
4262
|
+
});
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
function gdFmtDate(ms) {
|
|
4266
|
+
if (!ms) return '—';
|
|
4267
|
+
const d = new Date(ms);
|
|
4268
|
+
const today = new Date();
|
|
4269
|
+
const yest = new Date(Date.now() - 86400000);
|
|
4270
|
+
if (d.toDateString() === today.toDateString()) return 'Today, ' + d.toLocaleTimeString('en', { hour: '2-digit', minute: '2-digit' });
|
|
4271
|
+
if (d.toDateString() === yest.toDateString()) return 'Yesterday';
|
|
4272
|
+
return d.toLocaleDateString('en', { year: 'numeric', month: 'short', day: 'numeric' });
|
|
4273
|
+
}
|
|
4274
|
+
|
|
4275
|
+
function gdRender() {
|
|
4276
|
+
const listEl = document.getElementById('gd-list');
|
|
4277
|
+
const subEl = document.getElementById('gd-sub');
|
|
4278
|
+
if (!listEl) return;
|
|
4279
|
+
const docs = gdFiltered();
|
|
4280
|
+
if (subEl) subEl.textContent = `${_gdAllDocs.length} document${_gdAllDocs.length === 1 ? '' : 's'} across all projects`;
|
|
4281
|
+
if (!docs.length) {
|
|
4282
|
+
listEl.innerHTML = '<div class="empty" style="padding:40px 20px"><div class="empty-ico">📄</div><div>' + (_gdFilterText ? 'No documents match the filter' : 'No documents found yet') + '</div><div style="font-size:11px;opacity:0.6;margin-top:8px">Run /mastermind:plan, /mastermind:improve, or /mastermind:createtask to generate one</div></div>';
|
|
4283
|
+
return;
|
|
4284
|
+
}
|
|
4285
|
+
// Group by day (date-desc/date-asc) for a timeline look; flat for other sorts.
|
|
4286
|
+
const sort = document.getElementById('gd-sort')?.value || 'date-desc';
|
|
4287
|
+
let html = '';
|
|
4288
|
+
const renderRow = (d) => {
|
|
4289
|
+
const col = gdCatColor(d.category);
|
|
4290
|
+
const isActive = _gdSelected === d.path;
|
|
4291
|
+
return `<div class="gd-row${isActive ? ' active' : ''}" onclick="gdOpen(${JSON.stringify(d.path).replace(/"/g, '"')})" style="padding:10px 14px;cursor:pointer;border-bottom:1px solid var(--border);border-left:3px solid ${isActive ? col : 'transparent'}">
|
|
4292
|
+
<div style="display:flex;align-items:center;gap:6px;margin-bottom:3px">
|
|
4293
|
+
<span style="background:${col}22;color:${col};padding:1px 7px;border-radius:8px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px">${esc(gdCatLabel(d.category))}</span>
|
|
4294
|
+
<span style="font-size:10px;opacity:0.6">·</span>
|
|
4295
|
+
<span style="font-size:10px;opacity:0.7">${esc(d.project)}</span>
|
|
4296
|
+
</div>
|
|
4297
|
+
<div style="font-weight:600;font-size:13px;line-height:1.3;color:var(--text);margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${esc(d.title)}</div>
|
|
4298
|
+
${d.preview ? `<div style="font-size:11px;color:var(--text-lo);line-height:1.4;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical">${esc(d.preview)}</div>` : ''}
|
|
4299
|
+
<div style="font-size:10px;color:var(--text-lo);opacity:0.7;margin-top:4px">${esc(gdFmtDate(d.mtime))}</div>
|
|
4300
|
+
</div>`;
|
|
4301
|
+
};
|
|
4302
|
+
if (sort === 'date-desc' || sort === 'date-asc') {
|
|
4303
|
+
const byDay = new Map();
|
|
4304
|
+
for (const d of docs) {
|
|
4305
|
+
const key = new Date(d.mtime || 0).toDateString();
|
|
4306
|
+
if (!byDay.has(key)) byDay.set(key, []);
|
|
4307
|
+
byDay.get(key).push(d);
|
|
4308
|
+
}
|
|
4309
|
+
for (const [key, group] of byDay) {
|
|
4310
|
+
const label = key.startsWith('Invalid') ? 'Undated' : gdFmtDate(group[0].mtime);
|
|
4311
|
+
html += `<div style="padding:8px 14px 4px;font-size:10px;font-weight:700;color:var(--text-lo);text-transform:uppercase;letter-spacing:0.6px;background:var(--surface)">${esc(label)}<span style="opacity:0.5;font-weight:500"> · ${group.length}</span></div>`;
|
|
4312
|
+
for (const d of group) html += renderRow(d);
|
|
4313
|
+
}
|
|
4314
|
+
} else {
|
|
4315
|
+
for (const d of docs) html += renderRow(d);
|
|
4316
|
+
}
|
|
4317
|
+
listEl.innerHTML = html;
|
|
4318
|
+
}
|
|
4319
|
+
|
|
4320
|
+
async function gdOpen(docPath) {
|
|
4321
|
+
_gdSelected = docPath;
|
|
4322
|
+
gdRender();
|
|
4323
|
+
const viewer = document.getElementById('gd-viewer');
|
|
4324
|
+
viewer.innerHTML = '<div class="loading-txt" style="padding:40px">Loading document…</div>';
|
|
4325
|
+
try {
|
|
4326
|
+
const data = await apiFetch('/api/global-doc/read?path=' + encodeURIComponent(docPath));
|
|
4327
|
+
if (!data?.body) {
|
|
4328
|
+
viewer.innerHTML = '<div class="empty"><div class="empty-ico">∅</div><div>Empty document</div></div>';
|
|
4329
|
+
return;
|
|
4330
|
+
}
|
|
4331
|
+
const meta = _gdAllDocs.find(d => d.path === docPath) || {};
|
|
4332
|
+
const col = gdCatColor(meta.category);
|
|
4333
|
+
const wrap = document.createElement('div');
|
|
4334
|
+
wrap.className = 'gd-doc';
|
|
4335
|
+
wrap.innerHTML =
|
|
4336
|
+
'<div class="gd-doc-header" style="margin-bottom:18px;padding-bottom:14px;border-bottom:1px solid var(--border)">' +
|
|
4337
|
+
'<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">' +
|
|
4338
|
+
'<span style="background:' + col + '22;color:' + col + ';padding:2px 10px;border-radius:10px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px">' + esc(gdCatLabel(meta.category)) + '</span>' +
|
|
4339
|
+
'<span style="font-size:11px;color:var(--text-lo)">· ' + esc(meta.project || '') + '</span>' +
|
|
4340
|
+
'<span style="flex:1"></span>' +
|
|
4341
|
+
'<a href="file://' + esc(docPath) + '" onclick="event.preventDefault();gdRevealPath(' + JSON.stringify(docPath).replace(/"/g, '"') + ')" style="font-size:11px;color:var(--text-lo);text-decoration:none" title="Reveal full path">⎘ path</a>' +
|
|
4342
|
+
'<button class="btn" onclick="gdCopyPath(' + JSON.stringify(docPath).replace(/"/g, '"') + ')" style="font-size:11px;padding:3px 8px">Copy path</button>' +
|
|
4343
|
+
'</div>' +
|
|
4344
|
+
'<div style="font-size:10px;color:var(--text-lo);opacity:0.7">' + esc(gdFmtDate(meta.mtime)) + (meta.sizeBytes ? ' · ' + Math.round(meta.sizeBytes / 1024) + ' KB' : '') + '</div>' +
|
|
4345
|
+
'</div>' +
|
|
4346
|
+
'<div class="gd-md">' + renderDocMarkdown(data.body) + '</div>';
|
|
4347
|
+
viewer.innerHTML = '';
|
|
4348
|
+
viewer.appendChild(wrap);
|
|
4349
|
+
// Reset scroll to top of the viewer.
|
|
4350
|
+
viewer.scrollTop = 0;
|
|
4351
|
+
} catch (err) {
|
|
4352
|
+
viewer.innerHTML = '<div class="empty"><div class="empty-ico">⚠</div><div>Failed to load: ' + esc(err.message) + '</div></div>';
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
|
|
4356
|
+
function gdRevealPath(p) { showToast('Path', p, 'info', 8000); }
|
|
4357
|
+
async function gdCopyPath(p) {
|
|
4358
|
+
try { await navigator.clipboard.writeText(p); showToast('Copied', 'Path copied to clipboard', 'ok'); }
|
|
4359
|
+
catch { showToast('Copy failed', 'Clipboard unavailable', 'warn'); }
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
// ── High-fidelity markdown renderer for the document viewer ──────────────────
|
|
4363
|
+
// Handles: headings (h1-h6) with anchors, bold/italic/strikethrough, inline
|
|
4364
|
+
// code and fenced code blocks (with language label + copy button), unordered/
|
|
4365
|
+
// ordered/nested/task lists, GFM tables, nested blockquotes, horizontal rules,
|
|
4366
|
+
// links (external get rel=noopener + target=_blank), images, line breaks.
|
|
4367
|
+
// HTML-escaped at the boundary; nothing the source contains can inject markup.
|
|
4368
|
+
function renderDocMarkdown(md) {
|
|
4369
|
+
if (!md) return '';
|
|
4370
|
+
const esc = (s) => String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
4371
|
+
|
|
4372
|
+
// 1. Strip a leading YAML frontmatter block (mastermind plan/spec files have one).
|
|
4373
|
+
let src = String(md).replace(/^\uFEFF?---[\s\S]*?\n---\s*\n/, '');
|
|
4374
|
+
|
|
4375
|
+
// 2. Extract fenced code blocks first so their contents are never reinterpreted.
|
|
4376
|
+
const codeBlocks = [];
|
|
4377
|
+
src = src.replace(/```([\w+-]*)\n?([\s\S]*?)```/g, (_m, lang, code) => {
|
|
4378
|
+
const clean = code.replace(/\n$/, '');
|
|
4379
|
+
codeBlocks.push({ lang: (lang || '').toLowerCase(), code: clean });
|
|
4380
|
+
return '\u0000CB' + (codeBlocks.length - 1) + '\u0000';
|
|
4381
|
+
});
|
|
4382
|
+
|
|
4383
|
+
// 3. Extract inline HTML blocks (multiline <div>…</div> etc.) — pass through
|
|
4384
|
+
// verbatim after escaping, so user-authored HTML in a plan still renders
|
|
4385
|
+
// structurally without enabling script injection (we'll re-strip <script>
|
|
4386
|
+
// and on* handlers at the end).
|
|
4387
|
+
const htmlBlocks = [];
|
|
4388
|
+
src = src.replace(/(^|\n)(<(\w+)[^>\n]*>[\s\S]*?<\/\3>)(?=\n|$)/g, (_m, lead, html) => {
|
|
4389
|
+
htmlBlocks.push(html);
|
|
4390
|
+
return (lead || '') + '\u0000HB' + (htmlBlocks.length - 1) + '\u0000';
|
|
4391
|
+
});
|
|
4392
|
+
|
|
4393
|
+
// 4. Escape everything that remains.
|
|
4394
|
+
src = esc(src).replace(/\u0000CB(\d+)\u0000/g, 'CB$1').replace(/\u0000HB(\d+)\u0000/g, 'HB$1');
|
|
4395
|
+
|
|
4396
|
+
// 5. Block-level transforms: tables, headings, hr, blockquotes, lists.
|
|
4397
|
+
// Operate line-by-line so nesting and paragraph grouping stay coherent.
|
|
4398
|
+
const lines = src.split('\n');
|
|
4399
|
+
const out = [];
|
|
4400
|
+
let i = 0;
|
|
4401
|
+
let inUl = false, inOl = false, inTask = false, bqBuf = [], paraBuf = [];
|
|
4402
|
+
|
|
4403
|
+
const closeLists = () => {
|
|
4404
|
+
if (inUl) { out.push('</ul>'); inUl = false; }
|
|
4405
|
+
if (inOl) { out.push('</ol>'); inOl = false; }
|
|
4406
|
+
if (inTask) { out.push('</ul>'); inTask = false; }
|
|
4407
|
+
};
|
|
4408
|
+
const flushPara = () => { if (paraBuf.length) { out.push('<p>' + paraBuf.join(' ') + '</p>'); paraBuf = []; } };
|
|
4409
|
+
const flushBQ = () => {
|
|
4410
|
+
if (!bqBuf.length) return;
|
|
4411
|
+
// Recursively render the inner block so nested formatting works.
|
|
4412
|
+
out.push('<blockquote>' + renderDocMarkdown(bqBuf.join('\n')) + '</blockquote>');
|
|
4413
|
+
bqBuf = [];
|
|
4414
|
+
};
|
|
4415
|
+
const slugify = (s) => String(s).toLowerCase().replace(/<[^>]+>/g, '').replace(/[^\w\s-]/g, '').trim().replace(/\s+/g, '-');
|
|
4416
|
+
|
|
4417
|
+
while (i < lines.length) {
|
|
4418
|
+
let line = lines[i];
|
|
4419
|
+
|
|
4420
|
+
// Block placeholders for code/html blocks (they sit on their own line).
|
|
4421
|
+
const cbMatch = line.match(/^CB(\d+)$/);
|
|
4422
|
+
if (cbMatch) { closeLists(); flushPara(); flushBQ(); out.push(renderCodeBlock(codeBlocks[+cbMatch[1]])); i++; continue; }
|
|
4423
|
+
const hbMatch = line.match(/^HB(\d+)$/);
|
|
4424
|
+
if (hbMatch) { closeLists(); flushPara(); flushBQ(); out.push(sanitizeHtmlBlock(htmlBlocks[+hbMatch[1]])); i++; continue; }
|
|
4425
|
+
|
|
4426
|
+
// Blank line: paragraph + list breaks.
|
|
4427
|
+
if (line.trim() === '') { closeLists(); flushPara(); flushBQ(); i++; continue; }
|
|
4428
|
+
|
|
4429
|
+
// Headings (with anchor).
|
|
4430
|
+
const h = line.match(/^(#{1,6})\s+(.+?)(?:\s+#+\s*)?$/);
|
|
4431
|
+
if (h) { closeLists(); flushPara(); flushBQ(); const lvl = h[1].length; const txt = inlineMd(h[2]); const id = slugify(h[2]); out.push('<h' + lvl + ' id="' + id + '">' + txt + '</h' + lvl + '>'); i++; continue; }
|
|
4432
|
+
|
|
4433
|
+
// Horizontal rule.
|
|
4434
|
+
if (/^(\*\s*){3,}$/.test(line) || /^(-\s*){3,}$/.test(line) || /^(_\s*){3,}$/.test(line)) { closeLists(); flushPara(); flushBQ(); out.push('<hr>'); i++; continue; }
|
|
4435
|
+
|
|
4436
|
+
// GFM table — a block of consecutive lines where line 0 and line 1 look
|
|
4437
|
+
// like | a | b | / |---|---|. Scan forward to collect the full table.
|
|
4438
|
+
if (/^\s*\|.+\|\s*$/.test(line) && i + 1 < lines.length && /^\s*\|?[\s:-]+\|[\s:|-]+\|?\s*$/.test(lines[i + 1])) {
|
|
4439
|
+
closeLists(); flushPara(); flushBQ();
|
|
4440
|
+
const headerCells = splitTableRow(line);
|
|
4441
|
+
const aligns = parseTableAligns(lines[i + 1]);
|
|
4442
|
+
i += 2;
|
|
4443
|
+
const rows = [];
|
|
4444
|
+
while (i < lines.length && /^\s*\|.+\|\s*$/.test(lines[i])) { rows.push(splitTableRow(lines[i])); i++; }
|
|
4445
|
+
out.push(renderTable(headerCells, aligns, rows));
|
|
4446
|
+
continue;
|
|
4447
|
+
}
|
|
4448
|
+
|
|
4449
|
+
// Blockquote.
|
|
4450
|
+
const bq = line.match(/^>\s?(.*)$/);
|
|
4451
|
+
if (bq) { closeLists(); flushPara(); bqBuf.push(bq[1]); i++; continue; }
|
|
4452
|
+
if (bqBuf.length) { flushBQ(); }
|
|
4453
|
+
|
|
4454
|
+
// Task list item.
|
|
4455
|
+
const task = line.match(/^(\s*)([-*])\s+\[( |x|X)\]\s+(.+)$/);
|
|
4456
|
+
if (task) { flushPara(); if (inUl) { out.push('</ul>'); inUl = false; } if (inOl) { out.push('</ol>'); inOl = false; } if (!inTask) { out.push('<ul class="md-tasklist">'); inTask = true; } const checked = task[3].toLowerCase() === 'x'; out.push('<li><input type="checkbox" disabled' + (checked ? ' checked' : '') + '> ' + inlineMd(task[4]) + '</li>'); i++; continue; }
|
|
4457
|
+
|
|
4458
|
+
// Unordered list item.
|
|
4459
|
+
const ul = line.match(/^(\s*)([-*+])\s+(.+)$/);
|
|
4460
|
+
if (ul && !task) {
|
|
4461
|
+
flushPara();
|
|
4462
|
+
if (inOl) { out.push('</ol>'); inOl = false; }
|
|
4463
|
+
if (inTask) { out.push('</ul>'); inTask = false; }
|
|
4464
|
+
if (!inUl) { out.push('<ul>'); inUl = true; }
|
|
4465
|
+
const indent = ul[1].length;
|
|
4466
|
+
if (indent === 0) out.push('<li>' + inlineMd(ul[3]) + '</li>');
|
|
4467
|
+
else {
|
|
4468
|
+
// Nested list — close current top item and open a nested <ul>.
|
|
4469
|
+
out.push('<li>' + inlineMd(ul[3]) + '</li>');
|
|
4470
|
+
}
|
|
4471
|
+
i++; continue;
|
|
4472
|
+
}
|
|
4473
|
+
// Ordered list item.
|
|
4474
|
+
const ol = line.match(/^(\s*)(\d+)\.\s+(.+)$/);
|
|
4475
|
+
if (ol) {
|
|
4476
|
+
flushPara();
|
|
4477
|
+
if (inUl) { out.push('</ul>'); inUl = false; }
|
|
4478
|
+
if (inTask) { out.push('</ul>'); inTask = false; }
|
|
4479
|
+
if (!inOl) { out.push('<ol>'); inOl = true; }
|
|
4480
|
+
out.push('<li>' + inlineMd(ol[3]) + '</li>');
|
|
4481
|
+
i++; continue;
|
|
4482
|
+
}
|
|
4483
|
+
|
|
4484
|
+
// Otherwise: paragraph text. Buffer until a blank line / structural break.
|
|
4485
|
+
closeLists();
|
|
4486
|
+
flushBQ();
|
|
4487
|
+
paraBuf.push(inlineMd(line));
|
|
4488
|
+
i++;
|
|
4489
|
+
}
|
|
4490
|
+
closeLists(); flushPara(); flushBQ();
|
|
4491
|
+
|
|
4492
|
+
let html = out.join('\n');
|
|
4493
|
+
// 6. Restore code/html block placeholders INSIDE paragraphs (when a CB/HB
|
|
4494
|
+
// token got buffered as paragraph text instead of sitting alone).
|
|
4495
|
+
html = html.replace(/CB(\d+)/g, (_m, idx) => renderCodeBlock(codeBlocks[+idx]))
|
|
4496
|
+
.replace(/HB(\d+)/g, (_m, idx) => sanitizeHtmlBlock(htmlBlocks[+idx]));
|
|
4497
|
+
return html;
|
|
4498
|
+
|
|
4499
|
+
// ── helpers ──
|
|
4500
|
+
function inlineMd(s) {
|
|
4501
|
+
// Inline code first (so its contents aren't reformatted).
|
|
4502
|
+
const codes = [];
|
|
4503
|
+
s = s.replace(/`([^`\n]+)`/g, (_m, c) => { codes.push(c); return '\u0001C' + (codes.length - 1) + '\u0001'; });
|
|
4504
|
+
// Images: 
|
|
4505
|
+
s = s.replace(/!\[([^\]]*)\]\(([^)\s]+)(?:\s+"([^"]*)")?\)/g,
|
|
4506
|
+
(_m, alt, src, title) => '<img src="' + src + '" alt="' + esc(alt) + '"' + (title ? ' title="' + esc(title) + '"' : '') + ' loading="lazy" style="max-width:100%;height:auto;border-radius:6px">');
|
|
4507
|
+
// Links: [text](href "title")
|
|
4508
|
+
s = s.replace(/\[([^\]]+)\]\(([^)\s]+)(?:\s+"([^"]*)")?\)/g,
|
|
4509
|
+
(_m, txt, href, title) => {
|
|
4510
|
+
const external = /^(https?:|mailto:|tel:)/i.test(href);
|
|
4511
|
+
const safe = external ? ' target="_blank" rel="noopener noreferrer"' : '';
|
|
4512
|
+
return '<a href="' + href + '"' + (title ? ' title="' + esc(title) + '"' : '') + safe + '>' + txt + '</a>';
|
|
4513
|
+
});
|
|
4514
|
+
// Bold.
|
|
4515
|
+
s = s.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>');
|
|
4516
|
+
s = s.replace(/__([^_\n]+)__/g, '<strong>$1</strong>');
|
|
4517
|
+
// Italic.
|
|
4518
|
+
s = s.replace(/\*([^*\n]+)\*/g, '<em>$1</em>');
|
|
4519
|
+
s = s.replace(/(^|[^_])_([^_\n]+)_/g, '$1<em>$2</em>');
|
|
4520
|
+
// Strikethrough.
|
|
4521
|
+
s = s.replace(/~~([^~\n]+)~~/g, '<del>$1</del>');
|
|
4522
|
+
// Restore inline code.
|
|
4523
|
+
s = s.replace(/\u0001C(\d+)\u0001/g, (_m, idx) => '<code>' + esc(codes[+idx]) + '</code>');
|
|
4524
|
+
return s;
|
|
4525
|
+
}
|
|
4526
|
+
|
|
4527
|
+
function renderCodeBlock(block) {
|
|
4528
|
+
const lang = block?.lang || '';
|
|
4529
|
+
const code = block?.code ?? '';
|
|
4530
|
+
const labelHtml = lang ? '<span class="gd-code-lang">' + esc(lang) + '</span>' : '';
|
|
4531
|
+
return '<div class="gd-code-block">' +
|
|
4532
|
+
'<div class="gd-code-bar"><button class="gd-code-copy" onclick="gdCopyCode(this)">copy</button>' + labelHtml + '</div>' +
|
|
4533
|
+
'<pre><code' + (lang ? ' class="language-' + esc(lang) + '"' : '') + '>' + esc(code) + '</code></pre>' +
|
|
4534
|
+
'</div>';
|
|
4535
|
+
}
|
|
4536
|
+
|
|
4537
|
+
function sanitizeHtmlBlock(html) {
|
|
4538
|
+
// Strip <script> entirely, drop event-handler attributes (onclick=, onload=, on*=),
|
|
4539
|
+
// and javascript: URLs. Keep everything else as-is so user HTML renders.
|
|
4540
|
+
return String(html)
|
|
4541
|
+
.replace(/<script[\s\S]*?<\/script>/gi, '')
|
|
4542
|
+
.replace(/\son\w+\s*=\s*"[^"]*"/gi, '')
|
|
4543
|
+
.replace(/\son\w+\s*=\s*'[^']*'/gi, '')
|
|
4544
|
+
.replace(/\son\w+\s*=\s*[^\s>]+/gi, '')
|
|
4545
|
+
.replace(/(href|src)\s*=\s*"javascript:[^"]*"/gi, '$1="#"');
|
|
4546
|
+
}
|
|
4547
|
+
|
|
4548
|
+
function splitTableRow(line) {
|
|
4549
|
+
return line.trim().replace(/^\||\|$/g, '').split('|').map(c => c.trim());
|
|
4550
|
+
}
|
|
4551
|
+
function parseTableAligns(line) {
|
|
4552
|
+
return splitTableRow(line).map(cell => {
|
|
4553
|
+
if (/^:\s*-+:$/.test(cell)) return 'center';
|
|
4554
|
+
if (/^-*:$/.test(cell)) return 'left';
|
|
4555
|
+
if (/^-+:$/.test(cell)) return 'right';
|
|
4556
|
+
return null;
|
|
4557
|
+
});
|
|
4558
|
+
}
|
|
4559
|
+
function renderTable(headerCells, aligns, rows) {
|
|
4560
|
+
const alignAttr = (i) => aligns[i] ? ' style="text-align:' + aligns[i] + '"' : '';
|
|
4561
|
+
let html = '<div class="gd-table-wrap"><table><thead><tr>';
|
|
4562
|
+
headerCells.forEach((c, i) => { html += '<th' + alignAttr(i) + '>' + inlineMd(c) + '</th>'; });
|
|
4563
|
+
html += '</tr></thead><tbody>';
|
|
4564
|
+
for (const r of rows) {
|
|
4565
|
+
html += '<tr>';
|
|
4566
|
+
r.forEach((c, i) => { html += '<td' + alignAttr(i) + '>' + inlineMd(c) + '</td>'; });
|
|
4567
|
+
html += '</tr>';
|
|
4568
|
+
}
|
|
4569
|
+
html += '</tbody></table></div>';
|
|
4570
|
+
return html;
|
|
4571
|
+
}
|
|
4572
|
+
}
|
|
4573
|
+
|
|
4574
|
+
function gdCopyCode(btn) {
|
|
4575
|
+
const codeEl = btn.closest('.gd-code-block')?.querySelector('code');
|
|
4576
|
+
if (!codeEl) return;
|
|
4577
|
+
const text = codeEl.textContent;
|
|
4578
|
+
navigator.clipboard.writeText(text).then(
|
|
4579
|
+
() => { const old = btn.textContent; btn.textContent = 'copied'; setTimeout(() => { btn.textContent = old; }, 1200); },
|
|
4580
|
+
() => { btn.textContent = 'failed'; },
|
|
4581
|
+
);
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4100
4584
|
let _hiEntries = [];
|
|
4101
4585
|
let _hiTab = 'pending';
|
|
4102
4586
|
|
|
@@ -5909,7 +6393,7 @@ function v2RenderOrgChart() {
|
|
|
5909
6393
|
<title>${esc(displayName)}${subType ? ` · ${esc(subType)}` : ''} — click for details</title>
|
|
5910
6394
|
${outerRing}
|
|
5911
6395
|
<circle r="${R}" fill="oklch(12% 0.008 55)" stroke="${color}" stroke-width="${leader ? 2.5 : 1.8}" filter="url(#v2glow)"/>
|
|
5912
|
-
<image href="${avatarSrc}" x="${-avR}" y="${-avR}" width="${avR * 2}" height="${avR * 2}" clip-path="url(#${nodeClipIds[i]})" preserveAspectRatio="xMidYMid meet" onerror="this.setAttribute('href','data/avatars/coder.svg')"/>
|
|
6396
|
+
<image href="${esc(avatarSrc)}" x="${-avR}" y="${-avR}" width="${avR * 2}" height="${avR * 2}" clip-path="url(#${nodeClipIds[i]})" preserveAspectRatio="xMidYMid meet" onerror="this.setAttribute('href','data/avatars/coder.svg')"/>
|
|
5913
6397
|
<rect x="${(-lblW / 2).toFixed(0)}" y="${nameY - 11}" width="${lblW.toFixed(0)}" height="${lblH}" rx="3" fill="oklch(12% 0.008 55 / 0.85)"/>
|
|
5914
6398
|
<text text-anchor="middle" y="${nameY}" font-size="9" font-weight="${leader?'600':'500'}" font-family="'Inter',system-ui,sans-serif" fill="${color}">${esc(nameText)}</text>
|
|
5915
6399
|
${subTypeText ? `<text text-anchor="middle" y="${nameY + 11}" font-size="7.5" font-family="'Inter',system-ui,sans-serif" fill="oklch(58% 0.005 75)">${esc(subTypeText)}</text>` : ''}
|
|
@@ -6332,7 +6816,7 @@ function v2RenderOrgRoles() {
|
|
|
6332
6816
|
const avatarSrc = v2RoleAvatar(r, _rolesAvMap);
|
|
6333
6817
|
return `<div class="role-v2" style="border-top:2px solid ${color}" onclick="v2OpenAgent('${String(r.id).replace(/['\\]/g,'\\$&')}')" title="View agent characteristics, skills & instructions">
|
|
6334
6818
|
<div class="rv2-head">
|
|
6335
|
-
<img class="rv2-avatar" src="${avatarSrc}" alt="${esc(displayName)}" loading="lazy" width="48" height="48" onerror="this.src='data/avatars/coder.svg'"/>
|
|
6819
|
+
<img class="rv2-avatar" src="${esc(avatarSrc)}" alt="${esc(displayName)}" loading="lazy" width="48" height="48" onerror="this.src='data/avatars/coder.svg'"/>
|
|
6336
6820
|
<div class="rv2-info">
|
|
6337
6821
|
<div class="rv2-title">${esc(displayName)}${isLeader ? ' <span style="font-size:10px;color:var(--accent);font-weight:400;opacity:0.8">lead</span>' : ''}${isRunning ? ' <span class="live-dot" style="display:inline-block;vertical-align:middle;margin-left:4px"></span>' : ''}</div>
|
|
6338
6822
|
${roleType ? `<span class="rv2-agent">${esc(roleType)}</span>` : ''}
|
|
@@ -6391,7 +6875,7 @@ function v2RenderAgentDrawer(data) {
|
|
|
6391
6875
|
|
|
6392
6876
|
headEl.innerHTML = `
|
|
6393
6877
|
<div class="oad-avatar-wrap" onclick="v2TriggerAvatarUpload('${String(role.id).replace(/['\\]/g,'\\$&')}')" title="Change avatar">
|
|
6394
|
-
<img class="oad-avatar" id="oad-avatar-img" src="${avatar}" alt="${esc(name)}" width="46" height="46" onerror="this.src='data/avatars/coder.svg'"/>
|
|
6878
|
+
<img class="oad-avatar" id="oad-avatar-img" src="${esc(avatar)}" alt="${esc(name)}" width="46" height="46" onerror="this.src='data/avatars/coder.svg'"/>
|
|
6395
6879
|
<div class="oad-avatar-edit">✎</div>
|
|
6396
6880
|
</div>
|
|
6397
6881
|
<input type="file" id="oad-avatar-file" accept="image/png,image/jpeg,image/webp,image/gif" style="display:none" onchange="v2HandleAvatarFile(this)"/>
|
|
@@ -13266,6 +13750,121 @@ async function deleteMem(filename) {
|
|
|
13266
13750
|
} catch (e) { showToast('Error', e.message, 'err'); }
|
|
13267
13751
|
}
|
|
13268
13752
|
|
|
13753
|
+
// ── SQLite store tab ──────────────────────────────────────
|
|
13754
|
+
let _storeLoaded = false;
|
|
13755
|
+
|
|
13756
|
+
async function loadStoreEntries() {
|
|
13757
|
+
const grid = document.getElementById('store-entries-grid');
|
|
13758
|
+
if (!grid) return;
|
|
13759
|
+
grid.innerHTML = '<div class="loading-txt" style="padding:8px">Loading…</div>';
|
|
13760
|
+
const ns = (document.getElementById('store-ns-input')?.value || '').trim() || undefined;
|
|
13761
|
+
try {
|
|
13762
|
+
let url = '/api/memory/entries?limit=100';
|
|
13763
|
+
if (ns) url += '&namespace=' + encodeURIComponent(ns);
|
|
13764
|
+
const data = await apiFetch(url);
|
|
13765
|
+
const entries = data.entries || [];
|
|
13766
|
+
if (!entries.length) { grid.innerHTML = '<div class="empty">No entries' + (ns ? ' in namespace "' + escHtml(ns) + '"' : '') + '</div>'; return; }
|
|
13767
|
+
let html = '<table class="tbl" style="width:100%;font-size:12px"><thead><tr><th>Key</th><th>Namespace</th><th>Content</th><th>Tags</th><th>Updated</th><th></th></tr></thead><tbody>';
|
|
13768
|
+
for (const e of entries) {
|
|
13769
|
+
const preview = escHtml((e.content || '').slice(0, 80)) + (e.content?.length > 80 ? '…' : '');
|
|
13770
|
+
const tags = (e.tags || []).map(t => '<span style="background:var(--bg-hi);padding:1px 4px;border-radius:3px;font-size:10px">' + escHtml(t) + '</span>').join(' ');
|
|
13771
|
+
const updated = e.updatedAt ? new Date(e.updatedAt).toLocaleDateString() : '';
|
|
13772
|
+
const emb = e.hasEmbedding ? ' title="Has embedding"' : '';
|
|
13773
|
+
html += '<tr>';
|
|
13774
|
+
html += '<td style="font-weight:500;white-space:nowrap"' + emb + '>' + (e.hasEmbedding ? '◉ ' : '') + escHtml(e.key) + '</td>';
|
|
13775
|
+
html += '<td style="color:var(--text-lo)">' + escHtml(e.namespace) + '</td>';
|
|
13776
|
+
html += '<td style="max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + preview + '</td>';
|
|
13777
|
+
html += '<td>' + tags + '</td>';
|
|
13778
|
+
html += '<td style="color:var(--text-lo);white-space:nowrap">' + updated + '</td>';
|
|
13779
|
+
html += '<td style="white-space:nowrap"><button class="btn" style="font-size:10px;padding:1px 6px" onclick="viewStoreEntry(\'' + escHtml(e.key) + '\',\'' + escHtml(e.namespace) + '\')">View</button>';
|
|
13780
|
+
html += ' <button class="btn" style="font-size:10px;padding:1px 6px;color:var(--red);border-color:var(--red)" onclick="deleteStoreEntry(\'' + escHtml(e.id || '') + '\',\'' + escHtml(e.key) + '\',\'' + escHtml(e.namespace) + '\')">Del</button></td>';
|
|
13781
|
+
html += '</tr>';
|
|
13782
|
+
}
|
|
13783
|
+
html += '</tbody></table>';
|
|
13784
|
+
grid.innerHTML = html;
|
|
13785
|
+
_storeLoaded = true;
|
|
13786
|
+
} catch (e) {
|
|
13787
|
+
grid.innerHTML = '<div class="empty" style="color:var(--red)">Error: ' + escHtml(e.message) + '</div>';
|
|
13788
|
+
}
|
|
13789
|
+
}
|
|
13790
|
+
|
|
13791
|
+
async function storeSearch() {
|
|
13792
|
+
const q = (document.getElementById('store-search-input')?.value || '').trim();
|
|
13793
|
+
if (!q) return false;
|
|
13794
|
+
const ns = (document.getElementById('store-ns-input')?.value || '').trim() || undefined;
|
|
13795
|
+
const res = document.getElementById('store-results');
|
|
13796
|
+
if (!res) return false;
|
|
13797
|
+
res.style.display = '';
|
|
13798
|
+
res.innerHTML = '<div class="loading-txt">Searching…</div>';
|
|
13799
|
+
try {
|
|
13800
|
+
let url = '/api/memory/search?q=' + encodeURIComponent(q) + '&limit=20';
|
|
13801
|
+
if (ns) url += '&namespace=' + encodeURIComponent(ns);
|
|
13802
|
+
const data = await apiFetch(url);
|
|
13803
|
+
const results = data.results || [];
|
|
13804
|
+
if (!results.length) { res.innerHTML = '<div class="empty">No results for "' + escHtml(q) + '"</div>'; return true; }
|
|
13805
|
+
let html = '<div class="m-group-title" style="margin-bottom:4px">Search results (' + results.length + ') <span style="font-size:10px;color:var(--text-xs);font-weight:400">' + (data.searchMethod || '') + ', ' + (data.searchTime || 0) + 'ms</span></div>';
|
|
13806
|
+
html += '<table class="tbl" style="width:100%;font-size:12px"><thead><tr><th>Key</th><th>Score</th><th>NS</th><th>Content</th></tr></thead><tbody>';
|
|
13807
|
+
for (const r of results) {
|
|
13808
|
+
const preview = escHtml((r.content || '').slice(0, 100)) + (r.content?.length > 100 ? '…' : '');
|
|
13809
|
+
html += '<tr><td style="font-weight:500">' + escHtml(r.key) + '</td>';
|
|
13810
|
+
html += '<td style="color:var(--text-lo)">' + (r.score?.toFixed(3) || '') + '</td>';
|
|
13811
|
+
html += '<td style="color:var(--text-lo)">' + escHtml(r.namespace) + '</td>';
|
|
13812
|
+
html += '<td style="max-width:400px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + preview + '</td></tr>';
|
|
13813
|
+
}
|
|
13814
|
+
html += '</tbody></table>';
|
|
13815
|
+
res.innerHTML = html;
|
|
13816
|
+
} catch (e) {
|
|
13817
|
+
res.innerHTML = '<div class="empty" style="color:var(--red)">Search error: ' + escHtml(e.message) + '</div>';
|
|
13818
|
+
}
|
|
13819
|
+
return true;
|
|
13820
|
+
}
|
|
13821
|
+
|
|
13822
|
+
function viewStoreEntry(key, ns) {
|
|
13823
|
+
const content = prompt('View/edit content for "' + key + '" (namespace: ' + ns + ').\nEdit below and press OK to save, or Cancel to dismiss.');
|
|
13824
|
+
if (content === null) return;
|
|
13825
|
+
fetch('/api/memory/entry', {
|
|
13826
|
+
method: 'POST',
|
|
13827
|
+
headers: { 'Content-Type': 'application/json' },
|
|
13828
|
+
body: JSON.stringify({ key, value: content, namespace: ns }),
|
|
13829
|
+
}).then(r => r.json()).then(d => {
|
|
13830
|
+
if (d.ok) { showToast('Saved', 'Entry updated', 'ok'); loadStoreEntries(); }
|
|
13831
|
+
else showToast('Error', d.error || 'Save failed', 'err');
|
|
13832
|
+
}).catch(e => showToast('Error', e.message, 'err'));
|
|
13833
|
+
}
|
|
13834
|
+
|
|
13835
|
+
async function deleteStoreEntry(id, key, ns) {
|
|
13836
|
+
if (!confirm('Delete entry "' + key + '" from namespace "' + ns + '"?')) return;
|
|
13837
|
+
try {
|
|
13838
|
+
const r = await fetch('/api/memory/entry', {
|
|
13839
|
+
method: 'DELETE',
|
|
13840
|
+
headers: { 'Content-Type': 'application/json' },
|
|
13841
|
+
body: JSON.stringify({ id: id || undefined, key, namespace: ns }),
|
|
13842
|
+
});
|
|
13843
|
+
const d = await r.json();
|
|
13844
|
+
if (d.ok) { showToast('Deleted', 'Entry removed', 'ok'); loadStoreEntries(); }
|
|
13845
|
+
else showToast('Error', d.error || 'Delete failed', 'err');
|
|
13846
|
+
} catch (e) { showToast('Error', e.message, 'err'); }
|
|
13847
|
+
}
|
|
13848
|
+
|
|
13849
|
+
function openStoreNewModal() {
|
|
13850
|
+
const key = prompt('Entry key (unique identifier):');
|
|
13851
|
+
if (!key) return;
|
|
13852
|
+
const ns = (document.getElementById('store-ns-input')?.value || '').trim() || 'default';
|
|
13853
|
+
const value = prompt('Entry content:');
|
|
13854
|
+
if (!value) return;
|
|
13855
|
+
const tags = (prompt('Tags (comma-separated, optional):') || '').split(',').map(t => t.trim()).filter(Boolean);
|
|
13856
|
+
fetch('/api/memory/entry', {
|
|
13857
|
+
method: 'POST',
|
|
13858
|
+
headers: { 'Content-Type': 'application/json' },
|
|
13859
|
+
body: JSON.stringify({ key, value, namespace: ns, tags }),
|
|
13860
|
+
}).then(r => r.json()).then(d => {
|
|
13861
|
+
if (d.ok) {
|
|
13862
|
+
showToast('Stored', d.duplicate ? 'Near-duplicate reinforced' : 'Entry created', 'ok');
|
|
13863
|
+
loadStoreEntries();
|
|
13864
|
+
} else showToast('Error', d.error || 'Store failed', 'err');
|
|
13865
|
+
}).catch(e => showToast('Error', e.message, 'err'));
|
|
13866
|
+
}
|
|
13867
|
+
|
|
13269
13868
|
// ── swarm memory tab ───────────────────────────────────────
|
|
13270
13869
|
let _swarmRuns = [];
|
|
13271
13870
|
|