agim-cli 1.4.9 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +437 -402
- package/README.md +43 -7
- package/README.zh-CN.md +42 -7
- package/bin/agim_rpc.py +12 -12
- package/dist/cli-ui/cmd-handlers.d.ts +25 -4
- package/dist/cli-ui/cmd-handlers.d.ts.map +1 -1
- package/dist/cli-ui/cmd-handlers.js +315 -59
- package/dist/cli-ui/cmd-handlers.js.map +1 -1
- package/dist/cli-ui/config-wizard.d.ts +13 -1
- package/dist/cli-ui/config-wizard.d.ts.map +1 -1
- package/dist/cli-ui/config-wizard.js +120 -48
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/doctor.d.ts +15 -0
- package/dist/cli-ui/doctor.d.ts.map +1 -0
- package/dist/cli-ui/doctor.js +151 -0
- package/dist/cli-ui/doctor.js.map +1 -0
- package/dist/cli-ui/entry-menu.d.ts +6 -0
- package/dist/cli-ui/entry-menu.d.ts.map +1 -1
- package/dist/cli-ui/entry-menu.js +67 -30
- package/dist/cli-ui/entry-menu.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 +17 -8
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +39 -21
- 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/quickstart.d.ts +3 -0
- package/dist/cli-ui/quickstart.d.ts.map +1 -0
- package/dist/cli-ui/quickstart.js +108 -0
- package/dist/cli-ui/quickstart.js.map +1 -0
- package/dist/cli-ui/readiness.d.ts +10 -0
- package/dist/cli-ui/readiness.d.ts.map +1 -0
- package/dist/cli-ui/readiness.js +75 -0
- package/dist/cli-ui/readiness.js.map +1 -0
- package/dist/cli-ui/service.d.ts +30 -7
- package/dist/cli-ui/service.d.ts.map +1 -1
- package/dist/cli-ui/service.js +171 -77
- 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 +118 -436
- 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.d.ts.map +1 -1
- package/dist/core/acp-server.js +21 -7
- 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 +13 -6
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +72 -23
- 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/builtin.d.ts.map +1 -1
- package/dist/core/commands/builtin.js +12 -2
- package/dist/core/commands/builtin.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.d.ts.map +1 -1
- package/dist/core/commands/model.js +32 -3
- 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/anthropic-provider.js +2 -1
- package/dist/core/llm/anthropic-provider.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 +5 -4
- package/dist/core/llm/openai-compat-provider.js.map +1 -1
- package/dist/core/llm/provider-base.d.ts +5 -5
- package/dist/core/llm/provider-base.d.ts.map +1 -1
- package/dist/core/llm/provider-base.js +1 -1
- package/dist/core/llm/provider-base.js.map +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.js +9 -9
- 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.d.ts +1 -0
- package/dist/plugins/agents/native/index.d.ts.map +1 -1
- package/dist/plugins/agents/native/index.js +28 -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.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/factory.js +29 -13
- package/dist/plugins/agents/pi-native/factory.js.map +1 -1
- package/dist/plugins/agents/pi-native/index.d.ts +14 -3
- package/dist/plugins/agents/pi-native/index.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/index.js +58 -4
- package/dist/plugins/agents/pi-native/index.js.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts +2 -0
- package/dist/plugins/agents/pi-native/provider-resolver.d.ts.map +1 -1
- package/dist/plugins/agents/pi-native/provider-resolver.js +9 -1
- package/dist/plugins/agents/pi-native/provider-resolver.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-CTsDMefo.js +7 -0
- package/dist/web/public/assets/a2a-CTsDMefo.js.map +1 -0
- package/dist/web/public/assets/{activity-BnlFGipw.js → activity-ul8Os7Pz.js} +2 -2
- package/dist/web/public/assets/{activity-BnlFGipw.js.map → activity-ul8Os7Pz.js.map} +1 -1
- package/dist/web/public/assets/{admins-CH84Rw1d.js → admins-ByMAuquy.js} +3 -3
- package/dist/web/public/assets/{admins-CH84Rw1d.js.map → admins-ByMAuquy.js.map} +1 -1
- package/dist/web/public/assets/agents-Ds1zyxBj.js +2 -0
- package/dist/web/public/assets/agents-Ds1zyxBj.js.map +1 -0
- package/dist/web/public/assets/{approvals-DnzjbDR6.js → approvals-DOWlWI7Z.js} +3 -3
- package/dist/web/public/assets/{approvals-DnzjbDR6.js.map → approvals-DOWlWI7Z.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-DxlRHrs8.js → arrow-down-7i0xwCI2.js} +2 -2
- package/dist/web/public/assets/{arrow-down-DxlRHrs8.js.map → arrow-down-7i0xwCI2.js.map} +1 -1
- package/dist/web/public/assets/arrow-right-A889Wof8.js +7 -0
- package/dist/web/public/assets/arrow-right-A889Wof8.js.map +1 -0
- package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js → arrow-up-Dm0U4-6U.js} +2 -2
- package/dist/web/public/assets/{arrow-up-CAiQ2jy-.js.map → arrow-up-Dm0U4-6U.js.map} +1 -1
- package/dist/web/public/assets/{asks-DyUQopay.js → asks-DGuBsrJ7.js} +3 -3
- package/dist/web/public/assets/{asks-DyUQopay.js.map → asks-DGuBsrJ7.js.map} +1 -1
- package/dist/web/public/assets/{audit-BVHTMS82.js → audit-BRXsplJ2.js} +2 -2
- package/dist/web/public/assets/{audit-BVHTMS82.js.map → audit-BRXsplJ2.js.map} +1 -1
- package/dist/web/public/assets/{bell-D7iS7ctN.js → bell-B-UdeJsp.js} +2 -2
- package/dist/web/public/assets/{bell-D7iS7ctN.js.map → bell-B-UdeJsp.js.map} +1 -1
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js +2 -0
- package/dist/web/public/assets/bgjobs-CcRiffyJ.js.map +1 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js +7 -0
- package/dist/web/public/assets/book-open-CSCq5cjL.js.map +1 -0
- package/dist/web/public/assets/{brain-CCF25Egu.js → brain-Dl4DF5kX.js} +2 -2
- package/dist/web/public/assets/{brain-CCF25Egu.js.map → brain-Dl4DF5kX.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-BMLMD8nM.js → briefcase-CeKUkFSq.js} +2 -2
- package/dist/web/public/assets/{briefcase-BMLMD8nM.js.map → briefcase-CeKUkFSq.js.map} +1 -1
- package/dist/web/public/assets/chat-rLJMdJBk.js +12 -0
- package/dist/web/public/assets/chat-rLJMdJBk.js.map +1 -0
- package/dist/web/public/assets/{chevron-left-BDO3vw8G.js → chevron-left-01fAFVpo.js} +2 -2
- package/dist/web/public/assets/{chevron-left-BDO3vw8G.js.map → chevron-left-01fAFVpo.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-5ZUC2opg.js → chevron-right-CFRb-SM_.js} +3 -3
- package/dist/web/public/assets/{chevron-right-5ZUC2opg.js.map → chevron-right-CFRb-SM_.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js → circle-check-big-DBg2BD6o.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-DHAHqUlS.js.map → circle-check-big-DBg2BD6o.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-7VaoZ7dY.js → circle-x-CqFMzO-x.js} +2 -2
- package/dist/web/public/assets/{circle-x-7VaoZ7dY.js.map → circle-x-CqFMzO-x.js.map} +1 -1
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js +7 -0
- package/dist/web/public/assets/clipboard-list-lnqdk2_J.js.map +1 -0
- package/dist/web/public/assets/{clock-ZPVXnd6V.js → clock-4hd1joQe.js} +3 -3
- package/dist/web/public/assets/{clock-ZPVXnd6V.js.map → clock-4hd1joQe.js.map} +1 -1
- package/dist/web/public/assets/confirm-dialog-BDb0NLny.js +2 -0
- package/dist/web/public/assets/{confirm-dialog-CgpJL9oN.js.map → confirm-dialog-BDb0NLny.js.map} +1 -1
- package/dist/web/public/assets/{copy-BaZl52tH.js → copy-CD4A7VD8.js} +3 -3
- package/dist/web/public/assets/{copy-BaZl52tH.js.map → copy-CD4A7VD8.js.map} +1 -1
- package/dist/web/public/assets/dashboard-CG3WiG7h.js +2 -0
- package/dist/web/public/assets/dashboard-CG3WiG7h.js.map +1 -0
- package/dist/web/public/assets/{data-table-BLYG79TX.js → data-table-BkUshOZz.js} +2 -2
- package/dist/web/public/assets/{data-table-BLYG79TX.js.map → data-table-BkUshOZz.js.map} +1 -1
- package/dist/web/public/assets/database-lQzk64rV.js +7 -0
- package/dist/web/public/assets/database-lQzk64rV.js.map +1 -0
- package/dist/web/public/assets/distill-CPurVW3v.js +7 -0
- package/dist/web/public/assets/distill-CPurVW3v.js.map +1 -0
- package/dist/web/public/assets/{download-bzCepctg.js → download-CVZnHcwj.js} +2 -2
- package/dist/web/public/assets/{download-bzCepctg.js.map → download-CVZnHcwj.js.map} +1 -1
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js +7 -0
- package/dist/web/public/assets/dropdown-menu-BNH5SrVb.js.map +1 -0
- package/dist/web/public/assets/email-YlI4MWLp.js +7 -0
- package/dist/web/public/assets/email-YlI4MWLp.js.map +1 -0
- package/dist/web/public/assets/{empty-state-96qpPTNg.js → empty-state-CuiqdZiB.js} +2 -2
- package/dist/web/public/assets/{empty-state-96qpPTNg.js.map → empty-state-CuiqdZiB.js.map} +1 -1
- package/dist/web/public/assets/{external-link-J4nIlCem.js → external-link-1WPpVvdu.js} +2 -2
- package/dist/web/public/assets/{external-link-J4nIlCem.js.map → external-link-1WPpVvdu.js.map} +1 -1
- package/dist/web/public/assets/{eye-BvsBLK42.js → eye-BfPyNFzk.js} +2 -2
- package/dist/web/public/assets/{eye-BvsBLK42.js.map → eye-BfPyNFzk.js.map} +1 -1
- package/dist/web/public/assets/{facts-DMucDXYd.js → facts-xT_24pH8.js} +2 -2
- package/dist/web/public/assets/{facts-DMucDXYd.js.map → facts-xT_24pH8.js.map} +1 -1
- package/dist/web/public/assets/file-text-BxfdLM0-.js +7 -0
- package/dist/web/public/assets/file-text-BxfdLM0-.js.map +1 -0
- package/dist/web/public/assets/{goals-B9ETHgL0.js → goals-C8ZQfbhj.js} +3 -3
- package/dist/web/public/assets/{goals-B9ETHgL0.js.map → goals-C8ZQfbhj.js.map} +1 -1
- package/dist/web/public/assets/health-A2StNEfn.js +2 -0
- package/dist/web/public/assets/{health-DLzZ7KHc.js.map → health-A2StNEfn.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js → heart-pulse-DXlE9oic.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-CVEeD2sz.js.map → heart-pulse-DXlE9oic.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-B1BEBHge.js → heartbeat-ClO5gJrj.js} +3 -3
- package/dist/web/public/assets/{heartbeat-B1BEBHge.js.map → heartbeat-ClO5gJrj.js.map} +1 -1
- package/dist/web/public/assets/hot-bfTA-V_z.js +7 -0
- package/dist/web/public/assets/{hot-Yc7iad0D.js.map → hot-bfTA-V_z.js.map} +1 -1
- package/dist/web/public/assets/index-Bi2qWb-u.css +1 -0
- package/dist/web/public/assets/index-DCfdN5R7.js +244 -0
- package/dist/web/public/assets/index-DCfdN5R7.js.map +1 -0
- package/dist/web/public/assets/{injection-Ca-9gbo0.js → injection-omvCR6-p.js} +2 -2
- package/dist/web/public/assets/{injection-Ca-9gbo0.js.map → injection-omvCR6-p.js.map} +1 -1
- package/dist/web/public/assets/{installed-Zz34apdi.js → installed-DL6r3ktm.js} +4 -9
- package/dist/web/public/assets/installed-DL6r3ktm.js.map +1 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js +2 -0
- package/dist/web/public/assets/jobs-Biy5lYd4.js.map +1 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js +2 -0
- package/dist/web/public/assets/layout-BLm6NJ3V.js.map +1 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js +2 -0
- package/dist/web/public/assets/layout-BTKafRVZ.js.map +1 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js +2 -0
- package/dist/web/public/assets/layout-Bm-2s2fp.js.map +1 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js +2 -0
- package/dist/web/public/assets/layout-DsZ8eR4i.js.map +1 -0
- package/dist/web/public/assets/{layout-CtDc2i7w.js → layout-sxvovjEH.js} +2 -2
- package/dist/web/public/assets/{layout-CtDc2i7w.js.map → layout-sxvovjEH.js.map} +1 -1
- package/dist/web/public/assets/llm-JjZDbBvJ.js +37 -0
- package/dist/web/public/assets/llm-JjZDbBvJ.js.map +1 -0
- package/dist/web/public/assets/loader-circle-DDdmcH0k.js +7 -0
- package/dist/web/public/assets/{loader-circle-D8L1w9c1.js.map → loader-circle-DDdmcH0k.js.map} +1 -1
- package/dist/web/public/assets/{map-pin--GMunU9n.js → map-pin-C_jAxukI.js} +2 -2
- package/dist/web/public/assets/{map-pin--GMunU9n.js.map → map-pin-C_jAxukI.js.map} +1 -1
- package/dist/web/public/assets/{mcp-DhnXhO9B.js → mcp-vKajK1F8.js} +3 -3
- package/dist/web/public/assets/{mcp-DhnXhO9B.js.map → mcp-vKajK1F8.js.map} +1 -1
- package/dist/web/public/assets/memos-DAt4k3DO.js +7 -0
- package/dist/web/public/assets/memos-DAt4k3DO.js.map +1 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js +2 -0
- package/dist/web/public/assets/messengers-GYVTFlAj.js.map +1 -0
- package/dist/web/public/assets/{mobile-CUZ359rQ.js → mobile-VUyTo40E.js} +3 -3
- package/dist/web/public/assets/{mobile-CUZ359rQ.js.map → mobile-VUyTo40E.js.map} +1 -1
- package/dist/web/public/assets/{network-BBdRdrH_.js → network-BUeWK3bs.js} +2 -2
- package/dist/web/public/assets/{network-BBdRdrH_.js.map → network-BUeWK3bs.js.map} +1 -1
- package/dist/web/public/assets/outbox-CEE0rwN3.js +2 -0
- package/dist/web/public/assets/outbox-CEE0rwN3.js.map +1 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js +12 -0
- package/dist/web/public/assets/overview-BSOZ5gTD.js.map +1 -0
- package/dist/web/public/assets/overview-COop5K2Y.js +12 -0
- package/dist/web/public/assets/overview-COop5K2Y.js.map +1 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js +2 -0
- package/dist/web/public/assets/overview-DeH5ud6d.js.map +1 -0
- package/dist/web/public/assets/{pagination-DcsgDXXM.js → pagination-BBicLzXP.js} +3 -3
- package/dist/web/public/assets/{pagination-DcsgDXXM.js.map → pagination-BBicLzXP.js.map} +1 -1
- package/dist/web/public/assets/persona-CElXQZ4p.js +2 -0
- package/dist/web/public/assets/{persona-ig2ac4mY.js.map → persona-CElXQZ4p.js.map} +1 -1
- package/dist/web/public/assets/{plans-Bzbk8eUr.js → plans-Bo5LlLeH.js} +3 -8
- package/dist/web/public/assets/plans-Bo5LlLeH.js.map +1 -0
- package/dist/web/public/assets/{play-Di1jqulh.js → play-DX5wp4WH.js} +2 -2
- package/dist/web/public/assets/{play-Di1jqulh.js.map → play-DX5wp4WH.js.map} +1 -1
- package/dist/web/public/assets/{plus-C2zyJ1mF.js → plus-DH4J_YhN.js} +2 -2
- package/dist/web/public/assets/{plus-C2zyJ1mF.js.map → plus-DH4J_YhN.js.map} +1 -1
- package/dist/web/public/assets/policy-BrgOuDt_.js +2 -0
- package/dist/web/public/assets/policy-BrgOuDt_.js.map +1 -0
- package/dist/web/public/assets/{qr-code-C-ACsKv_.js → qr-code-YrEuhMPC.js} +2 -2
- package/dist/web/public/assets/{qr-code-C-ACsKv_.js.map → qr-code-YrEuhMPC.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js → refresh-ccw-DlAd-eTQ.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-7HdadG5V.js.map → refresh-ccw-DlAd-eTQ.js.map} +1 -1
- package/dist/web/public/assets/{reminders-BDeiVYTC.js → reminders-DBEE0zXG.js} +3 -3
- package/dist/web/public/assets/{reminders-BDeiVYTC.js.map → reminders-DBEE0zXG.js.map} +1 -1
- package/dist/web/public/assets/{save-BYFmz9gD.js → save-BDOtZrfp.js} +2 -2
- package/dist/web/public/assets/{save-BYFmz9gD.js.map → save-BDOtZrfp.js.map} +1 -1
- package/dist/web/public/assets/schedules-DAyhVI8-.js +2 -0
- package/dist/web/public/assets/schedules-DAyhVI8-.js.map +1 -0
- package/dist/web/public/assets/search-55mtgHrB.js +17 -0
- package/dist/web/public/assets/search-55mtgHrB.js.map +1 -0
- package/dist/web/public/assets/{search-DxkvV-8p.js → search-CAICU3aU.js} +2 -2
- package/dist/web/public/assets/{search-DxkvV-8p.js.map → search-CAICU3aU.js.map} +1 -1
- package/dist/web/public/assets/security-CbP4QgVp.js +2 -0
- package/dist/web/public/assets/security-CbP4QgVp.js.map +1 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js +7 -0
- package/dist/web/public/assets/server-Dg4e8pvm.js.map +1 -0
- package/dist/web/public/assets/service-gWZa3sup.js +7 -0
- package/dist/web/public/assets/service-gWZa3sup.js.map +1 -0
- package/dist/web/public/assets/{shield-alert-DXGk9Rak.js → shield-alert-DOKK9EnJ.js} +2 -2
- package/dist/web/public/assets/{shield-alert-DXGk9Rak.js.map → shield-alert-DOKK9EnJ.js.map} +1 -1
- package/dist/web/public/assets/sparkles-G0QIs9nP.js +7 -0
- package/dist/web/public/assets/sparkles-G0QIs9nP.js.map +1 -0
- package/dist/web/public/assets/start-D-abhl3q.js +2 -0
- package/dist/web/public/assets/start-D-abhl3q.js.map +1 -0
- package/dist/web/public/assets/{status-badge-D0nbFSom.js → status-badge-CyLdpsXq.js} +2 -2
- package/dist/web/public/assets/{status-badge-D0nbFSom.js.map → status-badge-CyLdpsXq.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-DFiAXvDp.js → subtasks-BnEjSGUR.js} +3 -3
- package/dist/web/public/assets/{subtasks-DFiAXvDp.js.map → subtasks-BnEjSGUR.js.map} +1 -1
- package/dist/web/public/assets/{table-_WsrnZ_T.js → table-sCMZBe_Z.js} +2 -2
- package/dist/web/public/assets/{table-_WsrnZ_T.js.map → table-sCMZBe_Z.js.map} +1 -1
- package/dist/web/public/assets/terminal-_pXeEjXG.js +7 -0
- package/dist/web/public/assets/terminal-_pXeEjXG.js.map +1 -0
- package/dist/web/public/assets/{topn-C2PHE4tX.js → topn-D1B-gS1M.js} +3 -3
- package/dist/web/public/assets/{topn-C2PHE4tX.js.map → topn-D1B-gS1M.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-1Km439fW.js → trash-2-D2x2UPuZ.js} +2 -2
- package/dist/web/public/assets/{trash-2-1Km439fW.js.map → trash-2-D2x2UPuZ.js.map} +1 -1
- package/dist/web/public/assets/use-a2a-C98e2Via.js +2 -0
- package/dist/web/public/assets/use-a2a-C98e2Via.js.map +1 -0
- package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js → use-agim-skills-BbuJP3NT.js} +2 -2
- package/dist/web/public/assets/{use-agim-skills-COSqZrdH.js.map → use-agim-skills-BbuJP3NT.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-CwFmOokw.js +2 -0
- package/dist/web/public/assets/{use-background-tasks-wCL7jn68.js.map → use-background-tasks-CwFmOokw.js.map} +1 -1
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js +2 -0
- package/dist/web/public/assets/use-jobs-BJjeJ5lh.js.map +1 -0
- package/dist/web/public/assets/use-memory-CXDwKCco.js +2 -0
- package/dist/web/public/assets/{use-memory-B9oRyQC8.js.map → use-memory-CXDwKCco.js.map} +1 -1
- package/dist/web/public/assets/use-observability-CY5ZUPrC.js +2 -0
- package/dist/web/public/assets/{use-observability-DGkN80qa.js.map → use-observability-CY5ZUPrC.js.map} +1 -1
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js +7 -0
- package/dist/web/public/assets/use-outbox-DT_XWB_7.js.map +1 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js +7 -0
- package/dist/web/public/assets/use-schedules-D4W8fMwo.js.map +1 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js +2 -0
- package/dist/web/public/assets/use-settings-DGIjmUX0.js.map +1 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js +7 -0
- package/dist/web/public/assets/use-skills-D2bMM580.js.map +1 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js +2 -0
- package/dist/web/public/assets/use-vector-BYOFwjU0.js.map +1 -0
- package/dist/web/public/assets/use-workspace-CuytyHwb.js +2 -0
- package/dist/web/public/assets/{use-workspace-BDXP5XO1.js.map → use-workspace-CuytyHwb.js.map} +1 -1
- package/dist/web/public/assets/vector-CL8ezpSR.js +2 -0
- package/dist/web/public/assets/vector-CL8ezpSR.js.map +1 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js +7 -0
- package/dist/web/public/assets/viewer-CD0iEfPU.js.map +1 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js +17 -0
- package/dist/web/public/assets/workspace-BA1_hso3.js.map +1 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js +7 -0
- package/dist/web/public/assets/workspaces-DyGLJUgB.js.map +1 -0
- package/dist/web/public/index.html +2 -2
- package/dist/web/public/loc.html +1 -1
- package/dist/web/public/login.html +2 -2
- package/dist/web/server.d.ts +2 -5
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +256 -122
- 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/a2a-CZxwvgvh.js +0 -7
- package/dist/web/public/assets/a2a-CZxwvgvh.js.map +0 -1
- package/dist/web/public/assets/agents-CFB4Uj6b.js +0 -7
- package/dist/web/public/assets/agents-CFB4Uj6b.js.map +0 -1
- package/dist/web/public/assets/bgjobs-BYCQhd_1.js +0 -7
- package/dist/web/public/assets/bgjobs-BYCQhd_1.js.map +0 -1
- package/dist/web/public/assets/chat-DPkKy5y_.js +0 -17
- package/dist/web/public/assets/chat-DPkKy5y_.js.map +0 -1
- package/dist/web/public/assets/circle-check-COhM5JsK.js +0 -7
- package/dist/web/public/assets/circle-check-COhM5JsK.js.map +0 -1
- package/dist/web/public/assets/confirm-dialog-CgpJL9oN.js +0 -2
- package/dist/web/public/assets/distill-D9p8O8Jf.js +0 -7
- package/dist/web/public/assets/distill-D9p8O8Jf.js.map +0 -1
- package/dist/web/public/assets/email-Douv-rZ5.js +0 -7
- package/dist/web/public/assets/email-Douv-rZ5.js.map +0 -1
- package/dist/web/public/assets/health-DLzZ7KHc.js +0 -2
- package/dist/web/public/assets/hot-Yc7iad0D.js +0 -12
- package/dist/web/public/assets/index-DY2Zglku.js +0 -209
- package/dist/web/public/assets/index-DY2Zglku.js.map +0 -1
- package/dist/web/public/assets/index-DknVjPYB.css +0 -1
- package/dist/web/public/assets/installed-Zz34apdi.js.map +0 -1
- package/dist/web/public/assets/jobs-CtVRpl0r.js +0 -2
- package/dist/web/public/assets/jobs-CtVRpl0r.js.map +0 -1
- package/dist/web/public/assets/layout-BTCLgkgN.js +0 -2
- package/dist/web/public/assets/layout-BTCLgkgN.js.map +0 -1
- package/dist/web/public/assets/layout-Cxch59sI.js +0 -2
- package/dist/web/public/assets/layout-Cxch59sI.js.map +0 -1
- package/dist/web/public/assets/layout-DnANw2Q2.js +0 -2
- package/dist/web/public/assets/layout-DnANw2Q2.js.map +0 -1
- package/dist/web/public/assets/layout-yIZG87fq.js +0 -2
- package/dist/web/public/assets/layout-yIZG87fq.js.map +0 -1
- package/dist/web/public/assets/llm-CMMa85Ig.js +0 -27
- package/dist/web/public/assets/llm-CMMa85Ig.js.map +0 -1
- package/dist/web/public/assets/loader-circle-D8L1w9c1.js +0 -7
- package/dist/web/public/assets/memos-DQZc7llR.js +0 -12
- package/dist/web/public/assets/memos-DQZc7llR.js.map +0 -1
- package/dist/web/public/assets/messengers-DwSmauLs.js +0 -2
- package/dist/web/public/assets/messengers-DwSmauLs.js.map +0 -1
- package/dist/web/public/assets/outbox-CmN0U35l.js +0 -7
- package/dist/web/public/assets/outbox-CmN0U35l.js.map +0 -1
- package/dist/web/public/assets/persona-ig2ac4mY.js +0 -2
- package/dist/web/public/assets/plans-Bzbk8eUr.js.map +0 -1
- package/dist/web/public/assets/policy-yD1c2Pcn.js +0 -2
- package/dist/web/public/assets/policy-yD1c2Pcn.js.map +0 -1
- package/dist/web/public/assets/schedules-BddzBrxI.js +0 -7
- package/dist/web/public/assets/schedules-BddzBrxI.js.map +0 -1
- package/dist/web/public/assets/search-B8PlbtLg.js +0 -17
- package/dist/web/public/assets/search-B8PlbtLg.js.map +0 -1
- package/dist/web/public/assets/security-DpOGp3nS.js +0 -2
- package/dist/web/public/assets/security-DpOGp3nS.js.map +0 -1
- package/dist/web/public/assets/service-BsY8CaNG.js +0 -7
- package/dist/web/public/assets/service-BsY8CaNG.js.map +0 -1
- package/dist/web/public/assets/use-background-tasks-wCL7jn68.js +0 -2
- package/dist/web/public/assets/use-memory-B9oRyQC8.js +0 -2
- package/dist/web/public/assets/use-observability-DGkN80qa.js +0 -2
- package/dist/web/public/assets/use-settings-Co-iafXD.js +0 -2
- package/dist/web/public/assets/use-settings-Co-iafXD.js.map +0 -1
- package/dist/web/public/assets/use-workspace-BDXP5XO1.js +0 -2
- package/dist/web/public/assets/vector-BfIEx8xX.js +0 -2
- package/dist/web/public/assets/vector-BfIEx8xX.js.map +0 -1
- package/dist/web/public/assets/viewer-BPMZkT05.js +0 -12
- package/dist/web/public/assets/viewer-BPMZkT05.js.map +0 -1
- package/dist/web/public/assets/workspace-BbCchiHE.js +0 -17
- package/dist/web/public/assets/workspace-BbCchiHE.js.map +0 -1
- package/dist/web/public/assets/workspaces-5HE7pjdA.js +0 -7
- package/dist/web/public/assets/workspaces-5HE7pjdA.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-skills-D2bMM580.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flame.js","../../src/hooks/use-skills.ts"],"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 Flame = createLucideIcon(\"Flame\", [\n [\n \"path\",\n {\n d: \"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\",\n key: \"96xj49\"\n }\n ]\n]);\n\nexport { Flame as default };\n//# sourceMappingURL=flame.js.map\n","/**\n * useSkills — read-only browse of the agent skills.\n *\n * useSkills() — list of every skill on disk\n * useSkillDetail(slug) — markdown body, fetched on demand\n * when the modal opens\n *\n * No mutations: installs happen via the skillhub CLI on the host,\n * agim is strictly read-only here.\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n ListSkillsResponse,\n RemoteHotSkillsResponse,\n SkillDetail,\n} from '@/types/api'\n\nexport const skillsKeys = {\n all: ['skills'] as const,\n list: ['skills', 'list'] as const,\n detail: (slug: string) => ['skills', 'detail', slug] as const,\n remoteHot: ['skills', 'remote', 'hot'] as const,\n}\n\nexport function useSkills() {\n return useQuery<ListSkillsResponse>({\n queryKey: skillsKeys.list,\n queryFn: () => api.listSkills(),\n })\n}\n\nexport function useSkillDetail(slug: string | null) {\n return useQuery<SkillDetail>({\n queryKey: skillsKeys.detail(slug ?? ''),\n queryFn: () => api.getSkillDetail(slug as string),\n enabled: Boolean(slug),\n })\n}\n\n/** skillhub.cn hot list. The proxy on the server caches for 5 min and\n * serves stale-while-error, so we don't need an aggressive client-side\n * refresh — the operator hits the refresh button when they want fresh\n * data. staleTime keeps tab-switch round-trips cheap. */\nexport function useSkillsRemoteHot() {\n return useQuery<RemoteHotSkillsResponse>({\n queryKey: skillsKeys.remoteHot,\n queryFn: () => api.getSkillsRemoteHot(),\n staleTime: 60_000,\n })\n}\n"],"names":["Flame","createLucideIcon","skillsKeys","useSkillsRemoteHot","useQuery","api"],"mappings":"iDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAQC,EAAiB,QAAS,CACtC,CACE,OACA,CACE,EAAG,4KACH,IAAK,QACX,CACA,CACA,CAAC,ECEYC,EAAa,CAIxB,UAAY,CAAC,SAAU,SAAU,KAAK,CACxC,EAqBO,SAASC,GAAqB,CACnC,OAAOC,EAAkC,CACvC,SAAUF,EAAW,UACrB,QAAS,IAAMG,EAAI,mBAAA,EACnB,UAAW,GAAA,CACZ,CACH","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as c,s as r,v as t,t as n}from"./index-DCfdN5R7.js";import{m as i}from"./use-memory-CXDwKCco.js";const a={all:["memory","vector"],status:e=>["memory","vector","status",e??null]};function y(e={}){return c({queryKey:a.status(e.user_key),queryFn:()=>r.getMemoryVectorStatus(e),refetchInterval:3e3,refetchIntervalInBackground:!1})}function u(e){return()=>{e.invalidateQueries({queryKey:a.all}),e.invalidateQueries({queryKey:i.all})}}function f(){const e=n(),o=u(e);return t({mutationFn:s=>r.backfillMemoryVector({user_key:s?.user_key},s?.max_rows?{max_rows:s.max_rows}:void 0),onSuccess:o})}function d(){const e=n();return t({mutationFn:()=>r.downloadMemoryVector(),onSuccess:u(e)})}function g(){const e=n();return t({mutationFn:o=>r.clearMemoryVector({user_key:o?.user_key}),onSuccess:u(e)})}function V(){return t({mutationFn:()=>r.testMemoryVector()})}export{V as a,d as b,f as c,g as d,y as u};
|
|
2
|
+
//# sourceMappingURL=use-vector-BYOFwjU0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-vector-BYOFwjU0.js","sources":["../../src/hooks/use-vector.ts"],"sourcesContent":["/**\n * useVector — react-query wrappers for the embedding/vector backend.\n *\n * useVectorStatus({ user_key }) — status + coverage + jobs\n * (polls every 3s; jobs\n * are async)\n * useTriggerVectorBackfill()\n * useTriggerVectorDownload()\n * useTriggerVectorClear() — DESTRUCTIVE; route gates\n * with ConfirmDialog\n * useTriggerVectorTest()\n *\n * Status polling stops backgrounded (refetchIntervalInBackground:\n * false) so an idle tab on a phone doesn't drain battery.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport { memoryKeys } from './use-memory'\nimport type {\n VectorActionResponse,\n VectorClearResponse,\n VectorStatus,\n VectorTestResponse,\n} from '@/types/api'\n\nexport const vectorKeys = {\n all: ['memory', 'vector'] as const,\n status: (user_key?: string) => ['memory', 'vector', 'status', user_key ?? null] as const,\n}\n\nexport function useVectorStatus(query: { user_key?: string } = {}) {\n return useQuery<VectorStatus>({\n queryKey: vectorKeys.status(query.user_key),\n queryFn: () => api.getMemoryVectorStatus(query),\n refetchInterval: 3000,\n refetchIntervalInBackground: false,\n })\n}\n\nfunction invalidateAfter(qc: ReturnType<typeof useQueryClient>): () => void {\n return () => {\n qc.invalidateQueries({ queryKey: vectorKeys.all })\n qc.invalidateQueries({ queryKey: memoryKeys.all })\n }\n}\n\nexport function useTriggerVectorBackfill() {\n const qc = useQueryClient()\n const invalidate = invalidateAfter(qc)\n return useMutation<\n VectorActionResponse,\n Error,\n { user_key?: string; max_rows?: number } | undefined\n >({\n mutationFn: (vars) => api.backfillMemoryVector(\n { user_key: vars?.user_key },\n vars?.max_rows ? { max_rows: vars.max_rows } : undefined,\n ),\n onSuccess: invalidate,\n })\n}\n\nexport function useTriggerVectorDownload() {\n const qc = useQueryClient()\n return useMutation<VectorActionResponse, Error, void>({\n mutationFn: () => api.downloadMemoryVector(),\n onSuccess: invalidateAfter(qc),\n })\n}\n\nexport function useTriggerVectorClear() {\n const qc = useQueryClient()\n return useMutation<VectorClearResponse, Error, { user_key?: string } | undefined>({\n mutationFn: (vars) => api.clearMemoryVector({ user_key: vars?.user_key }),\n onSuccess: invalidateAfter(qc),\n })\n}\n\nexport function useTriggerVectorTest() {\n return useMutation<VectorTestResponse, Error, void>({\n mutationFn: () => api.testMemoryVector(),\n })\n}\n"],"names":["vectorKeys","user_key","useVectorStatus","query","useQuery","api","invalidateAfter","qc","memoryKeys","useTriggerVectorBackfill","useQueryClient","invalidate","useMutation","vars","useTriggerVectorDownload","useTriggerVectorClear","useTriggerVectorTest"],"mappings":"0GA0BO,MAAMA,EAAa,CACxB,IAAQ,CAAC,SAAU,QAAQ,EAC3B,OAASC,GAAsB,CAAC,SAAU,SAAU,SAAUA,GAAY,IAAI,CAChF,EAEO,SAASC,EAAgBC,EAA+B,GAAI,CACjE,OAAOC,EAAuB,CAC5B,SAAUJ,EAAW,OAAOG,EAAM,QAAQ,EAC1C,QAAS,IAAME,EAAI,sBAAsBF,CAAK,EAC9C,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAEA,SAASG,EAAgBC,EAAmD,CAC1E,MAAO,IAAM,CACXA,EAAG,kBAAkB,CAAE,SAAUP,EAAW,IAAK,EACjDO,EAAG,kBAAkB,CAAE,SAAUC,EAAW,IAAK,CACnD,CACF,CAEO,SAASC,GAA2B,CACzC,MAAMF,EAAKG,EAAA,EACLC,EAAaL,EAAgBC,CAAE,EACrC,OAAOK,EAIL,CACA,WAAaC,GAASR,EAAI,qBACxB,CAAE,SAAUQ,GAAM,QAAA,EAClBA,GAAM,SAAW,CAAE,SAAUA,EAAK,UAAa,MAAA,EAEjD,UAAWF,CAAA,CACZ,CACH,CAEO,SAASG,GAA2B,CACzC,MAAMP,EAAKG,EAAA,EACX,OAAOE,EAA+C,CACpD,WAAY,IAAMP,EAAI,qBAAA,EACtB,UAAWC,EAAgBC,CAAE,CAAA,CAC9B,CACH,CAEO,SAASQ,GAAwB,CACtC,MAAMR,EAAKG,EAAA,EACX,OAAOE,EAA2E,CAChF,WAAaC,GAASR,EAAI,kBAAkB,CAAE,SAAUQ,GAAM,SAAU,EACxE,UAAWP,EAAgBC,CAAE,CAAA,CAC9B,CACH,CAEO,SAASS,GAAuB,CACrC,OAAOJ,EAA6C,CAClD,WAAY,IAAMP,EAAI,iBAAA,CAAiB,CACxC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as a,s as u,t as i,v as o}from"./index-DCfdN5R7.js";const t={all:["workspace"],files:(e,s)=>["workspace","files",e,s]};function c(){return a({queryKey:["agents","status"],queryFn:()=>u.getAgentsStatus()})}function y(e,s,r={}){return a({queryKey:t.files(e,s),queryFn:()=>u.getWorkspaceFiles({agent:e,...s?{path:s}:{}}),enabled:r.enabled!==!1&&!!e})}function f(){const e=i();return o({mutationFn:({agent:s,path:r,body:n})=>u.writeWorkspaceFile({agent:s,path:r},n),onSuccess:()=>e.invalidateQueries({queryKey:t.all})})}export{y as a,f as b,c as u};
|
|
2
|
+
//# sourceMappingURL=use-workspace-CuytyHwb.js.map
|
package/dist/web/public/assets/{use-workspace-BDXP5XO1.js.map → use-workspace-CuytyHwb.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-workspace-
|
|
1
|
+
{"version":3,"file":"use-workspace-CuytyHwb.js","sources":["../../src/hooks/use-workspace.ts"],"sourcesContent":["/**\n * useWorkspace — agent picker source + per-agent file browser +\n * write mutation.\n *\n * useAgentsStatus() — populate the picker\n * useWorkspaceFiles(agent, path) — dir listing or file\n * content (discriminated\n * by `type`)\n * useWriteWorkspaceFile() — PUT a file\n *\n * Both reads stay cached at the default 30s staleTime; the write\n * invalidates so the saved size/mtime re-paint immediately.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n WorkspaceFilesResponse,\n WriteWorkspaceFileBody,\n WriteWorkspaceFileResponse,\n} from '@/types/api'\n\nexport const workspaceKeys = {\n all: ['workspace'] as const,\n files: (agent: string, path: string) =>\n ['workspace', 'files', agent, path] as const,\n}\n\nexport function useAgentsStatus() {\n return useQuery<Record<string, boolean>>({\n queryKey: ['agents', 'status'],\n queryFn: () => api.getAgentsStatus(),\n })\n}\n\nexport function useWorkspaceFiles(\n agent: string,\n path: string,\n opts: { enabled?: boolean } = {},\n) {\n return useQuery<WorkspaceFilesResponse>({\n queryKey: workspaceKeys.files(agent, path),\n queryFn: () => api.getWorkspaceFiles({ agent, ...(path ? { path } : {}) }),\n enabled: opts.enabled !== false && Boolean(agent),\n })\n}\n\nexport function useInvalidateWorkspace() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: workspaceKeys.all })\n}\n\nexport function useWriteWorkspaceFile() {\n const qc = useQueryClient()\n return useMutation<\n WriteWorkspaceFileResponse,\n Error,\n { agent: string; path: string; body: WriteWorkspaceFileBody }\n >({\n mutationFn: ({ agent, path, body }) =>\n api.writeWorkspaceFile({ agent, path }, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: workspaceKeys.all }),\n })\n}\n"],"names":["workspaceKeys","agent","path","useAgentsStatus","useQuery","api","useWorkspaceFiles","opts","useWriteWorkspaceFile","qc","useQueryClient","useMutation","body"],"mappings":"6DAsBO,MAAMA,EAAgB,CAC3B,IAAO,CAAC,WAAW,EACnB,MAAO,CAACC,EAAeC,IACrB,CAAC,YAAa,QAASD,EAAOC,CAAI,CACtC,EAEO,SAASC,GAAkB,CAChC,OAAOC,EAAkC,CACvC,SAAU,CAAC,SAAU,QAAQ,EAC7B,QAAS,IAAMC,EAAI,gBAAA,CAAgB,CACpC,CACH,CAEO,SAASC,EACdL,EACAC,EACAK,EAA8B,CAAA,EAC9B,CACA,OAAOH,EAAiC,CACtC,SAAUJ,EAAc,MAAMC,EAAOC,CAAI,EACzC,QAAS,IAAMG,EAAI,kBAAkB,CAAE,MAAAJ,EAAO,GAAIC,EAAO,CAAE,KAAAA,GAAS,CAAA,EAAK,EACzE,QAASK,EAAK,UAAY,IAAS,EAAQN,CAAK,CACjD,CACH,CAOO,SAASO,GAAwB,CACtC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAIL,CACA,WAAY,CAAC,CAAE,MAAAV,EAAO,KAAAC,EAAM,KAAAU,CAAA,IAC1BP,EAAI,mBAAmB,CAAE,MAAAJ,EAAO,KAAAC,CAAA,EAAQU,CAAI,EAC9C,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUT,EAAc,IAAK,CAAA,CACtE,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as L,j as e,d as A,e as p,k as D,l as G,m as F,n as W,o as B,I as j,p as c,q as y,w as H,i as q,f as z}from"./index-DCfdN5R7.js";import{r as g}from"./react-DlP5eolq.js";import{b as Q,c as X}from"./use-settings-DGIjmUX0.js";import{a as P,u as Z,b as J,c as $,d as ee}from"./use-vector-BYOFwjU0.js";import{L as N}from"./loader-circle-DDdmcH0k.js";import{S as se}from"./save-BDOtZrfp.js";import{E as te,a as ae}from"./eye-BfPyNFzk.js";import{C as re}from"./confirm-dialog-BDb0NLny.js";import{E as oe}from"./empty-state-CuiqdZiB.js";import{C as Y}from"./circle-x-CqFMzO-x.js";import{R as ie}from"./refresh-ccw-DlAd-eTQ.js";import{P as V}from"./play-DX5wp4WH.js";import{D as ne}from"./download-CVZnHcwj.js";import{T as ce}from"./trash-2-D2x2UPuZ.js";import{C as le}from"./circle-check-big-DBg2BD6o.js";import"./use-memory-CXDwKCco.js";const m={backend:"off",localModel:"Xenova/bge-base-zh-v1.5",openaiBaseUrl:"https://api.openai.com/v1",openaiModel:"text-embedding-3-small",openaiApiKey:"",batchSize:"32",hybridWeight:"0.5"};function de(s){const t=(s.AGIM_MEMORY_VECTOR_BACKEND||"").toLowerCase();return{backend:t==="local"||t==="openai"?t:"off",localModel:s.AGIM_MEMORY_VECTOR_LOCAL_MODEL||"",openaiBaseUrl:s.AGIM_MEMORY_VECTOR_OPENAI_BASE_URL||"",openaiModel:s.AGIM_MEMORY_VECTOR_OPENAI_MODEL||"",openaiApiKey:"",batchSize:s.AGIM_MEMORY_VECTOR_BATCH_SIZE||"",hybridWeight:s.AGIM_MEMORY_VECTOR_HYBRID_WEIGHT||""}}function me({onSaved:s}){const{t}=L(["memory","common"]),n=Q({reveal:!1}),l=g.useMemo(()=>n.data?.env??{},[n.data?.env]),[r,f]=g.useState(m),[M,E]=g.useState(!1),u=g.useRef(m);g.useEffect(()=>{if(!n.data)return;const a=de(l);f(a),u.current=a},[l,n.data]);const b=X(),_=P(),C=g.useMemo(()=>{const a=u.current;return Object.keys(r).some(d=>r[d]!==a[d])},[r]);function h(a,d){f(o=>({...o,[a]:d}))}function R(a){f(d=>{const o={...d,backend:a};return a==="local"&&!o.localModel.trim()&&(o.localModel=m.localModel),a==="openai"&&(o.openaiBaseUrl.trim()||(o.openaiBaseUrl=m.openaiBaseUrl),o.openaiModel.trim()||(o.openaiModel=m.openaiModel)),a!=="off"&&(o.batchSize.trim()||(o.batchSize=m.batchSize),o.hybridWeight.trim()||(o.hybridWeight=m.hybridWeight)),o})}function k(){if(r.backend==="openai"){if(!r.openaiBaseUrl.trim())return t("vector.form.errors.baseUrlRequired");try{new URL(r.openaiBaseUrl.trim())}catch{return t("vector.form.errors.baseUrlInvalid")}if(!r.openaiModel.trim())return t("vector.form.errors.openaiModelRequired");if(!!!l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY&&!r.openaiApiKey.trim())return t("vector.form.errors.apiKeyRequired")}if(r.backend==="local"&&!r.localModel.trim())return t("vector.form.errors.localModelRequired");if(r.batchSize.trim()){const a=Number(r.batchSize);if(!Number.isFinite(a)||a<1||a>1024)return t("vector.form.errors.batchSizeRange")}if(r.hybridWeight.trim()){const a=Number(r.hybridWeight);if(!Number.isFinite(a)||a<0||a>1)return t("vector.form.errors.hybridWeightRange")}return null}function S(){const a=u.current,d={},o=(w,T,U)=>{T!==U&&(d[w]=T.trim()===""?null:T.trim())};return o("AGIM_MEMORY_VECTOR_BACKEND",r.backend,a.backend),o("AGIM_MEMORY_VECTOR_LOCAL_MODEL",r.localModel,a.localModel),o("AGIM_MEMORY_VECTOR_OPENAI_BASE_URL",r.openaiBaseUrl,a.openaiBaseUrl),o("AGIM_MEMORY_VECTOR_OPENAI_MODEL",r.openaiModel,a.openaiModel),o("AGIM_MEMORY_VECTOR_BATCH_SIZE",r.batchSize,a.batchSize),o("AGIM_MEMORY_VECTOR_HYBRID_WEIGHT",r.hybridWeight,a.hybridWeight),r.openaiApiKey.trim()&&(d.AGIM_MEMORY_VECTOR_OPENAI_API_KEY=r.openaiApiKey.trim()),d}async function I(){const a=k();if(a){c.error(a);return}const d=S();if(Object.keys(d).length===0){c.info(t("vector.form.nothingChanged"));return}try{await b.mutateAsync({updates:d}),c.success(t("vector.form.savedToast"));try{const o=await _.mutateAsync();o.ok?c.success(t("vector.actions.testOk")):c.error(t("vector.actions.testFail",{detail:o.error??""}))}catch(o){const{message:w}=y(o,t);c.error(t("vector.actions.testFail",{detail:w}))}s?.()}catch(o){const{message:w}=y(o,t);c.error(w)}}function O(){f(u.current)}const i=b.isPending||_.isPending,x=!!l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY;return e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-medium",children:t("vector.form.title")}),C&&e.jsx(A,{variant:"info",children:t("vector.form.dirty")}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[C&&e.jsx(p,{type:"button",variant:"secondary",size:"sm",onClick:O,disabled:i,children:t("vector.form.discard")}),e.jsxs(p,{type:"button",size:"sm",onClick:()=>void I(),disabled:!C||i,children:[i?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(se,{className:"h-4 w-4"}),t("vector.form.saveAndTest")]})]})]}),e.jsx("p",{className:"mt-1 text-xs text-text-dim",children:t("vector.form.hint")}),n.isLoading?e.jsx("div",{className:"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(v,{label:t("vector.form.backend"),help:t("vector.form.backendHelp"),children:e.jsxs(D,{value:r.backend,onValueChange:a=>R(a),children:[e.jsx(G,{children:e.jsx(F,{})}),e.jsxs(W,{children:[e.jsx(B,{value:"off",children:t("vector.form.backendOff")}),e.jsx(B,{value:"local",children:t("vector.form.backendLocal")}),e.jsx(B,{value:"openai",children:t("vector.form.backendOpenai")})]})]})}),r.backend==="local"&&e.jsx(v,{label:t("vector.form.localModel"),help:t("vector.form.localModelHelp"),children:e.jsx(j,{value:r.localModel,placeholder:m.localModel,onChange:a=>h("localModel",a.target.value),className:"font-mono text-xs"})}),r.backend==="openai"&&e.jsxs(e.Fragment,{children:[e.jsx(v,{label:t("vector.form.openaiBaseUrl"),help:t("vector.form.openaiBaseUrlHelp"),children:e.jsx(j,{value:r.openaiBaseUrl,placeholder:m.openaiBaseUrl,onChange:a=>h("openaiBaseUrl",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.openaiModel"),help:t("vector.form.openaiModelHelp"),children:e.jsx(j,{value:r.openaiModel,placeholder:m.openaiModel,onChange:a=>h("openaiModel",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.openaiApiKey"),help:t(x?"vector.form.apiKeyKeepHint":"vector.form.apiKeyNewHint"),children:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(j,{type:M?"text":"password",value:r.openaiApiKey,placeholder:x?l.AGIM_MEMORY_VECTOR_OPENAI_API_KEY||"••••":"sk-…",onChange:a=>h("openaiApiKey",a.target.value),className:"font-mono text-xs",autoComplete:"off"}),e.jsx(p,{type:"button",variant:"ghost",size:"icon",onClick:()=>E(a=>!a),"aria-label":t("vector.form.toggleApiKey"),children:M?e.jsx(te,{className:"h-4 w-4"}):e.jsx(ae,{className:"h-4 w-4"})})]})})]}),r.backend!=="off"&&e.jsxs(e.Fragment,{children:[e.jsx(v,{label:t("vector.form.batchSize"),help:t("vector.form.batchSizeHelp"),children:e.jsx(j,{type:"number",min:1,max:1024,step:1,value:r.batchSize,placeholder:m.batchSize,onChange:a=>h("batchSize",a.target.value),className:"font-mono text-xs"})}),e.jsx(v,{label:t("vector.form.hybridWeight"),help:t("vector.form.hybridWeightHelp"),children:e.jsx(j,{type:"number",min:0,max:1,step:.05,value:r.hybridWeight,placeholder:m.hybridWeight,onChange:a=>h("hybridWeight",a.target.value),className:"font-mono text-xs"})})]})]})]})}function v({label:s,help:t,children:n}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(H,{className:"text-xs text-text-dim",children:s}),n,t&&e.jsx("p",{className:"text-[11px] text-text-muted",children:t})]})}function ke(){const{t:s}=L(["memory","common"]),[t]=q(),n=t.get("user")??"",l=Z(n?{user_key:n}:{}),r=l.data?.status,f=l.data?.coverage,M=l.data?.jobs??[],E=P(),u=J(),b=$(),_=ee(),[C,h]=g.useState(!1);async function R(){try{const i=await E.mutateAsync();i.ok?c.success(s("vector.actions.testOk")):c.error(s("vector.actions.testFail",{detail:i.error??""}))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function k(){try{const i=await u.mutateAsync();c.success(i.alreadyReady?s("vector.actions.downloadAlreadyReady"):s("vector.actions.downloadStarted"))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function S(){try{await b.mutateAsync(n?{user_key:n}:void 0),c.success(s("vector.actions.backfillStarted"))}catch(i){const{message:x}=y(i,s);c.error(x)}}async function I(){try{const i=await _.mutateAsync(n?{user_key:n}:void 0);c.success(s("vector.actions.clearStarted",{count:i.cleared}))}catch(i){const{message:x}=y(i,s);throw c.error(x),i}}if(l.isLoading)return e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"});if(!r)return e.jsx(oe,{icon:e.jsx(Y,{}),title:s("common:states.error"),description:l.error?.message??""});const O=n?s("vector.coverage.scope_user",{userKey:n}):s("vector.coverage.scope_global");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.jsx("h1",{className:"text-xl font-semibold",children:s("vector.title")}),e.jsxs(p,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>l.refetch(),disabled:l.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[l.isFetching?e.jsx(N,{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("vector.subtitle")})]}),e.jsx(me,{onSaved:()=>void l.refetch()}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:s("vector.backendLabel")}),e.jsx(A,{variant:"secondary",children:r.backend}),e.jsx(A,{variant:r.ready?"success":"warning",children:r.ready?s("vector.readyTrue"):s("vector.readyFalse")}),r.downloaded&&e.jsx(A,{variant:"info",children:s("vector.downloadedTrue")})]}),e.jsxs("dl",{className:"mt-3 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm",children:[e.jsx("dt",{className:"text-text-dim",children:s("vector.modelLabel")}),e.jsx("dd",{className:"font-mono text-text",children:r.modelId||"—"}),e.jsx("dt",{className:"text-text-dim",children:s("vector.dimsLabel")}),e.jsx("dd",{className:"tabular-nums text-text",children:r.dims||"—"}),r.lastError&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:s("vector.lastError")}),e.jsx("dd",{className:"text-danger text-xs break-all",children:r.lastError})]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.coverage.title")}),e.jsx("div",{className:"mt-1 text-xs text-text-dim",children:O}),e.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-2",children:[e.jsx(K,{label:s("vector.coverage.total"),value:f?.total??0,tone:"info"}),e.jsx(K,{label:s("vector.coverage.withEmbedding"),value:f?.withEmbedding??0,tone:"success"}),e.jsx(K,{label:s("vector.coverage.withDifferentModel"),value:f?.withDifferentModel??0,tone:"warning"})]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.actions.title")}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(p,{variant:"secondary",size:"sm",onClick:()=>void R(),disabled:E.isPending,children:[E.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),s("vector.actions.test")]}),r.backend==="local"&&e.jsxs(p,{variant:"secondary",size:"sm",onClick:()=>void k(),disabled:u.isPending,children:[u.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(ne,{className:"h-4 w-4"}),s("vector.actions.download")]}),e.jsxs(p,{variant:"default",size:"sm",onClick:()=>void S(),disabled:b.isPending||!r.ready,children:[b.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),s("vector.actions.backfill")]}),e.jsxs(p,{variant:"destructive",size:"sm",onClick:()=>h(!0),disabled:_.isPending,children:[e.jsx(ce,{className:"h-4 w-4"}),s("vector.actions.clear")]})]})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface p-3",children:[e.jsx("div",{className:"text-sm font-medium",children:s("vector.jobs.title")}),M.length===0?e.jsx("div",{className:"mt-2 text-sm text-text-muted",children:s("vector.jobs.empty")}):e.jsx("ul",{className:"mt-2 flex flex-col gap-1.5 text-sm",children:M.map(i=>e.jsx("li",{children:e.jsx(he,{job:i})},i.id))})]}),e.jsx(re,{open:C,onOpenChange:h,title:s("vector.actions.confirmClear"),description:s("vector.actions.confirmClearDesc",{scope:O}),intent:"danger",confirmLabel:s("vector.actions.clear"),onConfirm:I})]})}const xe={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 K({label:s,value:t,tone:n}){return e.jsxs("div",{className:z("rounded-md border bg-bg px-2 py-2",xe[n]),children:[e.jsx("div",{className:"text-[10px] uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:t})]})}function he({job:s}){const{t}=L("memory"),n=s.phase==="done"?"text-success":s.phase==="failed"?"text-danger":"text-info";return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:[e.jsx(A,{variant:"outline",children:s.kind}),e.jsxs("span",{className:z("font-medium",n),children:[s.phase==="running"&&e.jsx(N,{className:"inline h-3 w-3 animate-spin"}),s.phase==="done"&&e.jsx(le,{className:"inline h-3 w-3"}),s.phase==="failed"&&e.jsx(Y,{className:"inline h-3 w-3"})," ",t(`vector.jobs.phase.${s.phase}`)]}),e.jsx("span",{className:"text-text-dim",children:s.message}),e.jsx("span",{className:"ml-auto text-text-muted tabular-nums",children:fe(s.finishedAt??s.startedAt)})]})}function fe(s){try{const t=new Date(s);return Number.isNaN(t.getTime())?String(s):t.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{ke as default};
|
|
2
|
+
//# sourceMappingURL=vector-CL8ezpSR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-CL8ezpSR.js","sources":["../../src/routes/memory/vector-backend-form.tsx","../../src/routes/memory/vector.tsx"],"sourcesContent":["/**\n * VectorBackendForm — inline, form-based editor for the seven\n * AGIM_MEMORY_VECTOR_* keys that drive the embedding backend.\n *\n * Replaces the older \"Edit in env\" link path: operators no longer\n * have to know which env var maps to which knob, and the on-the-wire\n * format (numbers, OpenAI URL shape) is enforced by the widget.\n *\n * Save flow: PUT /api/env (backend-side allowlist filters to just\n * these keys), then auto-trigger a single `vector/test` so the user\n * sees in toast whether the new config produces an embedding.\n *\n * API key: the GET /api/env response returns secrets masked (e.g.\n * \"sk-1***...abcd\"). The widget shows the mask as placeholder and\n * leaves the input empty by default — typing a value sends it as a\n * real update, leaving it empty sends nothing for that key (the\n * server already rejects masked echoes as \"no change\").\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Eye, EyeOff, Loader2, Save } from 'lucide-react'\n\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 { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { useTriggerVectorTest } from '@/hooks/use-vector'\nimport { describeError } from '@/lib/api/errors'\n\ntype BackendName = 'off' | 'local' | 'openai'\n\ninterface FormState {\n backend: BackendName\n localModel: string\n openaiBaseUrl: string\n openaiModel: string\n openaiApiKey: string // empty = \"keep existing\"\n batchSize: string\n hybridWeight: string\n}\n\nconst DEFAULTS: FormState = {\n backend: 'off',\n localModel: 'Xenova/bge-base-zh-v1.5',\n openaiBaseUrl: 'https://api.openai.com/v1',\n openaiModel: 'text-embedding-3-small',\n openaiApiKey: '',\n batchSize: '32',\n hybridWeight: '0.5',\n}\n\nfunction readFormFromEnv(env: Record<string, string>): FormState {\n const raw = (env.AGIM_MEMORY_VECTOR_BACKEND || '').toLowerCase()\n const backend: BackendName = raw === 'local' || raw === 'openai' ? raw : 'off'\n return {\n backend,\n localModel: env.AGIM_MEMORY_VECTOR_LOCAL_MODEL || '',\n openaiBaseUrl: env.AGIM_MEMORY_VECTOR_OPENAI_BASE_URL || '',\n openaiModel: env.AGIM_MEMORY_VECTOR_OPENAI_MODEL || '',\n openaiApiKey: '',\n batchSize: env.AGIM_MEMORY_VECTOR_BATCH_SIZE || '',\n hybridWeight: env.AGIM_MEMORY_VECTOR_HYBRID_WEIGHT || '',\n }\n}\n\nexport interface VectorBackendFormProps {\n /** Called after a successful save + test cycle so the parent page can\n * refresh status + coverage. */\n onSaved?: () => void\n}\n\nexport function VectorBackendForm({ onSaved }: VectorBackendFormProps): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n\n // Pull masked env (we never need real key on the client; the masked\n // value is shown as placeholder so the operator can tell a value is\n // configured without revealing it).\n const envQuery = useEnv({ reveal: false })\n const env = useMemo(() => envQuery.data?.env ?? {}, [envQuery.data?.env])\n\n const [form, setForm] = useState<FormState>(DEFAULTS)\n const [showApiKey, setShowApiKey] = useState(false)\n const initialRef = useRef<FormState>(DEFAULTS)\n\n // Reset from server only when the underlying env object identity\n // changes (after refetch). useEffect avoids stomping on local edits\n // mid-typing.\n useEffect(() => {\n if (!envQuery.data) return\n const next = readFormFromEnv(env)\n setForm(next)\n initialRef.current = next\n }, [env, envQuery.data])\n\n const updateEnv = useUpdateEnv()\n const test = useTriggerVectorTest()\n\n const dirty = useMemo(() => {\n const initial = initialRef.current\n return (Object.keys(form) as Array<keyof FormState>).some((k) => form[k] !== initial[k])\n }, [form])\n\n function set<K extends keyof FormState>(k: K, v: FormState[K]): void {\n setForm((prev) => ({ ...prev, [k]: v }))\n }\n\n // v1.2.75 — when the operator switches backend off→local / off→openai\n // and the per-backend fields are still empty, auto-prefill defaults so\n // they don't have to look up the BGE model id by hand. They can still\n // edit afterwards. Also fills shared numeric knobs (batch / weight)\n // since those have well-known sensible defaults too.\n function selectBackend(next: BackendName): void {\n setForm((prev) => {\n const out = { ...prev, backend: next }\n if (next === 'local' && !out.localModel.trim()) {\n out.localModel = DEFAULTS.localModel\n }\n if (next === 'openai') {\n if (!out.openaiBaseUrl.trim()) out.openaiBaseUrl = DEFAULTS.openaiBaseUrl\n if (!out.openaiModel.trim()) out.openaiModel = DEFAULTS.openaiModel\n }\n if (next !== 'off') {\n if (!out.batchSize.trim()) out.batchSize = DEFAULTS.batchSize\n if (!out.hybridWeight.trim()) out.hybridWeight = DEFAULTS.hybridWeight\n }\n return out\n })\n }\n\n function validate(): string | null {\n if (form.backend === 'openai') {\n if (!form.openaiBaseUrl.trim()) return t('vector.form.errors.baseUrlRequired')\n try { new URL(form.openaiBaseUrl.trim()) } catch { return t('vector.form.errors.baseUrlInvalid') }\n if (!form.openaiModel.trim()) return t('vector.form.errors.openaiModelRequired')\n const hasExistingKey = !!env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY\n if (!hasExistingKey && !form.openaiApiKey.trim()) {\n return t('vector.form.errors.apiKeyRequired')\n }\n }\n if (form.backend === 'local' && !form.localModel.trim()) {\n return t('vector.form.errors.localModelRequired')\n }\n if (form.batchSize.trim()) {\n const n = Number(form.batchSize)\n if (!Number.isFinite(n) || n < 1 || n > 1024) return t('vector.form.errors.batchSizeRange')\n }\n if (form.hybridWeight.trim()) {\n const n = Number(form.hybridWeight)\n if (!Number.isFinite(n) || n < 0 || n > 1) return t('vector.form.errors.hybridWeightRange')\n }\n return null\n }\n\n function buildUpdates(): Record<string, string | null> {\n const initial = initialRef.current\n const out: Record<string, string | null> = {}\n const diff = (key: string, current: string, prev: string): void => {\n if (current === prev) return\n out[key] = current.trim() === '' ? null : current.trim()\n }\n diff('AGIM_MEMORY_VECTOR_BACKEND', form.backend, initial.backend)\n diff('AGIM_MEMORY_VECTOR_LOCAL_MODEL', form.localModel, initial.localModel)\n diff('AGIM_MEMORY_VECTOR_OPENAI_BASE_URL', form.openaiBaseUrl, initial.openaiBaseUrl)\n diff('AGIM_MEMORY_VECTOR_OPENAI_MODEL', form.openaiModel, initial.openaiModel)\n diff('AGIM_MEMORY_VECTOR_BATCH_SIZE', form.batchSize, initial.batchSize)\n diff('AGIM_MEMORY_VECTOR_HYBRID_WEIGHT', form.hybridWeight, initial.hybridWeight)\n // API key: only send if the user actually typed a non-empty new value.\n // Empty input = keep current (which is the whole point of the placeholder UX).\n if (form.openaiApiKey.trim()) {\n out.AGIM_MEMORY_VECTOR_OPENAI_API_KEY = form.openaiApiKey.trim()\n }\n return out\n }\n\n async function onSave(): Promise<void> {\n const err = validate()\n if (err) {\n toast.error(err)\n return\n }\n const updates = buildUpdates()\n if (Object.keys(updates).length === 0) {\n toast.info(t('vector.form.nothingChanged'))\n return\n }\n try {\n await updateEnv.mutateAsync({ updates })\n toast.success(t('vector.form.savedToast'))\n // Auto-test against the freshly applied config. We don't await\n // the parent's refresh — the toast is the source of truth for the\n // operator; the status card behind it picks up dims / lastError\n // on its next 3s poll anyway.\n try {\n const r = await test.mutateAsync()\n if (r.ok) toast.success(t('vector.actions.testOk'))\n else toast.error(t('vector.actions.testFail', { detail: r.error ?? '' }))\n } catch (terr) {\n const { message } = describeError(terr, t)\n toast.error(t('vector.actions.testFail', { detail: message }))\n }\n onSaved?.()\n } catch (serr) {\n const { message } = describeError(serr, t)\n toast.error(message)\n }\n }\n\n function onDiscard(): void {\n setForm(initialRef.current)\n }\n\n const busy = updateEnv.isPending || test.isPending\n const hasExistingKey = !!env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY\n\n return (\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-medium\">{t('vector.form.title')}</h2>\n {dirty && <Badge variant=\"info\">{t('vector.form.dirty')}</Badge>}\n <div className=\"ml-auto flex items-center gap-2\">\n {dirty && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={onDiscard}\n disabled={busy}\n >\n {t('vector.form.discard')}\n </Button>\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={!dirty || busy}\n >\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Save className=\"h-4 w-4\" />}\n {t('vector.form.saveAndTest')}\n </Button>\n </div>\n </div>\n <p className=\"mt-1 text-xs text-text-dim\">{t('vector.form.hint')}</p>\n\n {envQuery.isLoading ? (\n <div className=\"mt-3 h-32 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {/* Backend selector — full row on mobile, half on desktop */}\n <Field label={t('vector.form.backend')} help={t('vector.form.backendHelp')}>\n <Select value={form.backend} onValueChange={(v) => selectBackend(v as BackendName)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"off\">{t('vector.form.backendOff')}</SelectItem>\n <SelectItem value=\"local\">{t('vector.form.backendLocal')}</SelectItem>\n <SelectItem value=\"openai\">{t('vector.form.backendOpenai')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {/* Local-only field */}\n {form.backend === 'local' && (\n <Field label={t('vector.form.localModel')} help={t('vector.form.localModelHelp')}>\n <Input\n value={form.localModel}\n placeholder={DEFAULTS.localModel}\n onChange={(e) => set('localModel', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n )}\n\n {/* OpenAI-only fields */}\n {form.backend === 'openai' && (\n <>\n <Field label={t('vector.form.openaiBaseUrl')} help={t('vector.form.openaiBaseUrlHelp')}>\n <Input\n value={form.openaiBaseUrl}\n placeholder={DEFAULTS.openaiBaseUrl}\n onChange={(e) => set('openaiBaseUrl', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('vector.form.openaiModel')} help={t('vector.form.openaiModelHelp')}>\n <Input\n value={form.openaiModel}\n placeholder={DEFAULTS.openaiModel}\n onChange={(e) => set('openaiModel', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field\n label={t('vector.form.openaiApiKey')}\n help={hasExistingKey ? t('vector.form.apiKeyKeepHint') : t('vector.form.apiKeyNewHint')}\n >\n <div className=\"flex items-center gap-1\">\n <Input\n type={showApiKey ? 'text' : 'password'}\n value={form.openaiApiKey}\n placeholder={hasExistingKey\n ? (env.AGIM_MEMORY_VECTOR_OPENAI_API_KEY || '••••')\n : 'sk-…'}\n onChange={(e) => set('openaiApiKey', e.target.value)}\n className=\"font-mono text-xs\"\n autoComplete=\"off\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setShowApiKey((v) => !v)}\n aria-label={t('vector.form.toggleApiKey')}\n >\n {showApiKey ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n </Button>\n </div>\n </Field>\n </>\n )}\n\n {/* Shared numeric knobs (hidden when off so they don't visually\n suggest the operator can tune anything without picking a\n backend first). */}\n {form.backend !== 'off' && (\n <>\n <Field label={t('vector.form.batchSize')} help={t('vector.form.batchSizeHelp')}>\n <Input\n type=\"number\"\n min={1}\n max={1024}\n step={1}\n value={form.batchSize}\n placeholder={DEFAULTS.batchSize}\n onChange={(e) => set('batchSize', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('vector.form.hybridWeight')} help={t('vector.form.hybridWeightHelp')}>\n <Input\n type=\"number\"\n min={0}\n max={1}\n step={0.05}\n value={form.hybridWeight}\n placeholder={DEFAULTS.hybridWeight}\n onChange={(e) => set('hybridWeight', e.target.value)}\n className=\"font-mono text-xs\"\n />\n </Field>\n </>\n )}\n </div>\n )}\n </div>\n )\n}\n\nfunction Field({\n label,\n help,\n children,\n}: {\n label: string\n help?: string\n children: React.ReactNode\n}): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs text-text-dim\">{label}</Label>\n {children}\n {help && <p className=\"text-[11px] text-text-muted\">{help}</p>}\n </div>\n )\n}\n","/**\n * /memory/vector — backend status + maintenance actions.\n *\n * Status (left): backend name + ready badge + model + dims + last\n * error. Coverage (right): three KPI tiles (total / embedded /\n * mismatched). Actions (bottom): test, download, backfill, clear\n * (destructive — ConfirmDialog). Recent-job strip pulls from the\n * shared in-memory tracker via the status endpoint.\n *\n * The clear action picks up the ?user= filter from the layout, so\n * clearing scoped to a single user is a one-click operation.\n */\n\nimport { useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle, Download, Loader2, Play, RefreshCcw, Trash2, XCircle } from 'lucide-react'\n\nimport { VectorBackendForm } from './vector-backend-form'\n\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n useVectorStatus,\n useTriggerVectorBackfill,\n useTriggerVectorClear,\n useTriggerVectorDownload,\n useTriggerVectorTest,\n} from '@/hooks/use-vector'\nimport { describeError } from '@/lib/api/errors'\nimport type { VectorJob } from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function MemoryVectorRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params] = useSearchParams()\n const userKey = params.get('user') ?? ''\n\n const statusQuery = useVectorStatus(userKey ? { user_key: userKey } : {})\n const status = statusQuery.data?.status\n const coverage = statusQuery.data?.coverage\n const jobs = statusQuery.data?.jobs ?? []\n\n const test = useTriggerVectorTest()\n const download = useTriggerVectorDownload()\n const backfill = useTriggerVectorBackfill()\n const clear = useTriggerVectorClear()\n const [confirmClear, setConfirmClear] = useState(false)\n\n async function onTest(): Promise<void> {\n try {\n const r = await test.mutateAsync()\n if (r.ok) toast.success(t('vector.actions.testOk'))\n else toast.error(t('vector.actions.testFail', { detail: r.error ?? '' }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onDownload(): Promise<void> {\n try {\n const r = await download.mutateAsync()\n toast.success(r.alreadyReady ? t('vector.actions.downloadAlreadyReady') : t('vector.actions.downloadStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onBackfill(): Promise<void> {\n try {\n await backfill.mutateAsync(userKey ? { user_key: userKey } : undefined)\n toast.success(t('vector.actions.backfillStarted'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n async function onConfirmClear(): Promise<void> {\n try {\n const r = await clear.mutateAsync(userKey ? { user_key: userKey } : undefined)\n toast.success(t('vector.actions.clearStarted', { count: r.cleared }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n if (statusQuery.isLoading) {\n return <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n }\n if (!status) {\n return (\n <EmptyState\n icon={<XCircle />}\n title={t('common:states.error')}\n description={statusQuery.error?.message ?? ''}\n />\n )\n }\n\n const coverageScope = userKey\n ? t('vector.coverage.scope_user', { userKey })\n : t('vector.coverage.scope_global')\n\n return (\n <div className=\"mx-auto flex max-w-5xl 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('vector.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => statusQuery.refetch()}\n disabled={statusQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {statusQuery.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('vector.subtitle')}</p>\n </header>\n\n {/* Backend configuration — inline form replaces the older\n \"Edit in env\" link. Saving runs PUT /api/env + an auto\n vector test against the freshly applied config. */}\n <VectorBackendForm onSaved={() => void statusQuery.refetch()} />\n\n {/* Status + Coverage */}\n <div className=\"grid gap-3 md:grid-cols-2\">\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <span className=\"font-medium\">{t('vector.backendLabel')}</span>\n <Badge variant=\"secondary\">{status.backend}</Badge>\n <Badge variant={status.ready ? 'success' : 'warning'}>\n {status.ready ? t('vector.readyTrue') : t('vector.readyFalse')}\n </Badge>\n {status.downloaded && <Badge variant=\"info\">{t('vector.downloadedTrue')}</Badge>}\n </div>\n <dl className=\"mt-3 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm\">\n <dt className=\"text-text-dim\">{t('vector.modelLabel')}</dt>\n <dd className=\"font-mono text-text\">{status.modelId || '—'}</dd>\n <dt className=\"text-text-dim\">{t('vector.dimsLabel')}</dt>\n <dd className=\"tabular-nums text-text\">{status.dims || '—'}</dd>\n {status.lastError && (\n <>\n <dt className=\"text-text-dim\">{t('vector.lastError')}</dt>\n <dd className=\"text-danger text-xs break-all\">{status.lastError}</dd>\n </>\n )}\n </dl>\n </div>\n\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.coverage.title')}</div>\n <div className=\"mt-1 text-xs text-text-dim\">{coverageScope}</div>\n <div className=\"mt-3 grid grid-cols-3 gap-2\">\n <CoverageTile label={t('vector.coverage.total')} value={coverage?.total ?? 0} tone=\"info\" />\n <CoverageTile label={t('vector.coverage.withEmbedding')} value={coverage?.withEmbedding ?? 0} tone=\"success\" />\n <CoverageTile label={t('vector.coverage.withDifferentModel')} value={coverage?.withDifferentModel ?? 0} tone=\"warning\" />\n </div>\n </div>\n </div>\n\n {/* Maintenance actions */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.actions.title')}</div>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onTest()}\n disabled={test.isPending}\n >\n {test.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('vector.actions.test')}\n </Button>\n {status.backend === 'local' && (\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => void onDownload()}\n disabled={download.isPending}\n >\n {download.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Download className=\"h-4 w-4\" />}\n {t('vector.actions.download')}\n </Button>\n )}\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={() => void onBackfill()}\n disabled={backfill.isPending || !status.ready}\n >\n {backfill.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"h-4 w-4\" />}\n {t('vector.actions.backfill')}\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmClear(true)}\n disabled={clear.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('vector.actions.clear')}\n </Button>\n </div>\n </div>\n\n {/* Jobs strip */}\n <div className=\"rounded-md border border-border bg-surface p-3\">\n <div className=\"text-sm font-medium\">{t('vector.jobs.title')}</div>\n {jobs.length === 0 ? (\n <div className=\"mt-2 text-sm text-text-muted\">{t('vector.jobs.empty')}</div>\n ) : (\n <ul className=\"mt-2 flex flex-col gap-1.5 text-sm\">\n {jobs.map((j) => <li key={j.id}><JobRow job={j} /></li>)}\n </ul>\n )}\n </div>\n\n <ConfirmDialog\n open={confirmClear}\n onOpenChange={setConfirmClear}\n title={t('vector.actions.confirmClear')}\n description={t('vector.actions.confirmClearDesc', { scope: coverageScope })}\n intent=\"danger\"\n confirmLabel={t('vector.actions.clear')}\n onConfirm={onConfirmClear}\n />\n </div>\n )\n}\n\ninterface CoverageTileProps {\n label: string\n value: number\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<CoverageTileProps['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 CoverageTile({ label, value, tone }: CoverageTileProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-bg px-2 py-2', TONE_STYLES[tone])}>\n <div className=\"text-[10px] uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\nfunction JobRow({ job }: { job: VectorJob }): JSX.Element {\n const { t } = useTranslation('memory')\n const phaseClass =\n job.phase === 'done' ? 'text-success' :\n job.phase === 'failed' ? 'text-danger' :\n 'text-info'\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs\">\n <Badge variant=\"outline\">{job.kind}</Badge>\n <span className={cn('font-medium', phaseClass)}>\n {job.phase === 'running' && <Loader2 className=\"inline h-3 w-3 animate-spin\" />}\n {job.phase === 'done' && <CheckCircle className=\"inline h-3 w-3\" />}\n {job.phase === 'failed' && <XCircle className=\"inline h-3 w-3\" />}\n {' '}\n {t(`vector.jobs.phase.${job.phase}`)}\n </span>\n <span className=\"text-text-dim\">{job.message}</span>\n <span className=\"ml-auto text-text-muted tabular-nums\">{formatEpoch(job.finishedAt ?? job.startedAt)}</span>\n </div>\n )\n}\n\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":["DEFAULTS","readFormFromEnv","env","raw","VectorBackendForm","onSaved","useTranslation","envQuery","useEnv","useMemo","form","setForm","useState","showApiKey","setShowApiKey","initialRef","useRef","useEffect","next","updateEnv","useUpdateEnv","test","useTriggerVectorTest","dirty","initial","k","set","v","prev","selectBackend","out","validate","n","buildUpdates","diff","key","current","onSave","err","toast","updates","r","terr","message","describeError","serr","onDiscard","busy","hasExistingKey","jsxs","jsx","Badge","Button","Loader2","Save","Field","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","e","Fragment","EyeOff","Eye","label","help","children","Label","MemoryVectorRoute","t","params","useSearchParams","userKey","statusQuery","useVectorStatus","status","coverage","jobs","download","useTriggerVectorDownload","backfill","useTriggerVectorBackfill","clear","useTriggerVectorClear","confirmClear","setConfirmClear","onTest","onDownload","onBackfill","onConfirmClear","EmptyState","XCircle","coverageScope","RefreshCcw","CoverageTile","Play","Download","Trash2","j","JobRow","ConfirmDialog","TONE_STYLES","value","tone","cn","job","phaseClass","CheckCircle","formatEpoch","ms","d"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{h as W,u as R,j as e,e as h,d as f,I as y,k as O,l as T,m as B,n as F,o as k,f as C,C as H,X as D,w as V,p as g,q as M}from"./index-DCfdN5R7.js";import{r as m}from"./react-DlP5eolq.js";import{b as z,c as G,j as q}from"./use-settings-DGIjmUX0.js";import{E as K,a as X}from"./eye-BfPyNFzk.js";import{L as N}from"./loader-circle-DDdmcH0k.js";import{R as P}from"./refresh-ccw-DlAd-eTQ.js";import{F as J}from"./file-text-BxfdLM0-.js";import{E as Q}from"./external-link-1WPpVvdu.js";import{S as U}from"./save-BDOtZrfp.js";import{M as Y}from"./map-pin-C_jAxukI.js";/**
|
|
2
|
+
* @license lucide-react v0.469.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Z=W("Earth",[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);function xe(){const{t:i}=R(["settings","common"]),[s,r]=m.useState(!1),a=z({reveal:s});return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-6",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:i("viewerSettings.title")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>r(t=>!t),disabled:a.isFetching,"aria-label":i(s?"viewerSettings.hide":"viewerSettings.reveal"),children:[s?e.jsx(K,{className:"h-4 w-4"}):e.jsx(X,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:i(s?"viewerSettings.hide":"viewerSettings.reveal")})]}),e.jsxs(h,{variant:"ghost",size:"sm",onClick:()=>void a.refetch(),disabled:a.isFetching,"aria-label":i("actions.refresh",{ns:"common"}),children:[a.isFetching?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:i("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:i("viewerSettings.subtitle")})]}),a.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx($,{env:a.data?.env??{}}),e.jsx(ee,{env:a.data?.env??{}})]})]})}function A(i){return{enabled:i.AGIM_VIEWER_ENABLED==="1"||i.AGIM_VIEWER_ENABLED?.toLowerCase()==="true",publicUrl:i.AGIM_VIEWER_PUBLIC_BASE_URL??"",tunnelMode:i.AGIM_VIEWER_TUNNEL_MODE==="quick"?"quick":"off",noDefaultRemote:i.AGIM_VIEWER_NO_DEFAULT_REMOTE==="1"||i.AGIM_VIEWER_NO_DEFAULT_REMOTE?.toLowerCase()==="true",chars:i.AGIM_VIEWER_CHARS??"",lines:i.AGIM_VIEWER_LINES??"",codeLines:i.AGIM_VIEWER_CODE_LINES??"",maxPastes:i.AGIM_VIEWER_MAX_PASTES??""}}function $({env:i}){const{t:s}=R(["settings","common"]),r=G(),a=q(),[t,d]=m.useState(()=>A(i)),[w,S]=m.useState("");m.useEffect(()=>{const n=A(i),x=JSON.stringify(n);x!==w&&(d(n),S(x))},[i.AGIM_VIEWER_ENABLED,i.AGIM_VIEWER_PUBLIC_BASE_URL,i.AGIM_VIEWER_TUNNEL_MODE,i.AGIM_VIEWER_CHARS,i.AGIM_VIEWER_LINES,i.AGIM_VIEWER_CODE_LINES,i.AGIM_VIEWER_MAX_PASTES,i.AGIM_VIEWER_NO_DEFAULT_REMOTE]);const c=m.useMemo(()=>A(i),[i]),b=m.useMemo(()=>JSON.stringify(t)!==JSON.stringify(c),[t,c]);function o(n,x){d(j=>({...j,[n]:x}))}async function _(){const n={};if(t.enabled!==c.enabled&&(n.AGIM_VIEWER_ENABLED=t.enabled?"1":"0"),t.publicUrl!==c.publicUrl&&(n.AGIM_VIEWER_PUBLIC_BASE_URL=t.publicUrl.trim()||null),t.tunnelMode!==c.tunnelMode&&(n.AGIM_VIEWER_TUNNEL_MODE=t.tunnelMode),t.chars!==c.chars&&(n.AGIM_VIEWER_CHARS=t.chars.trim()||null),t.lines!==c.lines&&(n.AGIM_VIEWER_LINES=t.lines.trim()||null),t.codeLines!==c.codeLines&&(n.AGIM_VIEWER_CODE_LINES=t.codeLines.trim()||null),t.maxPastes!==c.maxPastes&&(n.AGIM_VIEWER_MAX_PASTES=t.maxPastes.trim()||null),t.noDefaultRemote!==c.noDefaultRemote&&(n.AGIM_VIEWER_NO_DEFAULT_REMOTE=t.noDefaultRemote?"1":null),Object.keys(n).length!==0)try{await r.mutateAsync({updates:n}),g.success(s("viewerSettings.toast.saved"))}catch(x){g.error(M(x,s).message)}}function I(){d(c)}const l=a.data,L=l?.effectivePublicUrl;return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx(J,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("viewerSettings.viewer.title")}),t.enabled?e.jsx(f,{variant:"success",children:s("viewerSettings.viewer.on")}):e.jsx(f,{variant:"outline",children:s("viewerSettings.viewer.off")})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("viewerSettings.viewer.subtitle")}),e.jsx("div",{className:"flex items-center gap-3 px-4 py-3",children:e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:t.enabled,onChange:n=>{const x=n.target.checked;d(j=>({...j,enabled:x,noDefaultRemote:x?j.noDefaultRemote:!1}))},className:"h-4 w-4 accent-accent cursor-pointer"}),e.jsx("span",{className:"font-medium",children:s("viewerSettings.viewer.enableLabel")})]})}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 px-4 pb-3 sm:grid-cols-2",children:[e.jsx(u,{label:s("viewerSettings.viewer.publicUrl"),hint:s("viewerSettings.viewer.publicUrlHint"),children:e.jsx(y,{value:t.publicUrl,onChange:n=>o("publicUrl",n.target.value),placeholder:"https://agim.example.com",className:"font-mono text-xs"})}),e.jsx(u,{label:s("viewerSettings.viewer.tunnelMode"),hint:s("viewerSettings.viewer.tunnelHint"),children:e.jsxs(O,{value:t.tunnelMode,onValueChange:n=>o("tunnelMode",n),children:[e.jsx(T,{children:e.jsx(B,{})}),e.jsxs(F,{children:[e.jsx(k,{value:"off",children:s("viewerSettings.viewer.tunnelOff")}),e.jsx(k,{value:"quick",children:s("viewerSettings.viewer.tunnelQuick")})]})]})}),e.jsx(u,{label:s("viewerSettings.viewer.noDefaultRemote"),hint:s("viewerSettings.viewer.noDefaultRemoteHint"),children:e.jsxs("label",{className:C("inline-flex items-center gap-2 text-xs",!t.enabled&&"opacity-50 cursor-not-allowed"),children:[e.jsx("input",{type:"checkbox",checked:t.noDefaultRemote,disabled:!t.enabled,onChange:n=>o("noDefaultRemote",n.target.checked),className:"h-4 w-4 accent-accent cursor-pointer disabled:cursor-not-allowed"}),e.jsx("span",{children:s("viewerSettings.viewer.noDefaultRemoteLabel")})]})})]}),t.tunnelMode==="quick"&&e.jsxs("div",{className:"mx-4 mb-3 rounded-md border border-border bg-surface-2 p-3",children:[e.jsxs("div",{className:"mb-1 flex items-center gap-2",children:[e.jsx(Z,{className:"h-4 w-4 text-text-dim"}),e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-text-dim",children:s("viewerSettings.viewer.tunnelStatus")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void a.refetch(),disabled:a.isFetching,"aria-label":s("viewerSettings.viewer.refreshTunnel"),children:[a.isFetching?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("viewerSettings.viewer.refreshTunnel")})]})]}),l?e.jsxs("div",{className:"flex flex-col gap-1 text-xs",children:[e.jsx(p,{label:s("viewerSettings.viewer.tunnelRunning"),children:l.tunnel.running?e.jsxs("span",{className:"inline-flex items-center gap-1 text-success",children:[e.jsx(H,{className:"h-3 w-3"}),s("viewerSettings.viewer.yes")]}):e.jsx("span",{className:"text-text-dim",children:s("viewerSettings.viewer.no")})}),e.jsx(p,{label:s("viewerSettings.viewer.tunnelUrl"),children:l.tunnel.url?e.jsxs("a",{href:l.tunnel.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 break-all font-mono text-info hover:underline",children:[l.tunnel.url,e.jsx(Q,{className:"h-3 w-3 shrink-0"})]}):e.jsx("span",{className:"text-text-muted",children:"—"})}),e.jsx(p,{label:s("viewerSettings.viewer.effectiveUrl"),children:L?e.jsx("span",{className:"break-all font-mono text-text",children:L}):e.jsx("span",{className:"text-text-muted",children:"—"})}),e.jsx(p,{label:s("viewerSettings.viewer.binary"),children:l.tunnel.binaryFound?e.jsx("span",{className:"font-mono text-text",children:l.tunnel.binaryPath}):e.jsx("span",{className:"text-warning",children:s("viewerSettings.viewer.binaryMissing")})}),l.tunnel.lastError&&e.jsx(p,{label:s("viewerSettings.viewer.lastError"),children:e.jsx("span",{className:"break-words text-danger",children:l.tunnel.lastError})})]}):e.jsx("p",{className:"text-xs text-text-dim",children:s("viewerSettings.viewer.tunnelLoading")})]}),e.jsx("h3",{className:"border-t border-border px-4 pt-3 text-xs font-semibold uppercase tracking-wide text-text-dim",children:s("viewerSettings.viewer.thresholds")}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 px-4 py-3 sm:grid-cols-4",children:[e.jsx(u,{label:s("viewerSettings.viewer.chars"),hint:s("viewerSettings.viewer.charsHint"),children:e.jsx(E,{value:t.chars,onChange:n=>o("chars",n),min:100,max:1e4,placeholder:"500"})}),e.jsx(u,{label:s("viewerSettings.viewer.lines"),hint:s("viewerSettings.viewer.linesHint"),children:e.jsx(E,{value:t.lines,onChange:n=>o("lines",n),min:5,max:200,placeholder:"12"})}),e.jsx(u,{label:s("viewerSettings.viewer.codeLines"),hint:s("viewerSettings.viewer.codeLinesHint"),children:e.jsx(E,{value:t.codeLines,onChange:n=>o("codeLines",n),min:5,max:200,placeholder:"10"})}),e.jsx(u,{label:s("viewerSettings.viewer.maxPastes"),hint:s("viewerSettings.viewer.maxPastesHint"),children:e.jsx(E,{value:t.maxPastes,onChange:n=>o("maxPastes",n),min:100,max:1e6,placeholder:"10000"})})]}),b&&e.jsxs("div",{className:"flex items-center gap-2 border-t border-border px-4 py-3",children:[e.jsx(f,{variant:"info",children:s("viewerSettings.dirtyHint")}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:I,disabled:r.isPending,children:[e.jsx(D,{className:"h-4 w-4"}),s("viewerSettings.discard")]}),e.jsxs(h,{size:"sm",onClick:()=>void _(),disabled:r.isPending,children:[r.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),r.isPending?s("viewerSettings.saving"):s("viewerSettings.save")]})]})]})}function v(i){return/\*{3,}/.test(i)}function ee({env:i}){const{t:s}=R(["settings","common"]),r=G(),a=i.AGIM_BAIDU_MAP_AK??"",[t,d]=m.useState(a),[w,S]=m.useState("");m.useEffect(()=>{a!==w&&(d(a),S(a))},[a,w]);const c=!!a,b=t!==a&&!(v(t)&&t===a),o=t.length>0&&!v(t)&&t.length!==32;async function _(){if(b&&!v(t))try{await r.mutateAsync({updates:{AGIM_BAIDU_MAP_AK:t.trim()||null}}),g.success(s("viewerSettings.baidu.toast.saved"))}catch(l){g.error(M(l,s).message)}}async function I(){try{await r.mutateAsync({updates:{AGIM_BAIDU_MAP_AK:null}}),d(""),g.success(s("viewerSettings.baidu.toast.cleared"))}catch(l){g.error(M(l,s).message)}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx(Y,{className:"h-4 w-4 text-text-dim"}),e.jsx("h2",{className:"text-sm font-semibold",children:s("viewerSettings.baidu.title")}),c?e.jsx(f,{variant:"success",children:s("viewerSettings.baidu.configured")}):e.jsx(f,{variant:"outline",children:s("viewerSettings.baidu.empty")})]}),e.jsx("p",{className:"px-4 pt-2 text-xs text-text-dim",children:s("viewerSettings.baidu.subtitle")}),e.jsxs("div",{className:"px-4 py-3",children:[e.jsx(V,{htmlFor:"baidu-ak",className:"text-xs font-medium",children:"AGIM_BAIDU_MAP_AK"}),e.jsx(y,{id:"baidu-ak",value:t,onChange:l=>d(l.target.value),placeholder:s("viewerSettings.baidu.placeholder"),autoComplete:"off",className:C("mt-1 font-mono text-xs",v(t)&&"text-text-muted")}),o&&e.jsx("p",{className:"mt-1 text-[11px] text-warning",children:s("viewerSettings.baidu.suspicious",{length:t.length})}),e.jsx("p",{className:"mt-1 text-[11px] text-text-dim",children:s("viewerSettings.baidu.hint")})]}),e.jsxs("div",{className:"flex items-center gap-2 border-t border-border px-4 py-3",children:[e.jsxs(h,{variant:"ghost",size:"sm",onClick:()=>void I(),disabled:!c||r.isPending,className:"text-danger hover:text-danger",children:[e.jsx(D,{className:"h-4 w-4"}),s("viewerSettings.baidu.clear")]}),e.jsx("span",{className:"ml-auto"}),b&&e.jsxs(h,{size:"sm",onClick:()=>void _(),disabled:r.isPending||v(t),children:[r.isPending?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),r.isPending?s("viewerSettings.saving"):s("viewerSettings.save")]})]})]})}function u({label:i,hint:s,children:r}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(V,{className:"text-xs font-medium",children:i}),r,s&&e.jsx("p",{className:"text-[11px] text-text-dim",children:s})]})}function p({label:i,children:s}){return e.jsxs("div",{className:"flex flex-wrap items-baseline gap-2",children:[e.jsxs("span",{className:"shrink-0 font-medium text-text-dim",children:[i,":"]}),e.jsx("span",{className:"min-w-0 flex-1",children:s})]})}function E({value:i,onChange:s,min:r,max:a,placeholder:t}){return e.jsx(y,{type:"number",inputMode:"numeric",min:r,max:a,value:i,onChange:d=>s(d.target.value),placeholder:t})}export{xe as default};
|
|
7
|
+
//# sourceMappingURL=viewer-CD0iEfPU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer-CD0iEfPU.js","sources":["../../node_modules/lucide-react/dist/esm/icons/earth.js","../../src/routes/settings/viewer.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 Earth = createLucideIcon(\"Earth\", [\n [\"path\", { d: \"M21.54 15H17a2 2 0 0 0-2 2v4.54\", key: \"1djwo0\" }],\n [\n \"path\",\n {\n d: \"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17\",\n key: \"1tzkfa\"\n }\n ],\n [\"path\", { d: \"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05\", key: \"14pb5j\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]\n]);\n\nexport { Earth as default };\n//# sourceMappingURL=earth.js.map\n","/**\n * /settings/viewer — long-message Viewer card + Baidu Maps AK card.\n *\n * Both cards are env-driven (~/.agim/.env), each with its own dirty /\n * Save / Discard state so a change to one doesn't force re-save of the\n * other. The Viewer card additionally surfaces cloudflared tunnel\n * status via `GET /api/viewer/tunnel`, with a manual Refresh button\n * since tunnel state is essentially static between operator actions.\n *\n * Env keys covered:\n * * Viewer: AGIM_VIEWER_ENABLED / _PUBLIC_BASE_URL / _TUNNEL_MODE /\n * _CHARS / _LINES / _CODE_LINES / _MAX_PASTES\n * * Baidu: AGIM_BAIDU_MAP_AK (in SECRET_KEYS — masked unless\n * reveal=1 is passed)\n *\n * AK validation: v1 mentioned \"32-char AK starting with non-digit\" as\n * a hint, but isn't strictly enforced (Baidu has refreshed AK formats\n * over the years). We surface a `pattern-looks-suspicious` warning\n * rather than blocking save.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n CheckCircle2, Eye, EyeOff, ExternalLink, FileText, Globe2, Loader2,\n MapPin, RefreshCcw, Save, X,\n} from 'lucide-react'\n\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 { useEnv, useUpdateEnv, useViewerTunnel } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\n/* ─────────────── Page wrapper ─────────────── */\n\nexport default function SettingsViewerRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const [reveal, setReveal] = useState(false)\n const envQuery = useEnv({ reveal })\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-6\">\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('viewerSettings.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => setReveal((v) => !v)}\n disabled={envQuery.isFetching}\n aria-label={reveal ? t('viewerSettings.hide') : t('viewerSettings.reveal')}\n >\n {reveal ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">\n {reveal ? t('viewerSettings.hide') : t('viewerSettings.reveal')}\n </span>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <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('viewerSettings.subtitle')}</p>\n </header>\n\n {envQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <ViewerCard env={envQuery.data?.env ?? {}} />\n <BaiduCard env={envQuery.data?.env ?? {}} />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Viewer card ─────────────── */\n\ninterface ViewerDraft {\n enabled: boolean\n publicUrl: string\n tunnelMode: 'off' | 'quick'\n // v1.2.45 — remote-paste URL/Token are env-only advanced knobs.\n // Only the opt-out toggle stays in the UI.\n noDefaultRemote: boolean\n chars: string\n lines: string\n codeLines: string\n maxPastes: string\n}\n\nfunction viewerDraftFromEnv(env: Record<string, string>): ViewerDraft {\n return {\n enabled: env.AGIM_VIEWER_ENABLED === '1' || env.AGIM_VIEWER_ENABLED?.toLowerCase() === 'true',\n publicUrl: env.AGIM_VIEWER_PUBLIC_BASE_URL ?? '',\n tunnelMode: env.AGIM_VIEWER_TUNNEL_MODE === 'quick' ? 'quick' : 'off',\n noDefaultRemote: env.AGIM_VIEWER_NO_DEFAULT_REMOTE === '1' || env.AGIM_VIEWER_NO_DEFAULT_REMOTE?.toLowerCase() === 'true',\n chars: env.AGIM_VIEWER_CHARS ?? '',\n lines: env.AGIM_VIEWER_LINES ?? '',\n codeLines: env.AGIM_VIEWER_CODE_LINES ?? '',\n maxPastes: env.AGIM_VIEWER_MAX_PASTES ?? '',\n }\n}\n\nfunction ViewerCard({ env }: { env: Record<string, string> }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const updateEnv = useUpdateEnv()\n const tunnelQuery = useViewerTunnel()\n\n const [draft, setDraft] = useState<ViewerDraft>(() => viewerDraftFromEnv(env))\n const [syncedHash, setSyncedHash] = useState('')\n\n // Sync draft when env changes (initial load + post-save refetch).\n useEffect(() => {\n const next = viewerDraftFromEnv(env)\n const hash = JSON.stringify(next)\n if (hash !== syncedHash) {\n setDraft(next)\n setSyncedHash(hash)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [env.AGIM_VIEWER_ENABLED, env.AGIM_VIEWER_PUBLIC_BASE_URL,\n env.AGIM_VIEWER_TUNNEL_MODE, env.AGIM_VIEWER_CHARS,\n env.AGIM_VIEWER_LINES, env.AGIM_VIEWER_CODE_LINES,\n env.AGIM_VIEWER_MAX_PASTES, env.AGIM_VIEWER_NO_DEFAULT_REMOTE])\n\n const current = useMemo(() => viewerDraftFromEnv(env), [env])\n const isDirty = useMemo(\n () => JSON.stringify(draft) !== JSON.stringify(current),\n [draft, current],\n )\n\n function setField<K extends keyof ViewerDraft>(k: K, v: ViewerDraft[K]): void {\n setDraft((d) => ({ ...d, [k]: v }))\n }\n\n async function onSave(): Promise<void> {\n const updates: Record<string, string | null> = {}\n if (draft.enabled !== current.enabled) {\n updates.AGIM_VIEWER_ENABLED = draft.enabled ? '1' : '0'\n }\n if (draft.publicUrl !== current.publicUrl) {\n updates.AGIM_VIEWER_PUBLIC_BASE_URL = draft.publicUrl.trim() || null\n }\n if (draft.tunnelMode !== current.tunnelMode) {\n updates.AGIM_VIEWER_TUNNEL_MODE = draft.tunnelMode\n }\n if (draft.chars !== current.chars) {\n updates.AGIM_VIEWER_CHARS = draft.chars.trim() || null\n }\n if (draft.lines !== current.lines) {\n updates.AGIM_VIEWER_LINES = draft.lines.trim() || null\n }\n if (draft.codeLines !== current.codeLines) {\n updates.AGIM_VIEWER_CODE_LINES = draft.codeLines.trim() || null\n }\n if (draft.maxPastes !== current.maxPastes) {\n updates.AGIM_VIEWER_MAX_PASTES = draft.maxPastes.trim() || null\n }\n if (draft.noDefaultRemote !== current.noDefaultRemote) {\n updates.AGIM_VIEWER_NO_DEFAULT_REMOTE = draft.noDefaultRemote ? '1' : null\n }\n if (Object.keys(updates).length === 0) return\n try {\n await updateEnv.mutateAsync({ updates })\n toast.success(t('viewerSettings.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n function onDiscard(): void {\n setDraft(current)\n }\n\n const tunnel = tunnelQuery.data\n const effectivePublicUrl = tunnel?.effectivePublicUrl\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <FileText className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('viewerSettings.viewer.title')}</h2>\n {draft.enabled\n ? <Badge variant=\"success\">{t('viewerSettings.viewer.on')}</Badge>\n : <Badge variant=\"outline\">{t('viewerSettings.viewer.off')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('viewerSettings.viewer.subtitle')}</p>\n\n {/* Enable toggle */}\n <div className=\"flex items-center gap-3 px-4 py-3\">\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={draft.enabled}\n onChange={(e) => {\n const on = e.target.checked\n setDraft((d) => ({\n ...d,\n enabled: on,\n // Opt-out only applies when viewer is on; clear when disabling.\n noDefaultRemote: on ? d.noDefaultRemote : false,\n }))\n }}\n className=\"h-4 w-4 accent-accent cursor-pointer\"\n />\n <span className=\"font-medium\">{t('viewerSettings.viewer.enableLabel')}</span>\n </label>\n </div>\n\n {/* Public URL + tunnel mode */}\n <div className=\"grid grid-cols-1 gap-3 px-4 pb-3 sm:grid-cols-2\">\n <Field label={t('viewerSettings.viewer.publicUrl')} hint={t('viewerSettings.viewer.publicUrlHint')}>\n <Input\n value={draft.publicUrl}\n onChange={(e) => setField('publicUrl', e.target.value)}\n placeholder=\"https://agim.example.com\"\n className=\"font-mono text-xs\"\n />\n </Field>\n <Field label={t('viewerSettings.viewer.tunnelMode')} hint={t('viewerSettings.viewer.tunnelHint')}>\n <Select\n value={draft.tunnelMode}\n onValueChange={(v) => setField('tunnelMode', v as 'off' | 'quick')}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"off\">{t('viewerSettings.viewer.tunnelOff')}</SelectItem>\n <SelectItem value=\"quick\">{t('viewerSettings.viewer.tunnelQuick')}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n\n {/* v1.2.45 — only the opt-out toggle is in the UI. The\n community default endpoint (viewer.iclaw.host) is the\n implicit fallback when neither public base URL nor tunnel\n is set; operators who need to point at a different paste\n server use the AGIM_VIEWER_REMOTE_PASTE_URL env var\n (documented in docs/viewer-modes.md). */}\n <Field\n label={t('viewerSettings.viewer.noDefaultRemote')}\n hint={t('viewerSettings.viewer.noDefaultRemoteHint')}\n >\n <label className={cn(\n 'inline-flex items-center gap-2 text-xs',\n !draft.enabled && 'opacity-50 cursor-not-allowed',\n )}>\n <input\n type=\"checkbox\"\n checked={draft.noDefaultRemote}\n disabled={!draft.enabled}\n onChange={(e) => setField('noDefaultRemote', e.target.checked)}\n className=\"h-4 w-4 accent-accent cursor-pointer disabled:cursor-not-allowed\"\n />\n <span>{t('viewerSettings.viewer.noDefaultRemoteLabel')}</span>\n </label>\n </Field>\n </div>\n\n {/* Tunnel status panel (only when quick mode is selected) */}\n {draft.tunnelMode === 'quick' && (\n <div className=\"mx-4 mb-3 rounded-md border border-border bg-surface-2 p-3\">\n <div className=\"mb-1 flex items-center gap-2\">\n <Globe2 className=\"h-4 w-4 text-text-dim\" />\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-dim\">\n {t('viewerSettings.viewer.tunnelStatus')}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => void tunnelQuery.refetch()}\n disabled={tunnelQuery.isFetching}\n aria-label={t('viewerSettings.viewer.refreshTunnel')}\n >\n {tunnelQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('viewerSettings.viewer.refreshTunnel')}</span>\n </Button>\n </div>\n {tunnel ? (\n <div className=\"flex flex-col gap-1 text-xs\">\n <Row label={t('viewerSettings.viewer.tunnelRunning')}>\n {tunnel.tunnel.running ? (\n <span className=\"inline-flex items-center gap-1 text-success\">\n <CheckCircle2 className=\"h-3 w-3\" />\n {t('viewerSettings.viewer.yes')}\n </span>\n ) : (\n <span className=\"text-text-dim\">{t('viewerSettings.viewer.no')}</span>\n )}\n </Row>\n <Row label={t('viewerSettings.viewer.tunnelUrl')}>\n {tunnel.tunnel.url ? (\n <a\n href={tunnel.tunnel.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 break-all font-mono text-info hover:underline\"\n >\n {tunnel.tunnel.url}\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n </a>\n ) : <span className=\"text-text-muted\">—</span>}\n </Row>\n <Row label={t('viewerSettings.viewer.effectiveUrl')}>\n {effectivePublicUrl ? (\n <span className=\"break-all font-mono text-text\">{effectivePublicUrl}</span>\n ) : <span className=\"text-text-muted\">—</span>}\n </Row>\n <Row label={t('viewerSettings.viewer.binary')}>\n {tunnel.tunnel.binaryFound ? (\n <span className=\"font-mono text-text\">{tunnel.tunnel.binaryPath}</span>\n ) : (\n <span className=\"text-warning\">{t('viewerSettings.viewer.binaryMissing')}</span>\n )}\n </Row>\n {tunnel.tunnel.lastError && (\n <Row label={t('viewerSettings.viewer.lastError')}>\n <span className=\"break-words text-danger\">{tunnel.tunnel.lastError}</span>\n </Row>\n )}\n </div>\n ) : (\n <p className=\"text-xs text-text-dim\">{t('viewerSettings.viewer.tunnelLoading')}</p>\n )}\n </div>\n )}\n\n {/* Thresholds */}\n <h3 className=\"border-t border-border px-4 pt-3 text-xs font-semibold uppercase tracking-wide text-text-dim\">\n {t('viewerSettings.viewer.thresholds')}\n </h3>\n <div className=\"grid grid-cols-2 gap-3 px-4 py-3 sm:grid-cols-4\">\n <Field label={t('viewerSettings.viewer.chars')} hint={t('viewerSettings.viewer.charsHint')}>\n <NumberInput value={draft.chars} onChange={(v) => setField('chars', v)} min={100} max={10000} placeholder=\"500\" />\n </Field>\n <Field label={t('viewerSettings.viewer.lines')} hint={t('viewerSettings.viewer.linesHint')}>\n <NumberInput value={draft.lines} onChange={(v) => setField('lines', v)} min={5} max={200} placeholder=\"12\" />\n </Field>\n <Field label={t('viewerSettings.viewer.codeLines')} hint={t('viewerSettings.viewer.codeLinesHint')}>\n <NumberInput value={draft.codeLines} onChange={(v) => setField('codeLines', v)} min={5} max={200} placeholder=\"10\" />\n </Field>\n <Field label={t('viewerSettings.viewer.maxPastes')} hint={t('viewerSettings.viewer.maxPastesHint')}>\n <NumberInput value={draft.maxPastes} onChange={(v) => setField('maxPastes', v)} min={100} max={1000000} placeholder=\"10000\" />\n </Field>\n </div>\n\n {/* Save bar */}\n {isDirty && (\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Badge variant=\"info\">{t('viewerSettings.dirtyHint')}</Badge>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={onDiscard}\n disabled={updateEnv.isPending}\n >\n <X className=\"h-4 w-4\" />\n {t('viewerSettings.discard')}\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateEnv.isPending ? t('viewerSettings.saving') : t('viewerSettings.save')}\n </Button>\n </div>\n )}\n </section>\n )\n}\n\n/* ─────────────── Baidu Maps card ─────────────── */\n\nfunction isMasked(s: string): boolean {\n return /\\*{3,}/.test(s)\n}\n\nfunction BaiduCard({ env }: { env: Record<string, string> }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const updateEnv = useUpdateEnv()\n\n const currentAk = env.AGIM_BAIDU_MAP_AK ?? ''\n const [draftAk, setDraftAk] = useState(currentAk)\n const [syncedHash, setSyncedHash] = useState('')\n\n useEffect(() => {\n if (currentAk !== syncedHash) {\n setDraftAk(currentAk)\n setSyncedHash(currentAk)\n }\n }, [currentAk, syncedHash])\n\n const isConfigured = !!currentAk\n // Treat masked echo as no-change. Operator either typed something\n // new, or cleared. AK validity = looks-suspicious warning.\n const isDirty = draftAk !== currentAk && !(isMasked(draftAk) && draftAk === currentAk)\n const suspicious = draftAk.length > 0 && !isMasked(draftAk) && draftAk.length !== 32\n\n async function onSave(): Promise<void> {\n if (!isDirty) return\n if (isMasked(draftAk)) return // server would skip anyway; be explicit\n try {\n await updateEnv.mutateAsync({\n updates: { AGIM_BAIDU_MAP_AK: draftAk.trim() || null },\n })\n toast.success(t('viewerSettings.baidu.toast.saved'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n async function onClear(): Promise<void> {\n try {\n await updateEnv.mutateAsync({ updates: { AGIM_BAIDU_MAP_AK: null } })\n setDraftAk('')\n toast.success(t('viewerSettings.baidu.toast.cleared'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <MapPin className=\"h-4 w-4 text-text-dim\" />\n <h2 className=\"text-sm font-semibold\">{t('viewerSettings.baidu.title')}</h2>\n {isConfigured\n ? <Badge variant=\"success\">{t('viewerSettings.baidu.configured')}</Badge>\n : <Badge variant=\"outline\">{t('viewerSettings.baidu.empty')}</Badge>}\n </header>\n <p className=\"px-4 pt-2 text-xs text-text-dim\">{t('viewerSettings.baidu.subtitle')}</p>\n\n <div className=\"px-4 py-3\">\n <Label htmlFor=\"baidu-ak\" className=\"text-xs font-medium\">AGIM_BAIDU_MAP_AK</Label>\n <Input\n id=\"baidu-ak\"\n value={draftAk}\n onChange={(e) => setDraftAk(e.target.value)}\n placeholder={t('viewerSettings.baidu.placeholder')}\n autoComplete=\"off\"\n className={cn('mt-1 font-mono text-xs', isMasked(draftAk) && 'text-text-muted')}\n />\n {suspicious && (\n <p className=\"mt-1 text-[11px] text-warning\">\n {t('viewerSettings.baidu.suspicious', { length: draftAk.length })}\n </p>\n )}\n <p className=\"mt-1 text-[11px] text-text-dim\">{t('viewerSettings.baidu.hint')}</p>\n </div>\n\n <div className=\"flex items-center gap-2 border-t border-border px-4 py-3\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void onClear()}\n disabled={!isConfigured || updateEnv.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <X className=\"h-4 w-4\" />\n {t('viewerSettings.baidu.clear')}\n </Button>\n <span className=\"ml-auto\" />\n {isDirty && (\n <Button\n size=\"sm\"\n onClick={() => void onSave()}\n disabled={updateEnv.isPending || isMasked(draftAk)}\n >\n {updateEnv.isPending\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <Save className=\"h-4 w-4\" />}\n {updateEnv.isPending ? t('viewerSettings.saving') : t('viewerSettings.save')}\n </Button>\n )}\n </div>\n </section>\n )\n}\n\n/* ─────────────── Helpers ─────────────── */\n\ninterface FieldProps {\n label: string\n hint?: string\n children: React.ReactNode\n}\n\nfunction Field({ label, hint, children }: FieldProps): JSX.Element {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{label}</Label>\n {children}\n {hint && <p className=\"text-[11px] text-text-dim\">{hint}</p>}\n </div>\n )\n}\n\ninterface RowProps {\n label: string\n children: React.ReactNode\n}\n\nfunction Row({ label, children }: RowProps): JSX.Element {\n return (\n <div className=\"flex flex-wrap items-baseline gap-2\">\n <span className=\"shrink-0 font-medium text-text-dim\">{label}:</span>\n <span className=\"min-w-0 flex-1\">{children}</span>\n </div>\n )\n}\n\ninterface NumberInputProps {\n value: string\n onChange: (v: string) => void\n min?: number\n max?: number\n placeholder?: string\n}\n\nfunction NumberInput({ value, onChange, min, max, placeholder }: NumberInputProps): JSX.Element {\n return (\n <Input\n type=\"number\"\n inputMode=\"numeric\"\n min={min}\n max={max}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n />\n )\n}\n"],"names":["Earth","createLucideIcon","SettingsViewerRoute","t","useTranslation","reveal","setReveal","useState","envQuery","useEnv","jsxs","jsx","Button","v","EyeOff","Eye","Loader2","RefreshCcw","Fragment","ViewerCard","BaiduCard","viewerDraftFromEnv","env","updateEnv","useUpdateEnv","tunnelQuery","useViewerTunnel","draft","setDraft","syncedHash","setSyncedHash","useEffect","next","hash","current","useMemo","isDirty","setField","k","d","onSave","updates","toast","err","describeError","onDiscard","tunnel","effectivePublicUrl","FileText","Badge","e","on","Field","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","cn","Globe2","Row","CheckCircle2","ExternalLink","NumberInput","X","Save","isMasked","s","currentAk","draftAk","setDraftAk","isConfigured","suspicious","onClear","MapPin","Label","label","hint","children","value","onChange","min","max","placeholder"],"mappings":"qjBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAQC,EAAiB,QAAS,CACtC,CAAC,OAAQ,CAAE,EAAG,kCAAmC,IAAK,QAAQ,CAAE,EAChE,CACE,OACA,CACE,EAAG,uFACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,iEAAkE,IAAK,QAAQ,CAAE,EAC/F,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,QAAQ,CAAE,CAC3D,CAAC,EC0BD,SAAwBC,IAAmC,CACzD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7C,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAK,EACpCC,EAAWC,EAAO,CAAE,OAAAJ,EAAQ,EAElC,OACEK,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,sBAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAR,EAAE,sBAAsB,EAAE,EACjEO,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAMN,EAAWO,GAAM,CAACA,CAAC,EAClC,SAAUL,EAAS,WACnB,aAAqBL,EAATE,EAAW,sBAA2B,uBAAN,EAE3C,SAAA,CAAAA,EAASM,EAAAA,IAACG,GAAO,UAAU,SAAA,CAAU,EAAKH,EAAAA,IAACI,EAAA,CAAI,UAAU,SAAA,CAAU,EACpEJ,EAAAA,IAAC,OAAA,CAAK,UAAU,mBACb,SAASR,EAATE,EAAW,sBAA2B,uBAAN,CAA6B,CAChE,CAAA,CAAA,CAAA,EAEFK,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS,IAAM,KAAKJ,EAAS,QAAA,EAC7B,SAAUA,EAAS,WACnB,aAAYL,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAK,EAAS,iBACLQ,EAAA,CAAQ,UAAU,uBAAuB,EAC1CL,EAAAA,IAACM,EAAA,CAAW,UAAU,SAAA,CAAU,EACpCN,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,SAAAR,EAAE,kBAAmB,CAAE,GAAI,QAAA,CAAU,CAAA,CAAE,CAAA,CAAA,CAAA,CAC7E,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAAA,EAAE,yBAAyB,CAAA,CAAE,CAAA,EACrE,EAECK,EAAS,UACRG,MAAC,OAAI,UAAU,4CAAA,CAA6C,EAE5DD,EAAAA,KAAAQ,EAAAA,SAAA,CACE,SAAA,CAAAP,EAAAA,IAACQ,GAAW,IAAKX,EAAS,MAAM,KAAO,CAAA,EAAI,QAC1CY,GAAA,CAAU,IAAKZ,EAAS,MAAM,KAAO,EAAC,CAAG,CAAA,CAAA,CAC5C,CAAA,EAEJ,CAEJ,CAiBA,SAASa,EAAmBC,EAA0C,CACpE,MAAO,CACL,QAAYA,EAAI,sBAAwB,KAAOA,EAAI,qBAAqB,gBAAkB,OAC1F,UAAYA,EAAI,6BAA+B,GAC/C,WAAYA,EAAI,0BAA4B,QAAU,QAAU,MAChE,gBAAiBA,EAAI,gCAAkC,KAAOA,EAAI,+BAA+B,gBAAkB,OACnH,MAAYA,EAAI,mBAAqB,GACrC,MAAYA,EAAI,mBAAqB,GACrC,UAAYA,EAAI,wBAA0B,GAC1C,UAAYA,EAAI,wBAA0B,EAAA,CAE9C,CAEA,SAASH,EAAW,CAAE,IAAAG,GAAqD,CACzE,KAAM,CAAE,EAAAnB,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7CmB,EAAYC,EAAA,EACZC,EAAcC,EAAA,EAEd,CAACC,EAAOC,CAAQ,EAAIrB,EAAAA,SAAsB,IAAMc,EAAmBC,CAAG,CAAC,EACvE,CAACO,EAAYC,CAAa,EAAIvB,EAAAA,SAAS,EAAE,EAG/CwB,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAOX,EAAmBC,CAAG,EAC7BW,EAAO,KAAK,UAAUD,CAAI,EAC5BC,IAASJ,IACXD,EAASI,CAAI,EACbF,EAAcG,CAAI,EAGtB,EAAG,CAACX,EAAI,oBAAqBA,EAAI,4BAC7BA,EAAI,wBAAyBA,EAAI,kBACjCA,EAAI,kBAAmBA,EAAI,uBAC3BA,EAAI,uBAAwBA,EAAI,6BAAA,CAA8B,EAElE,MAAMY,EAAUC,EAAAA,QAAQ,IAAMd,EAAmBC,CAAG,EAAG,CAACA,CAAG,CAAC,EACtDc,EAAUD,EAAAA,QACd,IAAM,KAAK,UAAUR,CAAK,IAAM,KAAK,UAAUO,CAAO,EACtD,CAACP,EAAOO,CAAO,CAAA,EAGjB,SAASG,EAAsCC,EAAMzB,EAAyB,CAC5Ee,EAAUW,IAAO,CAAE,GAAGA,EAAG,CAACD,CAAC,EAAGzB,CAAA,EAAI,CACpC,CAEA,eAAe2B,GAAwB,CACrC,MAAMC,EAAyC,CAAA,EAyB/C,GAxBId,EAAM,UAAYO,EAAQ,UAC5BO,EAAQ,oBAAsBd,EAAM,QAAU,IAAM,KAElDA,EAAM,YAAcO,EAAQ,YAC9BO,EAAQ,4BAA8Bd,EAAM,UAAU,KAAA,GAAU,MAE9DA,EAAM,aAAeO,EAAQ,aAC/BO,EAAQ,wBAA0Bd,EAAM,YAEtCA,EAAM,QAAUO,EAAQ,QAC1BO,EAAQ,kBAAoBd,EAAM,MAAM,KAAA,GAAU,MAEhDA,EAAM,QAAUO,EAAQ,QAC1BO,EAAQ,kBAAoBd,EAAM,MAAM,KAAA,GAAU,MAEhDA,EAAM,YAAcO,EAAQ,YAC9BO,EAAQ,uBAAyBd,EAAM,UAAU,KAAA,GAAU,MAEzDA,EAAM,YAAcO,EAAQ,YAC9BO,EAAQ,uBAAyBd,EAAM,UAAU,KAAA,GAAU,MAEzDA,EAAM,kBAAoBO,EAAQ,kBACpCO,EAAQ,8BAAgCd,EAAM,gBAAkB,IAAM,MAEpE,OAAO,KAAKc,CAAO,EAAE,SAAW,EACpC,GAAI,CACF,MAAMlB,EAAU,YAAY,CAAE,QAAAkB,EAAS,EACvCC,EAAM,QAAQvC,EAAE,4BAA4B,CAAC,CAC/C,OAASwC,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAKxC,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,SAAS0C,GAAkB,CACzBjB,EAASM,CAAO,CAClB,CAEA,MAAMY,EAASrB,EAAY,KACrBsB,EAAqBD,GAAQ,mBAEnC,OACEpC,EAAAA,KAAC,UAAA,CAAQ,UAAU,6CACjB,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,2DAChB,SAAA,CAAAC,EAAAA,IAACqC,EAAA,CAAS,UAAU,uBAAA,CAAwB,QAC3C,KAAA,CAAG,UAAU,wBAAyB,SAAA7C,EAAE,6BAA6B,EAAE,EACvEwB,EAAM,QACHhB,EAAAA,IAACsC,EAAA,CAAM,QAAQ,UAAW,SAAA9C,EAAE,0BAA0B,CAAA,CAAE,QACvD8C,EAAA,CAAM,QAAQ,UAAW,SAAA9C,EAAE,2BAA2B,CAAA,CAAE,CAAA,EAC/D,QACC,IAAA,CAAE,UAAU,kCAAmC,SAAAA,EAAE,gCAAgC,EAAE,QAGnF,MAAA,CAAI,UAAU,oCACb,SAAAO,EAAAA,KAAC,QAAA,CAAM,UAAU,kCACf,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASgB,EAAM,QACf,SAAWuB,GAAM,CACf,MAAMC,EAAKD,EAAE,OAAO,QACpBtB,EAAUW,IAAO,CACf,GAAGA,EACH,QAASY,EAET,gBAAiBA,EAAKZ,EAAE,gBAAkB,EAAA,EAC1C,CACJ,EACA,UAAU,sCAAA,CAAA,QAEX,OAAA,CAAK,UAAU,cAAe,SAAApC,EAAE,mCAAmC,CAAA,CAAE,CAAA,CAAA,CACxE,CAAA,CACF,EAGAO,EAAAA,KAAC,MAAA,CAAI,UAAU,kDACb,SAAA,CAAAC,EAAAA,IAACyC,EAAA,CAAM,MAAOjD,EAAE,iCAAiC,EAAG,KAAMA,EAAE,qCAAqC,EAC/F,SAAAQ,EAAAA,IAAC0C,EAAA,CACC,MAAO1B,EAAM,UACb,SAAWuB,GAAMb,EAAS,YAAaa,EAAE,OAAO,KAAK,EACrD,YAAY,2BACZ,UAAU,mBAAA,CAAA,EAEd,EACAvC,EAAAA,IAACyC,GAAM,MAAOjD,EAAE,kCAAkC,EAAG,KAAMA,EAAE,kCAAkC,EAC7F,SAAAO,EAAAA,KAAC4C,EAAA,CACC,MAAO3B,EAAM,WACb,cAAgBd,GAAMwB,EAAS,aAAcxB,CAAoB,EAEjE,SAAA,CAAAF,EAAAA,IAAC4C,EAAA,CAAc,SAAA5C,EAAAA,IAAC6C,EAAA,CAAA,CAAY,EAAE,SAC7BC,EAAA,CACC,SAAA,CAAA9C,MAAC+C,EAAA,CAAW,MAAM,MAAO,SAAAvD,EAAE,iCAAiC,EAAE,QAC7DuD,EAAA,CAAW,MAAM,QAAS,SAAAvD,EAAE,mCAAmC,CAAA,CAAE,CAAA,CAAA,CACpE,CAAA,CAAA,CAAA,EAEJ,EAQAQ,EAAAA,IAACyC,EAAA,CACC,MAAOjD,EAAE,uCAAuC,EAChD,KAAMA,EAAE,2CAA2C,EAEnD,SAAAO,EAAAA,KAAC,SAAM,UAAWiD,EAChB,yCACA,CAAChC,EAAM,SAAW,+BAAA,EAElB,SAAA,CAAAhB,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASgB,EAAM,gBACf,SAAU,CAACA,EAAM,QACjB,SAAWuB,GAAMb,EAAS,kBAAmBa,EAAE,OAAO,OAAO,EAC7D,UAAU,kEAAA,CAAA,EAEZvC,EAAAA,IAAC,OAAA,CAAM,SAAAR,EAAE,4CAA4C,CAAA,CAAE,CAAA,CAAA,CACzD,CAAA,CAAA,CACF,EACF,EAGCwB,EAAM,aAAe,SACpBjB,EAAAA,KAAC,MAAA,CAAI,UAAU,6DACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAC,EAAAA,IAACiD,EAAA,CAAO,UAAU,uBAAA,CAAwB,QACzC,OAAA,CAAK,UAAU,4DACb,SAAAzD,EAAE,oCAAoC,EACzC,EACAO,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAM,KAAKa,EAAY,QAAA,EAChC,SAAUA,EAAY,WACtB,aAAYtB,EAAE,qCAAqC,EAElD,SAAA,CAAAsB,EAAY,iBACRT,EAAA,CAAQ,UAAU,uBAAuB,EAC1CL,EAAAA,IAACM,EAAA,CAAW,UAAU,SAAA,CAAU,QACnC,OAAA,CAAK,UAAU,mBAAoB,SAAAd,EAAE,qCAAqC,CAAA,CAAE,CAAA,CAAA,CAAA,CAC/E,EACF,EACC2C,EACCpC,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAC,EAAAA,IAACkD,EAAA,CAAI,MAAO1D,EAAE,qCAAqC,EAChD,SAAA2C,EAAO,OAAO,QACbpC,EAAAA,KAAC,OAAA,CAAK,UAAU,8CACd,SAAA,CAAAC,EAAAA,IAACmD,EAAA,CAAa,UAAU,SAAA,CAAU,EACjC3D,EAAE,2BAA2B,CAAA,CAAA,CAChC,QAEC,OAAA,CAAK,UAAU,gBAAiB,SAAAA,EAAE,0BAA0B,EAAE,CAAA,CAEnE,EACAQ,EAAAA,IAACkD,GAAI,MAAO1D,EAAE,iCAAiC,EAC5C,SAAA2C,EAAO,OAAO,IACbpC,EAAAA,KAAC,IAAA,CACC,KAAMoC,EAAO,OAAO,IACpB,OAAO,SACP,IAAI,sBACJ,UAAU,+EAET,SAAA,CAAAA,EAAO,OAAO,IACfnC,EAAAA,IAACoD,EAAA,CAAa,UAAU,kBAAA,CAAmB,CAAA,CAAA,CAAA,EAE3CpD,EAAAA,IAAC,OAAA,CAAK,UAAU,kBAAkB,aAAC,EACzC,QACCkD,EAAA,CAAI,MAAO1D,EAAE,oCAAoC,EAC/C,WACCQ,MAAC,OAAA,CAAK,UAAU,gCAAiC,WAAmB,EAClEA,EAAAA,IAAC,QAAK,UAAU,kBAAkB,aAAC,CAAA,CACzC,EACAA,EAAAA,IAACkD,EAAA,CAAI,MAAO1D,EAAE,8BAA8B,EACzC,SAAA2C,EAAO,OAAO,YACbnC,EAAAA,IAAC,OAAA,CAAK,UAAU,sBAAuB,SAAAmC,EAAO,OAAO,UAAA,CAAW,EAEhEnC,EAAAA,IAAC,OAAA,CAAK,UAAU,eAAgB,SAAAR,EAAE,qCAAqC,CAAA,CAAE,CAAA,CAE7E,EACC2C,EAAO,OAAO,WACbnC,EAAAA,IAACkD,EAAA,CAAI,MAAO1D,EAAE,iCAAiC,EAC7C,SAAAQ,EAAAA,IAAC,QAAK,UAAU,0BAA2B,SAAAmC,EAAO,OAAO,UAAU,CAAA,CACrE,CAAA,EAEJ,EAEAnC,MAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAR,EAAE,qCAAqC,CAAA,CAAE,CAAA,EAEnF,QAID,KAAA,CAAG,UAAU,+FACX,SAAAA,EAAE,kCAAkC,EACvC,EACAO,EAAAA,KAAC,MAAA,CAAI,UAAU,kDACb,SAAA,CAAAC,EAAAA,IAACyC,EAAA,CAAM,MAAOjD,EAAE,6BAA6B,EAAG,KAAMA,EAAE,iCAAiC,EACvF,SAAAQ,EAAAA,IAACqD,EAAA,CAAY,MAAOrC,EAAM,MAAO,SAAWd,GAAMwB,EAAS,QAASxB,CAAC,EAAG,IAAK,IAAK,IAAK,IAAO,YAAY,KAAA,CAAM,CAAA,CAClH,EACAF,EAAAA,IAACyC,EAAA,CAAM,MAAOjD,EAAE,6BAA6B,EAAG,KAAMA,EAAE,iCAAiC,EACvF,SAAAQ,EAAAA,IAACqD,EAAA,CAAY,MAAOrC,EAAM,MAAO,SAAWd,GAAMwB,EAAS,QAASxB,CAAC,EAAG,IAAK,EAAG,IAAK,IAAK,YAAY,IAAA,CAAK,CAAA,CAC7G,EACAF,EAAAA,IAACyC,EAAA,CAAM,MAAOjD,EAAE,iCAAiC,EAAG,KAAMA,EAAE,qCAAqC,EAC/F,SAAAQ,EAAAA,IAACqD,EAAA,CAAY,MAAOrC,EAAM,UAAW,SAAWd,GAAMwB,EAAS,YAAaxB,CAAC,EAAG,IAAK,EAAG,IAAK,IAAK,YAAY,IAAA,CAAK,CAAA,CACrH,EACAF,EAAAA,IAACyC,EAAA,CAAM,MAAOjD,EAAE,iCAAiC,EAAG,KAAMA,EAAE,qCAAqC,EAC/F,SAAAQ,EAAAA,IAACqD,EAAA,CAAY,MAAOrC,EAAM,UAAW,SAAWd,GAAMwB,EAAS,YAAaxB,CAAC,EAAG,IAAK,IAAK,IAAK,IAAS,YAAY,OAAA,CAAQ,CAAA,CAC9H,CAAA,EACF,EAGCuB,GACC1B,EAAAA,KAAC,MAAA,CAAI,UAAU,2DACb,SAAA,CAAAC,MAACsC,EAAA,CAAM,QAAQ,OAAQ,SAAA9C,EAAE,0BAA0B,EAAE,EACrDO,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAASiC,EACT,SAAUtB,EAAU,UAEpB,SAAA,CAAAZ,EAAAA,IAACsD,EAAA,CAAE,UAAU,SAAA,CAAU,EACtB9D,EAAE,wBAAwB,CAAA,CAAA,CAAA,EAE7BO,EAAAA,KAACE,EAAA,CACC,KAAK,KACL,QAAS,IAAM,KAAK4B,EAAA,EACpB,SAAUjB,EAAU,UAEnB,SAAA,CAAAA,EAAU,gBACNP,EAAA,CAAQ,UAAU,uBAAuB,EAC1CL,EAAAA,IAACuD,EAAA,CAAK,UAAU,SAAA,CAAU,EAC7B3C,EAAU,UAAYpB,EAAE,uBAAuB,EAAIA,EAAE,qBAAqB,CAAA,CAAA,CAAA,CAC7E,CAAA,CACF,CAAA,EAEJ,CAEJ,CAIA,SAASgE,EAASC,EAAoB,CACpC,MAAO,SAAS,KAAKA,CAAC,CACxB,CAEA,SAAShD,GAAU,CAAE,IAAAE,GAAqD,CACxE,KAAM,CAAE,EAAAnB,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7CmB,EAAYC,EAAA,EAEZ6C,EAAY/C,EAAI,mBAAqB,GACrC,CAACgD,EAASC,CAAU,EAAIhE,EAAAA,SAAS8D,CAAS,EAC1C,CAACxC,EAAYC,CAAa,EAAIvB,EAAAA,SAAS,EAAE,EAE/CwB,EAAAA,UAAU,IAAM,CACVsC,IAAcxC,IAChB0C,EAAWF,CAAS,EACpBvC,EAAcuC,CAAS,EAE3B,EAAG,CAACA,EAAWxC,CAAU,CAAC,EAE1B,MAAM2C,EAAe,CAAC,CAACH,EAGjBjC,EAAUkC,IAAYD,GAAa,EAAEF,EAASG,CAAO,GAAKA,IAAYD,GACtEI,EAAaH,EAAQ,OAAS,GAAK,CAACH,EAASG,CAAO,GAAKA,EAAQ,SAAW,GAElF,eAAe9B,GAAwB,CACrC,GAAKJ,GACD,CAAA+B,EAASG,CAAO,EACpB,GAAI,CACF,MAAM/C,EAAU,YAAY,CAC1B,QAAS,CAAE,kBAAmB+C,EAAQ,KAAA,GAAU,IAAA,CAAK,CACtD,EACD5B,EAAM,QAAQvC,EAAE,kCAAkC,CAAC,CACrD,OAASwC,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAKxC,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,eAAeuE,GAAyB,CACtC,GAAI,CACF,MAAMnD,EAAU,YAAY,CAAE,QAAS,CAAE,kBAAmB,IAAA,EAAQ,EACpEgD,EAAW,EAAE,EACb7B,EAAM,QAAQvC,EAAE,oCAAoC,CAAC,CACvD,OAASwC,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAKxC,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,OACEO,EAAAA,KAAC,UAAA,CAAQ,UAAU,6CACjB,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,2DAChB,SAAA,CAAAC,EAAAA,IAACgE,EAAA,CAAO,UAAU,uBAAA,CAAwB,QACzC,KAAA,CAAG,UAAU,wBAAyB,SAAAxE,EAAE,4BAA4B,EAAE,EACtEqE,EACG7D,EAAAA,IAACsC,EAAA,CAAM,QAAQ,UAAW,SAAA9C,EAAE,iCAAiC,CAAA,CAAE,QAC9D8C,EAAA,CAAM,QAAQ,UAAW,SAAA9C,EAAE,4BAA4B,CAAA,CAAE,CAAA,EAChE,QACC,IAAA,CAAE,UAAU,kCAAmC,SAAAA,EAAE,+BAA+B,EAAE,EAEnFO,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAC,MAACiE,EAAA,CAAM,QAAQ,WAAW,UAAU,sBAAsB,SAAA,oBAAiB,EAC3EjE,EAAAA,IAAC0C,EAAA,CACC,GAAG,WACH,MAAOiB,EACP,SAAWpB,GAAMqB,EAAWrB,EAAE,OAAO,KAAK,EAC1C,YAAa/C,EAAE,kCAAkC,EACjD,aAAa,MACb,UAAWwD,EAAG,yBAA0BQ,EAASG,CAAO,GAAK,iBAAiB,CAAA,CAAA,EAE/EG,GACC9D,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAR,EAAE,kCAAmC,CAAE,OAAQmE,EAAQ,MAAA,CAAQ,CAAA,CAClE,QAED,IAAA,CAAE,UAAU,iCAAkC,SAAAnE,EAAE,2BAA2B,CAAA,CAAE,CAAA,EAChF,EAEAO,EAAAA,KAAC,MAAA,CAAI,UAAU,2DACb,SAAA,CAAAA,EAAAA,KAACE,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS,IAAM,KAAK8D,EAAA,EACpB,SAAU,CAACF,GAAgBjD,EAAU,UACrC,UAAU,gCAEV,SAAA,CAAAZ,EAAAA,IAACsD,EAAA,CAAE,UAAU,SAAA,CAAU,EACtB9D,EAAE,4BAA4B,CAAA,CAAA,CAAA,EAEjCQ,EAAAA,IAAC,OAAA,CAAK,UAAU,SAAA,CAAU,EACzByB,GACC1B,EAAAA,KAACE,EAAA,CACC,KAAK,KACL,QAAS,IAAM,KAAK4B,EAAA,EACpB,SAAUjB,EAAU,WAAa4C,EAASG,CAAO,EAEhD,SAAA,CAAA/C,EAAU,gBACNP,EAAA,CAAQ,UAAU,uBAAuB,EAC1CL,EAAAA,IAACuD,EAAA,CAAK,UAAU,SAAA,CAAU,EAC7B3C,EAAU,UAAYpB,EAAE,uBAAuB,EAAIA,EAAE,qBAAqB,CAAA,CAAA,CAAA,CAC7E,CAAA,CAEJ,CAAA,EACF,CAEJ,CAUA,SAASiD,EAAM,CAAE,MAAAyB,EAAO,KAAAC,EAAM,SAAAC,GAAqC,CACjE,OACErE,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACb,SAAA,CAAAC,EAAAA,IAACiE,EAAA,CAAM,UAAU,sBAAuB,SAAAC,EAAM,EAC7CE,EACAD,GAAQnE,EAAAA,IAAC,IAAA,CAAE,UAAU,4BAA6B,SAAAmE,CAAA,CAAK,CAAA,EAC1D,CAEJ,CAOA,SAASjB,EAAI,CAAE,MAAAgB,EAAO,SAAAE,GAAmC,CACvD,OACErE,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,qCAAsC,SAAA,CAAAmE,EAAM,GAAA,EAAC,EAC7DlE,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,SAAAoE,CAAA,CAAS,CAAA,EAC7C,CAEJ,CAUA,SAASf,EAAY,CAAE,MAAAgB,EAAO,SAAAC,EAAU,IAAAC,EAAK,IAAAC,EAAK,YAAAC,GAA8C,CAC9F,OACEzE,EAAAA,IAAC0C,EAAA,CACC,KAAK,SACL,UAAU,UACV,IAAA6B,EACA,IAAAC,EACA,MAAAH,EACA,SAAW9B,GAAM+B,EAAS/B,EAAE,OAAO,KAAK,EACxC,YAAAkC,CAAA,CAAA,CAGN","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{h as F,u as f,i as W,j as e,T as V,e as u,w as $,k as H,l as Z,m as I,n as Q,o as L,b as _,f as N,d as j,U as C,p as y,q}from"./index-DCfdN5R7.js";import{r as k}from"./react-DlP5eolq.js";import{E as P}from"./empty-state-CuiqdZiB.js";import{u as K,a as Y,b as A}from"./use-workspace-CuytyHwb.js";import{u as G}from"./use-settings-DGIjmUX0.js";import{L as M}from"./loader-circle-DDdmcH0k.js";import{R as J}from"./refresh-ccw-DlAd-eTQ.js";import{B as X}from"./book-open-CSCq5cjL.js";import{F as v}from"./file-text-BxfdLM0-.js";/**
|
|
2
|
+
* @license lucide-react v0.469.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const ee=F("File",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}]]);/**
|
|
7
|
+
* @license lucide-react v0.469.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const T=F("FolderTree",[["path",{d:"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"hod4my"}],["path",{d:"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"w4yl2u"}],["path",{d:"M3 5a2 2 0 0 0 2 2h3",key:"f2jnh7"}],["path",{d:"M3 3v13a2 2 0 0 0 2 2h3",key:"k8epm1"}]]);/**
|
|
12
|
+
* @license lucide-react v0.469.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const se=F("Folder",[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]);function je(){const{t:s}=f(["workspace","common"]),[a,n]=W(),t=a.get("agent")??"",i=a.get("path")??"",l=K(),o=G(),c=l.data??{},x=k.useMemo(()=>Object.keys(c).sort(),[c]),g=x.join("\0"),h=o.data?.defaultAgent,d=Y(t,i,{enabled:!!t}),p=d.data,R=p?.type==="dir",U=p?.type==="file";function z(r){const m=new URLSearchParams(a);for(const[E,w]of Object.entries(r))w==null||w===""?m.delete(E):m.set(E,w);n(m,{replace:!1})}k.useEffect(()=>{if(t||l.isLoading)return;const r=h&&x.includes(h)?h:x.length===1?x[0]:"";if(!r)return;const m=new URLSearchParams(a);m.set("agent",r),m.delete("path"),n(m,{replace:!0})},[t,g,x,l.isLoading,h,a,n]);function O(r){z({agent:r||null,path:null})}function b(r){z({path:r||null})}function S(){if(!i)return;const r=i.lastIndexOf("/"),m=r>=0?i.slice(0,r):"";b(m)}return e.jsxs("div",{className:"flex min-h-dvh flex-col bg-bg",children:[e.jsx(V,{}),e.jsxs("main",{className:"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe",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("pageTitle")}),e.jsxs(u,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>d.refetch(),disabled:!t||d.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[d.isFetching?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(J,{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.jsx("div",{className:"flex flex-wrap items-end gap-2",children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx($,{htmlFor:"agent",className:"text-xs text-text-dim",children:s("agentPicker.label")}),e.jsxs(H,{value:t||"__placeholder__",onValueChange:r=>O(r==="__placeholder__"?"":r),children:[e.jsx(Z,{id:"agent",className:"w-64",children:e.jsx(I,{placeholder:s("agentPicker.placeholder")})}),e.jsxs(Q,{children:[e.jsx(L,{value:"__placeholder__",disabled:!0,children:s("agentPicker.placeholder")}),x.map(r=>e.jsx(L,{value:r,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs",children:_(r)}),e.jsx("span",{className:N("inline-block h-1.5 w-1.5 rounded-full",c[r]?"bg-success":"bg-text-muted")}),e.jsx("span",{className:"text-text-dim text-xs",children:c[r]?s("agentPicker.online"):s("agentPicker.offline")})]})},r))]})]})]})}),t?e.jsxs(e.Fragment,{children:[e.jsx(te,{agent:t,onNavigate:b}),e.jsx(ie,{path:i,onNavigate:b,onUp:S}),d.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):R&&p?.type==="dir"?e.jsx(ce,{entries:p.entries,onEnter:r=>b(i?`${i}/${r.name}`:r.name)}):U&&p?.type==="file"?e.jsx(le,{file:p,agent:t,onBack:S}):i&&d.isError&&re(i,d.error)?e.jsx(ne,{agent:t,path:i,onCreated:()=>{d.refetch()}}):e.jsx(P,{icon:e.jsx(T,{}),title:s("editor.loadFailed"),description:d.error?.message??""})]}):e.jsx(P,{icon:e.jsx(T,{}),title:s("noAgent.title"),description:s("noAgent.description")})]})]})}function te({agent:s,onNavigate:a}){const{t:n}=f("workspace"),t=ae(s);return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsx("span",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent-bg text-accent",children:e.jsx(X,{className:"h-4 w-4"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold",children:n("quick.title")}),e.jsx(j,{variant:"info",children:_(s)})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:n("quick.detail")})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(u,{type:"button",size:"sm",onClick:()=>a(t),children:[e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:n("quick.openRoleFile")})]}),e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>a("MEMORY.md"),children:[e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:n("quick.openMemory")})]})]})]})})}function ae(s){return s==="claude-code"?"CLAUDE.md":"AGENTS.md"}function ne({agent:s,path:a,onCreated:n}){const{t}=f("workspace"),i=A(),l=a==="MEMORY.md";async function o(){try{await i.mutateAsync({agent:s,path:a,body:{content:t(l?"quick.memoryTemplate":"quick.fileTemplate")}}),y.success(t("toast.created",{path:a})),n()}catch(c){y.error(q(c,t).message)}}return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center",children:[e.jsx("span",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim",children:e.jsx(v,{className:"h-4 w-4"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h2",{className:"text-sm font-semibold",children:t("quick.missingTitle")}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("quick.missingDetail",{path:a})})]}),e.jsxs(u,{type:"button",size:"sm",onClick:()=>void o(),disabled:i.isPending,children:[i.isPending?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(v,{className:"h-4 w-4"}),e.jsx("span",{children:t(l?"quick.createMemory":"quick.createFile")})]})]})})}function re(s,a){if(s.includes("/")||!s.endsWith(".md"))return!1;const n=a instanceof Error?a.message.toLowerCase():String(a).toLowerCase();return n.includes("not found")||n.includes("enoent")||n.includes("no such file")}function ie({path:s,onNavigate:a,onUp:n}){const{t}=f("workspace"),i=s?s.split("/"):[];return e.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-sm",children:[e.jsx(u,{type:"button",variant:"ghost",size:"sm",onClick:n,disabled:!s,"aria-label":t("tree.up"),children:e.jsx(C,{className:"h-4 w-4"})}),e.jsx("button",{type:"button",onClick:()=>a(""),className:"text-text-dim hover:text-text rounded px-1 py-0.5",children:t("tree.rootLabel")}),i.map((l,o)=>{const c=i.slice(0,o+1).join("/");return e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-text-muted",children:"/"}),e.jsx("button",{type:"button",onClick:()=>a(c),className:"text-text-dim hover:text-text rounded px-1 py-0.5",children:l})]},c)})]})}function ce({entries:s,onEnter:a}){const{t:n}=f("workspace");return s.length===0?e.jsx("div",{className:"rounded-md border border-border bg-surface p-3 text-sm text-text-dim",children:n("tree.empty")}):e.jsx("ul",{className:"divide-y divide-border rounded-md border border-border bg-surface",children:s.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>a(t),disabled:t.broken||t.symlink_escape,className:N("flex w-full items-center gap-2 px-3 py-2 text-sm text-left","transition-colors hover:bg-surface-hover disabled:opacity-50 disabled:cursor-not-allowed"),children:[t.isDir?e.jsx(se,{className:"h-4 w-4 text-accent"}):e.jsx(ee,{className:"h-4 w-4 text-text-dim"}),e.jsx("span",{className:t.isDir?"font-medium text-text":"text-text",children:t.name}),t.symlink_escape&&e.jsx(j,{variant:"warning",className:"ml-2",children:n("tree.symlinkEscape")}),t.broken&&!t.symlink_escape&&e.jsx(j,{variant:"danger",className:"ml-2",children:n("tree.broken")}),!t.isDir&&t.size!=null&&e.jsx("span",{className:"ml-auto text-xs text-text-muted tabular-nums",children:B(t.size)}),t.mtime&&e.jsx("span",{className:N("text-xs text-text-muted tabular-nums",!t.isDir&&t.size!=null?"ml-3":"ml-auto"),children:D(t.mtime)})]})},t.name))})}function le({file:s,agent:a,onBack:n}){const{t}=f(["workspace","common"]),[i,l]=k.useState(s.content);k.useEffect(()=>{l(s.content)},[s.content]);const o=i!==s.content,c=A();async function x(){try{await c.mutateAsync({agent:a,path:s.path,body:{content:i}}),y.success(t("toast.saved",{path:s.path}))}catch(g){const{message:h}=q(g,t);y.error(h)}}return s.encoding==="base64"?e.jsxs("div",{className:"rounded-md border border-border bg-surface p-4 text-sm",children:[e.jsxs(u,{variant:"ghost",size:"sm",onClick:n,className:"mb-3",children:[e.jsx(C,{className:"h-4 w-4"}),t("tree.up")]}),e.jsx("p",{className:"text-text-dim",children:t("editor.binary")}),e.jsxs("p",{className:"mt-2 text-xs text-text-muted tabular-nums",children:[s.path," · ",B(s.size)]})]}):e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(u,{variant:"ghost",size:"sm",onClick:n,children:[e.jsx(C,{className:"h-4 w-4"}),t("tree.up")]}),e.jsx("code",{className:"rounded bg-surface-2 px-1.5 py-0.5 text-xs font-mono",children:s.path}),s.truncated&&e.jsx(j,{variant:"warning",children:t("editor.truncatedBadge")}),o&&e.jsx(j,{variant:"info",children:t("editor.dirtyHint")}),e.jsxs(u,{type:"button",size:"sm",className:"ml-auto",onClick:()=>void x(),disabled:!o||c.isPending||s.truncated,children:[c.isPending?e.jsx(M,{className:"h-4 w-4 animate-spin"}):null,c.isPending?t("editor.saving"):t("editor.save")]})]}),s.truncated&&e.jsx("p",{className:"text-xs text-warning",children:t("editor.truncated")}),e.jsx("textarea",{value:i,onChange:g=>l(g.target.value),rows:24,spellCheck:!1,className:N("w-full resize-y rounded-md border bg-bg px-3 py-2","font-mono text-xs leading-5","focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg",o?"border-accent":"border-border")}),!o&&e.jsx("p",{className:"text-xs text-text-muted",children:t("editor.savedMeta",{size:s.size,at:D(s.mtime)})})]})}function D(s){if(s==null)return"—";try{const a=new Date(s);return Number.isNaN(a.getTime())?s:a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return s}}function B(s){return s<1024?`${s} B`:s<1024*1024?`${(s/1024).toFixed(1)} KiB`:`${(s/1024/1024).toFixed(1)} MiB`}export{je as default};
|
|
17
|
+
//# sourceMappingURL=workspace-BA1_hso3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-BA1_hso3.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file.js","../../node_modules/lucide-react/dist/esm/icons/folder-tree.js","../../node_modules/lucide-react/dist/esm/icons/folder.js","../../src/routes/workspace.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 File = createLucideIcon(\"File\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n]);\n\nexport { File as default };\n//# sourceMappingURL=file.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 FolderTree = createLucideIcon(\"FolderTree\", [\n [\n \"path\",\n {\n d: \"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"hod4my\"\n }\n ],\n [\n \"path\",\n {\n d: \"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"w4yl2u\"\n }\n ],\n [\"path\", { d: \"M3 5a2 2 0 0 0 2 2h3\", key: \"f2jnh7\" }],\n [\"path\", { d: \"M3 3v13a2 2 0 0 0 2 2h3\", key: \"k8epm1\" }]\n]);\n\nexport { FolderTree as default };\n//# sourceMappingURL=folder-tree.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 Folder = createLucideIcon(\"Folder\", [\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n]);\n\nexport { Folder as default };\n//# sourceMappingURL=folder.js.map\n","/**\n * /workspace — file browser + editor for the per-agent CWD.\n *\n * Single-column finder UI: pick an agent → drill into the workspace\n * via ?path=, click a file → opens the editor pane below the\n * listing. No recursive tree because the listing handler is cheap\n * and the typical workspace has ≤ 30 entries per dir.\n *\n * Editor is a plain `<textarea>` — Monaco / CodeMirror would balloon\n * the bundle for what is realistically operator-edits to\n * CLAUDE.md / AGENTS.md / config snippets. Binary files render a\n * read-only placeholder. Truncated files (> 1 MiB) block save to\n * prevent destructive overwrites.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport {\n BookOpen,\n ChevronUp,\n File,\n FileText,\n Folder,\n FolderTree,\n Loader2,\n RefreshCcw,\n} from 'lucide-react'\n\nimport { Topbar } from '@/components/shell/topbar'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useAgentsStatus,\n useWorkspaceFiles,\n useWriteWorkspaceFile,\n} from '@/hooks/use-workspace'\nimport { useConfig } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { agentDisplayName } from '@/lib/agent-label'\nimport type {\n WorkspaceFileContent,\n WorkspaceFileEntry,\n} from '@/types/api'\nimport { cn } from '@/lib/utils'\n\nexport default function WorkspaceRoute(): JSX.Element {\n const { t } = useTranslation(['workspace', 'common'])\n const [params, setParams] = useSearchParams()\n const agent = params.get('agent') ?? ''\n const path = params.get('path') ?? ''\n\n const agentsQuery = useAgentsStatus()\n const cfgQuery = useConfig()\n const agents = agentsQuery.data ?? {}\n const agentNames = useMemo(() => Object.keys(agents).sort(), [agents])\n const agentKey = agentNames.join('\\0')\n const defaultAgent = cfgQuery.data?.defaultAgent\n\n /** Query may resolve to either a dir listing or file content — we\n * branch on `data.type` in the render. */\n const filesQuery = useWorkspaceFiles(agent, path, { enabled: Boolean(agent) })\n const data = filesQuery.data\n const isDir = data?.type === 'dir'\n const isFile = data?.type === 'file'\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 setParams(next, { replace: false })\n }\n\n useEffect(() => {\n if (agent || agentsQuery.isLoading) return\n const preferred = defaultAgent && agentNames.includes(defaultAgent)\n ? defaultAgent\n : agentNames.length === 1\n ? agentNames[0]\n : ''\n if (!preferred) return\n const next = new URLSearchParams(params)\n next.set('agent', preferred)\n next.delete('path')\n setParams(next, { replace: true })\n }, [agent, agentKey, agentNames, agentsQuery.isLoading, defaultAgent, params, setParams])\n\n function setAgent(next: string): void {\n // Switching agent always resets the path so we don't drag a\n // claude-specific path into codex's workspace.\n patchParams({ agent: next || null, path: null })\n }\n function navigateTo(nextPath: string): void {\n patchParams({ path: nextPath || null })\n }\n function navigateUp(): void {\n if (!path) return\n const idx = path.lastIndexOf('/')\n const parent = idx >= 0 ? path.slice(0, idx) : ''\n navigateTo(parent)\n }\n\n return (\n <div className=\"flex min-h-dvh flex-col bg-bg\">\n <Topbar />\n\n <main className=\"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe\">\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('pageTitle')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => filesQuery.refetch()}\n disabled={!agent || filesQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {filesQuery.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 {/* Agent picker */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent\" className=\"text-xs text-text-dim\">\n {t('agentPicker.label')}\n </Label>\n <Select value={agent || '__placeholder__'} onValueChange={(v) => setAgent(v === '__placeholder__' ? '' : v)}>\n <SelectTrigger id=\"agent\" className=\"w-64\">\n <SelectValue placeholder={t('agentPicker.placeholder')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__placeholder__\" disabled>\n {t('agentPicker.placeholder')}\n </SelectItem>\n {agentNames.map((name) => (\n <SelectItem key={name} value={name}>\n <span className=\"flex items-center gap-2\">\n <span className=\"font-mono text-xs\">{agentDisplayName(name)}</span>\n <span className={cn(\n 'inline-block h-1.5 w-1.5 rounded-full',\n agents[name] ? 'bg-success' : 'bg-text-muted',\n )} />\n <span className=\"text-text-dim text-xs\">\n {agents[name] ? t('agentPicker.online') : t('agentPicker.offline')}\n </span>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {!agent ? (\n <EmptyState\n icon={<FolderTree />}\n title={t('noAgent.title')}\n description={t('noAgent.description')}\n />\n ) : (\n <>\n <WorkspaceStartCard\n agent={agent}\n onNavigate={navigateTo}\n />\n\n {/* Breadcrumb + Up */}\n <Breadcrumb\n path={path}\n onNavigate={navigateTo}\n onUp={navigateUp}\n />\n\n {filesQuery.isLoading ? (\n <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n ) : isDir && data?.type === 'dir' ? (\n <DirListing\n entries={data.entries}\n onEnter={(entry) => navigateTo(\n path ? `${path}/${entry.name}` : entry.name,\n )}\n />\n ) : isFile && data?.type === 'file' ? (\n <FileEditor\n file={data}\n agent={agent}\n onBack={navigateUp}\n />\n ) : path && filesQuery.isError && canCreateMissingFile(path, filesQuery.error) ? (\n <MissingFilePanel\n agent={agent}\n path={path}\n onCreated={() => { void filesQuery.refetch() }}\n />\n ) : (\n <EmptyState\n icon={<FolderTree />}\n title={t('editor.loadFailed')}\n description={filesQuery.error?.message ?? ''}\n />\n )}\n </>\n )}\n </main>\n </div>\n )\n}\n\ninterface WorkspaceStartCardProps {\n agent: string\n onNavigate: (path: string) => void\n}\n\nfunction WorkspaceStartCard({ agent, onNavigate }: WorkspaceStartCardProps): JSX.Element {\n const { t } = useTranslation('workspace')\n const roleFile = roleFileForAgent(agent)\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent-bg text-accent\">\n <BookOpen className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h2 className=\"text-sm font-semibold\">{t('quick.title')}</h2>\n <Badge variant=\"info\">{agentDisplayName(agent)}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t('quick.detail')}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={() => onNavigate(roleFile)}>\n <FileText className=\"h-4 w-4\" />\n <span>{t('quick.openRoleFile')}</span>\n </Button>\n <Button type=\"button\" variant=\"secondary\" size=\"sm\" onClick={() => onNavigate('MEMORY.md')}>\n <FileText className=\"h-4 w-4\" />\n <span>{t('quick.openMemory')}</span>\n </Button>\n </div>\n </div>\n </section>\n )\n}\n\nfunction roleFileForAgent(agent: string): string {\n return agent === 'claude-code' ? 'CLAUDE.md' : 'AGENTS.md'\n}\n\ninterface MissingFilePanelProps {\n agent: string\n path: string\n onCreated: () => void\n}\n\nfunction MissingFilePanel({ agent, path, onCreated }: MissingFilePanelProps): JSX.Element {\n const { t } = useTranslation('workspace')\n const write = useWriteWorkspaceFile()\n const isMemory = path === 'MEMORY.md'\n\n async function onCreate(): Promise<void> {\n try {\n await write.mutateAsync({\n agent,\n path,\n body: { content: t(isMemory ? 'quick.memoryTemplate' : 'quick.fileTemplate') },\n })\n toast.success(t('toast.created', { path }))\n onCreated()\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-surface-2 text-text-dim\">\n <FileText className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-sm font-semibold\">{t('quick.missingTitle')}</h2>\n <p className=\"mt-1 text-sm text-text-dim\">{t('quick.missingDetail', { path })}</p>\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => void onCreate()}\n disabled={write.isPending}\n >\n {write.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <FileText className=\"h-4 w-4\" />}\n <span>{t(isMemory ? 'quick.createMemory' : 'quick.createFile')}</span>\n </Button>\n </div>\n </section>\n )\n}\n\nfunction canCreateMissingFile(path: string, error: unknown): boolean {\n if (path.includes('/')) return false\n if (!path.endsWith('.md')) return false\n const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase()\n return message.includes('not found')\n || message.includes('enoent')\n || message.includes('no such file')\n}\n\ninterface BreadcrumbProps {\n path: string\n onNavigate: (path: string) => void\n onUp: () => void\n}\n\nfunction Breadcrumb({ path, onNavigate, onUp }: BreadcrumbProps): JSX.Element {\n const { t } = useTranslation('workspace')\n const parts = path ? path.split('/') : []\n return (\n <div className=\"flex flex-wrap items-center gap-1 text-sm\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onUp}\n disabled={!path}\n aria-label={t('tree.up')}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </Button>\n <button\n type=\"button\"\n onClick={() => onNavigate('')}\n className=\"text-text-dim hover:text-text rounded px-1 py-0.5\"\n >\n {t('tree.rootLabel')}\n </button>\n {parts.map((part, i) => {\n const upto = parts.slice(0, i + 1).join('/')\n return (\n <span key={upto} className=\"flex items-center gap-1\">\n <span className=\"text-text-muted\">/</span>\n <button\n type=\"button\"\n onClick={() => onNavigate(upto)}\n className=\"text-text-dim hover:text-text rounded px-1 py-0.5\"\n >\n {part}\n </button>\n </span>\n )\n })}\n </div>\n )\n}\n\ninterface DirListingProps {\n entries: WorkspaceFileEntry[]\n onEnter: (entry: WorkspaceFileEntry) => void\n}\n\nfunction DirListing({ entries, onEnter }: DirListingProps): JSX.Element {\n const { t } = useTranslation('workspace')\n if (entries.length === 0) {\n return <div className=\"rounded-md border border-border bg-surface p-3 text-sm text-text-dim\">{t('tree.empty')}</div>\n }\n return (\n <ul className=\"divide-y divide-border rounded-md border border-border bg-surface\">\n {entries.map((e) => (\n <li key={e.name}>\n <button\n type=\"button\"\n onClick={() => onEnter(e)}\n disabled={e.broken || e.symlink_escape}\n className={cn(\n 'flex w-full items-center gap-2 px-3 py-2 text-sm text-left',\n 'transition-colors hover:bg-surface-hover disabled:opacity-50 disabled:cursor-not-allowed',\n )}\n >\n {e.isDir ? <Folder className=\"h-4 w-4 text-accent\" /> : <File className=\"h-4 w-4 text-text-dim\" />}\n <span className={e.isDir ? 'font-medium text-text' : 'text-text'}>{e.name}</span>\n {e.symlink_escape && (\n <Badge variant=\"warning\" className=\"ml-2\">{t('tree.symlinkEscape')}</Badge>\n )}\n {e.broken && !e.symlink_escape && (\n <Badge variant=\"danger\" className=\"ml-2\">{t('tree.broken')}</Badge>\n )}\n {!e.isDir && e.size != null && (\n <span className=\"ml-auto text-xs text-text-muted tabular-nums\">{formatSize(e.size)}</span>\n )}\n {e.mtime && (\n <span className={cn('text-xs text-text-muted tabular-nums', !e.isDir && e.size != null ? 'ml-3' : 'ml-auto')}>\n {formatTime(e.mtime)}\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>\n )\n}\n\ninterface FileEditorProps {\n file: WorkspaceFileContent\n agent: string\n onBack: () => void\n}\n\nfunction FileEditor({ file, agent, onBack }: FileEditorProps): JSX.Element {\n const { t } = useTranslation(['workspace', 'common'])\n const [draft, setDraft] = useState(file.content)\n useEffect(() => { setDraft(file.content) }, [file.content])\n const dirty = draft !== file.content\n\n const write = useWriteWorkspaceFile()\n\n async function onSave(): Promise<void> {\n try {\n await write.mutateAsync({ agent, path: file.path, body: { content: draft } })\n toast.success(t('toast.saved', { path: file.path }))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n if (file.encoding === 'base64') {\n return (\n <div className=\"rounded-md border border-border bg-surface p-4 text-sm\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack} className=\"mb-3\">\n <ChevronUp className=\"h-4 w-4\" />\n {t('tree.up')}\n </Button>\n <p className=\"text-text-dim\">{t('editor.binary')}</p>\n <p className=\"mt-2 text-xs text-text-muted tabular-nums\">\n {file.path} · {formatSize(file.size)}\n </p>\n </div>\n )\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack}>\n <ChevronUp className=\"h-4 w-4\" />\n {t('tree.up')}\n </Button>\n <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs font-mono\">{file.path}</code>\n {file.truncated && <Badge variant=\"warning\">{t('editor.truncatedBadge')}</Badge>}\n {dirty && <Badge variant=\"info\">{t('editor.dirtyHint')}</Badge>}\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => void onSave()}\n disabled={!dirty || write.isPending || file.truncated}\n >\n {write.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n {write.isPending ? t('editor.saving') : t('editor.save')}\n </Button>\n </div>\n {file.truncated && (\n <p className=\"text-xs text-warning\">{t('editor.truncated')}</p>\n )}\n <textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={24}\n spellCheck={false}\n className={cn(\n 'w-full resize-y rounded-md border bg-bg px-3 py-2',\n 'font-mono text-xs leading-5',\n 'focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1 focus:ring-offset-bg',\n dirty ? 'border-accent' : 'border-border',\n )}\n />\n {!dirty && (\n <p className=\"text-xs text-text-muted\">\n {t('editor.savedMeta', { size: file.size, at: formatTime(file.mtime) })}\n </p>\n )}\n </div>\n )\n}\n\nfunction formatTime(iso: string | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n\nfunction formatSize(n: number): string {\n if (n < 1024) return `${n} B`\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KiB`\n return `${(n / 1024 / 1024).toFixed(1)} MiB`\n}\n"],"names":["File","createLucideIcon","FolderTree","Folder","WorkspaceRoute","t","useTranslation","params","setParams","useSearchParams","agent","path","agentsQuery","useAgentsStatus","cfgQuery","useConfig","agents","agentNames","useMemo","agentKey","defaultAgent","filesQuery","useWorkspaceFiles","data","isDir","isFile","patchParams","patch","next","k","v","useEffect","preferred","setAgent","navigateTo","nextPath","navigateUp","idx","parent","jsxs","jsx","Topbar","Button","Loader2","RefreshCcw","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","name","agentDisplayName","cn","Fragment","WorkspaceStartCard","Breadcrumb","DirListing","entry","FileEditor","canCreateMissingFile","MissingFilePanel","EmptyState","onNavigate","roleFile","roleFileForAgent","BookOpen","Badge","FileText","onCreated","write","useWriteWorkspaceFile","isMemory","onCreate","toast","err","describeError","error","message","onUp","parts","ChevronUp","part","i","upto","entries","onEnter","e","formatSize","formatTime","file","onBack","draft","setDraft","useState","dirty","onSave","iso","d","n"],"mappings":"mhBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAOC,EAAiB,OAAQ,CACpC,CAAC,OAAQ,CAAE,EAAG,6DAA8D,IAAK,QAAQ,CAAE,EAC3F,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,CAC1D,CAAC,ECZD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,EAAaD,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,qHACH,IAAK,QACX,CACA,EACE,CACE,OACA,CACE,EAAG,2HACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uBAAwB,IAAK,QAAQ,CAAE,EACrD,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,CAC1D,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,GAASF,EAAiB,SAAU,CACxC,CACE,OACA,CACE,EAAG,yHACH,IAAK,QACX,CACA,CACA,CAAC,ECuCD,SAAwBG,IAA8B,CACpD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,YAAa,QAAQ,CAAC,EAC9C,CAACC,EAAQC,CAAS,EAAIC,EAAA,EACtBC,EAAQH,EAAO,IAAI,OAAO,GAAK,GAC/BI,EAAQJ,EAAO,IAAI,MAAM,GAAM,GAE/BK,EAAcC,EAAA,EACdC,EAAWC,EAAA,EACXC,EAASJ,EAAY,MAAQ,CAAA,EAC7BK,EAAaC,UAAQ,IAAM,OAAO,KAAKF,CAAM,EAAE,KAAA,EAAQ,CAACA,CAAM,CAAC,EAC/DG,EAAWF,EAAW,KAAK,IAAI,EAC/BG,EAAeN,EAAS,MAAM,aAI9BO,EAAaC,EAAkBZ,EAAOC,EAAM,CAAE,QAAS,EAAQD,EAAQ,EACvEa,EAAOF,EAAW,KAClBG,EAAQD,GAAM,OAAS,MACvBE,EAASF,GAAM,OAAS,OAE9B,SAASG,EAAYC,EAA4C,CAC/D,MAAMC,EAAO,IAAI,gBAAgBrB,CAAM,EACvC,SAAW,CAACsB,EAAGC,CAAC,IAAK,OAAO,QAAQH,CAAK,EACnCG,GAAK,MAAQA,IAAM,GAAIF,EAAK,OAAOC,CAAC,EACnCD,EAAK,IAAIC,EAAGC,CAAC,EAEpBtB,EAAUoB,EAAM,CAAE,QAAS,EAAA,CAAO,CACpC,CAEAG,EAAAA,UAAU,IAAM,CACd,GAAIrB,GAASE,EAAY,UAAW,OACpC,MAAMoB,EAAYZ,GAAgBH,EAAW,SAASG,CAAY,EAC9DA,EACAH,EAAW,SAAW,EACpBA,EAAW,CAAC,EACZ,GACN,GAAI,CAACe,EAAW,OAChB,MAAMJ,EAAO,IAAI,gBAAgBrB,CAAM,EACvCqB,EAAK,IAAI,QAASI,CAAS,EAC3BJ,EAAK,OAAO,MAAM,EAClBpB,EAAUoB,EAAM,CAAE,QAAS,EAAA,CAAM,CACnC,EAAG,CAAClB,EAAOS,EAAUF,EAAYL,EAAY,UAAWQ,EAAcb,EAAQC,CAAS,CAAC,EAExF,SAASyB,EAASL,EAAoB,CAGpCF,EAAY,CAAE,MAAOE,GAAQ,KAAM,KAAM,KAAM,CACjD,CACA,SAASM,EAAWC,EAAwB,CAC1CT,EAAY,CAAE,KAAMS,GAAY,IAAA,CAAM,CACxC,CACA,SAASC,GAAmB,CAC1B,GAAI,CAACzB,EAAM,OACX,MAAM0B,EAAM1B,EAAK,YAAY,GAAG,EAC1B2B,EAASD,GAAO,EAAI1B,EAAK,MAAM,EAAG0B,CAAG,EAAI,GAC/CH,EAAWI,CAAM,CACnB,CAEA,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAO,EAERF,EAAAA,KAAC,OAAA,CAAK,UAAU,gFACd,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,sBAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAnC,EAAE,WAAW,EAAE,EACtDkC,EAAAA,KAACG,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAMrB,EAAW,QAAA,EAC1B,SAAU,CAACX,GAASW,EAAW,WAC/B,aAAYhB,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAgB,EAAW,iBAAcsB,EAAA,CAAQ,UAAU,uBAAuB,EAAKH,EAAAA,IAACI,EAAA,CAAW,UAAU,SAAA,CAAU,EACxGJ,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,SAAAnC,EAAE,kBAAmB,CAAE,GAAI,QAAA,CAAU,CAAA,CAAE,CAAA,CAAA,CAAA,CAC7E,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAAA,EAAE,UAAU,CAAA,CAAE,CAAA,EACtD,QAGC,MAAA,CAAI,UAAU,iCACb,SAAAkC,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACb,SAAA,CAAAC,EAAAA,IAACK,GAAM,QAAQ,QAAQ,UAAU,wBAC9B,SAAAxC,EAAE,mBAAmB,EACxB,EACAkC,EAAAA,KAACO,EAAA,CAAO,MAAOpC,GAAS,kBAAmB,cAAgBoB,GAAMG,EAASH,IAAM,kBAAoB,GAAKA,CAAC,EACxG,SAAA,CAAAU,EAAAA,IAACO,EAAA,CAAc,GAAG,QAAQ,UAAU,OAClC,SAAAP,EAAAA,IAACQ,EAAA,CAAY,YAAa3C,EAAE,yBAAyB,CAAA,CAAG,EAC1D,SACC4C,EAAA,CACC,SAAA,CAAAT,EAAAA,IAACU,GAAW,MAAM,kBAAkB,SAAQ,GACzC,SAAA7C,EAAE,yBAAyB,EAC9B,EACCY,EAAW,IAAKkC,GACfX,EAAAA,IAACU,EAAA,CAAsB,MAAOC,EAC5B,SAAAZ,EAAAA,KAAC,OAAA,CAAK,UAAU,0BACd,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,oBAAqB,SAAAY,EAAiBD,CAAI,EAAE,EAC5DX,MAAC,QAAK,UAAWa,EACf,wCACArC,EAAOmC,CAAI,EAAI,aAAe,eAAA,EAC7B,EACHX,EAAAA,IAAC,OAAA,CAAK,UAAU,wBACb,SAAAxB,EAAOmC,CAAI,EAAI9C,EAAE,oBAAoB,EAAIA,EAAE,qBAAqB,CAAA,CACnE,CAAA,CAAA,CACF,CAAA,EAVe8C,CAWjB,CACD,CAAA,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAEEzC,EAOA6B,EAAAA,KAAAe,WAAA,CACE,SAAA,CAAAd,EAAAA,IAACe,GAAA,CACC,MAAA7C,EACA,WAAYwB,CAAA,CAAA,EAIdM,EAAAA,IAACgB,GAAA,CACC,KAAA7C,EACA,WAAYuB,EACZ,KAAME,CAAA,CAAA,EAGPf,EAAW,UACVmB,MAAC,MAAA,CAAI,UAAU,6CAA6C,EAC1DhB,GAASD,GAAM,OAAS,MAC1BiB,EAAAA,IAACiB,GAAA,CACC,QAASlC,EAAK,QACd,QAAUmC,GAAUxB,EAClBvB,EAAO,GAAGA,CAAI,IAAI+C,EAAM,IAAI,GAAKA,EAAM,IAAA,CACzC,CAAA,EAEAjC,GAAUF,GAAM,OAAS,OAC3BiB,EAAAA,IAACmB,GAAA,CACC,KAAMpC,EACN,MAAAb,EACA,OAAQ0B,CAAA,CAAA,EAERzB,GAAQU,EAAW,SAAWuC,GAAqBjD,EAAMU,EAAW,KAAK,EAC3EmB,EAAAA,IAACqB,GAAA,CACC,MAAAnD,EACA,KAAAC,EACA,UAAW,IAAM,CAAOU,EAAW,QAAA,CAAU,CAAA,CAAA,EAG/CmB,EAAAA,IAACsB,EAAA,CACC,WAAO5D,EAAA,EAAW,EAClB,MAAOG,EAAE,mBAAmB,EAC5B,YAAagB,EAAW,OAAO,SAAW,EAAA,CAAA,CAC5C,CAAA,CAEJ,EA/CAmB,EAAAA,IAACsB,EAAA,CACC,WAAO5D,EAAA,EAAW,EAClB,MAAOG,EAAE,eAAe,EACxB,YAAaA,EAAE,qBAAqB,CAAA,CAAA,CA4CtC,CAAA,CAEJ,CAAA,EACF,CAEJ,CAOA,SAASkD,GAAmB,CAAE,MAAA7C,EAAO,WAAAqD,GAAoD,CACvF,KAAM,CAAE,EAAA1D,CAAA,EAAMC,EAAe,WAAW,EAClC0D,EAAWC,GAAiBvD,CAAK,EACvC,aACG,UAAA,CAAQ,UAAU,iDACjB,SAAA6B,EAAAA,KAAC,MAAA,CAAI,UAAU,kDACb,SAAA,CAAAC,EAAAA,IAAC,QAAK,UAAU,0FACd,eAAC0B,EAAA,CAAS,UAAU,UAAU,CAAA,CAChC,EACA3B,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAnC,EAAE,aAAa,EAAE,QACvD8D,EAAA,CAAM,QAAQ,OAAQ,SAAAf,EAAiB1C,CAAK,CAAA,CAAE,CAAA,EACjD,QACC,IAAA,CAAE,UAAU,6BAA8B,SAAAL,EAAE,cAAc,CAAA,CAAE,CAAA,EAC/D,EACAkC,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAA,EAAAA,KAACG,EAAA,CAAO,KAAK,SAAS,KAAK,KAAK,QAAS,IAAMqB,EAAWC,CAAQ,EAChE,SAAA,CAAAxB,EAAAA,IAAC4B,EAAA,CAAS,UAAU,SAAA,CAAU,EAC9B5B,EAAAA,IAAC,OAAA,CAAM,SAAAnC,EAAE,oBAAoB,CAAA,CAAE,CAAA,EACjC,EACAkC,EAAAA,KAACG,EAAA,CAAO,KAAK,SAAS,QAAQ,YAAY,KAAK,KAAK,QAAS,IAAMqB,EAAW,WAAW,EACvF,SAAA,CAAAvB,EAAAA,IAAC4B,EAAA,CAAS,UAAU,SAAA,CAAU,EAC9B5B,EAAAA,IAAC,OAAA,CAAM,SAAAnC,EAAE,kBAAkB,CAAA,CAAE,CAAA,CAAA,CAC/B,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAEA,SAAS4D,GAAiBvD,EAAuB,CAC/C,OAAOA,IAAU,cAAgB,YAAc,WACjD,CAQA,SAASmD,GAAiB,CAAE,MAAAnD,EAAO,KAAAC,EAAM,UAAA0D,GAAiD,CACxF,KAAM,CAAE,CAAA,EAAM/D,EAAe,WAAW,EAClCgE,EAAQC,EAAA,EACRC,EAAW7D,IAAS,YAE1B,eAAe8D,GAA0B,CACvC,GAAI,CACF,MAAMH,EAAM,YAAY,CACtB,MAAA5D,EACA,KAAAC,EACA,KAAM,CAAE,QAAS,EAAE6D,EAAW,uBAAyB,oBAAoB,CAAA,CAAE,CAC9E,EACDE,EAAM,QAAQ,EAAE,gBAAiB,CAAE,KAAA/D,CAAA,CAAM,CAAC,EAC1C0D,EAAA,CACF,OAASM,EAAK,CACZD,EAAM,MAAME,EAAcD,EAAK,CAAC,EAAE,OAAO,CAC3C,CACF,CAEA,aACG,UAAA,CAAQ,UAAU,iDACjB,SAAApC,EAAAA,KAAC,MAAA,CAAI,UAAU,kDACb,SAAA,CAAAC,EAAAA,IAAC,QAAK,UAAU,4FACd,eAAC4B,EAAA,CAAS,UAAU,UAAU,CAAA,CAChC,EACA7B,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAA,EAAE,oBAAoB,EAAE,EAC/DA,MAAC,KAAE,UAAU,6BAA8B,WAAE,sBAAuB,CAAE,KAAA7B,CAAA,CAAM,CAAA,CAAE,CAAA,EAChF,EACA4B,EAAAA,KAACG,EAAA,CACC,KAAK,SACL,KAAK,KACL,QAAS,IAAM,KAAK+B,EAAA,EACpB,SAAUH,EAAM,UAEf,SAAA,CAAAA,EAAM,gBAAa3B,EAAA,CAAQ,UAAU,uBAAuB,EAAKH,EAAAA,IAAC4B,EAAA,CAAS,UAAU,SAAA,CAAU,QAC/F,OAAA,CAAM,SAAA,EAAEI,EAAW,qBAAuB,kBAAkB,CAAA,CAAE,CAAA,CAAA,CAAA,CACjE,CAAA,CACF,CAAA,CACF,CAEJ,CAEA,SAASZ,GAAqBjD,EAAckE,EAAyB,CAEnE,GADIlE,EAAK,SAAS,GAAG,GACjB,CAACA,EAAK,SAAS,KAAK,EAAG,MAAO,GAClC,MAAMmE,EAAUD,aAAiB,MAAQA,EAAM,QAAQ,cAAgB,OAAOA,CAAK,EAAE,YAAA,EACrF,OAAOC,EAAQ,SAAS,WAAW,GAC9BA,EAAQ,SAAS,QAAQ,GACzBA,EAAQ,SAAS,cAAc,CACtC,CAQA,SAAStB,GAAW,CAAE,KAAA7C,EAAM,WAAAoD,EAAY,KAAAgB,GAAsC,CAC5E,KAAM,CAAE,CAAA,EAAMzE,EAAe,WAAW,EAClC0E,EAAQrE,EAAOA,EAAK,MAAM,GAAG,EAAI,CAAA,EACvC,OACE4B,EAAAA,KAAC,MAAA,CAAI,UAAU,4CACb,SAAA,CAAAC,EAAAA,IAACE,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,KACL,QAASqC,EACT,SAAU,CAACpE,EACX,aAAY,EAAE,SAAS,EAEvB,SAAA6B,EAAAA,IAACyC,EAAA,CAAU,UAAU,SAAA,CAAU,CAAA,CAAA,EAEjCzC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMuB,EAAW,EAAE,EAC5B,UAAU,oDAET,WAAE,gBAAgB,CAAA,CAAA,EAEpBiB,EAAM,IAAI,CAACE,EAAMC,IAAM,CACtB,MAAMC,EAAOJ,EAAM,MAAM,EAAGG,EAAI,CAAC,EAAE,KAAK,GAAG,EAC3C,OACE5C,EAAAA,KAAC,OAAA,CAAgB,UAAU,0BACzB,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,kBAAkB,SAAA,IAAC,EACnCA,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMuB,EAAWqB,CAAI,EAC9B,UAAU,oDAET,SAAAF,CAAA,CAAA,CACH,CAAA,EARSE,CASX,CAEJ,CAAC,CAAA,EACH,CAEJ,CAOA,SAAS3B,GAAW,CAAE,QAAA4B,EAAS,QAAAC,GAAyC,CACtE,KAAM,CAAE,EAAAjF,CAAA,EAAMC,EAAe,WAAW,EACxC,OAAI+E,EAAQ,SAAW,QACb,MAAA,CAAI,UAAU,uEAAwE,SAAAhF,EAAE,YAAY,EAAE,EAG9GmC,EAAAA,IAAC,MAAG,UAAU,oEACX,WAAQ,IAAK+C,GACZ/C,EAAAA,IAAC,KAAA,CACC,SAAAD,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM+C,EAAQC,CAAC,EACxB,SAAUA,EAAE,QAAUA,EAAE,eACxB,UAAWlC,EACT,6DACA,0FAAA,EAGD,SAAA,CAAAkC,EAAE,YAASpF,GAAA,CAAO,UAAU,sBAAsB,EAAKqC,EAAAA,IAACxC,GAAA,CAAK,UAAU,uBAAA,CAAwB,EAChGwC,EAAAA,IAAC,QAAK,UAAW+C,EAAE,MAAQ,wBAA0B,YAAc,WAAE,IAAA,CAAK,EACzEA,EAAE,gBACD/C,EAAAA,IAAC2B,EAAA,CAAM,QAAQ,UAAU,UAAU,OAAQ,SAAA9D,EAAE,oBAAoB,CAAA,CAAE,EAEpEkF,EAAE,QAAU,CAACA,EAAE,gBACd/C,EAAAA,IAAC2B,EAAA,CAAM,QAAQ,SAAS,UAAU,OAAQ,SAAA9D,EAAE,aAAa,EAAE,EAE5D,CAACkF,EAAE,OAASA,EAAE,MAAQ,MACrB/C,EAAAA,IAAC,OAAA,CAAK,UAAU,+CAAgD,SAAAgD,EAAWD,EAAE,IAAI,EAAE,EAEpFA,EAAE,OACD/C,EAAAA,IAAC,QAAK,UAAWa,EAAG,uCAAwC,CAACkC,EAAE,OAASA,EAAE,MAAQ,KAAO,OAAS,SAAS,EACxG,SAAAE,EAAWF,EAAE,KAAK,CAAA,CACrB,CAAA,CAAA,CAAA,CAEJ,EA1BOA,EAAE,IA2BX,CACD,EACH,CAEJ,CAQA,SAAS5B,GAAW,CAAE,KAAA+B,EAAM,MAAAhF,EAAO,OAAAiF,GAAwC,CACzE,KAAM,CAAE,CAAA,EAAMrF,EAAe,CAAC,YAAa,QAAQ,CAAC,EAC9C,CAACsF,EAAOC,CAAQ,EAAIC,EAAAA,SAASJ,EAAK,OAAO,EAC/C3D,EAAAA,UAAU,IAAM,CAAE8D,EAASH,EAAK,OAAO,CAAE,EAAG,CAACA,EAAK,OAAO,CAAC,EAC1D,MAAMK,EAAQH,IAAUF,EAAK,QAEvBpB,EAAQC,EAAA,EAEd,eAAeyB,GAAwB,CACrC,GAAI,CACF,MAAM1B,EAAM,YAAY,CAAE,MAAA5D,EAAO,KAAMgF,EAAK,KAAM,KAAM,CAAE,QAASE,CAAA,CAAM,CAAG,EAC5ElB,EAAM,QAAQ,EAAE,cAAe,CAAE,KAAMgB,EAAK,IAAA,CAAM,CAAC,CACrD,OAASf,EAAK,CACZ,KAAM,CAAE,QAAAG,CAAA,EAAYF,EAAcD,EAAK,CAAC,EACxCD,EAAM,MAAMI,CAAO,CACrB,CACF,CAEA,OAAIY,EAAK,WAAa,SAElBnD,EAAAA,KAAC,MAAA,CAAI,UAAU,yDACb,SAAA,CAAAA,EAAAA,KAACG,EAAA,CAAO,QAAQ,QAAQ,KAAK,KAAK,QAASiD,EAAQ,UAAU,OAC3D,SAAA,CAAAnD,EAAAA,IAACyC,EAAA,CAAU,UAAU,SAAA,CAAU,EAC9B,EAAE,SAAS,CAAA,EACd,QACC,IAAA,CAAE,UAAU,gBAAiB,SAAA,EAAE,eAAe,EAAE,EACjD1C,EAAAA,KAAC,IAAA,CAAE,UAAU,4CACV,SAAA,CAAAmD,EAAK,KAAK,MAAIF,EAAWE,EAAK,IAAI,CAAA,CAAA,CACrC,CAAA,EACF,EAKFnD,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,OAACG,GAAO,QAAQ,QAAQ,KAAK,KAAK,QAASiD,EACzC,SAAA,CAAAnD,EAAAA,IAACyC,EAAA,CAAU,UAAU,SAAA,CAAU,EAC9B,EAAE,SAAS,CAAA,EACd,EACAzC,EAAAA,IAAC,OAAA,CAAK,UAAU,uDAAwD,WAAK,KAAK,EACjFkD,EAAK,WAAalD,MAAC2B,EAAA,CAAM,QAAQ,UAAW,SAAA,EAAE,uBAAuB,EAAE,EACvE4B,GAASvD,EAAAA,IAAC2B,EAAA,CAAM,QAAQ,OAAQ,SAAA,EAAE,kBAAkB,EAAE,EACvD5B,EAAAA,KAACG,EAAA,CACC,KAAK,SACL,KAAK,KACL,UAAU,UACV,QAAS,IAAM,KAAKsD,EAAA,EACpB,SAAU,CAACD,GAASzB,EAAM,WAAaoB,EAAK,UAE3C,SAAA,CAAApB,EAAM,UAAY9B,MAACG,EAAA,CAAQ,UAAU,uBAAuB,EAAK,KACjE2B,EAAM,UAAY,EAAE,eAAe,EAAI,EAAE,aAAa,CAAA,CAAA,CAAA,CACzD,EACF,EACCoB,EAAK,WACJlD,MAAC,IAAA,CAAE,UAAU,uBAAwB,SAAA,EAAE,kBAAkB,EAAE,EAE7DA,EAAAA,IAAC,WAAA,CACC,MAAOoD,EACP,SAAWL,GAAMM,EAASN,EAAE,OAAO,KAAK,EACxC,KAAM,GACN,WAAY,GACZ,UAAWlC,EACT,oDACA,8BACA,6FACA0C,EAAQ,gBAAkB,eAAA,CAC5B,CAAA,EAED,CAACA,GACAvD,EAAAA,IAAC,KAAE,UAAU,0BACV,WAAE,mBAAoB,CAAE,KAAMkD,EAAK,KAAM,GAAID,EAAWC,EAAK,KAAK,CAAA,CAAG,CAAA,CACxE,CAAA,EAEJ,CAEJ,CAEA,SAASD,EAAWQ,EAA4B,CAC9C,GAAIA,GAAO,KAAM,MAAO,IACxB,GAAI,CACF,MAAMC,EAAI,IAAI,KAAKD,CAAG,EACtB,OAAI,OAAO,MAAMC,EAAE,QAAA,CAAS,EAAUD,EAC/BC,EAAE,eAAe,OAAW,CAAE,MAAO,QAAS,IAAK,UAAW,KAAM,UAAW,OAAQ,SAAA,CAAW,CAC3G,MAAQ,CACN,OAAOD,CACT,CACF,CAEA,SAAST,EAAWW,EAAmB,CACrC,OAAIA,EAAI,KAAa,GAAGA,CAAC,KACrBA,EAAI,KAAO,KAAa,IAAIA,EAAI,MAAM,QAAQ,CAAC,CAAC,OAC7C,IAAIA,EAAI,KAAO,MAAM,QAAQ,CAAC,CAAC,MACxC","x_google_ignoreList":[0,1,2]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{h as $,u as R,j as e,e as f,d as P,f as H,p as D,q as F,w as B,I,X as q}from"./index-DCfdN5R7.js";import{r as h}from"./react-DlP5eolq.js";import{C as Q}from"./confirm-dialog-BDb0NLny.js";import{E as _}from"./empty-state-CuiqdZiB.js";import{T as X,a as Y,b as A,c as k,d as G,e as N}from"./table-sCMZBe_Z.js";import{D as J,a as Z,b as V,d as ee,e as se,f as te}from"./dropdown-menu-BNH5SrVb.js";import{u as ae}from"./use-workspace-CuytyHwb.js";import{r as re,m as ne,s as ie,t as oe}from"./use-settings-DGIjmUX0.js";import{L as E}from"./loader-circle-DDdmcH0k.js";import{R as le}from"./refresh-ccw-DlAd-eTQ.js";import{B as ce}from"./briefcase-CeKUkFSq.js";import{T as me}from"./trash-2-D2x2UPuZ.js";import{S as de}from"./save-BDOtZrfp.js";import{P as xe}from"./plus-DH4J_YhN.js";import"./chevron-right-CFRb-SM_.js";/**
|
|
2
|
+
* @license lucide-react v0.469.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const ue=$("Pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]),z={id:"",name:"",agents:[],members:[],rate:"",intervalSec:"",burst:""},pe=[{id:"default",labelKey:"workspaces.form.ratePresets.default",descriptionKey:"workspaces.form.ratePresetDescriptions.default",rate:"",intervalSec:"",burst:""},{id:"strict",labelKey:"workspaces.form.ratePresets.strict",descriptionKey:"workspaces.form.ratePresetDescriptions.strict",rate:"3",intervalSec:"60",burst:"5"},{id:"busy",labelKey:"workspaces.form.ratePresets.busy",descriptionKey:"workspaces.form.ratePresetDescriptions.busy",rate:"30",intervalSec:"60",burst:"45"}];function fe(s){return{id:s.id,name:s.name,agents:v(s.agents),members:v(s.members??[]),rate:s.rateLimit?String(s.rateLimit.rate):"",intervalSec:s.rateLimit?String(s.rateLimit.intervalSec):"",burst:s.rateLimit?String(s.rateLimit.burst):""}}function he(s){const n={id:s.id.trim(),name:s.name.trim()||s.id.trim(),agents:v(s.agents),members:v(s.members)},c=Number(s.rate),d=Number(s.intervalSec),l=Number(s.burst);return Number.isFinite(c)&&c>0&&Number.isFinite(d)&&d>0&&Number.isFinite(l)&&l>0&&(n.rateLimit={rate:c,intervalSec:d,burst:l}),n}function be(s,n){return s.rate===n.rate&&s.intervalSec===n.intervalSec&&s.burst===n.burst}function ze(){const{t:s}=R(["settings","common"]),n=re(),c=ae(),d=ne(),l=ie(),w=oe(),[i,m]=h.useState(z),[y,b]=h.useState(null),[u,g]=h.useState(null);h.useEffect(()=>{i.id||i.name},[i.id,i.name]);function C(t){m(fe(t)),b(t.id)}function x(){m(z),b(null)}async function L(t){t.preventDefault();const a=he(i);if(a.id)try{await l.mutateAsync(a),D.success(s("workspaces.toast.saved")),x()}catch(o){D.error(F(o,s).message)}}async function T(){if(u)try{await w.mutateAsync(u.id),D.success(s("workspaces.toast.deleted")),y===u.id&&x(),g(null)}catch(t){throw D.error(F(t,s).message),t}}function M(t){m(a=>({...a,rate:t.rate,intervalSec:t.intervalSec,burst:t.burst}))}const p=n.data?.workspaces??[],r=p.length<=1&&p.every(t=>t.id==="default"),j=h.useMemo(()=>{const t=c.data??{};return Object.entries(t).sort(([a,o],[W,U])=>o!==U?o?-1:1:a.localeCompare(W)).map(([a,o])=>({value:a,label:a,badge:s(o?"workspaces.form.agentOnline":"workspaces.form.agentOffline"),muted:!o}))},[c.data,s]),O=h.useMemo(()=>{const t=new Map;for(const a of d.data?.knownUsers??[]){const o=ge(a);t.set(o,{value:o,label:o,detail:s("workspaces.form.memberLastSeen",{time:je(a.lastSeenAt)})})}for(const a of p)for(const o of a.members??[])o&&(t.has(o)||t.set(o,{value:o,label:o,detail:s("workspaces.form.memberFromScope",{scope:a.id})}));return[...t.values()].sort((a,o)=>a.label.localeCompare(o.label))},[d.data?.knownUsers,s,p]);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.jsx("h1",{className:"text-xl font-semibold",children:s("workspaces.title")}),e.jsxs(f,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>n.refetch(),disabled:n.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[n.isFetching?e.jsx(E,{className:"h-4 w-4 animate-spin"}):e.jsx(le,{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("workspaces.subtitle")})]}),n.isLoading?e.jsx("div",{className:"h-32 rounded-md bg-surface-2 animate-pulse"}):r?e.jsx(_,{icon:e.jsx(ce,{}),title:s("workspaces.empty.title"),description:s("workspaces.empty.description")}):e.jsxs(X,{children:[e.jsx(Y,{children:e.jsxs(A,{children:[e.jsx(k,{className:"w-32",children:s("workspaces.col.id")}),e.jsx(k,{children:s("workspaces.col.name")}),e.jsx(k,{children:s("workspaces.col.agents")}),e.jsx(k,{children:s("workspaces.col.members")}),e.jsx(k,{children:s("workspaces.col.rateLimit")}),e.jsx(k,{className:"w-36"})]})}),e.jsx(G,{children:p.map(t=>e.jsxs(A,{children:[e.jsx(N,{className:"font-mono text-xs",children:t.id}),e.jsx(N,{className:"font-medium",children:t.name}),e.jsx(N,{children:t.agents.length===0?e.jsx("span",{className:"text-text-muted text-xs",children:"—"}):e.jsx("div",{className:"flex flex-wrap gap-1",children:t.agents.map(a=>e.jsx(P,{variant:"secondary",children:a},a))})}),e.jsx(N,{children:(t.members??[]).length===0?e.jsx("span",{className:"text-text-muted text-xs",children:s("workspaces.membersOpen")}):e.jsx("span",{className:"text-text-dim text-xs",children:s("workspaces.membersCount",{count:t.members.length})})}),e.jsx(N,{className:"text-xs text-text-dim",children:t.rateLimit?s("workspaces.rateLimitFormat",{rate:t.rateLimit.rate,intervalSec:t.rateLimit.intervalSec,burst:t.rateLimit.burst}):"—"}),e.jsx(N,{children:e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[e.jsxs(f,{type:"button",variant:"ghost",size:"sm",onClick:()=>C(t),children:[e.jsx(ue,{className:"h-3 w-3"}),s("workspaces.edit")]}),t.id!=="default"&&e.jsxs(f,{type:"button",variant:"ghost",size:"sm",onClick:()=>g(t),disabled:w.isPending,"aria-label":s("workspaces.remove.ariaLabel",{id:t.id}),children:[e.jsx(me,{className:"h-3 w-3"}),s("workspaces.remove.label")]})]})})]},t.id))})]}),e.jsxs("form",{onSubmit:t=>void L(t),className:"rounded-md border border-border bg-surface p-4",children:[e.jsx("div",{className:"mb-1 text-sm font-medium",children:s("workspaces.form.title")}),y&&e.jsx("p",{className:"mb-3 text-xs text-text-dim",children:s("workspaces.form.subtitleEdit")}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(S,{id:"ws-id",label:s("workspaces.form.id"),hint:s("workspaces.form.idHint"),value:i.id,onChange:t=>m(a=>({...a,id:t})),placeholder:"team-foo",mono:!0}),e.jsx(S,{id:"ws-name",label:s("workspaces.form.name"),value:i.name,onChange:t=>m(a=>({...a,name:t})),placeholder:"Team Foo"}),e.jsx(K,{id:"ws-agents",label:s("workspaces.form.agents"),hint:s("workspaces.form.agentsHint"),emptyText:s("workspaces.form.emptyAgents"),chooseLabel:s("workspaces.form.selectAgents"),customPlaceholder:s("workspaces.form.customAgentPlaceholder"),choices:j,value:i.agents,loading:c.isLoading,onChange:t=>m(a=>({...a,agents:t}))}),e.jsx(K,{id:"ws-members",label:s("workspaces.form.members"),hint:s("workspaces.form.membersHint"),emptyText:s("workspaces.form.emptyMembers"),chooseLabel:s("workspaces.form.selectMembers"),customPlaceholder:s("workspaces.form.customMemberPlaceholder"),choices:O,value:i.members,loading:d.isLoading||n.isLoading,onChange:t=>m(a=>({...a,members:t}))})]}),e.jsxs("div",{className:"mt-3",children:[e.jsx("div",{className:"text-xs font-medium text-text-dim",children:s("workspaces.form.rateLimit")}),e.jsx("div",{className:"mt-2 grid grid-cols-1 gap-2 sm:grid-cols-3",children:pe.map(t=>{const a=be(i,t);return e.jsxs(f,{type:"button",variant:a?"default":"secondary",size:"sm",className:"h-auto flex-col items-start gap-0.5 whitespace-normal px-3 py-2 text-left",onClick:()=>M(t),"aria-pressed":a,children:[e.jsx("span",{children:s(t.labelKey)}),e.jsx("span",{className:H("text-[10px] font-normal",a?"text-accent-fg/80":"text-text-muted"),children:s(t.descriptionKey)})]},t.id)})}),e.jsx("p",{className:"mt-2 text-[10px] text-text-muted",children:s("workspaces.form.ratePresetHint")}),e.jsxs("div",{className:"mt-1 grid grid-cols-3 gap-2",children:[e.jsx(S,{id:"ws-rate",label:s("workspaces.form.rate"),value:i.rate,onChange:t=>m(a=>({...a,rate:t})),placeholder:"10",mono:!0}),e.jsx(S,{id:"ws-ivl",label:s("workspaces.form.intervalSec"),value:i.intervalSec,onChange:t=>m(a=>({...a,intervalSec:t})),placeholder:"60",mono:!0}),e.jsx(S,{id:"ws-burst",label:s("workspaces.form.burst"),value:i.burst,onChange:t=>m(a=>({...a,burst:t})),placeholder:"15",mono:!0})]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx(f,{type:"button",variant:"secondary",size:"sm",onClick:x,disabled:l.isPending,children:s("workspaces.form.reset")}),e.jsxs(f,{type:"submit",size:"sm",className:"ml-auto",disabled:l.isPending||!i.id.trim(),children:[l.isPending?e.jsx(E,{className:"h-4 w-4 animate-spin"}):e.jsx(de,{className:"h-4 w-4"}),s("workspaces.form.submit")]})]})]}),e.jsx(Q,{open:u!=null,onOpenChange:t=>{t||g(null)},title:s("workspaces.remove.confirmTitle",{id:u?.id??""}),description:s("workspaces.remove.confirmDescription",{name:u?.name??""}),intent:"danger",confirmLabel:s("workspaces.remove.confirm"),onConfirm:T})]})}function K({id:s,label:n,hint:c,emptyText:d,chooseLabel:l,customPlaceholder:w,choices:i,value:m,loading:y,onChange:b}){const{t:u}=R("settings"),[g,C]=h.useState(""),x=v(m),L=h.useMemo(()=>new Set(x),[x]);function T(r){L.has(r)?b(x.filter(j=>j!==r)):b([...x,r])}function M(r){b(x.filter(j=>j!==r))}function p(){const r=v(g.split(","));r.length!==0&&(b(v([...x,...r])),C(""))}return e.jsxs("div",{className:"flex flex-col gap-1 sm:col-span-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(B,{id:`${s}-label`,className:"text-xs text-text-dim",children:n}),e.jsx(P,{variant:"secondary",children:u("workspaces.form.selectedCount",{count:x.length})})]}),e.jsxs("div",{className:"rounded-md border border-border bg-surface-2 p-2",children:[e.jsx("div",{className:"flex min-h-8 flex-wrap items-center gap-1.5",children:x.length===0?e.jsx("span",{className:"px-1 text-xs text-text-muted",children:d}):x.map(r=>e.jsxs(P,{variant:"secondary",className:"normal-case tracking-normal",children:[e.jsx("span",{className:"font-mono",children:r}),e.jsx("button",{type:"button",className:"ml-1 rounded-full text-text-dim hover:text-text",onClick:()=>M(r),"aria-label":u("workspaces.form.removeSelected",{value:r}),children:e.jsx(q,{className:"h-3 w-3"})})]},r))}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsxs(J,{children:[e.jsx(Z,{asChild:!0,children:e.jsxs(f,{type:"button",variant:"outline",size:"sm",disabled:y,children:[y?e.jsx(E,{className:"h-4 w-4 animate-spin"}):e.jsx(xe,{className:"h-4 w-4"}),l]})}),e.jsxs(V,{align:"start",className:"max-h-80 w-80 overflow-y-auto",children:[e.jsx(ee,{children:l}),e.jsx(se,{}),i.length===0?e.jsx("div",{className:"px-2 py-2 text-sm text-text-muted",children:u("workspaces.form.noChoices")}):i.map(r=>e.jsxs(te,{checked:L.has(r.value),onCheckedChange:()=>T(r.value),onSelect:j=>j.preventDefault(),className:H("items-start gap-2",r.muted&&"text-text-muted"),children:[e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block truncate font-mono text-xs",children:r.label}),r.detail&&e.jsx("span",{className:"mt-0.5 block truncate text-xs text-text-muted",children:r.detail})]}),r.badge&&e.jsx(P,{variant:r.muted?"outline":"success",children:r.badge})]},r.value))]})]}),e.jsxs("div",{className:"flex min-w-[220px] flex-1 gap-2",children:[e.jsx(I,{id:s,value:g,onChange:r=>C(r.target.value),onKeyDown:r=>{r.key==="Enter"&&(r.preventDefault(),p())},placeholder:w,className:"h-7 font-mono text-xs","aria-labelledby":`${s}-label`}),e.jsx(f,{type:"button",variant:"secondary",size:"sm",onClick:p,disabled:!g.trim(),children:u("workspaces.form.addCustom")})]})]})]}),c&&e.jsx("span",{className:"text-[10px] text-text-muted",children:c})]})}function S({id:s,label:n,hint:c,value:d,onChange:l,placeholder:w,mono:i}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(B,{htmlFor:s,className:"text-xs text-text-dim",children:n}),e.jsx(I,{id:s,value:d,onChange:m=>l(m.target.value),placeholder:w,className:i?"font-mono text-xs":""}),c&&e.jsx("span",{className:"text-[10px] text-text-muted",children:c})]})}function v(s){const n=[],c=new Set;for(const d of s){const l=d.trim();!l||c.has(l)||(c.add(l),n.push(l))}return n}function ge(s){return`${s.platform}:${s.userId}`}function je(s){const n=new Date(s);return Number.isNaN(n.getTime())?s:n.toLocaleString()}export{ze as default};
|
|
7
|
+
//# sourceMappingURL=workspaces-DyGLJUgB.js.map
|