agim-cli 1.4.8 → 1.5.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/CHANGELOG.md +415 -402
- package/README.md +4 -4
- package/bin/agim_rpc.py +12 -12
- package/dist/cli-ui/cmd-handlers.d.ts +3 -3
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +11 -19
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/config-wizard.js +27 -27
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/env-file.d.ts +4 -4
- package/dist/cli-ui/env-file.js +13 -13
- package/dist/cli-ui/env-file.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +2 -2
- package/dist/cli-ui/i18n.js +9 -9
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/lang-picker.js +1 -1
- package/dist/cli-ui/lang-picker.js.map +1 -1
- package/dist/cli-ui/paths.d.ts.map +1 -1
- package/dist/cli-ui/paths.js +2 -4
- package/dist/cli-ui/paths.js.map +1 -1
- package/dist/cli-ui/service.d.ts +7 -7
- package/dist/cli-ui/service.d.ts.map +1 -1
- package/dist/cli-ui/service.js +57 -72
- package/dist/cli-ui/service.js.map +1 -1
- package/dist/cli-ui/tui/app.js +2 -2
- package/dist/cli-ui/tui/app.js.map +1 -1
- package/dist/cli-ui/tui/index.js +6 -6
- package/dist/cli-ui/tui/index.js.map +1 -1
- package/dist/cli-ui/tui/mouse-stdin.js +1 -1
- package/dist/cli-ui/tui/mouse-stdin.js.map +1 -1
- package/dist/cli-ui/tui/stream-reveal.d.ts +2 -2
- package/dist/cli-ui/tui/stream-reveal.d.ts.map +1 -1
- package/dist/cli-ui/tui/stream-reveal.js +4 -4
- package/dist/cli-ui/tui/stream-reveal.js.map +1 -1
- package/dist/cli.js +24 -45
- package/dist/cli.js.map +1 -1
- package/dist/core/a2a-notify.js +5 -5
- package/dist/core/a2a-notify.js.map +1 -1
- package/dist/core/a2a.d.ts +2 -2
- package/dist/core/a2a.d.ts.map +1 -1
- package/dist/core/a2a.js +12 -12
- package/dist/core/a2a.js.map +1 -1
- package/dist/core/access-token.d.ts +1 -1
- package/dist/core/access-token.js +7 -7
- package/dist/core/access-token.js.map +1 -1
- package/dist/core/acp-server.js +5 -5
- package/dist/core/acp-server.js.map +1 -1
- package/dist/core/admin-allowlist.js +5 -5
- package/dist/core/admin-allowlist.js.map +1 -1
- package/dist/core/agent-base.d.ts +1 -1
- package/dist/core/agent-base.js +3 -3
- package/dist/core/agent-base.js.map +1 -1
- package/dist/core/agent-cwd.d.ts +5 -6
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +15 -16
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/agim-paths.d.ts +1 -4
- package/dist/core/agim-paths.d.ts.map +1 -1
- package/dist/core/agim-paths.js +18 -35
- package/dist/core/agim-paths.js.map +1 -1
- package/dist/core/approval-bus.d.ts +4 -4
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +14 -14
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/approval-router.js +2 -2
- package/dist/core/artifacts.js +3 -3
- package/dist/core/artifacts.js.map +1 -1
- package/dist/core/ask-user-rpc.js +1 -1
- package/dist/core/ask-user-rpc.js.map +1 -1
- package/dist/core/audit-log.js +2 -2
- package/dist/core/audit-log.js.map +1 -1
- package/dist/core/bgjob-reader.d.ts +1 -1
- package/dist/core/bgjob-reader.js +4 -4
- package/dist/core/bgjob-reader.js.map +1 -1
- package/dist/core/commands/approval.js +2 -2
- package/dist/core/commands/approval.js.map +1 -1
- package/dist/core/commands/heartbeat.js +2 -2
- package/dist/core/commands/heartbeat.js.map +1 -1
- package/dist/core/commands/memo.js +1 -1
- package/dist/core/commands/memo.js.map +1 -1
- package/dist/core/commands/model.js +1 -1
- package/dist/core/commands/model.js.map +1 -1
- package/dist/core/commands/plan.js +3 -3
- package/dist/core/commands/plan.js.map +1 -1
- package/dist/core/commands/router-compare.js +3 -3
- package/dist/core/commands/router-compare.js.map +1 -1
- package/dist/core/commands/service.d.ts.map +1 -1
- package/dist/core/commands/service.js +1 -3
- package/dist/core/commands/service.js.map +1 -1
- package/dist/core/commands/sessions.js +4 -4
- package/dist/core/commands/sessions.js.map +1 -1
- package/dist/core/commands/skill.js +1 -1
- package/dist/core/commands/skill.js.map +1 -1
- package/dist/core/commands/stats.js +1 -1
- package/dist/core/commands/stats.js.map +1 -1
- package/dist/core/commands/web.js +5 -5
- package/dist/core/commands/web.js.map +1 -1
- package/dist/core/config-schema.js +1 -1
- package/dist/core/coord-systems.d.ts +1 -1
- package/dist/core/coord-systems.js +4 -4
- package/dist/core/coord-systems.js.map +1 -1
- package/dist/core/event-bus.d.ts +5 -5
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +3 -3
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/feature-flags.d.ts +2 -2
- package/dist/core/feature-flags.js +4 -4
- package/dist/core/feature-flags.js.map +1 -1
- package/dist/core/goal-rpc.js +2 -2
- package/dist/core/goal-rpc.js.map +1 -1
- package/dist/core/goals.d.ts +1 -1
- package/dist/core/goals.js +3 -3
- package/dist/core/goals.js.map +1 -1
- package/dist/core/heartbeat-store.d.ts +1 -1
- package/dist/core/heartbeat-store.d.ts.map +1 -1
- package/dist/core/heartbeat-store.js +3 -3
- package/dist/core/heartbeat-store.js.map +1 -1
- package/dist/core/heartbeat.js +4 -4
- package/dist/core/heartbeat.js.map +1 -1
- package/dist/core/intent-llm.d.ts +2 -2
- package/dist/core/intent-llm.js +5 -5
- package/dist/core/intent-llm.js.map +1 -1
- package/dist/core/job-board.d.ts +5 -5
- package/dist/core/job-board.d.ts.map +1 -1
- package/dist/core/job-board.js +17 -17
- package/dist/core/job-board.js.map +1 -1
- package/dist/core/llm/agent-loop.d.ts +3 -3
- package/dist/core/llm/agent-loop.js +14 -14
- package/dist/core/llm/agent-loop.js.map +1 -1
- package/dist/core/llm/{imhub-dispatcher.d.ts → agim-dispatcher.d.ts} +4 -4
- package/dist/core/llm/agim-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/{imhub-dispatcher.js → agim-dispatcher.js} +43 -43
- package/dist/core/llm/agim-dispatcher.js.map +1 -0
- package/dist/core/llm/agim-rpc-server.js +17 -17
- package/dist/core/llm/agim-rpc-server.js.map +1 -1
- package/dist/core/llm/auto-compact.d.ts +3 -3
- package/dist/core/llm/auto-compact.d.ts.map +1 -1
- package/dist/core/llm/auto-compact.js +5 -5
- package/dist/core/llm/auto-compact.js.map +1 -1
- package/dist/core/llm/builtin-dispatcher.js +3 -3
- package/dist/core/llm/builtin-dispatcher.js.map +1 -1
- package/dist/core/llm/exec-dispatcher.d.ts +2 -2
- package/dist/core/llm/exec-dispatcher.d.ts.map +1 -1
- package/dist/core/llm/exec-dispatcher.js +20 -22
- package/dist/core/llm/exec-dispatcher.js.map +1 -1
- package/dist/core/llm/fs-dispatcher.js +8 -8
- package/dist/core/llm/fs-dispatcher.js.map +1 -1
- package/dist/core/llm/goal-critic.js +4 -4
- package/dist/core/llm/goal-critic.js.map +1 -1
- package/dist/core/llm/hallucination-detector.js +2 -2
- package/dist/core/llm/hallucination-detector.js.map +1 -1
- package/dist/core/llm/mcp-client.d.ts +1 -1
- package/dist/core/llm/mcp-client.js +3 -3
- package/dist/core/llm/mcp-client.js.map +1 -1
- package/dist/core/llm/mcp-registry.js +3 -3
- package/dist/core/llm/mcp-registry.js.map +1 -1
- package/dist/core/llm/openai-compat-provider.d.ts +1 -1
- package/dist/core/llm/openai-compat-provider.js +2 -2
- package/dist/core/llm/openai-compat-provider.js.map +1 -1
- package/dist/core/llm/provider-base.d.ts +1 -1
- package/dist/core/llm/secrets.d.ts +2 -2
- package/dist/core/llm/secrets.d.ts.map +1 -1
- package/dist/core/llm/tool-dispatcher.d.ts +1 -1
- package/dist/core/llm/web-dispatcher.d.ts +1 -1
- package/dist/core/llm/web-dispatcher.js +15 -15
- package/dist/core/llm/web-dispatcher.js.map +1 -1
- package/dist/core/logger.d.ts +1 -1
- package/dist/core/logger.js +3 -3
- package/dist/core/logger.js.map +1 -1
- package/dist/core/memo-rpc.js +3 -3
- package/dist/core/memo-rpc.js.map +1 -1
- package/dist/core/memory-consolidate.js +4 -4
- package/dist/core/memory-consolidate.js.map +1 -1
- package/dist/core/memory-distill.js +4 -4
- package/dist/core/memory-distill.js.map +1 -1
- package/dist/core/memory-distiller.d.ts +10 -4
- package/dist/core/memory-distiller.d.ts.map +1 -1
- package/dist/core/memory-distiller.js +31 -17
- package/dist/core/memory-distiller.js.map +1 -1
- package/dist/core/memory-vector.js +9 -9
- package/dist/core/memory-vector.js.map +1 -1
- package/dist/core/memory.js +2 -2
- package/dist/core/memory.js.map +1 -1
- package/dist/core/memos.js +6 -6
- package/dist/core/memos.js.map +1 -1
- package/dist/core/message-sink.js +13 -13
- package/dist/core/message-sink.js.map +1 -1
- package/dist/core/notification-evaluator.d.ts +2 -2
- package/dist/core/notification-evaluator.js +4 -4
- package/dist/core/notification-evaluator.js.map +1 -1
- package/dist/core/onboarding.js +3 -3
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/outbox.js +2 -2
- package/dist/core/outbox.js.map +1 -1
- package/dist/core/persona.d.ts +1 -1
- package/dist/core/persona.d.ts.map +1 -1
- package/dist/core/persona.js +2 -2
- package/dist/core/persona.js.map +1 -1
- package/dist/core/plan-history.js +1 -1
- package/dist/core/plan-history.js.map +1 -1
- package/dist/core/plan-intent.js +5 -5
- package/dist/core/plan-intent.js.map +1 -1
- package/dist/core/plan-mode-state.d.ts +1 -1
- package/dist/core/plan-mode-state.js +4 -4
- package/dist/core/plan-mode-state.js.map +1 -1
- package/dist/core/push-rpc.d.ts +1 -1
- package/dist/core/push-rpc.js +6 -6
- package/dist/core/push-rpc.js.map +1 -1
- package/dist/core/registry.d.ts +4 -4
- package/dist/core/registry.js +10 -10
- package/dist/core/registry.js.map +1 -1
- package/dist/core/reminders.js +1 -1
- package/dist/core/reminders.js.map +1 -1
- package/dist/core/restart-flow.d.ts.map +1 -1
- package/dist/core/restart-flow.js +5 -7
- package/dist/core/restart-flow.js.map +1 -1
- package/dist/core/router.d.ts +1 -1
- package/dist/core/router.js +5 -5
- package/dist/core/router.js.map +1 -1
- package/dist/core/schedule.d.ts +2 -2
- package/dist/core/schedule.js +4 -4
- package/dist/core/schedule.js.map +1 -1
- package/dist/core/self-protect.js +3 -3
- package/dist/core/self-protect.js.map +1 -1
- package/dist/core/sender-allowlist.js +7 -7
- package/dist/core/sender-allowlist.js.map +1 -1
- package/dist/core/sensitive-paths.d.ts.map +1 -1
- package/dist/core/sensitive-paths.js +1 -2
- package/dist/core/sensitive-paths.js.map +1 -1
- package/dist/core/session.js +2 -2
- package/dist/core/session.js.map +1 -1
- package/dist/core/skills/builtin/ECC_NOTICE.md +1 -1
- package/dist/core/skills/builtin/agim-memory/SKILL.md +1 -1
- package/dist/core/skills/builtin/agim-reminders/SKILL.md +2 -2
- package/dist/core/skills/builtin/agim-self/SKILL.md +9 -9
- package/dist/core/skills/builtin/agim-skill-discovery/SKILL.md +5 -5
- package/dist/core/skills/builtin/image-generation/SKILL.md +2 -2
- package/dist/core/skills/builtin/long-goal/SKILL.md +7 -7
- package/dist/core/skills/builtin/my/SKILL.md +2 -2
- package/dist/core/skills/builtin/skill-creator/SKILL.md +2 -2
- package/dist/core/skills/loader.d.ts +4 -4
- package/dist/core/skills/loader.js +22 -22
- package/dist/core/skills/loader.js.map +1 -1
- package/dist/core/skills-rpc.js +1 -1
- package/dist/core/skills-rpc.js.map +1 -1
- package/dist/core/transcribe.js +13 -13
- package/dist/core/transcribe.js.map +1 -1
- package/dist/core/tunnel.js +1 -1
- package/dist/core/tunnel.js.map +1 -1
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/user-coord-prefs.js +1 -1
- package/dist/core/user-coord-prefs.js.map +1 -1
- package/dist/core/viewer-config.d.ts +8 -8
- package/dist/core/viewer-config.js +17 -17
- package/dist/core/viewer-config.js.map +1 -1
- package/dist/core/viewer-local.js +4 -4
- package/dist/core/viewer-local.js.map +1 -1
- package/dist/core/viewer-remote.js +1 -1
- package/dist/core/viewer-remote.js.map +1 -1
- package/dist/plugins/agents/acp/url-guard.d.ts +1 -1
- package/dist/plugins/agents/acp/url-guard.js +2 -2
- package/dist/plugins/agents/acp/url-guard.js.map +1 -1
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts +6 -6
- package/dist/plugins/agents/antigravity/ensure-mcp-config.d.ts.map +1 -1
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js +12 -12
- package/dist/plugins/agents/antigravity/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/antigravity/index.js +10 -10
- package/dist/plugins/agents/antigravity/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/index.d.ts +2 -2
- package/dist/plugins/agents/claude-code/index.js +16 -16
- package/dist/plugins/agents/claude-code/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +13 -13
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +4 -4
- package/dist/plugins/agents/codex/build-mcp-cli-args.js +14 -14
- package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -1
- package/dist/plugins/agents/codex/index.d.ts +3 -3
- package/dist/plugins/agents/codex/index.js +14 -14
- package/dist/plugins/agents/codex/index.js.map +1 -1
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts +5 -5
- package/dist/plugins/agents/cursor/ensure-mcp-config.d.ts.map +1 -1
- package/dist/plugins/agents/cursor/ensure-mcp-config.js +11 -11
- package/dist/plugins/agents/cursor/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/cursor/index.d.ts +1 -1
- package/dist/plugins/agents/cursor/index.js +12 -12
- package/dist/plugins/agents/cursor/index.js.map +1 -1
- package/dist/plugins/agents/native/index.js +14 -14
- package/dist/plugins/agents/native/index.js.map +1 -1
- package/dist/plugins/agents/native/tool-registry.d.ts +3 -3
- package/dist/plugins/agents/native/tool-registry.d.ts.map +1 -1
- package/dist/plugins/agents/native/tool-registry.js +5 -5
- package/dist/plugins/agents/native/tool-registry.js.map +1 -1
- package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +1 -1
- package/dist/plugins/agents/opencode/ensure-mcp-config.js +9 -9
- package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -1
- package/dist/plugins/agents/opencode/index.js +3 -3
- package/dist/plugins/agents/opencode/index.js.map +1 -1
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +4 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-http-adapter.js +16 -12
- package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +2 -2
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +7 -5
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
- package/dist/plugins/agents/opencode/serve-manager.d.ts +1 -1
- package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/serve-manager.js +10 -10
- package/dist/plugins/agents/opencode/serve-manager.js.map +1 -1
- package/dist/plugins/agents/pi-native/factory.js +10 -10
- package/dist/plugins/agents/pi-native/factory.js.map +1 -1
- package/dist/plugins/agents/pi-native/index.d.ts +3 -3
- package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/index.js +2 -2
- package/dist/plugins/agents/pi-native/index.js.map +1 -1
- package/dist/plugins/agents/pi-native/tool-bridge.js +1 -1
- package/dist/plugins/agents/pi-native/tool-bridge.js.map +1 -1
- package/dist/plugins/agents/pi-native/tools.js +4 -4
- package/dist/plugins/agents/pi-native/tools.js.map +1 -1
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +1 -1
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +2 -2
- package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -1
- package/dist/plugins/messengers/email/email-adapter.js +15 -15
- package/dist/plugins/messengers/email/email-adapter.js.map +1 -1
- package/dist/plugins/messengers/telegram/media-download.d.ts +1 -1
- package/dist/plugins/messengers/telegram/media-download.js +4 -4
- package/dist/plugins/messengers/telegram/media-download.js.map +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +1 -1
- package/dist/plugins/messengers/telegram/telegram-adapter.js +3 -3
- package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/context-store.js +1 -1
- package/dist/plugins/messengers/wechat/context-store.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-client.js +1 -1
- package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -1
- package/dist/plugins/messengers/wechat/media-download.js +1 -1
- package/dist/plugins/messengers/wechat/media-download.js.map +1 -1
- package/dist/scripts/migrate-gcj02-to-wgs84.js +1 -1
- package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -1
- package/dist/web/public/assets/{a2a-Dnc-MHI-.js → a2a-D7MoJ1iT.js} +2 -2
- package/dist/web/public/assets/{a2a-Dnc-MHI-.js.map → a2a-D7MoJ1iT.js.map} +1 -1
- package/dist/web/public/assets/{activity-CKQwfSVC.js → activity-BAgb2WZC.js} +2 -2
- package/dist/web/public/assets/{activity-CKQwfSVC.js.map → activity-BAgb2WZC.js.map} +1 -1
- package/dist/web/public/assets/{admins-C7MdDEF0.js → admins-CZYANmhn.js} +2 -2
- package/dist/web/public/assets/{admins-C7MdDEF0.js.map → admins-CZYANmhn.js.map} +1 -1
- package/dist/web/public/assets/{agents-Be4IUCYz.js → agents-BXThDW6f.js} +2 -2
- package/dist/web/public/assets/agents-BXThDW6f.js.map +1 -0
- package/dist/web/public/assets/{approvals-KCd1BSvN.js → approvals-ByPXIYVl.js} +2 -2
- package/dist/web/public/assets/{approvals-KCd1BSvN.js.map → approvals-ByPXIYVl.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-NRUr_gzg.js → arrow-down-B8DkdbEY.js} +2 -2
- package/dist/web/public/assets/{arrow-down-NRUr_gzg.js.map → arrow-down-B8DkdbEY.js.map} +1 -1
- package/dist/web/public/assets/{arrow-up-4KyqPaSd.js → arrow-up-i_dEdXkz.js} +2 -2
- package/dist/web/public/assets/{arrow-up-4KyqPaSd.js.map → arrow-up-i_dEdXkz.js.map} +1 -1
- package/dist/web/public/assets/{asks-nKwuDJpD.js → asks-yD_inOnM.js} +2 -2
- package/dist/web/public/assets/{asks-nKwuDJpD.js.map → asks-yD_inOnM.js.map} +1 -1
- package/dist/web/public/assets/{audit-Bf4Yv1or.js → audit-teCIRtgN.js} +2 -2
- package/dist/web/public/assets/{audit-Bf4Yv1or.js.map → audit-teCIRtgN.js.map} +1 -1
- package/dist/web/public/assets/{bell--lSOhH-X.js → bell-CeWDMs8_.js} +2 -2
- package/dist/web/public/assets/{bell--lSOhH-X.js.map → bell-CeWDMs8_.js.map} +1 -1
- package/dist/web/public/assets/{bgjobs-Daya2BMh.js → bgjobs-Rc05aEy9.js} +2 -2
- package/dist/web/public/assets/bgjobs-Rc05aEy9.js.map +1 -0
- package/dist/web/public/assets/{brain-DF90t0yo.js → brain-BQqv0Zhc.js} +2 -2
- package/dist/web/public/assets/{brain-DF90t0yo.js.map → brain-BQqv0Zhc.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-aRM_fCrr.js → briefcase-DUXbR4xs.js} +2 -2
- package/dist/web/public/assets/{briefcase-aRM_fCrr.js.map → briefcase-DUXbR4xs.js.map} +1 -1
- package/dist/web/public/assets/{chat-BhnNXkIJ.js → chat-DQpQLW9j.js} +2 -2
- package/dist/web/public/assets/{chat-BhnNXkIJ.js.map → chat-DQpQLW9j.js.map} +1 -1
- package/dist/web/public/assets/{chevron-left-DK-fhgiL.js → chevron-left-RC6mMSiX.js} +2 -2
- package/dist/web/public/assets/{chevron-left-DK-fhgiL.js.map → chevron-left-RC6mMSiX.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-BGhMfCcE.js → chevron-right-DrkYVi19.js} +2 -2
- package/dist/web/public/assets/{chevron-right-BGhMfCcE.js.map → chevron-right-DrkYVi19.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-BWBI4Qhk.js → circle-check-DZnkaUdk.js} +2 -2
- package/dist/web/public/assets/{circle-check-BWBI4Qhk.js.map → circle-check-DZnkaUdk.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-BppjBT7j.js → circle-check-big-BC8ntMsz.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-BppjBT7j.js.map → circle-check-big-BC8ntMsz.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-BZ3UUhcm.js → circle-x-DHK7ypFY.js} +2 -2
- package/dist/web/public/assets/{circle-x-BZ3UUhcm.js.map → circle-x-DHK7ypFY.js.map} +1 -1
- package/dist/web/public/assets/{clock-ChP0IxI4.js → clock-DXHhWqJH.js} +2 -2
- package/dist/web/public/assets/{clock-ChP0IxI4.js.map → clock-DXHhWqJH.js.map} +1 -1
- package/dist/web/public/assets/{confirm-dialog-DrP5Lfwx.js → confirm-dialog-gPKJnvEW.js} +2 -2
- package/dist/web/public/assets/{confirm-dialog-DrP5Lfwx.js.map → confirm-dialog-gPKJnvEW.js.map} +1 -1
- package/dist/web/public/assets/{copy-CR2c0pyG.js → copy-DtQxgcR0.js} +2 -2
- package/dist/web/public/assets/{copy-CR2c0pyG.js.map → copy-DtQxgcR0.js.map} +1 -1
- package/dist/web/public/assets/{data-table-DElP7TJm.js → data-table-DOKUic1J.js} +2 -2
- package/dist/web/public/assets/{data-table-DElP7TJm.js.map → data-table-DOKUic1J.js.map} +1 -1
- package/dist/web/public/assets/distill-p6P7-1UR.js +7 -0
- package/dist/web/public/assets/distill-p6P7-1UR.js.map +1 -0
- package/dist/web/public/assets/{download-DO4Kw3Fi.js → download-CqNiIHa8.js} +2 -2
- package/dist/web/public/assets/{download-DO4Kw3Fi.js.map → download-CqNiIHa8.js.map} +1 -1
- package/dist/web/public/assets/email-DwbfTUlV.js +7 -0
- package/dist/web/public/assets/email-DwbfTUlV.js.map +1 -0
- package/dist/web/public/assets/{empty-state-DGH3i5i2.js → empty-state-CTwOQemt.js} +2 -2
- package/dist/web/public/assets/{empty-state-DGH3i5i2.js.map → empty-state-CTwOQemt.js.map} +1 -1
- package/dist/web/public/assets/{external-link-B6aOBfUG.js → external-link-BY7Ye8yi.js} +2 -2
- package/dist/web/public/assets/{external-link-B6aOBfUG.js.map → external-link-BY7Ye8yi.js.map} +1 -1
- package/dist/web/public/assets/{eye-BMxHZFil.js → eye-6RUADoDS.js} +2 -2
- package/dist/web/public/assets/{eye-BMxHZFil.js.map → eye-6RUADoDS.js.map} +1 -1
- package/dist/web/public/assets/{facts-B9PlO3xo.js → facts-DXE0aJmb.js} +2 -2
- package/dist/web/public/assets/{facts-B9PlO3xo.js.map → facts-DXE0aJmb.js.map} +1 -1
- package/dist/web/public/assets/{goals-DX_RjDAM.js → goals-C1LCm3qL.js} +2 -2
- package/dist/web/public/assets/{goals-DX_RjDAM.js.map → goals-C1LCm3qL.js.map} +1 -1
- package/dist/web/public/assets/{health-BAcwcy02.js → health-wqCp-K_o.js} +2 -2
- package/dist/web/public/assets/{health-BAcwcy02.js.map → health-wqCp-K_o.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-Cl-tJTJY.js → heart-pulse-DfqI4GF7.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-Cl-tJTJY.js.map → heart-pulse-DfqI4GF7.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-BF_rPcKb.js → heartbeat-Bumv4XtQ.js} +2 -2
- package/dist/web/public/assets/{heartbeat-BF_rPcKb.js.map → heartbeat-Bumv4XtQ.js.map} +1 -1
- package/dist/web/public/assets/{hot-XOCA1xAY.js → hot-B-CMjQIr.js} +2 -2
- package/dist/web/public/assets/{hot-XOCA1xAY.js.map → hot-B-CMjQIr.js.map} +1 -1
- package/dist/web/public/assets/{index-CzlhMSb2.js → index-DHh1LYlA.js} +29 -29
- package/dist/web/public/assets/{index-CzlhMSb2.js.map → index-DHh1LYlA.js.map} +1 -1
- package/dist/web/public/assets/{injection-ecvQ-6Ya.js → injection-Dn_XqgLG.js} +2 -2
- package/dist/web/public/assets/{injection-ecvQ-6Ya.js.map → injection-Dn_XqgLG.js.map} +1 -1
- package/dist/web/public/assets/{installed-D8VzYRBe.js → installed-Cet-1M2Q.js} +2 -2
- package/dist/web/public/assets/{installed-D8VzYRBe.js.map → installed-Cet-1M2Q.js.map} +1 -1
- package/dist/web/public/assets/{jobs-CpuY6G8D.js → jobs-CfEzOOAC.js} +2 -2
- package/dist/web/public/assets/{jobs-CpuY6G8D.js.map → jobs-CfEzOOAC.js.map} +1 -1
- package/dist/web/public/assets/{layout-BROGs5wv.js → layout-BX43KyXM.js} +2 -2
- package/dist/web/public/assets/{layout-BROGs5wv.js.map → layout-BX43KyXM.js.map} +1 -1
- package/dist/web/public/assets/{layout--XsfZzpI.js → layout-BcYZlaqf.js} +2 -2
- package/dist/web/public/assets/{layout--XsfZzpI.js.map → layout-BcYZlaqf.js.map} +1 -1
- package/dist/web/public/assets/{layout-DdbuRh8P.js → layout-Cb7looUv.js} +2 -2
- package/dist/web/public/assets/{layout-DdbuRh8P.js.map → layout-Cb7looUv.js.map} +1 -1
- package/dist/web/public/assets/{layout-BezPqRLV.js → layout-D7xH78OU.js} +2 -2
- package/dist/web/public/assets/{layout-BezPqRLV.js.map → layout-D7xH78OU.js.map} +1 -1
- package/dist/web/public/assets/{layout-Pxfmfh_2.js → layout-D_3ZcVG7.js} +2 -2
- package/dist/web/public/assets/{layout-Pxfmfh_2.js.map → layout-D_3ZcVG7.js.map} +1 -1
- package/dist/web/public/assets/llm-BZ9qqp-D.js +27 -0
- package/dist/web/public/assets/llm-BZ9qqp-D.js.map +1 -0
- package/dist/web/public/assets/{loader-circle-AgQ2XO06.js → loader-circle-DgdBWYl0.js} +2 -2
- package/dist/web/public/assets/{loader-circle-AgQ2XO06.js.map → loader-circle-DgdBWYl0.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-C6sGB9SZ.js → map-pin-3QS1A0-I.js} +2 -2
- package/dist/web/public/assets/{map-pin-C6sGB9SZ.js.map → map-pin-3QS1A0-I.js.map} +1 -1
- package/dist/web/public/assets/{mcp-jqsjSumH.js → mcp-DwKZULET.js} +2 -2
- package/dist/web/public/assets/{mcp-jqsjSumH.js.map → mcp-DwKZULET.js.map} +1 -1
- package/dist/web/public/assets/{memos-C38YN2Rf.js → memos-BBtqFcoH.js} +2 -2
- package/dist/web/public/assets/{memos-C38YN2Rf.js.map → memos-BBtqFcoH.js.map} +1 -1
- package/dist/web/public/assets/{messengers-l74nqYZF.js → messengers-i7WvNT3o.js} +2 -2
- package/dist/web/public/assets/messengers-i7WvNT3o.js.map +1 -0
- package/dist/web/public/assets/{mobile-CHhYS0Tw.js → mobile-Bq0FH9JV.js} +2 -2
- package/dist/web/public/assets/{mobile-CHhYS0Tw.js.map → mobile-Bq0FH9JV.js.map} +1 -1
- package/dist/web/public/assets/{network-CIrcKaZn.js → network--s113Jkm.js} +2 -2
- package/dist/web/public/assets/{network-CIrcKaZn.js.map → network--s113Jkm.js.map} +1 -1
- package/dist/web/public/assets/{outbox-O1lzMZPk.js → outbox-BbfC5kuG.js} +2 -2
- package/dist/web/public/assets/{outbox-O1lzMZPk.js.map → outbox-BbfC5kuG.js.map} +1 -1
- package/dist/web/public/assets/{pagination-CXBUSf6r.js → pagination-DkdCTctJ.js} +2 -2
- package/dist/web/public/assets/{pagination-CXBUSf6r.js.map → pagination-DkdCTctJ.js.map} +1 -1
- package/dist/web/public/assets/{persona-CI4tkm_n.js → persona-BvtcZh6G.js} +2 -2
- package/dist/web/public/assets/{persona-CI4tkm_n.js.map → persona-BvtcZh6G.js.map} +1 -1
- package/dist/web/public/assets/{plans-D8RZ9aXq.js → plans-i3a6lrqF.js} +2 -2
- package/dist/web/public/assets/{plans-D8RZ9aXq.js.map → plans-i3a6lrqF.js.map} +1 -1
- package/dist/web/public/assets/{play-DQ3P_XWl.js → play-CPoE_JnS.js} +2 -2
- package/dist/web/public/assets/{play-DQ3P_XWl.js.map → play-CPoE_JnS.js.map} +1 -1
- package/dist/web/public/assets/{plus-Zai0UXKL.js → plus-CfzKV_0u.js} +2 -2
- package/dist/web/public/assets/{plus-Zai0UXKL.js.map → plus-CfzKV_0u.js.map} +1 -1
- package/dist/web/public/assets/policy-Cm88P8LO.js +2 -0
- package/dist/web/public/assets/policy-Cm88P8LO.js.map +1 -0
- package/dist/web/public/assets/{qr-code-zcjicWRK.js → qr-code-DMkV8nv2.js} +2 -2
- package/dist/web/public/assets/{qr-code-zcjicWRK.js.map → qr-code-DMkV8nv2.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-CM-Cjwud.js → refresh-ccw-nBMm5Xal.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-CM-Cjwud.js.map → refresh-ccw-nBMm5Xal.js.map} +1 -1
- package/dist/web/public/assets/{reminders-BR6noe6I.js → reminders-DjEujanC.js} +2 -2
- package/dist/web/public/assets/{reminders-BR6noe6I.js.map → reminders-DjEujanC.js.map} +1 -1
- package/dist/web/public/assets/{save-xBMgs6Bd.js → save-DbrrCFDM.js} +2 -2
- package/dist/web/public/assets/{save-xBMgs6Bd.js.map → save-DbrrCFDM.js.map} +1 -1
- package/dist/web/public/assets/{schedules-Brp1Fomd.js → schedules-DzwDWykc.js} +2 -2
- package/dist/web/public/assets/{schedules-Brp1Fomd.js.map → schedules-DzwDWykc.js.map} +1 -1
- package/dist/web/public/assets/search-5q3dkINm.js +17 -0
- package/dist/web/public/assets/search-5q3dkINm.js.map +1 -0
- package/dist/web/public/assets/{search-CIc8bWW1.js → search-DbE4VEm9.js} +2 -2
- package/dist/web/public/assets/{search-CIc8bWW1.js.map → search-DbE4VEm9.js.map} +1 -1
- package/dist/web/public/assets/security-BIcnUrAs.js +2 -0
- package/dist/web/public/assets/security-BIcnUrAs.js.map +1 -0
- package/dist/web/public/assets/{service-Bo9rkfQX.js → service-CnorFHzZ.js} +2 -2
- package/dist/web/public/assets/{service-Bo9rkfQX.js.map → service-CnorFHzZ.js.map} +1 -1
- package/dist/web/public/assets/{shield-alert-bg0_ILjD.js → shield-alert-WOa69jy3.js} +2 -2
- package/dist/web/public/assets/{shield-alert-bg0_ILjD.js.map → shield-alert-WOa69jy3.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-Bw4TDDCb.js → status-badge-D5xhwquL.js} +2 -2
- package/dist/web/public/assets/{status-badge-Bw4TDDCb.js.map → status-badge-D5xhwquL.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-D58R9C_Z.js → subtasks-DMRyk6YS.js} +2 -2
- package/dist/web/public/assets/{subtasks-D58R9C_Z.js.map → subtasks-DMRyk6YS.js.map} +1 -1
- package/dist/web/public/assets/{table-D4S5FCk_.js → table-Dx65w6V0.js} +2 -2
- package/dist/web/public/assets/{table-D4S5FCk_.js.map → table-Dx65w6V0.js.map} +1 -1
- package/dist/web/public/assets/{topn-DDxDNIZf.js → topn-L7Juczp3.js} +2 -2
- package/dist/web/public/assets/{topn-DDxDNIZf.js.map → topn-L7Juczp3.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-CB7X8tay.js → trash-2-7xrfqd-v.js} +2 -2
- package/dist/web/public/assets/{trash-2-CB7X8tay.js.map → trash-2-7xrfqd-v.js.map} +1 -1
- package/dist/web/public/assets/{use-agim-skills-BV2IJPlc.js → use-agim-skills-pFjfgqMF.js} +2 -2
- package/dist/web/public/assets/{use-agim-skills-BV2IJPlc.js.map → use-agim-skills-pFjfgqMF.js.map} +1 -1
- package/dist/web/public/assets/{use-background-tasks-Dk9S55ip.js → use-background-tasks-D1--hHjp.js} +2 -2
- package/dist/web/public/assets/{use-background-tasks-Dk9S55ip.js.map → use-background-tasks-D1--hHjp.js.map} +1 -1
- package/dist/web/public/assets/{use-memory-DncmZXGJ.js → use-memory-Bz1Zao7g.js} +2 -2
- package/dist/web/public/assets/{use-memory-DncmZXGJ.js.map → use-memory-Bz1Zao7g.js.map} +1 -1
- package/dist/web/public/assets/{use-observability-CcDO7PdN.js → use-observability-DtqSWVjM.js} +2 -2
- package/dist/web/public/assets/{use-observability-CcDO7PdN.js.map → use-observability-DtqSWVjM.js.map} +1 -1
- package/dist/web/public/assets/{use-settings-DZhfMpNR.js → use-settings-DKbDqCEJ.js} +2 -2
- package/dist/web/public/assets/{use-settings-DZhfMpNR.js.map → use-settings-DKbDqCEJ.js.map} +1 -1
- package/dist/web/public/assets/{use-workspace-ywkrT7Aj.js → use-workspace-CConjEx0.js} +2 -2
- package/dist/web/public/assets/{use-workspace-ywkrT7Aj.js.map → use-workspace-CConjEx0.js.map} +1 -1
- package/dist/web/public/assets/vector-D8sEa2W-.js +2 -0
- package/dist/web/public/assets/vector-D8sEa2W-.js.map +1 -0
- package/dist/web/public/assets/viewer-aSIjAKVA.js +12 -0
- package/dist/web/public/assets/viewer-aSIjAKVA.js.map +1 -0
- package/dist/web/public/assets/{workspace-BvrXvliN.js → workspace-BqwWoinI.js} +2 -2
- package/dist/web/public/assets/{workspace-BvrXvliN.js.map → workspace-BqwWoinI.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-0H6Dzz6N.js → workspaces-ChsJcrav.js} +2 -2
- package/dist/web/public/assets/{workspaces-0H6Dzz6N.js.map → workspaces-ChsJcrav.js.map} +1 -1
- package/dist/web/public/index.html +1 -1
- package/dist/web/public/loc.html +1 -1
- package/dist/web/public/login.html +2 -2
- package/dist/web/server.d.ts +2 -2
- package/dist/web/server.js +121 -120
- package/dist/web/server.js.map +1 -1
- package/package.json +2 -3
- package/dist/core/llm/imhub-dispatcher.d.ts.map +0 -1
- package/dist/core/llm/imhub-dispatcher.js.map +0 -1
- package/dist/web/public/assets/agents-Be4IUCYz.js.map +0 -1
- package/dist/web/public/assets/bgjobs-Daya2BMh.js.map +0 -1
- package/dist/web/public/assets/distill-DxSq7g_8.js +0 -7
- package/dist/web/public/assets/distill-DxSq7g_8.js.map +0 -1
- package/dist/web/public/assets/email-Dkqwudqq.js +0 -7
- package/dist/web/public/assets/email-Dkqwudqq.js.map +0 -1
- package/dist/web/public/assets/llm-IXFv_MMM.js +0 -27
- package/dist/web/public/assets/llm-IXFv_MMM.js.map +0 -1
- package/dist/web/public/assets/messengers-l74nqYZF.js.map +0 -1
- package/dist/web/public/assets/policy-BodrOHl5.js +0 -2
- package/dist/web/public/assets/policy-BodrOHl5.js.map +0 -1
- package/dist/web/public/assets/search-nk8nyLFI.js +0 -17
- package/dist/web/public/assets/search-nk8nyLFI.js.map +0 -1
- package/dist/web/public/assets/security-DWxWfpuX.js +0 -2
- package/dist/web/public/assets/security-DWxWfpuX.js.map +0 -1
- package/dist/web/public/assets/vector-B3h4iyfn.js +0 -2
- package/dist/web/public/assets/vector-B3h4iyfn.js.map +0 -1
- package/dist/web/public/assets/viewer-Bz3wL-99.js +0 -12
- package/dist/web/public/assets/viewer-Bz3wL-99.js.map +0 -1
package/dist/web/public/assets/{external-link-B6aOBfUG.js.map → external-link-BY7Ye8yi.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-link-
|
|
1
|
+
{"version":3,"file":"external-link-BY7Ye8yi.js","sources":["../../node_modules/lucide-react/dist/esm/icons/external-link.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ExternalLink = createLucideIcon(\"ExternalLink\", [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n]);\n\nexport { ExternalLink as default };\n//# sourceMappingURL=external-link.js.map\n"],"names":["ExternalLink","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,cAAe,IAAK,QAAQ,CAAE,EAC5C,CAAC,OAAQ,CAAE,EAAG,2DAA4D,IAAK,QAAQ,CAAE,CAC3F,CAAC","x_google_ignoreList":[0]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{o as e}from"./index-
|
|
1
|
+
import{o as e}from"./index-DHh1LYlA.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -9,4 +9,4 @@ import{o as e}from"./index-CzlhMSb2.js";/**
|
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
11
|
*/const y=e("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);export{c as E,y as a};
|
|
12
|
-
//# sourceMappingURL=eye-
|
|
12
|
+
//# sourceMappingURL=eye-6RUADoDS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eye-
|
|
1
|
+
{"version":3,"file":"eye-6RUADoDS.js","sources":["../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../node_modules/lucide-react/dist/esm/icons/eye.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n"],"names":["EyeOff","createLucideIcon","Eye"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CACE,OACA,CACE,EAAG,iGACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,EACrE,CACE,OACA,CACE,EAAG,+FACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACC,EAAMD,EAAiB,MAAO,CAClC,CACE,OACA,CACE,EAAG,wGACH,IAAK,QACX,CACA,EACE,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as Q,f as Y,j as e,l as D,B as b,L as E,I as J,S as W,g as X,h as Z,i as ee,k,m as g,n as T}from"./index-
|
|
2
|
-
//# sourceMappingURL=facts-
|
|
1
|
+
import{u as Q,f as Y,j as e,l as D,B as b,L as E,I as J,S as W,g as X,h as Z,i as ee,k,m as g,n as T}from"./index-DHh1LYlA.js";import{r}from"./react-DlP5eolq.js";import{D as te}from"./data-table-DOKUic1J.js";import{E as B}from"./empty-state-CTwOQemt.js";import{P as se}from"./pagination-DkdCTctJ.js";import{C as M}from"./confirm-dialog-gPKJnvEW.js";import{a as ae,b as ne,c as ce}from"./use-memory-Bz1Zao7g.js";import{T as A}from"./trash-2-7xrfqd-v.js";import{B as R}from"./brain-BQqv0Zhc.js";import{L as re}from"./loader-circle-DgdBWYl0.js";import{R as ie}from"./refresh-ccw-nBMm5Xal.js";import{S as le}from"./search-DbE4VEm9.js";import"./table-Dx65w6V0.js";import"./arrow-up-i_dEdXkz.js";import"./arrow-down-B8DkdbEY.js";import"./chevron-left-RC6mMSiX.js";import"./chevron-right-DrkYVi19.js";const oe=["fact","preference","goal","history","profile"],me=[25,50,100],F=50,de=300;function Ee(){const{t:s}=Q(["memory","common"]),[n,L]=Y(),c=n.get("user")??"",i=n.get("q")??"",m=n.get("cat")??null,d=Math.max(1,Number(n.get("page"))||1),l=Number(n.get("per_page"))||F,[f,I]=r.useState(i);r.useEffect(()=>{if(f===i)return;const t=window.setTimeout(()=>h({q:f||null}),de);return()=>window.clearTimeout(t)},[f]);const q=r.useMemo(()=>({user_key:c,...i?{query:i}:{},...m?{category:m}:{},limit:l,offset:(d-1)*l}),[c,i,m,d,l]),{data:S,isLoading:z,isFetching:C,refetch:U}=ae(q,{enabled:!!c}),_=S?.facts??[],P=S?.total??0,G=Math.max(1,Math.ceil(P/l)),[u,p]=r.useState(new Set);r.useEffect(()=>{p(new Set)},[c,i,m,d,l]);const j=ne(),x=ce(),[y,v]=r.useState(null),[V,O]=r.useState(!1);function h(t){const a=new URLSearchParams(n);for(const[o,w]of Object.entries(t))w==null||w===""?a.delete(o):a.set(o,w);Object.keys(t).some(o=>o!=="page")&&a.delete("page"),L(a,{replace:!1})}async function $(){if(!(y==null||!c))try{await j.mutateAsync({id:y,user_key:c}),g.success(s("facts.toast.deletedOne"))}catch(t){const{message:a}=T(t,s);throw g.error(a),t}}async function H(){if(!c||u.size===0)return;const t=Array.from(u).map(Number).filter(Number.isFinite);try{const a=await x.mutateAsync({user_key:c,body:{ids:t}});g.success(s("facts.toast.deletedMany",{count:a.deleted})),p(new Set)}catch(a){const{message:o}=T(a,s);throw g.error(o),a}}const K=r.useMemo(()=>[{id:"id",header:s("facts.col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"what",header:s("facts.col.what"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text",children:t.what}),asCardTitle:!0},{id:"category",header:s("facts.col.category"),cell:t=>e.jsx(D,{variant:"outline",children:s(`facts.category.${t.category}`,{defaultValue:t.category})}),headClassName:"w-28"},{id:"confidence",header:s("facts.col.confidence"),cell:t=>e.jsx("span",{className:"tabular-nums text-text-dim",children:t.confidence.toFixed(2)}),headClassName:"w-24",hideOnMobile:!0},{id:"source",header:s("facts.col.source"),cell:t=>e.jsx("span",{className:"text-text-dim text-xs",children:t.source}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:s("facts.col.createdAt"),cell:t=>e.jsx("span",{className:"text-text-dim",children:fe(t.created_at)}),headClassName:"w-32",hideOnMobile:!0},{id:"actions",header:"",cell:t=>e.jsx("div",{className:"flex justify-end",children:e.jsxs(b,{variant:"ghost",size:"sm",onClick:a=>{a.stopPropagation(),v(t.id)},disabled:j.isPending||x.isPending,"aria-label":s("facts.action.delete"),children:[e.jsx(A,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:s("facts.action.delete")})]})}),headClassName:"w-24"}],[s,j.isPending,x.isPending]);if(!c)return e.jsx("div",{className:"mx-auto max-w-3xl",children:e.jsx(B,{icon:e.jsx(R,{}),title:s("noUserSelected.title"),description:s("noUserSelected.description")})});const N=u.size;return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("facts.title")}),e.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>U(),disabled:C,"aria-label":s("actions.refresh",{ns:"common"}),children:[C?e.jsx(re,{className:"h-4 w-4 animate-spin"}):e.jsx(ie,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[200px] max-w-md",children:[e.jsx(E,{htmlFor:"search",className:"text-xs text-text-dim",children:s("facts.filter.search")}),e.jsx(le,{className:"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted"}),e.jsx(J,{id:"search",value:f,onChange:t=>I(t.target.value),className:"pl-7 mt-1"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(E,{htmlFor:"category",className:"text-xs text-text-dim",children:s("facts.filter.category")}),e.jsxs(W,{value:m??"__any__",onValueChange:t=>h({cat:t==="__any__"?null:t}),children:[e.jsx(X,{id:"category",className:"w-[140px]",children:e.jsx(Z,{})}),e.jsxs(ee,{children:[e.jsx(k,{value:"__any__",children:s("facts.filter.categoryAny")}),oe.map(t=>e.jsx(k,{value:t,children:s(`facts.category.${t}`)},t))]})]})]}),N>0&&e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(D,{variant:"secondary",children:s("facts.batch.selected",{count:N})}),e.jsxs(b,{variant:"destructive",size:"sm",onClick:()=>O(!0),disabled:x.isPending,children:[e.jsx(A,{className:"h-4 w-4"}),s("facts.batch.deleteSelected")]})]})]}),e.jsx(te,{columns:K,rows:_,getRowId:t=>String(t.id),loading:z,selection:u,onSelectionChange:p,emptyState:e.jsx(B,{icon:e.jsx(R,{}),title:s("facts.empty.title"),description:s("facts.empty.description")})}),(_.length>0||d>1)&&e.jsx(se,{page:d,totalPages:G,totalRows:P,perPage:l,perPageOptions:me,onPageChange:t=>h({page:t===1?null:String(t)}),onPerPageChange:t=>h({per_page:t===F?null:String(t)})}),e.jsx(M,{open:y!=null,onOpenChange:t=>{t||v(null)},title:s("facts.action.confirmDelete"),description:s("facts.action.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.action.delete"),onConfirm:$}),e.jsx(M,{open:V,onOpenChange:O,title:s("facts.batch.confirmDelete",{count:N}),description:s("facts.batch.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.batch.deleteSelected"),onConfirm:H})]})}function fe(s){try{const n=new Date(s);return Number.isNaN(n.getTime())?String(s):n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{Ee as default};
|
|
2
|
+
//# sourceMappingURL=facts-DXE0aJmb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facts-B9PlO3xo.js","sources":["../../src/routes/memory/facts.tsx"],"sourcesContent":["/**\n * /memory/facts — list / search / delete the user's facts.\n *\n * Reads `?user=` from the URL (the layout writes it). Without a\n * user_key the route shows a friendly empty state pointing at the\n * picker — no query fires until a user is chosen.\n *\n * Search + category filter live in URL params so deep-link sharing\n * works (\"show me john's goals matching tax\"). The free-text input\n * is local-only with a 300ms debounce, same pattern as /memos, so\n * the FTS5 layer isn't hit on every keystroke.\n *\n * Single-row delete via the per-row Delete button; batch delete via\n * checkbox selection + the bulk-delete action bar. Both route\n * through ConfirmDialog.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, Loader2, RefreshCcw, Search, Trash2 } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Pagination } from '@/components/common/pagination'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useMemoryFacts,\n useDeleteFactById,\n useBulkDeleteFacts,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport type { Fact, FactCategory, ListMemoryFactsQuery } from '@/types/api'\n\nconst CATEGORY_OPTIONS: FactCategory[] = ['fact', 'preference', 'goal', 'history', 'profile']\nconst PER_PAGE_OPTIONS = [25, 50, 100]\nconst DEFAULT_PER_PAGE = 50\nconst SEARCH_DEBOUNCE_MS = 300\n\nexport default function MemoryFactsRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params, setParams] = useSearchParams()\n\n const userKey = params.get('user') ?? ''\n const q = params.get('q') ?? ''\n const cat = (params.get('cat') as FactCategory | null) ?? null\n const page = Math.max(1, Number(params.get('page')) || 1)\n const perPage = Number(params.get('per_page')) || DEFAULT_PER_PAGE\n\n const [qDraft, setQDraft] = useState(q)\n useEffect(() => {\n if (qDraft === q) return\n const timer = window.setTimeout(() => patchParams({ q: qDraft || null }), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [qDraft])\n\n const query: ListMemoryFactsQuery = useMemo(\n () => ({\n user_key: userKey,\n ...(q ? { query: q } : {}),\n ...(cat ? { category: cat } : {}),\n limit: perPage,\n offset: (page - 1) * perPage,\n }),\n [userKey, q, cat, page, perPage],\n )\n\n const { data, isLoading, isFetching, refetch } = useMemoryFacts(query, { enabled: Boolean(userKey) })\n const facts = data?.facts ?? []\n const total = data?.total ?? 0\n const totalPages = Math.max(1, Math.ceil(total / perPage))\n\n // Selection state for the bulk delete bar.\n const [selection, setSelection] = useState<Set<string>>(new Set())\n useEffect(() => { setSelection(new Set()) }, [userKey, q, cat, page, perPage])\n\n const deleteOne = useDeleteFactById()\n const bulkDelete = useBulkDeleteFacts()\n\n const [confirmOneId, setConfirmOneId] = useState<number | null>(null)\n const [confirmBulk, setConfirmBulk] = useState(false)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n // Reset to page 1 on any filter mutation.\n if (Object.keys(patch).some((k) => k !== 'page')) next.delete('page')\n setParams(next, { replace: false })\n }\n\n async function onConfirmDeleteOne(): Promise<void> {\n if (confirmOneId == null || !userKey) return\n try {\n await deleteOne.mutateAsync({ id: confirmOneId, user_key: userKey })\n toast.success(t('facts.toast.deletedOne'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmBulk(): Promise<void> {\n if (!userKey || selection.size === 0) return\n const ids = Array.from(selection).map(Number).filter(Number.isFinite)\n try {\n const r = await bulkDelete.mutateAsync({ user_key: userKey, body: { ids } })\n toast.success(t('facts.toast.deletedMany', { count: r.deleted }))\n setSelection(new Set())\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n const columns: DataTableColumn<Fact>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('facts.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'what',\n header: t('facts.col.what'),\n cell: (r) => <span className=\"line-clamp-2 text-text\">{r.what}</span>,\n asCardTitle: true,\n },\n {\n id: 'category',\n header: t('facts.col.category'),\n cell: (r) => (\n <Badge variant=\"outline\">\n {t(`facts.category.${r.category}`, { defaultValue: r.category })}\n </Badge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'confidence',\n header: t('facts.col.confidence'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">{r.confidence.toFixed(2)}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('facts.col.source'),\n cell: (r) => <span className=\"text-text-dim text-xs\">{r.source}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('facts.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatEpoch(r.created_at)}</span>,\n headClassName: 'w-32',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) => (\n <div className=\"flex justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmOneId(r.id)\n }}\n disabled={deleteOne.isPending || bulkDelete.isPending}\n aria-label={t('facts.action.delete')}\n >\n <Trash2 className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('facts.action.delete')}</span>\n </Button>\n </div>\n ),\n headClassName: 'w-24',\n },\n ],\n [t, deleteOne.isPending, bulkDelete.isPending],\n )\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n const selectedCount = selection.size\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('facts.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\n <Label htmlFor=\"search\" className=\"text-xs text-text-dim\">\n {t('facts.filter.search')}\n </Label>\n <Search className=\"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted\" />\n <Input\n id=\"search\"\n value={qDraft}\n onChange={(e) => setQDraft(e.target.value)}\n className=\"pl-7 mt-1\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"category\" className=\"text-xs text-text-dim\">\n {t('facts.filter.category')}\n </Label>\n <Select\n value={cat ?? '__any__'}\n onValueChange={(v) => patchParams({ cat: v === '__any__' ? null : v })}\n >\n <SelectTrigger id=\"category\" className=\"w-[140px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__any__\">{t('facts.filter.categoryAny')}</SelectItem>\n {CATEGORY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`facts.category.${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {selectedCount > 0 && (\n <div className=\"ml-auto flex items-center gap-2\">\n <Badge variant=\"secondary\">\n {t('facts.batch.selected', { count: selectedCount })}\n </Badge>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmBulk(true)}\n disabled={bulkDelete.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('facts.batch.deleteSelected')}\n </Button>\n </div>\n )}\n </div>\n\n <DataTable\n columns={columns}\n rows={facts}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n selection={selection}\n onSelectionChange={setSelection}\n emptyState={\n <EmptyState\n icon={<Brain />}\n title={t('facts.empty.title')}\n description={t('facts.empty.description')}\n />\n }\n />\n\n {(facts.length > 0 || page > 1) && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalRows={total}\n perPage={perPage}\n perPageOptions={PER_PAGE_OPTIONS}\n onPageChange={(p) => patchParams({ page: p === 1 ? null : String(p) })}\n onPerPageChange={(pp) => patchParams({ per_page: pp === DEFAULT_PER_PAGE ? null : String(pp) })}\n />\n )}\n\n <ConfirmDialog\n open={confirmOneId != null}\n onOpenChange={(open) => { if (!open) setConfirmOneId(null) }}\n title={t('facts.action.confirmDelete')}\n description={t('facts.action.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.action.delete')}\n onConfirm={onConfirmDeleteOne}\n />\n\n <ConfirmDialog\n open={confirmBulk}\n onOpenChange={setConfirmBulk}\n title={t('facts.batch.confirmDelete', { count: selectedCount })}\n description={t('facts.batch.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.batch.deleteSelected')}\n onConfirm={onConfirmBulk}\n />\n </div>\n )\n}\n\n/** Format an epoch-ms number as a short locale string. */\nfunction formatEpoch(ms: number): string {\n try {\n const d = new Date(ms)\n if (Number.isNaN(d.getTime())) return String(ms)\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return String(ms)\n }\n}\n"],"names":["CATEGORY_OPTIONS","PER_PAGE_OPTIONS","DEFAULT_PER_PAGE","SEARCH_DEBOUNCE_MS","MemoryFactsRoute","t","useTranslation","params","setParams","useSearchParams","userKey","q","cat","page","perPage","qDraft","setQDraft","useState","useEffect","timer","patchParams","query","useMemo","data","isLoading","isFetching","refetch","useMemoryFacts","facts","total","totalPages","selection","setSelection","deleteOne","useDeleteFactById","bulkDelete","useBulkDeleteFacts","confirmOneId","setConfirmOneId","confirmBulk","setConfirmBulk","patch","next","k","v","onConfirmDeleteOne","toast","err","message","describeError","onConfirmBulk","ids","r","columns","jsxs","jsx","Badge","formatEpoch","Button","e","Trash2","EmptyState","Brain","selectedCount","Loader2","RefreshCcw","Label","Search","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","c","DataTable","Pagination","p","pp","ConfirmDialog","open","ms","d"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"facts-DXE0aJmb.js","sources":["../../src/routes/memory/facts.tsx"],"sourcesContent":["/**\n * /memory/facts — list / search / delete the user's facts.\n *\n * Reads `?user=` from the URL (the layout writes it). Without a\n * user_key the route shows a friendly empty state pointing at the\n * picker — no query fires until a user is chosen.\n *\n * Search + category filter live in URL params so deep-link sharing\n * works (\"show me john's goals matching tax\"). The free-text input\n * is local-only with a 300ms debounce, same pattern as /memos, so\n * the FTS5 layer isn't hit on every keystroke.\n *\n * Single-row delete via the per-row Delete button; batch delete via\n * checkbox selection + the bulk-delete action bar. Both route\n * through ConfirmDialog.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, Loader2, RefreshCcw, Search, Trash2 } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Pagination } from '@/components/common/pagination'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useMemoryFacts,\n useDeleteFactById,\n useBulkDeleteFacts,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport type { Fact, FactCategory, ListMemoryFactsQuery } from '@/types/api'\n\nconst CATEGORY_OPTIONS: FactCategory[] = ['fact', 'preference', 'goal', 'history', 'profile']\nconst PER_PAGE_OPTIONS = [25, 50, 100]\nconst DEFAULT_PER_PAGE = 50\nconst SEARCH_DEBOUNCE_MS = 300\n\nexport default function MemoryFactsRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params, setParams] = useSearchParams()\n\n const userKey = params.get('user') ?? ''\n const q = params.get('q') ?? ''\n const cat = (params.get('cat') as FactCategory | null) ?? null\n const page = Math.max(1, Number(params.get('page')) || 1)\n const perPage = Number(params.get('per_page')) || DEFAULT_PER_PAGE\n\n const [qDraft, setQDraft] = useState(q)\n useEffect(() => {\n if (qDraft === q) return\n const timer = window.setTimeout(() => patchParams({ q: qDraft || null }), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [qDraft])\n\n const query: ListMemoryFactsQuery = useMemo(\n () => ({\n user_key: userKey,\n ...(q ? { query: q } : {}),\n ...(cat ? { category: cat } : {}),\n limit: perPage,\n offset: (page - 1) * perPage,\n }),\n [userKey, q, cat, page, perPage],\n )\n\n const { data, isLoading, isFetching, refetch } = useMemoryFacts(query, { enabled: Boolean(userKey) })\n const facts = data?.facts ?? []\n const total = data?.total ?? 0\n const totalPages = Math.max(1, Math.ceil(total / perPage))\n\n // Selection state for the bulk delete bar.\n const [selection, setSelection] = useState<Set<string>>(new Set())\n useEffect(() => { setSelection(new Set()) }, [userKey, q, cat, page, perPage])\n\n const deleteOne = useDeleteFactById()\n const bulkDelete = useBulkDeleteFacts()\n\n const [confirmOneId, setConfirmOneId] = useState<number | null>(null)\n const [confirmBulk, setConfirmBulk] = useState(false)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n // Reset to page 1 on any filter mutation.\n if (Object.keys(patch).some((k) => k !== 'page')) next.delete('page')\n setParams(next, { replace: false })\n }\n\n async function onConfirmDeleteOne(): Promise<void> {\n if (confirmOneId == null || !userKey) return\n try {\n await deleteOne.mutateAsync({ id: confirmOneId, user_key: userKey })\n toast.success(t('facts.toast.deletedOne'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmBulk(): Promise<void> {\n if (!userKey || selection.size === 0) return\n const ids = Array.from(selection).map(Number).filter(Number.isFinite)\n try {\n const r = await bulkDelete.mutateAsync({ user_key: userKey, body: { ids } })\n toast.success(t('facts.toast.deletedMany', { count: r.deleted }))\n setSelection(new Set())\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n const columns: DataTableColumn<Fact>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('facts.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'what',\n header: t('facts.col.what'),\n cell: (r) => <span className=\"line-clamp-2 text-text\">{r.what}</span>,\n asCardTitle: true,\n },\n {\n id: 'category',\n header: t('facts.col.category'),\n cell: (r) => (\n <Badge variant=\"outline\">\n {t(`facts.category.${r.category}`, { defaultValue: r.category })}\n </Badge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'confidence',\n header: t('facts.col.confidence'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">{r.confidence.toFixed(2)}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('facts.col.source'),\n cell: (r) => <span className=\"text-text-dim text-xs\">{r.source}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('facts.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatEpoch(r.created_at)}</span>,\n headClassName: 'w-32',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) => (\n <div className=\"flex justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmOneId(r.id)\n }}\n disabled={deleteOne.isPending || bulkDelete.isPending}\n aria-label={t('facts.action.delete')}\n >\n <Trash2 className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('facts.action.delete')}</span>\n </Button>\n </div>\n ),\n headClassName: 'w-24',\n },\n ],\n [t, deleteOne.isPending, bulkDelete.isPending],\n )\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n const selectedCount = selection.size\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('facts.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\n <Label htmlFor=\"search\" className=\"text-xs text-text-dim\">\n {t('facts.filter.search')}\n </Label>\n <Search className=\"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted\" />\n <Input\n id=\"search\"\n value={qDraft}\n onChange={(e) => setQDraft(e.target.value)}\n className=\"pl-7 mt-1\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"category\" className=\"text-xs text-text-dim\">\n {t('facts.filter.category')}\n </Label>\n <Select\n value={cat ?? '__any__'}\n onValueChange={(v) => patchParams({ cat: v === '__any__' ? null : v })}\n >\n <SelectTrigger id=\"category\" className=\"w-[140px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__any__\">{t('facts.filter.categoryAny')}</SelectItem>\n {CATEGORY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`facts.category.${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {selectedCount > 0 && (\n <div className=\"ml-auto flex items-center gap-2\">\n <Badge variant=\"secondary\">\n {t('facts.batch.selected', { count: selectedCount })}\n </Badge>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmBulk(true)}\n disabled={bulkDelete.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('facts.batch.deleteSelected')}\n </Button>\n </div>\n )}\n </div>\n\n <DataTable\n columns={columns}\n rows={facts}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n selection={selection}\n onSelectionChange={setSelection}\n emptyState={\n <EmptyState\n icon={<Brain />}\n title={t('facts.empty.title')}\n description={t('facts.empty.description')}\n />\n }\n />\n\n {(facts.length > 0 || page > 1) && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalRows={total}\n perPage={perPage}\n perPageOptions={PER_PAGE_OPTIONS}\n onPageChange={(p) => patchParams({ page: p === 1 ? null : String(p) })}\n onPerPageChange={(pp) => patchParams({ per_page: pp === DEFAULT_PER_PAGE ? null : String(pp) })}\n />\n )}\n\n <ConfirmDialog\n open={confirmOneId != null}\n onOpenChange={(open) => { if (!open) setConfirmOneId(null) }}\n title={t('facts.action.confirmDelete')}\n description={t('facts.action.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.action.delete')}\n onConfirm={onConfirmDeleteOne}\n />\n\n <ConfirmDialog\n open={confirmBulk}\n onOpenChange={setConfirmBulk}\n title={t('facts.batch.confirmDelete', { count: selectedCount })}\n description={t('facts.batch.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.batch.deleteSelected')}\n onConfirm={onConfirmBulk}\n />\n </div>\n )\n}\n\n/** Format an epoch-ms number as a short locale string. */\nfunction formatEpoch(ms: number): string {\n try {\n const d = new Date(ms)\n if (Number.isNaN(d.getTime())) return String(ms)\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return String(ms)\n }\n}\n"],"names":["CATEGORY_OPTIONS","PER_PAGE_OPTIONS","DEFAULT_PER_PAGE","SEARCH_DEBOUNCE_MS","MemoryFactsRoute","t","useTranslation","params","setParams","useSearchParams","userKey","q","cat","page","perPage","qDraft","setQDraft","useState","useEffect","timer","patchParams","query","useMemo","data","isLoading","isFetching","refetch","useMemoryFacts","facts","total","totalPages","selection","setSelection","deleteOne","useDeleteFactById","bulkDelete","useBulkDeleteFacts","confirmOneId","setConfirmOneId","confirmBulk","setConfirmBulk","patch","next","k","v","onConfirmDeleteOne","toast","err","message","describeError","onConfirmBulk","ids","r","columns","jsxs","jsx","Badge","formatEpoch","Button","e","Trash2","EmptyState","Brain","selectedCount","Loader2","RefreshCcw","Label","Search","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","c","DataTable","Pagination","p","pp","ConfirmDialog","open","ms","d"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-
|
|
1
|
+
import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-DHh1LYlA.js";import{r as u}from"./react-DlP5eolq.js";import{T as b,a as N,b as m,c as i,d as v,e as l}from"./table-Dx65w6V0.js";import{b as k,c as w}from"./use-background-tasks-D1--hHjp.js";import{L as C}from"./loader-circle-DgdBWYl0.js";import{R as T}from"./refresh-ccw-nBMm5Xal.js";import{C as L}from"./circle-check-DZnkaUdk.js";import{C as M}from"./circle-x-DHK7ypFY.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -14,4 +14,4 @@ import{o as h,u as g,j as e,l as p,B as d,m as j}from"./index-CzlhMSb2.js";impor
|
|
|
14
14
|
* This source code is licensed under the ISC license.
|
|
15
15
|
* See the LICENSE file in the root directory of this source tree.
|
|
16
16
|
*/const B=h("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);function D(){const{t:s}=g(["tasks","common"]),r=k(),o=w(),[y,f]=u.useState(null);async function n(a,c){try{await o.mutateAsync({id:a.id,status:c}),j.success(s("goals.statusUpdated",{status:s(`goals.status.${c}`,{defaultValue:c})}))}catch(t){j.error(t?.message??String(t))}}const x=r.data?.goals??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(B,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("goals.title")}),e.jsx(p,{variant:"info",children:x.length}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(C,{className:"h-4 w-4 animate-spin"}):e.jsx(T,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("goals.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("goals.subtitle")}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx(P,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(b,{children:[e.jsx(N,{children:e.jsxs(m,{children:[e.jsx(i,{className:"w-12",children:s("goals.col.id")}),e.jsx(i,{children:s("goals.col.thread")}),e.jsx(i,{children:s("goals.col.title")}),e.jsx(i,{children:s("goals.col.progress")}),e.jsx(i,{children:s("goals.col.updated")}),e.jsx(i,{children:s("goals.col.actions")})]})}),e.jsx(v,{children:x.map(a=>{const c=y===a.id;return e.jsxs(u.Fragment,{children:[e.jsxs(m,{children:[e.jsx(l,{className:"font-mono text-xs",children:a.id}),e.jsxs(l,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(l,{children:e.jsx(d,{variant:"ghost",size:"sm",className:"-ml-2 text-left",onClick:()=>f(c?null:a.id),title:s(c?"goals.hideBody":"goals.showBody"),children:a.title})}),e.jsx(l,{children:e.jsx(p,{variant:"outline",children:a.progressCount})}),e.jsx(l,{className:"text-[11px] text-text-dim",children:a.updatedAt}),e.jsxs(l,{className:"flex flex-wrap gap-1",children:[e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.pause"),onClick:()=>void n(a,"paused"),disabled:o.isPending,children:e.jsx(z,{className:"h-4 w-4"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.complete"),onClick:()=>void n(a,"completed"),disabled:o.isPending,children:e.jsx(L,{className:"h-4 w-4 text-success"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.cancel"),onClick:()=>void n(a,"cancelled"),disabled:o.isPending,className:"text-danger hover:text-danger",children:e.jsx(M,{className:"h-4 w-4"})})]})]}),c&&e.jsxs(m,{children:[e.jsx(l,{}),e.jsx(l,{colSpan:5,children:e.jsxs("div",{className:"space-y-2 rounded bg-surface-2 p-3 text-xs",children:[a.body&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.body")}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words",children:a.body})]}),a.progressLog.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.recentProgress",{count:a.progressLog.length})}),e.jsx("ul",{className:"mt-1 space-y-1",children:a.progressLog.slice().reverse().map(t=>e.jsxs("li",{className:"font-mono text-[11px]",children:[e.jsxs("span",{className:"text-text-dim",children:[t.ts.slice(0,19)," (",t.by,")"]})," ",t.text]},`${t.ts}-${t.by}-${t.text}`))})]}),e.jsxs("div",{className:"text-[11px] text-text-dim",children:[s("goals.created",{at:a.createdAt}),a.closedAt?` · ${s("goals.closed",{at:a.closedAt})}`:""]})]})})]})]},a.id)})})]})})]})}function P(){const{t:s}=g("tasks");return e.jsxs("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:[s("goals.empty"),e.jsx("div",{className:"mt-2",children:e.jsx(S,{className:"mx-auto h-8 w-8 opacity-30"})})]})}export{D as default};
|
|
17
|
-
//# sourceMappingURL=goals-
|
|
17
|
+
//# sourceMappingURL=goals-C1LCm3qL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goals-DX_RjDAM.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', {\n status: t(`goals.status.${status}`, { defaultValue: status }),\n }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n) => (\n <li key={`${n.ts}-${n.by}-${n.text}`} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
1
|
+
{"version":3,"file":"goals-C1LCm3qL.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', {\n status: t(`goals.status.${status}`, { defaultValue: status }),\n }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n) => (\n <li key={`${n.ts}-${n.by}-${n.text}`} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as p,f,j as e,B as g,c as y}from"./index-
|
|
2
|
-
//# sourceMappingURL=health-
|
|
1
|
+
import{u as p,f,j as e,B as g,c as y}from"./index-DHh1LYlA.js";import{r as N}from"./react-DlP5eolq.js";import{E as v}from"./empty-state-CTwOQemt.js";import{T as w,a as C,b as h,c as i,d as M,e as o}from"./table-Dx65w6V0.js";import{u as L}from"./use-observability-DtqSWVjM.js";import{L as T}from"./loader-circle-DgdBWYl0.js";import{R as k}from"./refresh-ccw-nBMm5Xal.js";import{A as D}from"./activity-BAgb2WZC.js";function K(){const{t:s}=p(["observability","common"]),[l]=f(),n=Math.max(1,Number(l.get("days"))||7),{data:c,isLoading:u,isFetching:m,refetch:j}=L(n),a=c?.totals,d=c?.byDay??[],b=N.useMemo(()=>d.reduce((t,x)=>x.calls>t?x.calls:t,0),[d]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("health.title")}),e.jsxs(g,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>j(),disabled:m,"aria-label":s("actions.refresh",{ns:"common"}),children:[m?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),c&&e.jsxs("p",{className:"text-xs text-text-dim tabular-nums",children:[c.since," → ",c.until]})]}),u?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):!a||a.calls===0&&d.length===0?e.jsx(v,{icon:e.jsx(D,{}),title:s("health.empty.title"),description:s("health.empty.description")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6",children:[e.jsx(r,{label:s("health.kpi.calls"),value:String(a.calls),tone:"info"}),e.jsx(r,{label:s("health.kpi.cost"),value:`$${a.cost.toFixed(4)}`,tone:"info"}),e.jsx(r,{label:s("health.kpi.errors"),value:String(a.errors),tone:a.errors>0?"danger":"success"}),e.jsx(r,{label:s("health.kpi.errorRate"),value:`${(a.errorRate*100).toFixed(1)}%`,tone:a.errorRate>.05?"warning":"success"}),e.jsx(r,{label:s("health.kpi.avgLatencyMs"),value:`${Math.round(a.avgLatencyMs)}ms`,tone:"info"}),e.jsx(r,{label:s("health.kpi.p95LatencyMs"),value:`${Math.round(a.p95LatencyMs)}ms`,tone:"info"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim",children:s("health.byDay")}),e.jsxs(w,{children:[e.jsx(C,{children:e.jsxs(h,{children:[e.jsx(i,{className:"w-28",children:s("health.byDayCol.date")}),e.jsx(i,{children:s("health.byDayCol.calls")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.cost")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.errors")}),e.jsx(i,{className:"w-32",children:s("health.byDayCol.avgLatencyMs")})]})}),e.jsx(M,{children:d.map(t=>e.jsxs(h,{children:[e.jsx(o,{className:"font-mono text-xs",children:t.date}),e.jsx(o,{children:e.jsx(S,{value:t.calls,max:b})}),e.jsxs(o,{className:"tabular-nums",children:["$",t.cost.toFixed(4)]}),e.jsx(o,{className:"tabular-nums",children:e.jsx("span",{className:t.errors>0?"text-danger":"text-text-dim",children:t.errors})}),e.jsxs(o,{className:"tabular-nums",children:[Math.round(t.avgLatencyMs),"ms"]})]},t.date))})]})]})]})]})}const R={info:"border-info/30 text-info",success:"border-success/30 text-success",warning:"border-warning/30 text-warning",danger:"border-danger/30 text-danger"};function r({label:s,value:l,tone:n}){return e.jsxs("div",{className:y("rounded-md border bg-surface px-3 py-2",R[n]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:l})]})}function S({value:s,max:l}){const n=l>0?s/l*100:0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2",children:e.jsx("div",{className:"absolute inset-y-0 left-0 bg-accent/60",style:{width:`${n}%`}})}),e.jsx("span",{className:"tabular-nums text-sm text-text-dim",children:s})]})}export{K as default};
|
|
2
|
+
//# sourceMappingURL=health-wqCp-K_o.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-BAcwcy02.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('health.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"health-wqCp-K_o.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('health.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{o as e}from"./index-
|
|
1
|
+
import{o as e}from"./index-DHh1LYlA.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const t=e("HeartPulse",[["path",{d:"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z",key:"c3ymky"}],["path",{d:"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27",key:"1uw2ng"}]]);export{t as H};
|
|
7
|
-
//# sourceMappingURL=heart-pulse-
|
|
7
|
+
//# sourceMappingURL=heart-pulse-DfqI4GF7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heart-pulse-
|
|
1
|
+
{"version":3,"file":"heart-pulse-DfqI4GF7.js","sources":["../../node_modules/lucide-react/dist/esm/icons/heart-pulse.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst HeartPulse = createLucideIcon(\"HeartPulse\", [\n [\n \"path\",\n {\n d: \"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\",\n key: \"c3ymky\"\n }\n ],\n [\"path\", { d: \"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\", key: \"1uw2ng\" }]\n]);\n\nexport { HeartPulse as default };\n//# sourceMappingURL=heart-pulse.js.map\n"],"names":["HeartPulse","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,2IACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAQ,CAAE,CAC3E,CAAC","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{o as w,u as b,j as e,l as o,B as h,m}from"./index-
|
|
1
|
+
import{o as w,u as b,j as e,l as o,B as h,m}from"./index-DHh1LYlA.js";import{r as N}from"./react-DlP5eolq.js";import{T as v,a as T,b as u,c as l,d as y,e as c}from"./table-Dx65w6V0.js";import{u as k,a as A}from"./use-background-tasks-D1--hHjp.js";import{H}from"./heart-pulse-DfqI4GF7.js";import{L as R}from"./loader-circle-DgdBWYl0.js";import{R as S}from"./refresh-ccw-nBMm5Xal.js";import{P as C}from"./play-CPoE_JnS.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const P=w("Pause",[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]]);function K(){const{t}=b(["tasks","common"]),s=k(),r=A(),[j,f]=N.useState(null);async function g(a,n){try{await r.mutateAsync({row:a,op:n}),m.success(t(n==="enable"?"heartbeat.enabledToast":"heartbeat.disabledToast"))}catch(i){m.error(i?.message??String(i))}}const d=s.data?.bindings??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(H,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:t("heartbeat.title")}),e.jsx(o,{variant:"info",children:d.length}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(S,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("heartbeat.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("heartbeat.subtitle")}),s.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(z,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(v,{children:[e.jsx(T,{children:e.jsxs(u,{children:[e.jsx(l,{children:t("heartbeat.col.thread")}),e.jsx(l,{children:t("heartbeat.col.owner")}),e.jsx(l,{children:t("heartbeat.col.interval")}),e.jsx(l,{children:t("heartbeat.col.lastTick")}),e.jsx(l,{children:t("heartbeat.col.enabled")}),e.jsx(l,{children:t("heartbeat.col.body")})]})}),e.jsx(y,{children:d.map(a=>{const n=`${a.platform}:${a.channelId}:${a.threadId}`,i=j===n,p=a.lastTickAt?a.lastStatus==="delivered"?e.jsx(o,{variant:"success",children:x(a.lastTickAt,t)}):a.lastStatus==="error"?e.jsxs(o,{variant:"danger",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsxs(o,{variant:"outline",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsx(o,{variant:"outline",children:t("heartbeat.never")});return e.jsxs(u,{children:[e.jsxs(c,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(c,{className:"font-mono text-[11px]",children:a.userId||"—"}),e.jsx(c,{className:"text-xs",children:t("heartbeat.intervalMin",{count:a.intervalMinutes})}),e.jsx(c,{children:p}),e.jsx(c,{children:e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>void g(a,a.enabled?"disable":"enable"),disabled:r.isPending,children:a.enabled?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.pause")})]}):e.jsxs(e.Fragment,{children:[e.jsx(C,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.enable")})]})})}),e.jsxs(c,{className:"max-w-md",children:[e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>f(i?null:n),className:"-ml-2",children:t(i?"heartbeat.hide":"heartbeat.show")}),i&&e.jsx("pre",{className:"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim",children:a.body})]})]},n)})})]})})]})}function z(){const{t}=b("tasks");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:t("heartbeat.empty")})}function x(t,s){if(!t)return s("heartbeat.never");const r=Date.now()-new Date(t).getTime();return!Number.isFinite(r)||r<0||r<6e4?s("heartbeat.justNow"):r<36e5?s("heartbeat.minutesAgo",{count:Math.floor(r/6e4)}):r<864e5?s("heartbeat.hoursAgo",{count:Math.floor(r/36e5)}):s("heartbeat.daysAgo",{count:Math.floor(r/864e5)})}export{K as default};
|
|
7
|
-
//# sourceMappingURL=heartbeat-
|
|
7
|
+
//# sourceMappingURL=heartbeat-Bumv4XtQ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat-BF_rPcKb.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"heartbeat-Bumv4XtQ.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{o as w,b as y,d as C,u as x,j as e,B as u,I as S,l as m,c as k,D as L,t as D,v as F,w as H,x as R,m as j}from"./index-
|
|
1
|
+
import{o as w,b as y,d as C,u as x,j as e,B as u,I as S,l as m,c as k,D as L,t as D,v as F,w as H,x as R,m as j}from"./index-DHh1LYlA.js";import{r as o}from"./react-DlP5eolq.js";import{E as z}from"./empty-state-CTwOQemt.js";import{E}from"./external-link-BY7Ye8yi.js";import{L as M}from"./loader-circle-DgdBWYl0.js";import{R as T}from"./refresh-ccw-nBMm5Xal.js";import{S as I}from"./search-DbE4VEm9.js";import{D as $}from"./download-CqNiIHa8.js";import{C as A}from"./copy-DtQxgcR0.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -9,4 +9,4 @@ import{o as w,b as y,d as C,u as x,j as e,B as u,I as S,l as m,c as k,D as L,t a
|
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
10
|
* See the LICENSE file in the root directory of this source tree.
|
|
11
11
|
*/const B=w("Star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]),q={remoteHot:["skills","remote","hot"]};function K(){return y({queryKey:q.remoteHot,queryFn:()=>C.getSkillsRemoteHot(),staleTime:6e4})}function ee(){const{t:s}=x(["skills","common"]),{data:n,isLoading:l,isFetching:r,refetch:i}=K(),a=n?.skills??[],[h,b]=o.useState(""),[p,g]=o.useState(null),f=o.useMemo(()=>{const t=h.trim().toLowerCase();return t?a.filter(d=>d.slug.toLowerCase().includes(t)||(d.name||"").toLowerCase().includes(t)||(d.description||"").toLowerCase().includes(t)||(d.category||"").toLowerCase().includes(t)):a},[a,h]),v=p?a.find(t=>t.slug===p)??null:null;return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("h1",{className:"text-xl font-semibold inline-flex items-center gap-2",children:[e.jsx(N,{className:"h-5 w-5 text-warning"}),s("hot.title")]}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(u,{asChild:!0,variant:"ghost",size:"sm",children:e.jsxs("a",{href:"https://skillhub.cn",target:"_blank",rel:"noopener noreferrer",children:[e.jsx(E,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("hot.openHub")})]})}),e.jsxs(u,{variant:"ghost",size:"sm",onClick:()=>i(),disabled:r,"aria-label":s("actions.refresh",{ns:"common"}),children:[r?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(T,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("hot.subtitle")}),n&&e.jsx(O,{cached:!!n.cached,stale:!!n.stale,fetchedAt:n.fetchedAt})]}),a.length>0&&e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[180px] max-w-md",children:[e.jsx(I,{className:"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted"}),e.jsx(S,{value:h,onChange:t=>b(t.target.value),placeholder:s("actions.search",{ns:"common"}),className:"pl-7"})]}),e.jsxs(m,{variant:"secondary",className:"ml-auto",children:[f.length," / ",a.length]})]}),l?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):a.length===0?e.jsx(z,{icon:e.jsx(N,{}),title:s("hot.empty")}):e.jsx("ul",{className:"flex flex-col gap-2",children:f.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>g(t.slug),className:k("flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left","transition-colors hover:border-border-strong hover:bg-surface-hover"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name||t.slug}),t.version&&e.jsxs("span",{className:"text-text-muted text-xs font-mono",children:["v",t.version]}),t.category&&e.jsx(m,{variant:"outline",children:t.category}),e.jsxs("div",{className:"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(B,{className:"h-3 w-3"}),c(t.stars)]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx($,{className:"h-3 w-3"}),c(t.installs)]})]})]}),e.jsx("code",{className:"text-text-muted text-xs font-mono",children:t.slug}),t.description&&e.jsx("p",{className:"line-clamp-2 text-sm text-text-dim",children:t.description})]})},t.slug))}),e.jsx(Q,{skill:v,onOpenChange:t=>{t||g(null)}})]})}function O({cached:s,stale:n,fetchedAt:l}){const{t:r}=x("skills"),i=o.useMemo(()=>{try{const a=new Date(l);return Number.isNaN(a.getTime())?"":a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}},[l]);return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-text-muted",children:[e.jsx("span",{children:r("hot.updatedAt",{at:i})}),s&&e.jsx(m,{variant:"outline",children:r("hot.cached")}),n&&e.jsx(m,{variant:"warning",children:r("hot.stale")})]})}function Q({skill:s,onOpenChange:n}){const{t:l,i18n:r}=x("skills"),i=o.useMemo(()=>s?[{key:"cliInstall",cmd:`skillhub install ${s.slug}`},{key:"cliSearch",cmd:`skillhub search ${s.slug}`},{key:"imAsk",cmd:r.language.startsWith("zh")?`请用 skillhub 安装 ${s.slug} 技能`:`Please install ${s.slug} via skillhub`}]:[],[r.language,s]);return e.jsx(L,{open:s!=null,onOpenChange:n,children:e.jsxs(D,{className:"sm:max-w-2xl",children:[e.jsxs(F,{children:[e.jsx(H,{children:s?.name||s?.slug||""}),s?.description&&e.jsx(R,{children:s.description})]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs",children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.slug")}),e.jsx("dd",{className:"font-mono",children:s.slug}),s.version&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.version")}),e.jsxs("dd",{className:"font-mono",children:["v",s.version]})]}),s.category&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.category")}),e.jsx("dd",{children:s.category})]}),e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.stars")}),e.jsx("dd",{className:"tabular-nums",children:c(s.stars)}),e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.installs")}),e.jsx("dd",{className:"tabular-nums",children:c(s.installs)}),s.downloads!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:l("hot.detail.downloads")}),e.jsx("dd",{className:"tabular-nums",children:c(s.downloads)})]})]}),e.jsxs("div",{className:"mt-4 border-t border-border pt-3",children:[e.jsx("h3",{className:"text-sm font-medium",children:l("hot.detail.howInstall")}),e.jsx("ul",{className:"mt-2 flex flex-col gap-2",children:i.map(a=>e.jsxs("li",{className:"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2",children:[e.jsx("span",{className:"text-xs text-text-dim sm:w-40 sm:shrink-0",children:l(`hot.detail.label.${a.key}`)}),e.jsx("code",{className:"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all",children:a.cmd}),e.jsx(_,{text:a.cmd})]},a.key))}),e.jsx("p",{className:"mt-3 text-[11px] text-text-muted",children:l("hot.detail.hint")})]})]})]})})}function _({text:s}){const{t:n}=x("skills"),[l,r]=o.useState(!1);async function i(){try{await navigator.clipboard.writeText(s),r(!0),j.success(n("hot.detail.copied")),setTimeout(()=>r(!1),1500)}catch(a){j.error(String(a?.message??a))}}return e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>void i(),className:"shrink-0",children:[e.jsx(A,{className:"h-3 w-3"}),n(l?"hot.detail.copied":"hot.detail.copy")]})}function c(s){return s==null||!Number.isFinite(s)?"—":s.toLocaleString()}export{ee as default};
|
|
12
|
-
//# sourceMappingURL=hot-
|
|
12
|
+
//# sourceMappingURL=hot-B-CMjQIr.js.map
|