@xopcai/xopcbot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -0
- package/README.zh-CN.md +130 -0
- package/dist/__tests__/core.test.d.ts +1 -0
- package/dist/__tests__/core.test.js +72 -0
- package/dist/__tests__/core.test.js.map +1 -0
- package/dist/agent/fallback/__tests__/index.test.d.ts +1 -0
- package/dist/agent/fallback/__tests__/index.test.js +111 -0
- package/dist/agent/fallback/__tests__/index.test.js.map +1 -0
- package/dist/agent/fallback/candidates.d.ts +23 -0
- package/dist/agent/fallback/candidates.js +62 -0
- package/dist/agent/fallback/candidates.js.map +1 -0
- package/dist/agent/fallback/error.d.ts +22 -0
- package/dist/agent/fallback/error.js +27 -0
- package/dist/agent/fallback/error.js.map +1 -0
- package/dist/agent/fallback/index.d.ts +6 -0
- package/dist/agent/fallback/index.js +5 -0
- package/dist/agent/fallback/index.js.map +1 -0
- package/dist/agent/fallback/reason.d.ts +7 -0
- package/dist/agent/fallback/reason.js +78 -0
- package/dist/agent/fallback/reason.js.map +1 -0
- package/dist/agent/fallback/runner.d.ts +22 -0
- package/dist/agent/fallback/runner.js +34 -0
- package/dist/agent/fallback/runner.js.map +1 -0
- package/dist/agent/helpers.d.ts +38 -0
- package/dist/agent/helpers.js +122 -0
- package/dist/agent/helpers.js.map +1 -0
- package/dist/agent/index.d.ts +7 -0
- package/dist/agent/index.js +7 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/memory/compaction.d.ts +63 -0
- package/dist/agent/memory/compaction.js +233 -0
- package/dist/agent/memory/compaction.js.map +1 -0
- package/dist/agent/memory/window.d.ts +29 -0
- package/dist/agent/memory/window.js +64 -0
- package/dist/agent/memory/window.js.map +1 -0
- package/dist/agent/model-manager.d.ts +80 -0
- package/dist/agent/model-manager.js +213 -0
- package/dist/agent/model-manager.js.map +1 -0
- package/dist/agent/prompt/heartbeat.d.ts +97 -0
- package/dist/agent/prompt/heartbeat.js +313 -0
- package/dist/agent/prompt/heartbeat.js.map +1 -0
- package/dist/agent/prompt/index.d.ts +65 -0
- package/dist/agent/prompt/index.js +215 -0
- package/dist/agent/prompt/index.js.map +1 -0
- package/dist/agent/prompt/memory/index.d.ts +37 -0
- package/dist/agent/prompt/memory/index.js +241 -0
- package/dist/agent/prompt/memory/index.js.map +1 -0
- package/dist/agent/prompt/modes.d.ts +44 -0
- package/dist/agent/prompt/modes.js +167 -0
- package/dist/agent/prompt/modes.js.map +1 -0
- package/dist/agent/prompt/safety.d.ts +88 -0
- package/dist/agent/prompt/safety.js +290 -0
- package/dist/agent/prompt/safety.js.map +1 -0
- package/dist/agent/service.d.ts +91 -0
- package/dist/agent/service.js +641 -0
- package/dist/agent/service.js.map +1 -0
- package/dist/agent/session-tracker.d.ts +73 -0
- package/dist/agent/session-tracker.js +137 -0
- package/dist/agent/session-tracker.js.map +1 -0
- package/dist/agent/skills/__tests__/test-framework.test.d.ts +4 -0
- package/dist/agent/skills/__tests__/test-framework.test.js +343 -0
- package/dist/agent/skills/__tests__/test-framework.test.js.map +1 -0
- package/dist/agent/skills/config.d.ts +58 -0
- package/dist/agent/skills/config.js +212 -0
- package/dist/agent/skills/config.js.map +1 -0
- package/dist/agent/skills/index.d.ts +25 -0
- package/dist/agent/skills/index.js +349 -0
- package/dist/agent/skills/index.js.map +1 -0
- package/dist/agent/skills/installer.d.ts +38 -0
- package/dist/agent/skills/installer.js +352 -0
- package/dist/agent/skills/installer.js.map +1 -0
- package/dist/agent/skills/scanner.d.ts +32 -0
- package/dist/agent/skills/scanner.js +265 -0
- package/dist/agent/skills/scanner.js.map +1 -0
- package/dist/agent/skills/test-framework.d.ts +107 -0
- package/dist/agent/skills/test-framework.js +607 -0
- package/dist/agent/skills/test-framework.js.map +1 -0
- package/dist/agent/skills/types.d.ts +181 -0
- package/dist/agent/skills/types.js +7 -0
- package/dist/agent/skills/types.js.map +1 -0
- package/dist/agent/skills/watcher.d.ts +37 -0
- package/dist/agent/skills/watcher.js +124 -0
- package/dist/agent/skills/watcher.js.map +1 -0
- package/dist/agent/tools/communication.d.ts +18 -0
- package/dist/agent/tools/communication.js +56 -0
- package/dist/agent/tools/communication.js.map +1 -0
- package/dist/agent/tools/edit-diff.d.ts +21 -0
- package/dist/agent/tools/edit-diff.js +69 -0
- package/dist/agent/tools/edit-diff.js.map +1 -0
- package/dist/agent/tools/edit.d.ts +13 -0
- package/dist/agent/tools/edit.js +65 -0
- package/dist/agent/tools/edit.js.map +1 -0
- package/dist/agent/tools/find.d.ts +24 -0
- package/dist/agent/tools/find.js +99 -0
- package/dist/agent/tools/find.js.map +1 -0
- package/dist/agent/tools/grep.d.ts +33 -0
- package/dist/agent/tools/grep.js +183 -0
- package/dist/agent/tools/grep.js.map +1 -0
- package/dist/agent/tools/index.d.ts +13 -0
- package/dist/agent/tools/index.js +18 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/tools/list-dir.d.ts +6 -0
- package/dist/agent/tools/list-dir.js +37 -0
- package/dist/agent/tools/list-dir.js.map +1 -0
- package/dist/agent/tools/memory-tool.d.ts +14 -0
- package/dist/agent/tools/memory-tool.js +81 -0
- package/dist/agent/tools/memory-tool.js.map +1 -0
- package/dist/agent/tools/path-utils.d.ts +4 -0
- package/dist/agent/tools/path-utils.js +13 -0
- package/dist/agent/tools/path-utils.js.map +1 -0
- package/dist/agent/tools/read.d.ts +7 -0
- package/dist/agent/tools/read.js +47 -0
- package/dist/agent/tools/read.js.map +1 -0
- package/dist/agent/tools/send-media.d.ts +18 -0
- package/dist/agent/tools/send-media.js +104 -0
- package/dist/agent/tools/send-media.js.map +1 -0
- package/dist/agent/tools/shell.d.ts +13 -0
- package/dist/agent/tools/shell.js +114 -0
- package/dist/agent/tools/shell.js.map +1 -0
- package/dist/agent/tools/truncate.d.ts +36 -0
- package/dist/agent/tools/truncate.js +98 -0
- package/dist/agent/tools/truncate.js.map +1 -0
- package/dist/agent/tools/web.d.ts +14 -0
- package/dist/agent/tools/web.js +109 -0
- package/dist/agent/tools/web.js.map +1 -0
- package/dist/agent/tools/write.d.ts +7 -0
- package/dist/agent/tools/write.js +35 -0
- package/dist/agent/tools/write.js.map +1 -0
- package/dist/agent/types.d.ts +8 -0
- package/dist/agent/types.js +2 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent/typing.d.ts +9 -0
- package/dist/agent/typing.js +32 -0
- package/dist/agent/typing.js.map +1 -0
- package/dist/auth/index.d.ts +12 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth/anthropic.d.ts +7 -0
- package/dist/auth/oauth/anthropic.js +89 -0
- package/dist/auth/oauth/anthropic.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts +8 -0
- package/dist/auth/oauth/github-copilot.js +35 -0
- package/dist/auth/oauth/github-copilot.js.map +1 -0
- package/dist/auth/oauth/google-antigravity.d.ts +7 -0
- package/dist/auth/oauth/google-antigravity.js +27 -0
- package/dist/auth/oauth/google-antigravity.js.map +1 -0
- package/dist/auth/oauth/google-gemini-cli.d.ts +7 -0
- package/dist/auth/oauth/google-gemini-cli.js +28 -0
- package/dist/auth/oauth/google-gemini-cli.js.map +1 -0
- package/dist/auth/oauth/index.d.ts +14 -0
- package/dist/auth/oauth/index.js +15 -0
- package/dist/auth/oauth/index.js.map +1 -0
- package/dist/auth/oauth/kimi.d.ts +8 -0
- package/dist/auth/oauth/kimi.js +104 -0
- package/dist/auth/oauth/kimi.js.map +1 -0
- package/dist/auth/oauth/minimax.d.ts +8 -0
- package/dist/auth/oauth/minimax.js +109 -0
- package/dist/auth/oauth/minimax.js.map +1 -0
- package/dist/auth/oauth/openai-codex.d.ts +7 -0
- package/dist/auth/oauth/openai-codex.js +33 -0
- package/dist/auth/oauth/openai-codex.js.map +1 -0
- package/dist/auth/oauth/pkce.d.ts +8 -0
- package/dist/auth/oauth/pkce.js +22 -0
- package/dist/auth/oauth/pkce.js.map +1 -0
- package/dist/auth/oauth/qwen.d.ts +7 -0
- package/dist/auth/oauth/qwen.js +114 -0
- package/dist/auth/oauth/qwen.js.map +1 -0
- package/dist/auth/oauth/types.d.ts +46 -0
- package/dist/auth/oauth/types.js +7 -0
- package/dist/auth/oauth/types.js.map +1 -0
- package/dist/auth/profiles/index.d.ts +16 -0
- package/dist/auth/profiles/index.js +17 -0
- package/dist/auth/profiles/index.js.map +1 -0
- package/dist/auth/profiles/oauth.d.ts +12 -0
- package/dist/auth/profiles/oauth.js +106 -0
- package/dist/auth/profiles/oauth.js.map +1 -0
- package/dist/auth/profiles/order.d.ts +19 -0
- package/dist/auth/profiles/order.js +63 -0
- package/dist/auth/profiles/order.js.map +1 -0
- package/dist/auth/profiles/profiles.d.ts +27 -0
- package/dist/auth/profiles/profiles.js +110 -0
- package/dist/auth/profiles/profiles.js.map +1 -0
- package/dist/auth/profiles/store.d.ts +17 -0
- package/dist/auth/profiles/store.js +234 -0
- package/dist/auth/profiles/store.js.map +1 -0
- package/dist/auth/profiles/types.d.ts +64 -0
- package/dist/auth/profiles/types.js +7 -0
- package/dist/auth/profiles/types.js.map +1 -0
- package/dist/auth/profiles/usage.d.ts +24 -0
- package/dist/auth/profiles/usage.js +99 -0
- package/dist/auth/profiles/usage.js.map +1 -0
- package/dist/auth/storage.d.ts +99 -0
- package/dist/auth/storage.js +315 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/bus/index.d.ts +3 -0
- package/dist/bus/index.js +2 -0
- package/dist/bus/index.js.map +1 -0
- package/dist/bus/queue.d.ts +20 -0
- package/dist/bus/queue.js +57 -0
- package/dist/bus/queue.js.map +1 -0
- package/dist/channels/__tests__/access-control.test.d.ts +4 -0
- package/dist/channels/__tests__/access-control.test.js +310 -0
- package/dist/channels/__tests__/access-control.test.js.map +1 -0
- package/dist/channels/__tests__/draft-stream.test.d.ts +4 -0
- package/dist/channels/__tests__/draft-stream.test.js +243 -0
- package/dist/channels/__tests__/draft-stream.test.js.map +1 -0
- package/dist/channels/__tests__/format.test.d.ts +4 -0
- package/dist/channels/__tests__/format.test.js +146 -0
- package/dist/channels/__tests__/format.test.js.map +1 -0
- package/dist/channels/__tests__/manager.test.d.ts +6 -0
- package/dist/channels/__tests__/manager.test.js +34 -0
- package/dist/channels/__tests__/manager.test.js.map +1 -0
- package/dist/channels/__tests__/typing-controller.test.d.ts +4 -0
- package/dist/channels/__tests__/typing-controller.test.js +109 -0
- package/dist/channels/__tests__/typing-controller.test.js.map +1 -0
- package/dist/channels/__tests__/update-offset-store.test.d.ts +7 -0
- package/dist/channels/__tests__/update-offset-store.test.js +35 -0
- package/dist/channels/__tests__/update-offset-store.test.js.map +1 -0
- package/dist/channels/access-control.d.ts +93 -0
- package/dist/channels/access-control.js +201 -0
- package/dist/channels/access-control.js.map +1 -0
- package/dist/channels/draft-stream.d.ts +55 -0
- package/dist/channels/draft-stream.js +211 -0
- package/dist/channels/draft-stream.js.map +1 -0
- package/dist/channels/format.d.ts +38 -0
- package/dist/channels/format.js +187 -0
- package/dist/channels/format.js.map +1 -0
- package/dist/channels/index.d.ts +22 -0
- package/dist/channels/index.js +23 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/manager.d.ts +30 -0
- package/dist/channels/manager.js +125 -0
- package/dist/channels/manager.js.map +1 -0
- package/dist/channels/telegram/__tests__/index.test.d.ts +4 -0
- package/dist/channels/telegram/__tests__/index.test.js +153 -0
- package/dist/channels/telegram/__tests__/index.test.js.map +1 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.d.ts +4 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.js +99 -0
- package/dist/channels/telegram/__tests__/inline-keyboards.test.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +48 -0
- package/dist/channels/telegram/client.js +177 -0
- package/dist/channels/telegram/client.js.map +1 -0
- package/dist/channels/telegram/command-handler.d.ts +28 -0
- package/dist/channels/telegram/command-handler.js +209 -0
- package/dist/channels/telegram/command-handler.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +8 -0
- package/dist/channels/telegram/index.js +9 -0
- package/dist/channels/telegram/index.js.map +1 -0
- package/dist/channels/telegram/inline-keyboards.d.ts +20 -0
- package/dist/channels/telegram/inline-keyboards.js +38 -0
- package/dist/channels/telegram/inline-keyboards.js.map +1 -0
- package/dist/channels/telegram/plugin.d.ts +33 -0
- package/dist/channels/telegram/plugin.js +640 -0
- package/dist/channels/telegram/plugin.js.map +1 -0
- package/dist/channels/telegram/webhook.d.ts +31 -0
- package/dist/channels/telegram/webhook.js +129 -0
- package/dist/channels/telegram/webhook.js.map +1 -0
- package/dist/channels/types.d.ts +186 -0
- package/dist/channels/types.js +7 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/typing-controller.d.ts +47 -0
- package/dist/channels/typing-controller.js +117 -0
- package/dist/channels/typing-controller.js.map +1 -0
- package/dist/channels/update-offset-store.d.ts +37 -0
- package/dist/channels/update-offset-store.js +165 -0
- package/dist/channels/update-offset-store.js.map +1 -0
- package/dist/channels/whatsapp/index.d.ts +4 -0
- package/dist/channels/whatsapp/index.js +5 -0
- package/dist/channels/whatsapp/index.js.map +1 -0
- package/dist/channels/whatsapp/plugin.d.ts +27 -0
- package/dist/channels/whatsapp/plugin.js +66 -0
- package/dist/channels/whatsapp/plugin.js.map +1 -0
- package/dist/cli/__tests__/registry.test.d.ts +1 -0
- package/dist/cli/__tests__/registry.test.js +366 -0
- package/dist/cli/__tests__/registry.test.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +1 -0
- package/dist/cli/commands/agent.js +216 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +6 -0
- package/dist/cli/commands/auth.js +440 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/config.d.ts +1 -0
- package/dist/cli/commands/config.js +135 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/configure.d.ts +1 -0
- package/dist/cli/commands/configure.js +173 -0
- package/dist/cli/commands/configure.js.map +1 -0
- package/dist/cli/commands/cron.d.ts +1 -0
- package/dist/cli/commands/cron.js +81 -0
- package/dist/cli/commands/cron.js.map +1 -0
- package/dist/cli/commands/gateway.d.ts +1 -0
- package/dist/cli/commands/gateway.js +91 -0
- package/dist/cli/commands/gateway.js.map +1 -0
- package/dist/cli/commands/index.d.ts +0 -0
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/models.d.ts +1 -0
- package/dist/cli/commands/models.js +79 -0
- package/dist/cli/commands/models.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +1 -0
- package/dist/cli/commands/onboard.js +621 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +1 -0
- package/dist/cli/commands/plugin.js +341 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/session.d.ts +1 -0
- package/dist/cli/commands/session.js +450 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/skills-test.d.ts +9 -0
- package/dist/cli/commands/skills-test.js +195 -0
- package/dist/cli/commands/skills-test.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +9 -0
- package/dist/cli/commands/skills.js +385 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/index.d.ts +19 -0
- package/dist/cli/index.js +40 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/registry.d.ts +43 -0
- package/dist/cli/registry.js +82 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/cli/templates.d.ts +19 -0
- package/dist/cli/templates.js +191 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/utils/colors.d.ts +13 -0
- package/dist/cli/utils/colors.js +16 -0
- package/dist/cli/utils/colors.js.map +1 -0
- package/dist/config/__tests__/diff.test.d.ts +1 -0
- package/dist/config/__tests__/diff.test.js +192 -0
- package/dist/config/__tests__/diff.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +1 -0
- package/dist/config/__tests__/loader.test.js +356 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/paths.test.d.ts +1 -0
- package/dist/config/__tests__/paths.test.js +192 -0
- package/dist/config/__tests__/paths.test.js.map +1 -0
- package/dist/config/__tests__/reload.test.d.ts +1 -0
- package/dist/config/__tests__/reload.test.js +374 -0
- package/dist/config/__tests__/reload.test.js.map +1 -0
- package/dist/config/__tests__/rules.test.d.ts +1 -0
- package/dist/config/__tests__/rules.test.js +204 -0
- package/dist/config/__tests__/rules.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +1 -0
- package/dist/config/__tests__/schema.test.js +672 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/diff.d.ts +7 -0
- package/dist/config/diff.js +46 -0
- package/dist/config/diff.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +5 -0
- package/dist/config/loader.js +81 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/paths.d.ts +35 -0
- package/dist/config/paths.js +79 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/reload.d.ts +78 -0
- package/dist/config/reload.js +190 -0
- package/dist/config/reload.js.map +1 -0
- package/dist/config/rules.d.ts +42 -0
- package/dist/config/rules.js +114 -0
- package/dist/config/rules.js.map +1 -0
- package/dist/config/schema.d.ts +1340 -0
- package/dist/config/schema.js +611 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/cron/executor.d.ts +54 -0
- package/dist/cron/executor.js +364 -0
- package/dist/cron/executor.js.map +1 -0
- package/dist/cron/index.d.ts +5 -0
- package/dist/cron/index.js +6 -0
- package/dist/cron/index.js.map +1 -0
- package/dist/cron/persistence.d.ts +61 -0
- package/dist/cron/persistence.js +188 -0
- package/dist/cron/persistence.js.map +1 -0
- package/dist/cron/service.d.ts +94 -0
- package/dist/cron/service.js +382 -0
- package/dist/cron/service.js.map +1 -0
- package/dist/cron/types.d.ts +119 -0
- package/dist/cron/types.js +3 -0
- package/dist/cron/types.js.map +1 -0
- package/dist/cron/validation.d.ts +144 -0
- package/dist/cron/validation.js +113 -0
- package/dist/cron/validation.js.map +1 -0
- package/dist/errors/__tests__/index.test.d.ts +1 -0
- package/dist/errors/__tests__/index.test.js +301 -0
- package/dist/errors/__tests__/index.test.js.map +1 -0
- package/dist/errors/index.d.ts +114 -0
- package/dist/errors/index.js +278 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/gateway/hono/app.d.ts +7 -0
- package/dist/gateway/hono/app.js +668 -0
- package/dist/gateway/hono/app.js.map +1 -0
- package/dist/gateway/hono/index.d.ts +2 -0
- package/dist/gateway/hono/index.js +3 -0
- package/dist/gateway/hono/index.js.map +1 -0
- package/dist/gateway/hono/middleware/auth.d.ts +18 -0
- package/dist/gateway/hono/middleware/auth.js +79 -0
- package/dist/gateway/hono/middleware/auth.js.map +1 -0
- package/dist/gateway/hono/middleware/logger.d.ts +1 -0
- package/dist/gateway/hono/middleware/logger.js +17 -0
- package/dist/gateway/hono/middleware/logger.js.map +1 -0
- package/dist/gateway/hono/sse.d.ts +55 -0
- package/dist/gateway/hono/sse.js +224 -0
- package/dist/gateway/hono/sse.js.map +1 -0
- package/dist/gateway/index.d.ts +4 -0
- package/dist/gateway/index.js +5 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/protocol.d.ts +28 -0
- package/dist/gateway/protocol.js +14 -0
- package/dist/gateway/protocol.js.map +1 -0
- package/dist/gateway/server.d.ts +19 -0
- package/dist/gateway/server.js +64 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/gateway/service.d.ts +265 -0
- package/dist/gateway/service.js +621 -0
- package/dist/gateway/service.js.map +1 -0
- package/dist/gateway/static/root/assets/main-CfIxL-cL.js +2105 -0
- package/dist/gateway/static/root/assets/main-CfIxL-cL.js.map +1 -0
- package/dist/gateway/static/root/assets/main-DndcTCgX.css +1 -0
- package/dist/gateway/static/root/index.html +116 -0
- package/dist/heartbeat/index.d.ts +1 -0
- package/dist/heartbeat/index.js +2 -0
- package/dist/heartbeat/index.js.map +1 -0
- package/dist/heartbeat/service.d.ts +19 -0
- package/dist/heartbeat/service.js +61 -0
- package/dist/heartbeat/service.js.map +1 -0
- package/dist/plugin-sdk/index.d.ts +21 -0
- package/dist/plugin-sdk/index.js +12 -0
- package/dist/plugin-sdk/index.js.map +1 -0
- package/dist/plugins/__tests__/api.test.d.ts +1 -0
- package/dist/plugins/__tests__/api.test.js +164 -0
- package/dist/plugins/__tests__/api.test.js.map +1 -0
- package/dist/plugins/__tests__/hooks.test.d.ts +1 -0
- package/dist/plugins/__tests__/hooks.test.js +159 -0
- package/dist/plugins/__tests__/hooks.test.js.map +1 -0
- package/dist/plugins/__tests__/loader.test.d.ts +1 -0
- package/dist/plugins/__tests__/loader.test.js +120 -0
- package/dist/plugins/__tests__/loader.test.js.map +1 -0
- package/dist/plugins/api.d.ts +41 -0
- package/dist/plugins/api.js +131 -0
- package/dist/plugins/api.js.map +1 -0
- package/dist/plugins/hooks.d.ts +153 -0
- package/dist/plugins/hooks.js +172 -0
- package/dist/plugins/hooks.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/install.d.ts +59 -0
- package/dist/plugins/install.js +324 -0
- package/dist/plugins/install.js.map +1 -0
- package/dist/plugins/loader.d.ts +84 -0
- package/dist/plugins/loader.js +545 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/types.d.ts +190 -0
- package/dist/plugins/types.js +7 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/providers/__tests__/registry.test.d.ts +1 -0
- package/dist/providers/__tests__/registry.test.js +110 -0
- package/dist/providers/__tests__/registry.test.js.map +1 -0
- package/dist/providers/api-strategies.d.ts +15 -0
- package/dist/providers/api-strategies.js +96 -0
- package/dist/providers/api-strategies.js.map +1 -0
- package/dist/providers/auto-discovery.d.ts +84 -0
- package/dist/providers/auto-discovery.js +236 -0
- package/dist/providers/auto-discovery.js.map +1 -0
- package/dist/providers/config.d.ts +25 -0
- package/dist/providers/config.js +42 -0
- package/dist/providers/config.js.map +1 -0
- package/dist/providers/index.d.ts +25 -0
- package/dist/providers/index.js +55 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-catalog.d.ts +205 -0
- package/dist/providers/model-catalog.js +1071 -0
- package/dist/providers/model-catalog.js.map +1 -0
- package/dist/providers/models-dev-data.d.ts +11 -0
- package/dist/providers/models-dev-data.js +1035 -0
- package/dist/providers/models-dev-data.js.map +1 -0
- package/dist/providers/models-dev.d.ts +30 -0
- package/dist/providers/models-dev.js +42 -0
- package/dist/providers/models-dev.js.map +1 -0
- package/dist/providers/pi-ai.d.ts +62 -0
- package/dist/providers/pi-ai.js +221 -0
- package/dist/providers/pi-ai.js.map +1 -0
- package/dist/providers/provider-catalog.d.ts +173 -0
- package/dist/providers/provider-catalog.js +834 -0
- package/dist/providers/provider-catalog.js.map +1 -0
- package/dist/providers/registry.d.ts +155 -0
- package/dist/providers/registry.js +524 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/types.d.ts +95 -0
- package/dist/providers/types.js +7 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session/chat-manager.d.ts +49 -0
- package/dist/session/chat-manager.js +167 -0
- package/dist/session/chat-manager.js.map +1 -0
- package/dist/session/chat-types.d.ts +53 -0
- package/dist/session/chat-types.js +63 -0
- package/dist/session/chat-types.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.js +5 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +103 -0
- package/dist/session/manager.js +200 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/store.d.ts +114 -0
- package/dist/session/store.js +687 -0
- package/dist/session/store.js.map +1 -0
- package/dist/session/types.d.ts +88 -0
- package/dist/session/types.js +10 -0
- package/dist/session/types.js.map +1 -0
- package/dist/types/index.d.ts +177 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/providers.d.ts +67 -0
- package/dist/types/providers.js +7 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +17 -0
- package/dist/utils/frontmatter.js +104 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/helpers.d.ts +5 -0
- package/dist/utils/helpers.js +36 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/log-store.d.ts +78 -0
- package/dist/utils/log-store.js +432 -0
- package/dist/utils/log-store.js.map +1 -0
- package/dist/utils/logger.d.ts +127 -0
- package/dist/utils/logger.js +481 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/logger.types.d.ts +152 -0
- package/dist/utils/logger.types.js +30 -0
- package/dist/utils/logger.types.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,Fira Code,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}input:where([type=text]),input:where(:not([type])),input:where([type=email]),input:where([type=url]),input:where([type=password]),input:where([type=number]),input:where([type=date]),input:where([type=datetime-local]),input:where([type=month]),input:where([type=search]),input:where([type=tel]),input:where([type=time]),input:where([type=week]),select:where([multiple]),textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow: 0 0 #0000}input:where([type=text]):focus,input:where(:not([type])):focus,input:where([type=email]):focus,input:where([type=url]):focus,input:where([type=password]):focus,input:where([type=number]):focus,input:where([type=date]):focus,input:where([type=datetime-local]):focus,input:where([type=month]):focus,input:where([type=search]):focus,input:where([type=tel]):focus,input:where([type=time]):focus,input:where([type=week]):focus,select:where([multiple]):focus,textarea:focus,select:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}select{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}select:where([multiple]),select:where([size]:not([size="1"])){background-image:initial;background-position:initial;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}input:where([type=checkbox]),input:where([type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;--tw-shadow: 0 0 #0000}input:where([type=checkbox]){border-radius:0}input:where([type=radio]){border-radius:100%}input:where([type=checkbox]):focus,input:where([type=radio]):focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 2px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}input:where([type=checkbox]):checked,input:where([type=radio]):checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}input:where([type=checkbox]):checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")}@media(forced-colors:active){input:where([type=checkbox]):checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}input:where([type=radio]):checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")}@media(forced-colors:active){input:where([type=radio]):checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}input:where([type=checkbox]):checked:hover,input:where([type=checkbox]):checked:focus,input:where([type=radio]):checked:hover,input:where([type=radio]):checked:focus{border-color:transparent;background-color:currentColor}input:where([type=checkbox]):indeterminate{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}@media(forced-colors:active){input:where([type=checkbox]):indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}input:where([type=checkbox]):indeterminate:hover,input:where([type=checkbox]):indeterminate:focus{border-color:transparent;background-color:currentColor}input:where([type=file]){background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}input:where([type=file]):focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.fixed{position:fixed}.mx-auto{margin-left:auto;margin-right:auto}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-2{margin-top:.5rem}.block{display:block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-full{height:100%}.h-screen{height:100vh}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.max-w-3xl{max-width:48rem}.max-w-\[85\%\]{max-width:85%}.max-w-\[calc\(100\%-3rem\)\]{max-width:calc(100% - 3rem)}.max-w-full{max-width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}@keyframes pulse{50%{opacity:.5}}@keyframes spin{to{transform:rotate(360deg)}0%{transform:rotate(0)}to{transform:rotate(360deg)}}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.items-center{align-items:center}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.overflow-y-auto{overflow-y:auto}.whitespace-pre-wrap{white-space:pre-wrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.75rem}.rounded-xl{border-radius:1rem}.border{border-width:1px}.border-2{border-width:2px}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity))}.border-t-transparent{border-top-color:transparent}.bg-background{background-color:var(--bg-primary)}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity))}.bg-primary-light{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity))}.bg-secondary{background-color:var(--text-secondary)}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.pb-0{padding-bottom:0}.pb-4{padding-bottom:1rem}.text-center{text-align:center}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity))}.text-foreground{color:var(--text-primary)}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity))}.text-muted{color:var(--text-muted)}.text-primary{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity))}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}:root,html.light{--bg-primary: #fafaf9;--bg-secondary: #f5f5f4;--bg-tertiary: #e7e5e4;--bg-hover: #d6d3d1;--text-primary: #1c1917;--text-secondary: #57534e;--text-muted: #a8a29e;--text-inverse: #fafaf9;--accent-primary: #4f46e5;--accent-primary-hover: #4338ca;--accent-primary-light: #e0e7ff;--accent-primary-soft: #c7d2fe;--accent-success: #059669;--accent-success-light: #d1fae5;--accent-success-soft: #a7f3d0;--accent-warning: #d97706;--accent-warning-light: #fef3c7;--accent-warning-soft: #fde68a;--accent-error: #dc2626;--accent-error-light: #fee2e2;--accent-error-soft: #fecaca;--accent-info: #0891b2;--accent-info-light: #cffafe;--accent-info-soft: #a5f3fc;--border-color: #e7e5e4;--border-strong: #d6d3d1;--border-subtle: #f5f5f4;--shadow-xs: 0 1px 2px 0 rgb(28 25 23 / .05);--shadow-sm: 0 1px 3px 0 rgb(28 25 23 / .08), 0 1px 2px -1px rgb(28 25 23 / .05);--shadow-md: 0 4px 6px -1px rgb(28 25 23 / .08), 0 2px 4px -2px rgb(28 25 23 / .05);--shadow-lg: 0 10px 15px -3px rgb(28 25 23 / .08), 0 4px 6px -4px rgb(28 25 23 / .05);--shadow-xl: 0 20px 25px -5px rgb(28 25 23 / .08), 0 8px 10px -6px rgb(28 25 23 / .05);--shadow-glow: 0 0 20px -5px rgb(79 70 229 / .3);--gradient-primary: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #db2777 100%);--gradient-surface: linear-gradient(180deg, #ffffff 0%, #fafaf9 100%);--gradient-subtle: linear-gradient(180deg, rgba(255,255,255,.8) 0%, rgba(255,255,255,0) 100%);--radius-xs: .25rem;--radius-sm: .375rem;--radius-md: .5rem;--radius-lg: .75rem;--radius-xl: 1rem;--radius-2xl: 1.5rem;--radius-full: 9999px;--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;--font-mono: "JetBrains Mono", "Fira Code", "SF Mono", Consolas, monospace;--transition-fast: .15s cubic-bezier(.4, 0, .2, 1);--transition-normal: .2s cubic-bezier(.4, 0, .2, 1);--transition-slow: .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: .3s cubic-bezier(.34, 1.56, .64, 1)}html.dark{--bg-primary: #121212;--bg-secondary: #1a1a1a;--bg-tertiary: #242424;--bg-hover: #333333;--text-primary: #E0E0E0;--text-secondary: #B0B0B0;--text-muted: #707070;--text-inverse: #121212;--accent-primary: #888888;--accent-primary-hover: #a0a0a0;--accent-primary-light: #2a2a2a;--accent-primary-soft: #444444;--accent-success: #6b9b6b;--accent-success-light: #1a2e1a;--accent-success-soft: #2a3f2a;--accent-warning: #c4a35a;--accent-warning-light: #2a2515;--accent-warning-soft: #3f3520;--accent-error: #b55a5a;--accent-error-light: #2a1515;--accent-error-soft: #3f2020;--accent-info: #5a8a9a;--accent-info-light: #152a30;--accent-info-soft: #203f4a;--border-color: #444444;--border-strong: #555555;--border-subtle: #333333;--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .4);--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .5), 0 1px 2px -1px rgb(0 0 0 / .4);--shadow-md: 0 4px 6px -1px rgb(0 0 0 / .5), 0 2px 4px -2px rgb(0 0 0 / .4);--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .5), 0 4px 6px -4px rgb(0 0 0 / .4);--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .5), 0 8px 10px -6px rgb(0 0 0 / .4);--shadow-glow: 0 0 30px -5px rgb(136 136 136 / .15);--gradient-primary: linear-gradient(135deg, #888888 0%, #999999 50%, #777777 100%);--gradient-surface: linear-gradient(180deg, #1a1a1a 0%, #121212 100%);--gradient-subtle: linear-gradient(180deg, rgba(26,26,26,.8) 0%, rgba(18,18,18,0) 100%)}@media(prefers-color-scheme:dark){:root:not(.light):not(.dark){--bg-primary: #121212;--bg-secondary: #1a1a1a;--bg-tertiary: #242424;--bg-hover: #333333;--text-primary: #E0E0E0;--text-secondary: #B0B0B0;--text-muted: #707070;--text-inverse: #121212;--accent-primary: #888888;--accent-primary-hover: #a0a0a0;--accent-primary-light: #2a2a2a;--accent-primary-soft: #444444;--accent-success: #6b9b6b;--accent-success-light: #1a2e1a;--accent-success-soft: #2a3f2a;--accent-warning: #c4a35a;--accent-warning-light: #2a2515;--accent-warning-soft: #3f3520;--accent-error: #b55a5a;--accent-error-light: #2a1515;--accent-error-soft: #3f2020;--accent-info: #5a8a9a;--accent-info-light: #152a30;--accent-info-soft: #203f4a;--border-color: #444444;--border-strong: #555555;--border-subtle: #333333;--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .4);--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .5), 0 1px 2px -1px rgb(0 0 0 / .4);--shadow-md: 0 4px 6px -1px rgb(0 0 0 / .5), 0 2px 4px -2px rgb(0 0 0 / .4);--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .5), 0 4px 6px -4px rgb(0 0 0 / .4);--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .5), 0 8px 10px -6px rgb(0 0 0 / .4);--shadow-glow: 0 0 30px -5px rgb(136 136 136 / .15);--gradient-primary: linear-gradient(135deg, #888888 0%, #999999 50%, #777777 100%);--gradient-surface: linear-gradient(180deg, #1c1917 0%, #0c0a09 100%);--gradient-subtle: linear-gradient(180deg, rgba(28,25,23,.8) 0%, rgba(12,10,9,0) 100%)}}*{box-sizing:border-box}html,body{margin:0;padding:0;height:100%;font-family:var(--font-sans);background:var(--bg-primary);color:var(--text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transition:background-color var(--transition-normal),color var(--transition-normal)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:var(--radius-full);border:2px solid var(--bg-primary)}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}*{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}@keyframes pulse{0%,to{opacity:1}50%{opacity:.6}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slideIn{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-spin{animation:spin 1s linear infinite}.streaming-cursor:after{content:"|";animation:blink 1s step-end infinite;color:var(--accent-primary);font-weight:300}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}.avatar{width:2rem;height:2rem;border-radius:var(--radius-full);display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:600;flex-shrink:0;background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-color);transition:all var(--transition-fast)}.avatar.user{background:var(--gradient-primary);color:#fff;border:none;box-shadow:var(--shadow-sm)}.avatar.assistant{background:linear-gradient(135deg,var(--accent-primary-soft) 0%,var(--accent-primary) 100%);color:#fff;border:none;box-shadow:var(--shadow-sm)}.avatar.tool{background:var(--bg-secondary);color:var(--text-muted)}.message-bubble{border-radius:var(--radius-lg);padding:.875rem 1rem;transition:all var(--transition-fast);max-width:100%;word-wrap:break-word}.message-bubble.user{background:linear-gradient(135deg,var(--accent-primary) 0%,var(--accent-primary-hover) 100%);color:#fff;box-shadow:var(--shadow-md)}.message-bubble.assistant{background:var(--bg-secondary);border:1px solid var(--border-color);box-shadow:var(--shadow-sm)}.message-item{display:flex;gap:.75rem;animation:fadeIn var(--transition-normal) ease-out;margin-bottom:1rem}.shell{display:flex;flex-direction:column;height:100vh;width:100vw;background:var(--bg-primary);overflow:hidden}.topbar{display:flex;align-items:center;justify-content:space-between;height:3.5rem;padding:0 1rem;background:var(--bg-primary);border-bottom:1px solid var(--border-color);flex-shrink:0;z-index:50}.topbar-left,.brand{display:flex;align-items:center;gap:.75rem}.brand-logo{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:var(--radius-md);background:var(--gradient-primary);box-shadow:var(--shadow-glow)}.brand-text{display:flex;flex-direction:column}.brand-title{font-size:.875rem;font-weight:700;letter-spacing:.05em;background:var(--gradient-primary);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.brand-sub{font-size:.6875rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.1em}.topbar-status{display:flex;align-items:center;gap:.5rem}.pill-toggle{display:inline-flex;background:var(--bg-tertiary);border-radius:var(--radius-md);padding:2px}.pill-btn{display:inline-flex;align-items:center;justify-content:center;padding:.375rem .5rem;border:none;background:transparent;color:var(--text-muted);font-size:.75rem;font-weight:500;border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition-fast);min-width:28px}.pill-btn:hover{color:var(--text-secondary)}.pill-btn.active{background:var(--bg-primary);color:var(--accent-primary);font-weight:600;box-shadow:var(--shadow-sm)}.shell-main{display:flex;flex:1;min-height:0;position:relative;overflow:hidden}.nav{width:16rem;background:var(--bg-primary);border-right:1px solid var(--border-color);display:flex;flex-direction:column;flex-shrink:0;transition:width var(--transition-normal),transform var(--transition-normal);overflow-y:auto;z-index:40}.nav--collapsed{width:4.5rem}.nav-overlay{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:35;animation:fadeIn var(--transition-fast)}.nav-group{padding:.5rem 0}.nav-label{padding:1rem 1.25rem .5rem;font-size:.7rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em}.nav--collapsed .nav-label{display:none}.nav-item{display:flex;align-items:center;gap:.75rem;padding:.625rem 1.25rem;margin:.125rem .5rem;border-radius:var(--radius-md);font-size:.875rem;font-weight:500;color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast);position:relative}.nav-item:hover{background:var(--bg-secondary);color:var(--text-primary)}.nav-item--active{background:var(--accent-primary-light);color:var(--accent-primary);font-weight:600}.nav-item--active:before{content:"";position:absolute;left:-.5rem;top:.5rem;bottom:.5rem;width:3px;background:var(--accent-primary);border-radius:0 var(--radius-full) var(--radius-full) 0}.nav--collapsed .nav-item__text{display:none}.nav-item__icon{width:1.25rem;display:flex;justify-content:center;flex-shrink:0}.content{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--bg-primary)}.page-title{font-size:1rem;font-weight:600}.chat-container{display:flex;flex-direction:column;flex:1;overflow:hidden;height:100%}.chat-messages{flex:1;overflow-y:auto;padding:1.5rem 0;position:relative}.chat-messages-inner{max-width:80rem;margin:0 auto;padding:0 1rem;width:100%}.chat-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-bottom:1px solid var(--border-color, #e5e7eb);background:var(--bg-primary, #fff);flex-shrink:0}.chat-header-title{display:flex;align-items:center;font-size:1rem;color:var(--text-primary)}.new-session-btn{display:flex;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.875rem;font-weight:500;color:var(--text-primary);background:var(--bg-secondary, #f3f4f6);border:1px solid var(--border-color, #e5e7eb);border-radius:.5rem;cursor:pointer;transition:background .2s,border-color .2s}.new-session-btn:hover{background:var(--bg-tertiary, #e5e7eb)}.scroll-to-bottom-btn{position:absolute;bottom:1rem;right:1.5rem;width:2.5rem;height:2.5rem;border-radius:50%;background:var(--color-primary, #3b82f6);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px #00000026;transition:transform .2s,background .2s;z-index:10}.scroll-to-bottom-btn:hover{transform:scale(1.05);background:var(--color-primary-hover, #2563eb)}.chat-input-container{padding:0 1.5rem 1.5rem;flex-shrink:0}.chat-input-inner{max-width:80rem;margin:0 auto;width:100%}.editor-container{background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);display:flex;flex-direction:column;transition:all var(--transition-normal)}.editor-container:focus-within{border-color:var(--accent-primary);box-shadow:0 0 0 2px var(--accent-primary-light),var(--shadow-md);background:var(--bg-primary)}.input-row{display:flex;align-items:flex-end;gap:.5rem;padding:.5rem 1rem}.text-input{flex:1;background:transparent;border:none;outline:none;resize:none;font-size:.9375rem;line-height:1.5;padding:.5rem 0;min-height:2.5rem;max-height:15rem;color:var(--text-primary)}.input-actions{display:flex;align-items:center;gap:.5rem;padding-bottom:.25rem}.attach-btn,.send-btn,.stop-btn{width:2.25rem;height:2.25rem;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md);border:1px solid var(--border-color);background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast);flex-shrink:0}.attach-btn:hover{background:var(--bg-tertiary)}.send-btn.active{background:var(--accent-primary);color:#fff;border-color:var(--accent-primary)}.stop-btn{background:var(--accent-error);color:#fff;border-color:var(--accent-error)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center;color:var(--text-muted);padding-bottom:5rem}.empty-state .icon{font-size:3rem;margin-bottom:1rem}@media(max-width:768px){.nav{position:fixed;top:3.5rem;left:0;bottom:0;width:16rem;transform:translate(-100%);box-shadow:var(--shadow-xl)}.nav--mobile-open{transform:translate(0)}.content-header{display:none}.chat-input-container{padding:0 1rem 1rem}.input-row{flex-wrap:wrap;padding:.75rem}.text-input{flex:0 0 100%;order:-1;margin-bottom:.5rem;min-height:3rem}.attach-btn{order:1}.input-actions{flex:1;order:2;justify-content:flex-end;gap:.5rem;padding-bottom:0}.attach-btn,.send-btn,.stop-btn{width:2rem;height:2rem}}.settings-overlay{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:100;animation:fadeIn var(--transition-fast)}.settings-dialog{width:100%;max-width:56rem;height:80vh;background:var(--bg-primary);border-radius:var(--radius-xl);box-shadow:var(--shadow-xl);display:flex;flex-direction:column;overflow:hidden;animation:slideIn var(--transition-normal)}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.5rem;border-bottom:1px solid var(--border-color);flex-shrink:0}.settings-title{display:flex;align-items:center;gap:.5rem;font-size:1.125rem;font-weight:600;color:var(--text-primary)}.close-btn{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:var(--radius-md);color:var(--text-muted);background:transparent;border:none;cursor:pointer;transition:all var(--transition-fast)}.close-btn:hover{background:var(--bg-secondary);color:var(--text-primary)}.settings-content{display:flex;flex:1;overflow:hidden}.settings-sidebar{width:14rem;border-right:1px solid var(--border-color);padding:1rem .5rem;overflow-y:auto;flex-shrink:0;background:var(--bg-primary)}.sidebar-item{display:flex;align-items:center;gap:.75rem;width:100%;padding:.625rem 1rem;border-radius:var(--radius-md);font-size:.875rem;font-weight:500;color:var(--text-secondary);background:transparent;border:1px solid transparent;cursor:pointer;transition:all var(--transition-fast);text-align:left;margin-bottom:.25rem}.sidebar-item:hover{background:var(--bg-secondary);color:var(--text-primary)}.sidebar-item.active{background:var(--accent-primary-light);color:var(--accent-primary)}.sidebar-item .chevron{margin-left:auto;opacity:0;transition:opacity var(--transition-fast)}.sidebar-item.active .chevron{opacity:1}.settings-main{flex:1;padding:1.5rem 2rem;overflow-y:auto;background:var(--bg-primary)}.section-header{margin-bottom:1.5rem}.section-header h2{font-size:1.25rem;font-weight:600;color:var(--text-primary);margin:0 0 .25rem}.section-description{font-size:.875rem;color:var(--text-muted);margin:0}.fields-grid{display:flex;flex-direction:column;gap:1.25rem}.field-group{display:flex;flex-direction:column;gap:.5rem}.field-header{display:flex;align-items:center;gap:.375rem}.field-label{font-size:.875rem;font-weight:500;color:var(--text-primary)}.required-mark{color:var(--accent-error)}.field-description{font-size:.8125rem;color:var(--text-muted);margin:0;line-height:1.4}.text-input,.textarea-input,.select-input{width:100%;padding:.625rem .875rem;font-size:.875rem;color:var(--text-primary);background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);outline:none;transition:all var(--transition-fast)}.text-input:focus,.textarea-input:focus,.select-input:focus{border-color:var(--accent-primary);box-shadow:0 0 0 2px var(--accent-primary-light)}.textarea-input{resize:vertical;min-height:6rem;max-height:12rem;font-family:inherit}.input-wrapper{position:relative;display:flex;align-items:center}.input-wrapper .text-input{padding-right:2.5rem}.password-toggle{position:absolute;right:.5rem;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;background:transparent;border:none;color:var(--text-muted);cursor:pointer;transition:color var(--transition-fast)}.password-toggle:hover{color:var(--text-primary)}.field-error{display:flex;align-items:center;gap:.375rem;font-size:.8125rem;color:var(--accent-error);padding-top:.25rem}.field-dirty{font-size:.75rem;color:var(--accent-warning);padding-top:.25rem}.toggle-label{display:flex;align-items:center;gap:.75rem;cursor:pointer}.toggle-input{display:none}.toggle-switch{width:2.5rem;height:1.375rem;background:var(--bg-tertiary);border-radius:var(--radius-full);position:relative;transition:background var(--transition-fast);flex-shrink:0}.toggle-switch:after{content:"";position:absolute;top:.125rem;left:.125rem;width:1.125rem;height:1.125rem;background:#fff;border-radius:50%;transition:transform var(--transition-fast);box-shadow:var(--shadow-sm)}.toggle-input:checked+.toggle-switch{background:var(--accent-primary)}.toggle-input:checked+.toggle-switch:after{transform:translate(1.125rem)}.toggle-text{font-size:.875rem;color:var(--text-secondary)}.settings-footer{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--border-color);background:var(--bg-primary);flex-shrink:0}settings-page,session-manager,cron-manager,log-manager,xopcbot-gateway-chat{display:flex;flex:1;min-height:0;overflow:hidden}.settings-page{display:flex;flex:1;min-height:0;overflow:hidden;position:relative;background:var(--bg-primary)}.settings-page .settings-sidebar{width:200px;border-right:1px solid var(--border-color);padding:0;flex-shrink:0;overflow-y:auto}.settings-page .sidebar-header{padding:1rem 1.25rem;border-bottom:1px solid var(--border-color)}.settings-page .sidebar-header h3{font-size:1rem;font-weight:600;color:var(--text-primary);margin:0}.settings-page .sidebar-nav{padding:.75rem .5rem}.settings-page .nav-item{display:flex;align-items:center;gap:.75rem;width:100%;padding:.625rem 1rem;border-radius:var(--radius-md);font-size:.875rem;font-weight:500;color:var(--text-secondary);background:transparent;border:none;cursor:pointer;transition:all var(--transition-fast);text-align:left;margin-bottom:.25rem}.settings-page .nav-item:hover{background:var(--bg-secondary);color:var(--text-primary)}.settings-page .nav-item.active{background:var(--accent-primary-light);color:var(--accent-primary);font-weight:600}.settings-page .settings-main{flex:1;min-height:0;overflow-y:auto;padding:2rem;position:relative}.settings-page .section-content{max-width:600px;min-height:-moz-min-content;min-height:min-content}.settings-page .section-header{margin-bottom:2rem}.settings-page .section-header h2{font-size:1.5rem;font-weight:600;color:var(--text-primary);margin:0 0 .5rem}.settings-page .section-desc{font-size:.875rem;color:var(--text-secondary);margin:0}.settings-page .fields-grid{display:flex;flex-direction:column;gap:1.5rem}.settings-page .field-group{display:flex;flex-direction:column;gap:.5rem}.settings-page .field-header{display:flex;align-items:center;gap:.5rem}.settings-page .field-label{font-size:.875rem;font-weight:500;color:var(--text-primary)}.settings-page .field-desc{font-size:.8125rem;color:var(--text-secondary);margin:0}.settings-page .text-input,.settings-page .select-input{width:100%;padding:.625rem .875rem;border:1px solid var(--border-color);border-radius:var(--radius-md);font-size:.875rem;background:var(--bg-primary);color:var(--text-primary);transition:all var(--transition-fast)}.settings-page .text-input:focus,.settings-page .select-input:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 3px var(--color-primary-alpha)}.settings-page .toggle-label{display:flex;align-items:center;gap:.75rem;cursor:pointer}.settings-page .toggle-input{display:none}.settings-page .toggle-switch{position:relative;width:44px;height:24px;background:var(--bg-secondary);border-radius:12px;transition:all var(--transition-fast)}.settings-page .toggle-switch:after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:#fff;border-radius:50%;transition:all var(--transition-fast)}.settings-page .toggle-input:checked+.toggle-switch{background:var(--accent-primary)}.settings-page .toggle-input:checked+.toggle-switch:after{transform:translate(20px)}.settings-page .toggle-text{font-size:.875rem;color:var(--text-secondary)}.settings-page .loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:1rem}.settings-page .loading-state .spinner{width:32px;height:32px;border:3px solid var(--border-color);border-top-color:var(--accent-primary);border-radius:50%;animation:spin .8s linear infinite}.settings-page .loading-state p{color:var(--text-secondary);font-size:.875rem}.settings-page .floating-save{position:absolute;bottom:2rem;right:2rem;display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg)}.settings-page .dirty-count{font-size:.8125rem;color:var(--text-secondary)}.settings-page .spinner-sm{width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.btn{display:inline-flex;align-items:center;gap:.5rem;padding:.625rem 1rem;border-radius:var(--radius-md);font-size:.875rem;font-weight:500;cursor:pointer;transition:all var(--transition-fast);border:1px solid transparent}.btn-ghost{background:transparent;color:var(--text-secondary)}.btn-ghost:hover{background:var(--bg-secondary);color:var(--text-primary)}.btn-primary{background:var(--accent-primary);color:#fff;box-shadow:var(--shadow-sm)}.btn-primary:hover{background:var(--accent-primary-hover);box-shadow:var(--shadow-md)}.btn-primary:disabled{opacity:.5;cursor:not-allowed}.image-gallery{display:grid;gap:.25rem;max-width:100%;overflow:hidden}.image-gallery img{max-width:80px;max-height:80px;width:80px;height:80px;-o-object-fit:cover;object-fit:cover;border-radius:var(--radius-md);cursor:pointer;transition:transform .15s ease}.image-gallery img:hover{transform:scale(1.05)}.image-gallery.single{grid-template-columns:repeat(auto-fill,minmax(80px,1fr))}.image-gallery.double,.image-gallery.triple,.image-gallery.quad{grid-template-columns:repeat(auto-fill,minmax(60px,1fr))}.attachments-row{display:flex;flex-wrap:wrap;gap:.5rem;padding:.5rem 1rem;border-bottom:1px solid var(--border-color)}.attachment-chip{display:flex;align-items:center;gap:.375rem;padding:.25rem .5rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);font-size:.75rem}.attachment-preview{width:24px;height:24px;display:flex;align-items:center;justify-content:center;overflow:hidden;border-radius:var(--radius-xs)}.attachment-preview img{max-width:100%;max-height:100%;-o-object-fit:cover;object-fit:cover}.attachment-name{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary)}.attachment-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:transparent;border:none;color:var(--text-muted);cursor:pointer;border-radius:var(--radius-full);transition:all var(--transition-fast)}.attachment-remove:hover{background:var(--bg-tertiary);color:var(--accent-error)}@media(max-width:768px){.settings-dialog{height:100vh;max-width:100%;border-radius:0}.settings-content{flex-direction:column}.settings-sidebar{width:100%;border-right:none;border-bottom:1px solid var(--border-color);padding:.5rem;display:flex;overflow-x:auto;gap:.25rem}.sidebar-item{flex-shrink:0;padding:.5rem .75rem}.sidebar-item span:not(.chevron){display:none}.sidebar-item.active span:not(.chevron){display:inline}.sidebar-item .chevron{display:none}.settings-main{padding:1rem;flex:1}}.session-manager{display:flex;flex-direction:column;flex:1;min-height:0;padding:1.5rem;gap:1rem;overflow-y:auto}.session-manager__header{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap}.session-manager__header .page-title{display:flex;align-items:center;gap:.5rem;font-size:1.25rem;font-weight:600;color:var(--text-primary);margin:0}.search-box{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);min-width:280px;transition:border-color var(--transition-fast)}.search-box:focus-within{border-color:var(--accent-primary)}.search-box svg{width:1.125rem;height:1.125rem;color:var(--text-muted);flex-shrink:0}.search-box input{flex:1;background:transparent;border:none;outline:none;font-size:.875rem;color:var(--text-primary)}.search-box input::-moz-placeholder{color:var(--text-muted)}.search-box input::placeholder{color:var(--text-muted)}.session-manager__filters{display:flex;gap:.5rem;flex-wrap:wrap}.filter-btn{display:flex;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.8125rem;font-weight:500;color:var(--text-secondary);background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);cursor:pointer;transition:all var(--transition-fast)}.filter-btn:hover{background:var(--bg-tertiary);border-color:var(--border-strong)}.filter-btn--active{color:var(--accent-primary);background:var(--accent-primary-light);border-color:var(--accent-primary-soft)}.filter-btn svg{width:.875rem;height:.875rem}.session-manager__stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:.75rem}.session-list{display:flex;flex-direction:column;gap:1rem}.session-list__toolbar{display:flex;justify-content:space-between;align-items:center;padding:0 .25rem}.session-list__count{font-size:.8125rem;color:var(--text-muted)}.session-list__view-toggle{display:flex;gap:.25rem}.session-list__content{display:grid;gap:.75rem}.session-list__content--grid{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.session-list__content--list{grid-template-columns:1fr}.session-list__load-more{display:flex;justify-content:center;padding:1rem}.session-card{display:flex;flex-direction:column;padding:1rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);cursor:pointer;transition:all var(--transition-fast);position:relative}.session-card:hover{border-color:var(--border-strong);box-shadow:var(--shadow-sm);transform:translateY(-1px)}.session-card--selected{border-color:var(--accent-primary);box-shadow:0 0 0 1px var(--accent-primary)}.session-card--archived{opacity:.7}.session-card--archived .session-card__title{text-decoration:line-through;color:var(--text-muted)}.session-card__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem}.session-card__channel{display:flex;align-items:center;gap:.375rem}.channel-icon{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;color:var(--text-muted)}.channel-icon svg{width:1rem;height:1rem}.channel-name{font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.025em;color:var(--text-muted)}.session-card__meta{display:flex;align-items:center;gap:.5rem}.pin-badge{display:flex;align-items:center;color:var(--accent-primary)}.pin-badge svg{width:.875rem;height:.875rem;fill:currentColor}.date{font-size:.6875rem;color:var(--text-muted)}.session-card__title{font-size:.9375rem;font-weight:500;color:var(--text-primary);margin-bottom:.75rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.session-card__stats{display:flex;gap:1rem;margin-bottom:.75rem}.stat{display:flex;align-items:center;gap:.375rem;font-size:.75rem;color:var(--text-muted)}.stat svg{width:.875rem;height:.875rem}.session-card__tags{display:flex;flex-wrap:wrap;gap:.375rem;margin-bottom:.75rem}.tag{display:inline-flex;padding:.125rem .5rem;font-size:.6875rem;font-weight:500;color:var(--text-secondary);background:var(--bg-tertiary);border-radius:var(--radius-sm)}.tag--more{color:var(--text-muted);background:transparent}.session-card__actions{display:flex;gap:.25rem;margin-top:auto;padding-top:.5rem;border-top:1px solid var(--border-subtle);opacity:0;transition:opacity var(--transition-fast)}.session-card:hover .session-card__actions{opacity:1}.session-list--empty{display:flex;align-items:center;justify-content:center;min-height:300px}.empty-state{text-align:center}.empty-state__icon{display:flex;align-items:center;justify-content:center;width:4rem;height:4rem;margin:0 auto 1rem;color:var(--text-muted)}.empty-state__icon svg{width:2.5rem;height:2.5rem}.empty-state__title{font-size:1rem;font-weight:500;color:var(--text-primary);margin-bottom:.375rem}.empty-state__description{font-size:.8125rem;color:var(--text-muted)}.session-list--loading{min-height:300px}.session-list__skeleton{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:.75rem}.skeleton-card{display:flex;flex-direction:column;gap:.75rem;padding:1rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.skeleton--header{height:1rem;width:40%}.skeleton--title{height:1.25rem;width:80%}.skeleton--stats{height:.875rem;width:60%}@keyframes skeleton-pulse{0%,to{opacity:1}50%{opacity:.5}}.error-banner{padding:.75rem 1rem;background:var(--accent-error-light);border:1px solid var(--accent-error-soft);border-radius:var(--radius-md);font-size:.8125rem;color:var(--accent-error)}@media(max-width:768px){.session-manager{padding:1rem}.session-manager__header{flex-direction:column;align-items:stretch;gap:.75rem}.session-manager__header .page-title{font-size:1.1rem}.session-manager__header .search-box{width:100%}.session-list__content--grid{grid-template-columns:1fr}.session-card__actions{opacity:1}.cron-manager{padding:1rem}.cron-manager__header{flex-direction:column;align-items:stretch;gap:.75rem}.cron-manager__header .page-title{font-size:1.1rem}.cron-manager__actions{width:100%;justify-content:stretch}.cron-manager__actions .btn{flex:1}}.drawer-overlay{position:fixed;inset:0;background:#00000080;z-index:100}.drawer-backdrop{position:fixed;inset:0;background:#00000080;z-index:100;display:flex;justify-content:flex-end}.drawer{position:fixed;right:0;top:0;width:480px;max-width:100%;height:100%;background:var(--bg-primary);border-left:1px solid var(--border-color);display:flex;flex-direction:column;z-index:101;animation:drawer-slide-in .2s ease-out;box-shadow:-4px 0 12px #0000001a}.drawer--right{right:0;left:auto}@keyframes drawer-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}.drawer-header{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;border-bottom:1px solid var(--border-color);gap:.75rem}.drawer-header__info{flex:1;min-width:0}.drawer-header__title{display:flex;align-items:center;gap:.5rem;font-size:1rem;font-weight:600;color:var(--text-primary);margin:0;word-break:break-all}.btn-icon{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid var(--border-color);border-radius:var(--radius-sm);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast);flex-shrink:0}.btn-icon:hover{background:var(--bg-tertiary);color:var(--text-primary);border-color:var(--border-color)}.btn-icon svg{width:1.125rem;height:1.125rem}.btn-icon--small{width:1.5rem;height:1.5rem}.btn-icon--small svg{width:.875rem;height:.875rem}.drawer-header__meta{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:var(--text-muted);flex-wrap:wrap}.drawer-search{padding:.75rem 1rem;border-bottom:1px solid var(--border-color);display:flex;align-items:center;gap:.5rem}.search-input-wrapper{flex:1;display:flex;align-items:center;gap:.5rem;padding:.375rem .75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.search-input-wrapper:focus-within{border-color:var(--accent-primary)}.search-input-wrapper svg{width:1rem;height:1rem;color:var(--text-muted);flex-shrink:0}.search-input-wrapper input{flex:1;background:transparent;border:none;outline:none;font-size:.875rem;color:var(--text-primary)}.search-input-wrapper input::-moz-placeholder{color:var(--text-muted)}.search-input-wrapper input::placeholder{color:var(--text-muted)}.search-nav{display:flex;align-items:center;gap:.25rem}.search-count{font-size:.75rem;color:var(--text-muted);padding:0 .5rem;min-width:3rem;text-align:center}.drawer-content{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.drawer-content--loading{align-items:center;justify-content:center;gap:.75rem;color:var(--text-muted)}.drawer-content--empty{align-items:center;justify-content:center;color:var(--text-muted)}.message{display:flex;flex-direction:column;gap:.375rem;padding:.75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.message.user{border-left:3px solid var(--accent-primary)}.message.assistant{border-left:3px solid var(--accent-success)}.message--highlight{background:var(--accent-primary-light);border-color:var(--accent-primary-soft)}.message--current{box-shadow:0 0 0 2px var(--accent-primary)}.message__header{display:flex;justify-content:space-between;align-items:center}.message__role{font-size:.6875rem;font-weight:600;text-transform:uppercase;color:var(--text-muted)}.message__time{font-size:.6875rem;color:var(--text-muted)}.message__content{font-size:.875rem;color:var(--text-primary);line-height:1.5;white-space:pre-wrap;word-break:break-word}.search-highlight{background:var(--accent-primary);color:#fff;padding:.125rem .25rem;border-radius:var(--radius-sm)}.drawer-actions{display:flex;gap:.5rem;padding:.75rem 1rem;border-top:1px solid var(--border-color);background:var(--bg-secondary);overflow-x:auto}.archive-badge{display:inline-flex;padding:.125rem .5rem;font-size:.6875rem;font-weight:500;color:var(--text-muted);background:var(--bg-tertiary);border-radius:var(--radius-sm)}.modal-backdrop{position:fixed;inset:0;background:#00000080;z-index:200;display:flex;align-items:center;justify-content:center;padding:1rem}.modal{background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-lg);max-width:400px;width:100%;text-align:center;animation:modal-fade-in .15s ease-out;overflow:hidden}.modal--form{max-width:520px;max-height:90vh;display:flex;flex-direction:column;text-align:left}.modal--form .modal__content{flex:1;overflow-y:auto;max-height:calc(90vh - 140px)}.modal__header{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;border-bottom:1px solid var(--border-color)}.modal__header .modal__title{margin:0}.modal__content{padding:1.5rem}.modal__actions{display:flex;gap:.75rem;justify-content:flex-end;padding:1rem 1.5rem;border-top:1px solid var(--border-color);background:var(--bg-secondary)}.form-field{margin-bottom:1.25rem}.form-field:last-child{margin-bottom:0}.form-field__label{display:block;font-size:.875rem;font-weight:500;color:var(--text-primary);margin-bottom:.5rem}.form-field__input,.form-field__textarea,.form-field__select{width:100%;padding:.625rem .75rem;font-size:.875rem;color:var(--text-primary);background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-md);transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.form-field__input:focus,.form-field__textarea:focus,.form-field__select:focus{outline:none;border-color:var(--accent-primary);box-shadow:0 0 0 3px #3b82f61a}.form-field__textarea{min-height:100px;resize:vertical}.form-field__hint{font-size:.75rem;color:var(--text-muted);margin-top:.375rem}@keyframes modal-fade-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.modal__icon{display:flex;justify-content:center;margin-bottom:1rem}.modal__icon svg{width:3rem;height:3rem}.modal__title{font-size:1.125rem;font-weight:600;color:var(--text-primary);margin-bottom:.5rem}.modal__message{font-size:.875rem;color:var(--text-secondary);line-height:1.5;margin-bottom:1.5rem;white-space:pre-line}.modal__actions{display:flex;gap:.75rem;justify-content:center}.text-red-500{color:var(--accent-error)}.text-amber-500{color:var(--accent-warning)}.text-blue-500{color:var(--accent-info)}.text-gray-500{color:var(--text-muted)}@media(max-width:640px){.drawer{width:100%}.drawer-actions{flex-wrap:wrap}.drawer-actions .btn{flex:1;min-width:0}}.cron-manager{display:flex;flex-direction:column;flex:1;min-height:0;padding:1.5rem;gap:1rem;overflow-y:auto}.cron-manager__header{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap}.cron-manager__header .page-title{display:flex;align-items:center;gap:.5rem;font-size:1.25rem;font-weight:600;color:var(--text-primary);margin:0}.cron-manager__actions{display:flex;gap:.5rem}.cron-manager__stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:.75rem;margin-bottom:1rem}.subagents-manager{display:flex;flex-direction:column;flex:1;min-height:0;padding:1.5rem;gap:1rem;overflow-y:auto}.subagents-manager__header{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap}.subagents-manager__header .page-title{display:flex;align-items:center;gap:.5rem;font-size:1.25rem;font-weight:600;color:var(--text-primary);margin:0}.subagents-manager__empty{display:flex;align-items:center;justify-content:center;min-height:400px}.subagents-list{display:flex;flex-direction:column;gap:.75rem}.subagent-card{display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);cursor:pointer;transition:all var(--transition-fast)}.subagent-card:hover{border-color:var(--border-strong);box-shadow:var(--shadow-sm);transform:translateY(-1px)}.subagent-card__icon{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;background:linear-gradient(135deg,var(--accent-primary-soft) 0%,var(--accent-primary-light) 100%);border-radius:var(--radius-md);color:var(--accent-primary);flex-shrink:0}.subagent-card__icon svg{width:1.5rem;height:1.5rem}.subagent-card__info{flex:1;min-width:0}.subagent-card__name{font-size:.9375rem;font-weight:600;color:var(--text-primary);margin-bottom:.25rem}.subagent-card__meta{display:flex;align-items:center;gap:.5rem;font-size:.8125rem;color:var(--text-muted)}.subagent-card__meta .meta-item{display:flex;align-items:center;gap:.375rem}.subagent-card__meta .meta-item svg{width:.875rem;height:.875rem}.subagent-card__meta .meta-divider{color:var(--border-strong)}.subagent-card__arrow{color:var(--text-muted);transition:transform var(--transition-fast)}.subagent-card:hover .subagent-card__arrow{transform:translate(2px);color:var(--text-secondary)}.subagent-detail{display:flex;flex-direction:column;gap:1.5rem;animation:fadeIn var(--transition-normal) ease-out}.subagent-detail__header{display:flex;align-items:center;gap:.75rem}.subagent-detail__content{display:flex;flex-direction:column;gap:1.5rem}.subagent-detail__title{display:flex;align-items:center;gap:.75rem;padding-bottom:1rem;border-bottom:1px solid var(--border-color)}.subagent-detail__icon{display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;background:linear-gradient(135deg,var(--accent-primary) 0%,var(--accent-primary-hover) 100%);border-radius:var(--radius-md);color:#fff}.subagent-detail__icon svg{width:1.5rem;height:1.5rem}.subagent-detail__title h2{font-size:1.25rem;font-weight:600;color:var(--text-primary);margin:0}.detail-section{display:flex;flex-direction:column;gap:.75rem}.detail-section .section-title{font-size:.875rem;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin:0}.detail-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1rem}.detail-item{display:flex;flex-direction:column;gap:.375rem;padding:.75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.detail-item__label{font-size:.75rem;font-weight:500;color:var(--text-muted)}.detail-item__value{font-size:.875rem;color:var(--text-primary)}.detail-item__value--code{font-family:var(--font-mono);font-size:.8125rem;word-break:break-all}.status-badge{display:inline-flex;padding:.25rem .625rem;font-size:.75rem;font-weight:600;text-transform:uppercase;border-radius:var(--radius-sm)}.status-badge--active{color:var(--accent-success);background:var(--accent-success-light)}.status-badge--idle{color:var(--accent-warning);background:var(--accent-warning-light)}.status-badge--archived{color:var(--text-muted);background:var(--bg-tertiary)}.tags-list{display:flex;flex-wrap:wrap;gap:.5rem}.skeleton-list{display:flex;flex-direction:column;gap:.75rem}.skeleton-card{display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.skeleton-card .skeleton--icon{width:3rem;height:3rem;border-radius:var(--radius-md);flex-shrink:0}.skeleton-card .skeleton--content{flex:1;display:flex;flex-direction:column;gap:.5rem}.skeleton-card .skeleton--title{width:40%;height:1rem}.skeleton-card .skeleton--meta{width:60%;height:.75rem}@media(max-width:768px){.subagents-manager{padding:1rem}.subagents-manager__header{flex-direction:column;align-items:stretch}.subagents-manager__header .btn{width:100%}.subagent-card{padding:.875rem}.subagent-card__icon{width:2.5rem;height:2.5rem}.detail-grid{grid-template-columns:1fr}}.log-manager{display:flex;flex-direction:column;flex:1;min-height:0;padding:1rem;gap:.5rem;overflow:hidden;height:calc(100vh - 50px)}.log-manager__header{flex-shrink:0;display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;gap:1rem}.log-manager__title{display:flex;align-items:center;gap:.75rem;color:var(--text-primary)}.title-icon{display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;background:var(--gradient-primary);border-radius:var(--radius-md);color:#fff;flex-shrink:0;box-shadow:0 2px 8px #00000026}.title-icon svg{width:1.25rem;height:1.25rem}.title-text{display:flex;flex-direction:column;justify-content:center}.title-text h1{font-size:1.25rem;font-weight:600;color:var(--text-primary)!important;margin:0;line-height:1.2}.title-subtitle{font-size:.8125rem;color:var(--text-muted)!important;margin-top:.125rem;display:block}.log-manager__actions{display:flex;align-items:center;gap:.375rem}.log-manager__actions .btn-icon{position:relative}.log-manager__actions .badge{position:absolute;top:-.25rem;right:-.25rem;min-width:1rem;height:1rem;padding:0 .25rem;font-size:.625rem;font-weight:600;color:#fff;background:var(--primary);border-radius:1rem;display:flex;align-items:center;justify-content:center}.log-manager__actions .btn-icon--active{background:var(--accent-primary, #3b82f6);color:#fff;border-color:var(--accent-primary, #3b82f6);box-shadow:0 2px 8px #3b82f64d}.log-manager__actions .btn-icon--active:hover{background:var(--accent-primary-hover, #2563eb);border-color:var(--accent-primary-hover, #2563eb)}.log-manager__main{display:flex;flex-direction:column;flex:1;min-height:0;gap:.75rem;overflow:hidden}.log-manager__filters{display:flex;align-items:flex-end;gap:.75rem;padding:.75rem 1rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);flex-shrink:0}.filter-group{display:flex;flex-direction:column;gap:.375rem}.filter-label{font-size:.6875rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.filter-row{display:flex;gap:.5rem;flex-wrap:nowrap;align-items:flex-end}.filter-row .filter-group{min-width:140px}.filter-row select,.filter-row input[type=datetime-local],.log-manager__filters select,.log-manager__filters input[type=datetime-local]{padding:.375rem .625rem;font-size:.8125rem;border:1px solid var(--border-color);border-radius:var(--radius-sm);background:var(--bg-primary);color:var(--text-primary);min-width:140px}.filter-row .btn-ghost{padding:.375rem .75rem;font-size:.8125rem;height:-moz-fit-content;height:fit-content}.level-filters{display:flex;gap:.375rem;flex-wrap:nowrap}.log-manager__filters .filter-group{display:flex;flex-direction:column;gap:.375rem}.log-manager__filters .filter-label{font-size:.6875rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.level-badge{display:inline-flex;align-items:center;padding:.1875rem .5rem;font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.025em;color:var(--level-color, var(--text-secondary));background:color-mix(in srgb,var(--level-color, var(--bg-tertiary)) 15%,transparent);border:1px solid color-mix(in srgb,var(--level-color, var(--border-color)) 30%,transparent);border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition-fast)}.level-badge:hover{background:color-mix(in srgb,var(--level-color, var(--bg-tertiary)) 25%,transparent)}.level-badge--active{background:color-mix(in srgb,var(--level-color, var(--accent-primary)) 25%,transparent);border-color:var(--level-color, var(--accent-primary));box-shadow:0 0 0 1px var(--level-color, var(--accent-primary))}.level-badge--small{padding:.125rem .375rem;font-size:.625rem}.log-table-container{display:flex;flex-direction:column;gap:.75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md);overflow:auto;flex:1;min-height:0}.log-table{display:table!important;width:100%;table-layout:fixed}.log-table thead{display:table-header-group!important}.log-table tbody{display:table-row-group!important}.log-table tr{display:table-row!important}.log-table th,.log-table td{display:table-cell!important}.log-table{width:100%;border-collapse:collapse;font-size:.8125rem}.log-table th{padding:.5rem .625rem;text-align:left;font-weight:600;color:var(--text-secondary);background:var(--bg-tertiary);border-bottom:1px solid var(--border-color);white-space:nowrap;position:sticky;top:0;z-index:10}.log-table td{padding:.5rem .625rem;border-bottom:1px solid var(--border-subtle);vertical-align:top}.log-row{cursor:pointer;transition:background var(--transition-fast)}.log-row:hover{background:var(--bg-tertiary)}.log-row--trace{border-left:3px solid #9ca3af}.log-row--debug{border-left:3px solid #6b7280}.log-row--info{border-left:3px solid #3b82f6}.log-row--warn{border-left:3px solid #f59e0b}.log-row--error{border-left:3px solid #ef4444}.log-row--fatal{border-left:3px solid #dc2626}.log-cell--time{white-space:nowrap;font-family:var(--font-mono);font-size:.75rem;color:var(--text-muted);width:150px}.log-cell--level{width:70px}.log-cell--module{white-space:nowrap;font-family:var(--font-mono);font-size:.75rem;color:var(--text-secondary);width:180px;max-width:180px;overflow:hidden;text-overflow:ellipsis}.log-cell--message{color:var(--text-primary);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.log-table__load-more{display:flex;justify-content:center;padding:1rem;border-top:1px solid var(--border-color)}.drawer-content{flex:1;overflow-y:auto;padding:1rem 1.25rem}.log-detail{display:flex;flex-direction:column;gap:1rem;padding:0 .5rem}.log-detail__field{display:flex;flex-direction:column;gap:.375rem}.log-detail__field label{font-size:.75rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.log-detail__field code,.log-detail__field pre{font-family:var(--font-mono);font-size:.8125rem;padding:.5rem .75rem;background:var(--bg-tertiary);border-radius:var(--radius-sm);color:var(--text-primary);margin:0}.log-detail__message,.log-detail__meta{font-family:var(--font-mono);font-size:.8125rem;padding:.75rem 1rem;background:var(--bg-tertiary);border-radius:var(--radius-md);color:var(--text-primary);white-space:pre-wrap;word-break:break-word;max-height:300px;overflow-y:auto;margin:0}.log-files{margin-top:.5rem;padding:.75rem;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:var(--radius-md)}.section-title{display:flex;align-items:center;gap:.5rem;font-size:.875rem;font-weight:600;color:var(--text-primary);margin:0 0 .5rem}.files-panel{position:fixed;right:0;top:0;width:320px;max-width:90vw;height:100vh;background:var(--bg-primary);border-left:1px solid var(--border-color);box-shadow:-4px 0 12px #0000001a;transform:translate(100%);transition:transform .2s ease;z-index:100;display:flex;flex-direction:column}.files-panel--open{transform:translate(0)}.files-panel__header{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.25rem;border-bottom:1px solid var(--border-color);background:var(--bg-secondary)}.files-panel__toggle{display:flex;align-items:center;gap:.5rem;padding:0;font-size:.9375rem;font-weight:600;color:var(--text-primary);background:none;border:none;cursor:pointer}.files-panel__content{flex:1;overflow-y:auto;padding:.75rem 1rem}.files-panel__empty{padding:2rem 1rem;text-align:center;color:var(--text-muted);font-size:.875rem}.file-list{display:flex;flex-direction:column;gap:.375rem}.file-item{display:flex;flex-direction:column;gap:.25rem;padding:.5rem .625rem;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-sm);font-size:.75rem;transition:border-color var(--transition-fast)}.file-item:hover{border-color:var(--border-hover)}.file-name{display:flex;align-items:center;gap:.375rem;color:var(--text-primary);font-weight:500;word-break:break-all}.file-meta{display:flex;gap:.5rem;font-size:.6875rem;color:var(--text-muted)}.file-size,.file-time{font-family:var(--font-mono)}.skeleton-table{display:flex;flex-direction:column;gap:.5rem;padding:.75rem}.skeleton-row{display:flex;gap:.75rem;padding:.625rem 0;border-bottom:1px solid var(--border-subtle)}.skeleton{background:var(--bg-tertiary);border-radius:var(--radius-sm);animation:skeleton-pulse 2s ease-in-out infinite}.skeleton--time{width:120px;height:1rem}.skeleton--level{width:60px;height:1rem}.skeleton--module{width:120px;height:1rem}.skeleton--message{flex:1;height:1rem}@media(max-width:768px){.log-manager{padding:1rem}.log-manager__header{flex-direction:column;align-items:stretch}.log-manager__actions{width:100%;justify-content:stretch}.log-manager__actions .btn{flex:1}.filter-row{flex-direction:column;align-items:stretch}.filter-row select,.filter-row input[type=datetime-local]{width:100%}.log-table th,.log-table td{padding:.5rem}.log-cell--module{display:none}.log-cell--message{max-width:200px}}:is(:where(.dark) .dark\:bg-blue-900\/30){background-color:#1e3a8a4d}:is(:where(.dark) .dark\:bg-gray-800){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity))}:is(:where(.dark) .dark\:bg-green-900\/30){background-color:#14532d4d}:is(:where(.dark) .dark\:text-blue-400){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity))}:is(:where(.dark) .dark\:text-gray-400){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity))}:is(:where(.dark) .dark\:text-green-400){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity))}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>xopcbot UI</title>
|
|
7
|
+
<style>
|
|
8
|
+
/* Prevent flash of unstyled content - default to light theme */
|
|
9
|
+
html { background: #fafaf9; }
|
|
10
|
+
html.dark { background: #0c0a09; }
|
|
11
|
+
@media (prefers-color-scheme: dark) {
|
|
12
|
+
html:not(.light) { background: #0c0a09; }
|
|
13
|
+
}
|
|
14
|
+
</style>
|
|
15
|
+
<script type="module" crossorigin src="/assets/main-CfIxL-cL.js"></script>
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/main-DndcTCgX.css">
|
|
17
|
+
</head>
|
|
18
|
+
<body class="h-screen">
|
|
19
|
+
<div id="app" class="h-full">
|
|
20
|
+
<xopcbot-app id="app-root"></xopcbot-app>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
// Initialize the app with gateway config
|
|
25
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
26
|
+
const app = document.getElementById('app-root');
|
|
27
|
+
if (app) {
|
|
28
|
+
// Get gateway URL from current location or use default
|
|
29
|
+
// For dev (port 3000), default to 18790. For prod, use same port.
|
|
30
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
31
|
+
const currentHost = window.location.hostname || 'localhost';
|
|
32
|
+
const currentPort = window.location.port || (window.location.protocol === 'https:' ? '443' : '80');
|
|
33
|
+
// Default to 18790 (gateway port), but respect ?gateway= param
|
|
34
|
+
const defaultPort = currentPort === '3000' ? '18790' : currentPort;
|
|
35
|
+
const gatewayUrl = urlParams.get('gateway') || `${window.location.protocol}//${currentHost}:${defaultPort}`;
|
|
36
|
+
|
|
37
|
+
// Get token from URL if provided
|
|
38
|
+
const token = urlParams.get('token') || undefined;
|
|
39
|
+
|
|
40
|
+
app.gatewayConfig = {
|
|
41
|
+
url: gatewayUrl,
|
|
42
|
+
token: token
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Settings sections are now defined in app.ts by default
|
|
46
|
+
// Only override if you need custom sections
|
|
47
|
+
// app.settingsSections is already set by the component
|
|
48
|
+
|
|
49
|
+
// Default settings values
|
|
50
|
+
app.settingsValues = {
|
|
51
|
+
gatewayUrl: gatewayUrl,
|
|
52
|
+
token: token,
|
|
53
|
+
theme: 'system',
|
|
54
|
+
enableAttachments: true,
|
|
55
|
+
enableModelSelector: true,
|
|
56
|
+
enableThinkingSelector: true,
|
|
57
|
+
// Agent settings
|
|
58
|
+
model: 'anthropic/claude-sonnet-4-5',
|
|
59
|
+
maxTokens: 8192,
|
|
60
|
+
temperature: 0.7,
|
|
61
|
+
maxToolIterations: 20,
|
|
62
|
+
// Channel settings
|
|
63
|
+
telegramEnabled: false,
|
|
64
|
+
whatsappEnabled: false,
|
|
65
|
+
// Gateway settings
|
|
66
|
+
heartbeatEnabled: true,
|
|
67
|
+
heartbeatIntervalMs: 60000
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Handle settings save
|
|
71
|
+
app.onSettingsSave = (values) => {
|
|
72
|
+
console.log('Settings saved:', values);
|
|
73
|
+
|
|
74
|
+
// Update gateway config if changed
|
|
75
|
+
if (values.gatewayUrl && values.gatewayUrl !== app.gatewayConfig?.url) {
|
|
76
|
+
app.gatewayConfig = {
|
|
77
|
+
url: values.gatewayUrl,
|
|
78
|
+
token: values.token
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Save to localStorage (but don't store gatewayUrl/token for security)
|
|
83
|
+
const safeValues = { ...values };
|
|
84
|
+
delete safeValues.gatewayUrl;
|
|
85
|
+
delete safeValues.token;
|
|
86
|
+
localStorage.setItem('xopcbot-settings', JSON.stringify(safeValues));
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Load saved settings (but ignore old gateway URLs to avoid port issues)
|
|
90
|
+
const savedSettings = localStorage.getItem('xopcbot-settings');
|
|
91
|
+
if (savedSettings) {
|
|
92
|
+
try {
|
|
93
|
+
const parsed = JSON.parse(savedSettings);
|
|
94
|
+
// Only apply non-connection settings from localStorage
|
|
95
|
+
const { gatewayUrl, token, ...otherSettings } = parsed;
|
|
96
|
+
Object.assign(app.settingsValues, otherSettings);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error('Failed to load saved settings:', e);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Add keyboard shortcut to open settings
|
|
103
|
+
document.addEventListener('keydown', (e) => {
|
|
104
|
+
if ((e.metaKey || e.ctrlKey) && e.key === ',') {
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
app.showSettings();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Expose app to window for debugging
|
|
111
|
+
window.xopcbotApp = app;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
</script>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/heartbeat/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CronService } from '../cron/service.js';
|
|
2
|
+
import { Config } from '../config/index.js';
|
|
3
|
+
export interface HeartbeatConfig {
|
|
4
|
+
intervalMs: number;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class HeartbeatService {
|
|
8
|
+
private intervalId;
|
|
9
|
+
private cronService;
|
|
10
|
+
constructor(cronService: CronService);
|
|
11
|
+
start(config: HeartbeatConfig): void;
|
|
12
|
+
private checkAndWake;
|
|
13
|
+
stop(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Update heartbeat configuration (hot reload)
|
|
16
|
+
*/
|
|
17
|
+
updateConfig(config: Config): void;
|
|
18
|
+
isRunning(): boolean;
|
|
19
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createLogger } from '../utils/logger.js';
|
|
2
|
+
const log = createLogger('HeartbeatService');
|
|
3
|
+
export class HeartbeatService {
|
|
4
|
+
intervalId = null;
|
|
5
|
+
cronService;
|
|
6
|
+
constructor(cronService) {
|
|
7
|
+
this.cronService = cronService;
|
|
8
|
+
}
|
|
9
|
+
start(config) {
|
|
10
|
+
if (!config.enabled) {
|
|
11
|
+
log.info('Heartbeat disabled');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
log.info({ intervalMs: config.intervalMs }, 'Starting heartbeat service');
|
|
15
|
+
this.intervalId = setInterval(async () => {
|
|
16
|
+
await this.checkAndWake();
|
|
17
|
+
}, config.intervalMs);
|
|
18
|
+
}
|
|
19
|
+
async checkAndWake() {
|
|
20
|
+
try {
|
|
21
|
+
// Check cron metrics
|
|
22
|
+
const metrics = await this.cronService.getMetrics();
|
|
23
|
+
// Log status
|
|
24
|
+
log.info({
|
|
25
|
+
runningJobs: metrics.runningJobs,
|
|
26
|
+
enabledJobs: metrics.enabledJobs
|
|
27
|
+
}, 'Heartbeat active');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
log.error({ err: error }, 'Heartbeat error');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
stop() {
|
|
34
|
+
if (this.intervalId) {
|
|
35
|
+
clearInterval(this.intervalId);
|
|
36
|
+
this.intervalId = null;
|
|
37
|
+
log.info('Heartbeat stopped');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Update heartbeat configuration (hot reload)
|
|
42
|
+
*/
|
|
43
|
+
updateConfig(config) {
|
|
44
|
+
const heartbeatConfig = config.gateway?.heartbeat;
|
|
45
|
+
if (!heartbeatConfig?.enabled) {
|
|
46
|
+
this.stop();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Restart with new config
|
|
50
|
+
this.stop();
|
|
51
|
+
this.start({
|
|
52
|
+
intervalMs: heartbeatConfig.intervalMs || 60000,
|
|
53
|
+
enabled: heartbeatConfig.enabled ?? true,
|
|
54
|
+
});
|
|
55
|
+
log.info('Heartbeat config updated');
|
|
56
|
+
}
|
|
57
|
+
isRunning() {
|
|
58
|
+
return this.intervalId !== null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/heartbeat/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AAO7C,MAAM,OAAO,gBAAgB;IACnB,UAAU,GAA0C,IAAI,CAAC;IACzD,WAAW,CAAc;IAEjC,YAAY,WAAwB;QAClC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,MAAuB;QAC3B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,4BAA4B,CAAC,CAAC;QAE1E,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACvC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC;YACH,qBAAqB;YACrB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;YAEpD,aAAa;YACb,GAAG,CAAC,IAAI,CAAC;gBACP,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,EAAE,kBAAkB,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,iBAAiB,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,MAAc;QACzB,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC;QAClD,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,KAAK,CAAC;YACT,UAAU,EAAE,eAAe,CAAC,UAAU,IAAI,KAAK;YAC/C,OAAO,EAAE,eAAe,CAAC,OAAO,IAAI,IAAI;SACzC,CAAC,CAAC;QACH,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xopcbot Plugin SDK
|
|
3
|
+
*
|
|
4
|
+
* Official SDK for developing xopcbot plugins.
|
|
5
|
+
* Import types and utilities from this module:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import type { PluginApi, PluginDefinition } from 'xopcbot/plugin-sdk';
|
|
9
|
+
*/
|
|
10
|
+
export type { PluginDefinition, PluginModule, PluginKind, PluginManifest, PluginRecord, PluginRegistry, ResolvedPluginConfig, PluginOrigin, } from '../plugins/types.js';
|
|
11
|
+
export type { PluginApi, PluginLogger, } from '../plugins/types.js';
|
|
12
|
+
export type { PluginTool, PluginToolContext, } from '../plugins/types.js';
|
|
13
|
+
export type { PluginHookEvent, PluginHookHandler, HookOptions, } from '../plugins/types.js';
|
|
14
|
+
export type { HookContext, BeforeAgentStartContext, BeforeAgentStartResult, AgentEndContext, BeforeCompactionContext, AfterCompactionContext, MessageReceivedContext, MessageSendingContext, MessageSendingResult, MessageSentContext, BeforeToolCallContext, BeforeToolCallResult, AfterToolCallContext, SessionStartContext, SessionEndContext, GatewayStartContext, GatewayStopContext, } from '../plugins/hooks.js';
|
|
15
|
+
export { HookRunner, createHookContext, isHookEvent } from '../plugins/hooks.js';
|
|
16
|
+
export type { ChannelPlugin, OutboundMessage, } from '../plugins/types.js';
|
|
17
|
+
export type { HttpRequestHandler, HttpRequest, HttpResponse, } from '../plugins/types.js';
|
|
18
|
+
export type { PluginCommand, CommandContext, CommandResult, } from '../plugins/types.js';
|
|
19
|
+
export type { PluginService, ServiceContext, } from '../plugins/types.js';
|
|
20
|
+
export type { GatewayMethodHandler, GatewayContext, } from '../plugins/types.js';
|
|
21
|
+
export type { Config } from '../types/index.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xopcbot Plugin SDK
|
|
3
|
+
*
|
|
4
|
+
* Official SDK for developing xopcbot plugins.
|
|
5
|
+
* Import types and utilities from this module:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import type { PluginApi, PluginDefinition } from 'xopcbot/plugin-sdk';
|
|
9
|
+
*/
|
|
10
|
+
// Export hook runner and utilities
|
|
11
|
+
export { HookRunner, createHookContext, isHookEvent } from '../plugins/hooks.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin-sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsDH,mCAAmC;AACnC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { PluginApiImpl, createPluginLogger, createPathResolver } from '../api.js';
|
|
3
|
+
// Mock dependencies
|
|
4
|
+
const mockLogger = {
|
|
5
|
+
debug: vi.fn(),
|
|
6
|
+
info: vi.fn(),
|
|
7
|
+
warn: vi.fn(),
|
|
8
|
+
error: vi.fn(),
|
|
9
|
+
};
|
|
10
|
+
const mockConfig = {
|
|
11
|
+
agents: {
|
|
12
|
+
defaults: {
|
|
13
|
+
model: 'test-model',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const mockPluginConfig = {
|
|
18
|
+
setting: 'value',
|
|
19
|
+
};
|
|
20
|
+
const mockResolvePath = (input) => `/resolved/${input}`;
|
|
21
|
+
describe('PluginApiImpl', () => {
|
|
22
|
+
let api;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
api = new PluginApiImpl('test-plugin', 'Test Plugin', '1.0.0', '/path/to/plugin', mockConfig, mockPluginConfig, mockLogger, mockResolvePath);
|
|
25
|
+
});
|
|
26
|
+
describe('registerTool()', () => {
|
|
27
|
+
it('should register a tool', () => {
|
|
28
|
+
const tool = {
|
|
29
|
+
name: 'test_tool',
|
|
30
|
+
description: 'A test tool',
|
|
31
|
+
parameters: { type: 'object' },
|
|
32
|
+
execute: async () => 'result',
|
|
33
|
+
};
|
|
34
|
+
api.registerTool(tool);
|
|
35
|
+
const tools = api._getTools();
|
|
36
|
+
expect(tools.has('test_tool')).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('should warn when registering duplicate tool', () => {
|
|
39
|
+
const tool = {
|
|
40
|
+
name: 'test_tool',
|
|
41
|
+
description: 'A test tool',
|
|
42
|
+
parameters: { type: 'object' },
|
|
43
|
+
execute: async () => 'result',
|
|
44
|
+
};
|
|
45
|
+
api.registerTool(tool);
|
|
46
|
+
api.registerTool(tool);
|
|
47
|
+
expect(mockLogger.warn).toHaveBeenCalled();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('registerHook()', () => {
|
|
51
|
+
it('should register a hook handler', () => {
|
|
52
|
+
const handler = vi.fn();
|
|
53
|
+
api.registerHook('before_tool_call', handler);
|
|
54
|
+
const hooks = api._getHooks();
|
|
55
|
+
expect(hooks.has('before_tool_call')).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
it('should support once option', () => {
|
|
58
|
+
const handler = vi.fn();
|
|
59
|
+
api.registerHook('before_tool_call', handler, { once: true });
|
|
60
|
+
const hooks = api._getHooks();
|
|
61
|
+
expect(hooks.has('before_tool_call')).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('resolvePath()', () => {
|
|
65
|
+
it('should resolve paths using the resolver', () => {
|
|
66
|
+
const result = api.resolvePath('test.txt');
|
|
67
|
+
expect(result).toBe('/resolved/test.txt');
|
|
68
|
+
});
|
|
69
|
+
it('should handle absolute paths', () => {
|
|
70
|
+
const api2 = new PluginApiImpl('test-plugin', 'Test Plugin', '1.0.0', '/path/to/plugin', mockConfig, mockPluginConfig, mockLogger, (input) => input);
|
|
71
|
+
const result = api2.resolvePath('/absolute/path');
|
|
72
|
+
expect(result).toBe('/absolute/path');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('emit/on/off (event bus)', () => {
|
|
76
|
+
it('should emit and receive events', () => {
|
|
77
|
+
const handler = vi.fn();
|
|
78
|
+
api.on('test-event', handler);
|
|
79
|
+
api.emit('test-event', { data: 'test' });
|
|
80
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
81
|
+
expect(handler).toHaveBeenCalledWith({ data: 'test' });
|
|
82
|
+
});
|
|
83
|
+
it('should remove event handlers', () => {
|
|
84
|
+
const handler = vi.fn();
|
|
85
|
+
api.on('test-event', handler);
|
|
86
|
+
api.off('test-event', handler);
|
|
87
|
+
api.emit('test-event', { data: 'test' });
|
|
88
|
+
expect(handler).not.toHaveBeenCalled();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('registerCommand()', () => {
|
|
92
|
+
it('should not throw when registering a command', () => {
|
|
93
|
+
const command = {
|
|
94
|
+
name: 'test',
|
|
95
|
+
description: 'Test command',
|
|
96
|
+
handler: async () => ({ content: 'result' }),
|
|
97
|
+
};
|
|
98
|
+
// Should not throw
|
|
99
|
+
expect(() => api.registerCommand(command)).not.toThrow();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe('registerHttpRoute()', () => {
|
|
103
|
+
it('should not throw when registering an HTTP route', () => {
|
|
104
|
+
const handler = async () => { };
|
|
105
|
+
// Should not throw
|
|
106
|
+
expect(() => api.registerHttpRoute('/test', handler)).not.toThrow();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('registerService()', () => {
|
|
110
|
+
it('should not throw when registering a service', () => {
|
|
111
|
+
const service = {
|
|
112
|
+
id: 'test-service',
|
|
113
|
+
start: vi.fn(),
|
|
114
|
+
};
|
|
115
|
+
// Should not throw
|
|
116
|
+
expect(() => api.registerService(service)).not.toThrow();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('registerGatewayMethod()', () => {
|
|
120
|
+
it('should not throw when registering a gateway method', () => {
|
|
121
|
+
const handler = async () => 'result';
|
|
122
|
+
// Should not throw
|
|
123
|
+
expect(() => api.registerGatewayMethod('test.method', handler)).not.toThrow();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe('createPluginLogger', () => {
|
|
128
|
+
it('should create a logger with prefix', () => {
|
|
129
|
+
const logger = createPluginLogger('test-prefix');
|
|
130
|
+
expect(typeof logger.debug).toBe('function');
|
|
131
|
+
expect(typeof logger.info).toBe('function');
|
|
132
|
+
expect(typeof logger.warn).toBe('function');
|
|
133
|
+
expect(typeof logger.error).toBe('function');
|
|
134
|
+
});
|
|
135
|
+
it('should call underlying logger with prefix', () => {
|
|
136
|
+
const logger = createPluginLogger('[my-plugin]');
|
|
137
|
+
logger.info('Test message');
|
|
138
|
+
// The underlying logger should be called (implementation detail)
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('createPathResolver', () => {
|
|
142
|
+
it('should resolve relative paths from plugin dir', () => {
|
|
143
|
+
const resolver = createPathResolver('/plugin/dir', '/workspace');
|
|
144
|
+
const result = resolver('./data.json');
|
|
145
|
+
expect(result).toBe('/plugin/dir/data.json');
|
|
146
|
+
});
|
|
147
|
+
it('should resolve paths relative to workspace', () => {
|
|
148
|
+
const resolver = createPathResolver('/plugin/dir', '/workspace');
|
|
149
|
+
const result = resolver('config.json');
|
|
150
|
+
expect(result).toBe('/workspace/config.json');
|
|
151
|
+
});
|
|
152
|
+
it('should handle tilde paths', () => {
|
|
153
|
+
const resolver = createPathResolver('/plugin/dir', '/workspace');
|
|
154
|
+
process.env.HOME = '/home/user';
|
|
155
|
+
const result = resolver('~/file.txt');
|
|
156
|
+
expect(result).toBe('/home/user/file.txt');
|
|
157
|
+
});
|
|
158
|
+
it('should return absolute paths unchanged', () => {
|
|
159
|
+
const resolver = createPathResolver('/plugin/dir', '/workspace');
|
|
160
|
+
const result = resolver('/absolute/path');
|
|
161
|
+
expect(result).toBe('/absolute/path');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=api.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.test.js","sourceRoot":"","sources":["../../../src/plugins/__tests__/api.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|