@weavecode/weave 0.1.3 → 0.1.4
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/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/.editorconfig +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/CHANGELOG.md +45 -22
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/README.md +26 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/dist/qs.js +27 -27
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/eslint.config.mjs +61 -50
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/formats.js +7 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/parse.js +13 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/stringify.js +5 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/utils.js +15 -7
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/package.json +6 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/dist/common.js +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/package.json +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/README.md +2 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/helper/css/common.js +8 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/helper/css/index.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/helper/route/index.js +3 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/jsx/base.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +8 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/middleware/serve-static/index.js +3 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/router/trie-router/node.js +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/cjs/utils/url.js +11 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/helper/css/common.js +8 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/helper/css/index.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/helper/route/index.js +3 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/jsx/base.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/middleware/bearer-auth/index.js +8 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/middleware/serve-static/index.js +3 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/router/trie-router/node.js +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/aws-lambda/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/bun/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/bun/ssg.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/cloudflare-pages/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/cloudflare-workers/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/deno/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/deno/ssg.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/lambda-edge/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/netlify/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/adapter/vercel/conninfo.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/helper/testing/index.d.ts +2 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/hono-base.d.ts +21 -9
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/index.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/jsx/components.d.ts +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/jsx/context.d.ts +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/jsx/dom/components.d.ts +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/jsx/dom/css.d.ts +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/jsx/streaming.d.ts +4 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/middleware/bearer-auth/index.d.ts +2 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/middleware/ip-restriction/index.d.ts +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +3 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/types/utils/ipaddr.d.ts +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/dist/utils/url.js +11 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/hono/package.json +1 -1
- package/node_modules/@weavecode/cli/dist/cli.js +4 -4
- package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
- package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +2 -1
- package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +14 -0
- package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +4 -3
- package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
- package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
- package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +3 -3
- package/node_modules/@weavecode/cli/dist/init/executor.d.ts +5 -4
- package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
- package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
- package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
- package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
- package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
- package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
- package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
- package/node_modules/@weavecode/cli/dist/init/provision.d.ts +25 -0
- package/node_modules/@weavecode/cli/dist/init/provision.js +1 -0
- package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
- package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
- package/node_modules/@weavecode/cli/dist/parser.js +1 -1
- package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
- package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
- package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
- package/node_modules/@weavecode/cli/package.json +5 -5
- package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
- package/node_modules/@weavecode/core/dist/harness.d.ts +13 -1
- package/node_modules/@weavecode/core/dist/harness.js +1 -1
- package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
- package/node_modules/@weavecode/core/dist/index.js +1 -1
- package/node_modules/@weavecode/core/dist/platform.js +1 -1
- package/node_modules/@weavecode/core/dist/types.js +1 -1
- package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
- package/node_modules/@weavecode/core/dist/utils/logger.js +1 -1
- package/node_modules/@weavecode/core/package.json +1 -1
- package/node_modules/@weavecode/harness/dist/claude/assets.js +4 -4
- package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
- package/node_modules/@weavecode/harness/dist/claude/commands.js +3 -3
- package/node_modules/@weavecode/harness/dist/claude/config.d.ts +9 -0
- package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/event-source.d.ts +2 -0
- package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/index.d.ts +4 -2
- package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/liveness.d.ts +64 -0
- package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -0
- package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/model-aliases.d.ts +4 -0
- package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/narration.d.ts +13 -0
- package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -0
- package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
- package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
- package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +14 -14
- package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/transcript.d.ts +13 -0
- package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -6
- package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/capture.d.ts +1 -2
- package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
- package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
- package/node_modules/@weavecode/harness/dist/codex/config.d.ts +10 -0
- package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
- package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/event-source.d.ts +1 -1
- package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
- package/node_modules/@weavecode/harness/dist/codex/images.d.ts +2 -0
- package/node_modules/@weavecode/harness/dist/codex/images.js +1 -0
- package/node_modules/@weavecode/harness/dist/codex/index.d.ts +13 -2
- package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/liveness.d.ts +38 -0
- package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -0
- package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/messaging.d.ts +7 -3
- package/node_modules/@weavecode/harness/dist/codex/messaging.js +3 -3
- package/node_modules/@weavecode/harness/dist/codex/narration.d.ts +10 -0
- package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -0
- package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
- package/node_modules/@weavecode/harness/dist/codex/provision.d.ts +12 -0
- package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -0
- package/node_modules/@weavecode/harness/dist/codex/questions.d.ts +9 -0
- package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -0
- package/node_modules/@weavecode/harness/dist/codex/resume.js +1 -1
- package/node_modules/@weavecode/harness/dist/codex/rollout.d.ts +8 -5
- package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
- package/node_modules/@weavecode/harness/dist/codex/side-question.d.ts +12 -0
- package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -0
- package/node_modules/@weavecode/harness/dist/codex/titles.d.ts +8 -0
- package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -0
- package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
- package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
- package/node_modules/@weavecode/harness/dist/driver.d.ts +162 -8
- package/node_modules/@weavecode/harness/dist/driver.js +1 -1
- package/node_modules/@weavecode/harness/dist/index.d.ts +1 -0
- package/node_modules/@weavecode/harness/dist/index.js +1 -1
- package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
- package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
- package/node_modules/@weavecode/harness/dist/install.d.ts +9 -0
- package/node_modules/@weavecode/harness/dist/install.js +1 -0
- package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
- package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
- package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
- package/node_modules/@weavecode/harness/dist/zcode/assets.js +1 -1
- package/node_modules/@weavecode/harness/dist/zcode/capture.js +3 -3
- package/node_modules/@weavecode/harness/dist/zcode/mcp.js +2 -2
- package/node_modules/@weavecode/harness/package.json +2 -2
- package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
- package/node_modules/@weavecode/server/dist/config/profiles.d.ts +10 -1
- package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
- package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
- package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
- package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/auto-start.js +6 -6
- package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/claude-liveness.d.ts +4 -55
- package/node_modules/@weavecode/server/dist/daemon/claude-liveness.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/data-bus.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.d.ts +2 -0
- package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/liveness.d.ts +7 -0
- package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/narration-watcher.d.ts +28 -0
- package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.d.ts +16 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.d.ts +20 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +12 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.d.ts +23 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.d.ts +19 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.d.ts +87 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.d.ts +45 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend.d.ts +115 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +4 -4
- package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.d.ts +8 -5
- package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
- package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +23 -120
- package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -13
- package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/project-files.d.ts +17 -2
- package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -1
- package/node_modules/@weavecode/server/dist/daemon/project-harnesses.d.ts +2 -0
- package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/project-files.d.ts +6 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/search.d.ts +38 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/server.d.ts +8 -2
- package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
- package/node_modules/@weavecode/server/dist/daemon/session-open.d.ts +10 -1
- package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
- package/node_modules/@weavecode/server/dist/db/db.js +5 -2
- package/node_modules/@weavecode/server/dist/db/layout.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +10 -0
- package/node_modules/@weavecode/server/dist/hooks/bus.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.d.ts +20 -0
- package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/keys.d.ts +7 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/queue.d.ts +4 -4
- package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/delivery/views.d.ts +3 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/dispatcher.d.ts +5 -0
- package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
- package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/inbox-worker.d.ts +15 -0
- package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
- package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +64 -6
- package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +3 -2
- package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
- package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
- package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/plugin-installer.d.ts +5 -0
- package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
- package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
- package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/session-sweeper.d.ts +2 -0
- package/node_modules/@weavecode/server/dist/hooks/session-sweeper.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
- package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
- package/node_modules/@weavecode/server/dist/index.d.ts +1 -0
- package/node_modules/@weavecode/server/dist/index.js +1 -1
- package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
- package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
- package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
- package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
- package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
- package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
- package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
- package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
- package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
- package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
- package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
- package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
- package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
- package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
- package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
- package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
- package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
- package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
- package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
- package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
- package/node_modules/@weavecode/server/dist/market/import.js +2 -2
- package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
- package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
- package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
- package/node_modules/@weavecode/server/dist/registry.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +5 -5
- package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +19 -1
- package/node_modules/@weavecode/server/dist/repositories/hook-events.js +9 -3
- package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
- package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
- package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
- package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
- package/node_modules/@weavecode/server/dist/repositories/projects.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
- package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +12 -2
- package/node_modules/@weavecode/server/dist/repositories/sessions.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/side-questions.d.ts +7 -0
- package/node_modules/@weavecode/server/dist/repositories/side-questions.js +8 -5
- package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
- package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
- package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
- package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
- package/node_modules/@weavecode/server/dist/surfaces.d.ts +8 -1
- package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
- package/node_modules/@weavecode/server/dist/version.d.ts +1 -11
- package/node_modules/@weavecode/server/dist/version.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
- package/node_modules/@weavecode/server/package.json +4 -4
- package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-etRkSvQM.js → abnfDiagram-WEYOIA3C-DA-K085F.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{arc-FxRZALAZ.js → arc-BI1jnmdZ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-5OxZ-ffz.js → architectureDiagram-ZHVYKT53-DbdBgric.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-C-CgMF0O.js → blockDiagram-RJAE7QA3-BPRBmzb-.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-B6TqN1Pw.js → c4Diagram-XDPPPE54-C4D5sRs1.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/channel-DcCJrvon.js +1 -0
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-Bdzr5RRj.js → chunk-2E7WHVMD-9ZSKiNU3.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-gBZASjAC.js → chunk-2Q5K7J3B-i0AOjw_8.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-DSlUhKMw.js → chunk-4EMNKR2T-DTpLfX1H.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-BDQ6zpGR.js → chunk-55XCU76K-COQYRD4q.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-DPnewKbl.js → chunk-5VM5RSS4-VsftEbvo.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-DagmT8Cc.js → chunk-JWPE2WC7-DonektJN.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-Da_2PxfM.js → chunk-VQ5W62QI-CaKUwuul.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-Cdaysois.js → chunk-XXDRQBXY-DXH3D_MT.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-CvgYfbjU.js → chunk-ZCHMQSOR-COwyAuGn.js} +2 -2
- package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-ahplYD2h.js → classDiagram-v2-4MYWR3UA-DEvMZ6mX.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-DFyUfgKj.js → cose-bilkent-JH36ORCC-6JBJHfH6.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-mr2qRwod.js → cynefin-EF2NZ3EQ-C4GM4sjT.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-BC26VqNp.js → cynefinDiagram-WF24UDRP-Cqgi0MBP.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-DoKn_P1x.js → dagre-NK4GIZVX-CljrnkCY.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-C9WfEmt3.js → diagram-CBK3MWTC-C3PyOj5J.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-D4Ibieda.js → diagram-I5XIIV2D-I5brQlaZ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-wsLbYLi0.js → diagram-ODIL2UCW-BX9uFNbU.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-DBioMmDk.js → diagram-PFBEJUXE-y7D-VmqJ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-Cl5gKsWm.js → diagram-RJA3I4VV-DLUL8W42.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-BSXOaZic.js → diagram-TYUNFSNR-DLCC3ILi.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-CJIGOag6.js → ebnfDiagram-V4P3TTPT-D7vALia7.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ-D6nd2OVX.js → elk-QONTBCTQ-Ct2_hatz.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-gmXjWsuF.js → erDiagram-KYQIGQAA-DxLai58T.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-DWAiZ43K.js → flowDiagram-IUGLLWBU-AWn2IHrF.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-De4v6Wtt.js → ganttDiagram-R7GPNTJY-DmRHd4Wz.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-CouLBWOB.js → gitGraphDiagram-PDYL7XHY-Ccj-t3zg.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/index-BSxzia7U.js +1031 -0
- package/node_modules/@weavecode/server/web/dist/assets/index-CEpJpR7P.css +11 -0
- package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-CeMCdduD.js → infoDiagram-MVDRKAX5-BHquFlQa.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-DK6hETwg.js → ishikawaDiagram-HPEHV2GE-CVogEbdm.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-BcgwTlST.js → journeyDiagram-BOSHW7O7-DC9XG9oh.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-CTVMJNz2.js → kanban-definition-FNSA4HC5-C_eu7DC_.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{linear-CqQf5eWO.js → linear-keTbWHJ-.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-B6KZaljU.js → mermaid.core-4sbg0MnY.js} +4 -4
- package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-cpKvrQTI.js → mindmap-definition-6OY57UG3-kMQS0S2l.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-Bv2bNqMZ.js → pegDiagram-ECIUJNBX-DcUFoEwP.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-CXOnA429.js → pieDiagram-GNMPY74T-BQJ7WDCx.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-BFDUpWZb.js → quadrantDiagram-D57K4MC3-C7Oi1-sq.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-BHoDSO0D.js → railroadDiagram-Y72NRBL7-CEF2QbOF.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-B8JGji7q.js → requirementDiagram-EQYSW5RA-CTjjFS7X.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-BbE2-6ZM.js → sankeyDiagram-SY24JHO5-j0S5kubS.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-DwK4X2MT.js → sequenceDiagram-BLEHNHQU-B76EsZp4.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-CY10zRMe.js → sizeCapture-INFHLROL-r0DZuqAy.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-32t4Zx8b.js → stateDiagram-v2-A6IESKWZ-B4DR9LHz.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-CZlYQ8_g.js → swimlanes-B3ENRKFQ-Dbcl85ro.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-CZ_6SSBd.js +8 -0
- package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-8VsB-Jwg.js → timeline-definition-JXYKGLGB-BlBXXRNf.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-CKOTONay.js → usecaseDiagram-WPOLBNNX-Ck1M0dpc.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-BzrNjxtm.js → vennDiagram-Q3Y3IDCW-N8B-ohWk.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-CrSd-v8I.js → wardleyDiagram-IVAIDKWA-DX-AMXq_.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-t9cV9_9b.js → xychartDiagram-4URNHDU4-4fgL48Yl.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/index.html +5 -4
- package/node_modules/@weavecode/templates/package.json +2 -2
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/@peculiar/asn1-x509-attr/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/package.json +4 -4
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/@peculiar/asn1-pfx/package.json +5 -5
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/@peculiar/asn1-pkcs8/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/@peculiar/asn1-x509-attr/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/package.json +7 -7
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/package.json +3 -3
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/package.json +1 -1
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/build/cjs/time.js +1 -1
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/build/es2015/time.js +1 -1
- package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/package.json +2 -2
- package/package.json +6 -6
- package/node_modules/@weavecode/server/web/dist/assets/channel-Dv4QUMOJ.js +0 -1
- package/node_modules/@weavecode/server/web/dist/assets/index-BXhLerZ4.js +0 -1008
- package/node_modules/@weavecode/server/web/dist/assets/index-BYRxC-Zz.css +0 -11
- package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-BlIxQLON.js +0 -8
|
@@ -1,13 +1 @@
|
|
|
1
|
-
import{spawn as H}from"node:child_process";import{basename as X}from"node:path";import{TERMINAL_LOCATOR_ENV as d}from"@weavecode/core";import{pidAlive as J}from"./claude-liveness.js";import{readDaemonSettings as Q}from"./settings.js";import{joinCmd as y,quotePath as W,throughCmd as $}from"./opener/shared.js";import{BRACKETED_PASTE_END as U,BRACKETED_PASTE_START as Y,parseWtPaneId as v,parseWtTargetId as K,wtInjectKeys as C,wtPanePidFromEnv as Z,wtPanesAsWindows as M,wtPanesCached as b,wtWindowSlug as A}from"./opener/wt.js";import{winRaiseTerminalWindow as F}from"./opener/win-raise.js";import{doScriptInTerminalWindow as B,listTerminalAppSurfaces as ee,listTerminalAppTargets as te,parseTerminalAppTargetId as ne,pickTerminalAppWindow as re,terminalAppSurfacesCached as ae}from"./opener/pty-terminals.js";export{parseTerminalAppDump,parseTerminalAppTargetId,parsePsRootPids,parseLsofCwds,pickTerminalAppWindow,terminalAppTargets}from"./opener/pty-terminals.js";export{winRaiseEncodedScript}from"./opener/win-raise.js";export{parseWtPaneId,parseWtProcDump,parseWtTargetId,wtInjectEncodedScript,wtPanePidFromEnv,wtPanes,wtWindowSlug}from"./opener/wt.js";export{planWeztermGrid}from"./opener/wezterm-mux.js";export{quotePath}from"./opener/shared.js";import{MAX_PANES_PER_SCREEN as O,planWeztermGrid as se,weztermSpawnAndSend as oe,captureCommand as S,countWindowsByDir as T,listAttachTargets as ie,normalizeDirKey as k,openInWezterm as ce,parseAttachTargetId as D,runInWezterm as le,weztermCli as u,weztermGuiPidOf as pe,weztermLiveMuxes as P,weztermMuxForId as f,weztermMuxKey as j,weztermPaneFromEnv as we,sessionScreensFromEnvs as me,weztermStepError as h}from"./opener/wezterm-mux.js";export{attachTargetsFromMuxes,countWindowsByDir,listAttachTargets,normalizeDirKey,parseAttachTargetId,parseWeztermPanes,planWeztermNewWindow,planWeztermReuse,sessionScreensFromEnvs,SocketProbeGate,weztermActiveWorkspaceOf,weztermCliArgs,weztermMuxKey,weztermPaneFromEnv,weztermSocketCandidates}from"./opener/wezterm-mux.js";function R(r,e,t){const n=`cd ${W(e,"darwin")} && ${y(t,"darwin")}`.replace(/\\/g,"\\\\").replace(/"/g,'\\"');return r==="Terminal"?["-e",`tell application "Terminal" to do script "${n}"`,"-e",'tell application "Terminal" to activate']:["-e",'tell application "iTerm" to create window with default profile',"-e",`tell application "iTerm" to tell current window to write text "${n}"`]}export function parsePromptPaneId(r){const e=/^([0-9a-f]{8}):(\d+)$/.exec(r);return e?{muxKey:e[1],paneId:Number(e[2])}:null}export class TerminalBackend{preset;enumerable;platform;textAddressable;constructor(e,t,n=process.platform,a=!1){this.preset=e,this.enumerable=t,this.platform=n,this.textAddressable=a}async open(e){await this.spawnFirst(this.candidates(e),`Terminal preset "${this.preset}" is unavailable on this platform`)}async run(e,t){await this.spawnFirst(this.candidates(e,t),`Terminal preset "${this.preset}" cannot run a command here \u2014 pick another preset in settings`)}async countWindows(e){return new Map}async listTargets(e){return[]}async runAt(e,t,n){throw new Error(`Terminal preset "${this.preset}" cannot attach to a chosen pane \u2014 pick wezterm, wt or Terminal.app in settings`)}async focusTarget(e,t){throw new Error(`Terminal preset "${this.preset}" cannot bring an open terminal to the front \u2014 pick wezterm or wt in settings`)}async listPromptPanes(){return[]}async locatePane(e){return null}ownsPaneId(e){return!1}async locateScreens(e){return{}}async sendPromptText(e,t){throw new Error(`Terminal preset "${this.preset}" cannot send text into an open pane \u2014 pick wezterm in settings`)}async sendKeys(e,t){throw new Error(`Terminal preset "${this.preset}" cannot send keys to an open pane \u2014 pick wezterm in settings`)}async closePane(e){throw new Error(`Terminal preset "${this.preset}" cannot close an open pane \u2014 pick wezterm in settings`)}async spawnFirst(e,t){for(const n of e)if(await trySpawn(n))return;throw new Error(e.length===0?t:"No usable terminal found (tried: "+e.map(n=>n.command).join(", ")+")")}}class I extends TerminalBackend{make;constructor(e,t,n){super(e,!1,t),this.make=n}candidates(e,t){return this.make(e,t,this.platform)}}const p={wt:(r,e,t)=>t==="win32"?[{command:"wt.exe",args:["-w",A(r),"-d",r,...$(e,!0)??[]]}]:[],powershell:(r,e,t)=>t==="win32"?[e?{command:"powershell.exe",args:["-NoExit","-Command",y(e,"win32")],cwd:r}:{command:"powershell.exe",args:["-NoExit"],cwd:r}]:[],cmd:(r,e,t)=>t==="win32"?[e?{command:"cmd.exe",args:["/K",y(e,"win32")],cwd:r}:{command:"cmd.exe",args:["/K"],cwd:r}]:[],terminal:(r,e,t)=>t!=="darwin"?[]:e?[{command:"osascript",args:R("Terminal",r,e)}]:[{command:"open",args:["-a","Terminal",r]}],iterm:(r,e,t)=>t!=="darwin"?[]:e?[{command:"osascript",args:R("iTerm",r,e)}]:[{command:"open",args:["-a","iTerm",r]}],gnome:(r,e)=>[{command:"gnome-terminal",args:[`--working-directory=${r}`,...e?["--",...e]:[]]}],konsole:(r,e)=>[{command:"konsole",args:["--workdir",r,...e?["-e",...e]:[]]}],ghostty:(r,e,t)=>t==="win32"?[]:t==="darwin"?e?[]:[{command:"open",args:["-a","Ghostty",r]}]:[{command:"ghostty",args:[`--working-directory=${r}`,...e?["-e",...e]:[]]}]};class de extends TerminalBackend{terminal;constructor(e,t){super("custom",!1,t),this.terminal=e}candidates(e,t){const n=this.terminal.customCommand.trim();if(!n)return[];let a=n.replace(/\{path\}/g,W(e,this.platform));const o=t?y(t,this.platform):"";return a=a.includes("{command}")?a.replace(/\{command\}/g,o):t?`${a} ${o}`:a,[{command:a,args:[],shell:!0}]}}class ue extends TerminalBackend{constructor(e){super("ghostty",!1,e)}candidates(e,t){return p.ghostty(e,t,this.platform)}async openViaIpcThenStandalone(e,t){if(this.platform==="linux"){const n=["+new-window",`--working-directory=${e}`,...t.length>0?["-e",...t]:[]];if((await S("ghostty",n))?.ok)return}await this.spawnFirst(this.candidates(e,t.length>0?t:void 0),`Terminal preset "${this.preset}" is unavailable on this platform`)}open(e){return this.openViaIpcThenStandalone(e,[])}run(e,t){return this.openViaIpcThenStandalone(e,t)}}class N extends TerminalBackend{constructor(e){super("wt",e==="win32",e,e==="win32")}candidates(e,t){return p.wt(e,t,this.platform)}async countWindows(e){if(e.length===0||this.platform!=="win32")return new Map(e.map(n=>[n,0]));const t=await b();return t.length===0?new Map(e.map(n=>[n,0])):T(e,M(t))}async listTargets(e){if(this.platform!=="win32")return[];const t=await b(),n=T([e],M(t)).get(e)??0;return n===0?[]:[{id:`wt:${A(e)}`,windowId:0,tabId:0,title:X(e),matchCount:n,paneCount:n,active:!1,full:!1}]}async runAt(e,t,n){if(this.platform!=="win32")throw new Error(`Terminal preset "${this.preset}" is unavailable on this platform`);if(!K(n))throw new Error(`Invalid terminal target "${n}"`);await this.spawnFirst([{command:"wt.exe",args:["-w",A(e),"split-pane","-d",e,...$(t,!0)??[]]}],`Terminal preset "${this.preset}" is unavailable on this platform`)}async focusTarget(e,t){if(!K(t))throw new Error(`Invalid terminal target "${t}"`);const n=k(e,this.platform),a=(await b()).filter(o=>n!==null&&k(o.cwd,this.platform)===n).map(o=>o.pid);if(!a.length)throw new Error("That terminal is gone \u2014 reopen the list");await F({panePids:a,exe:"windowsterminal.exe"})}async locatePane(e){const t=Z(e);return t==null||!J(t)?null:`wt:${t}`}ownsPaneId(e){return v(e)!==null}async sendPromptText(e,t){const n=v(e);if(n==null)throw new Error(`Invalid prompt pane "${e}"`);await C(n,`${Y}${t}${U}\r`)}async sendKeys(e,t){const n=v(e);if(n==null)throw new Error(`Invalid prompt pane "${e}"`);await C(n,t)}}class _ extends TerminalBackend{constructor(e){super("wezterm",!0,e,!0)}candidates(e,t){return[{command:"wezterm",args:["start","--cwd",e,...$(t,this.platform==="win32")??[]]}]}async open(e){await ce(e)||await super.open(e)}async run(e,t){await le(e,t)||await super.run(e,t)}async countWindows(e){if(e.length===0)return new Map;const{muxes:t}=await weztermLiveMuxesCached();return t.length===0?new Map(e.map(n=>[n,0])):T(e,t.flatMap(n=>n.panes.map(a=>({muxKey:n.socket,windowId:a.windowId,tabId:a.tabId,cwd:a.cwd}))))}listTargets(e){return ie(e,this.platform)}runAt(e,t,n){return runInWeztermAt(e,t,n,this.platform)}async focusTarget(e,t){const n=D(t);if(!n)throw new Error(`Invalid terminal target "${t}"`);const a=await f(n.muxKey);if(!a)throw new Error("wezterm instance is gone \u2014 cannot bring the terminal to the front");const o=a.panes.find(l=>l.windowId===n.windowId&&l.tabId===n.tabId);if(!o)throw new Error("That terminal is gone \u2014 reopen the list");const s=["cli","activate-pane","--pane-id",String(o.paneId)],i=await u(s,a.socket);if(!i?.ok)throw new Error(h(s,a.socket,i));if(this.platform!=="win32")return;const c=(await f(n.muxKey))?.panes??a.panes,w=[(c.find(l=>l.paneId===o.paneId)??o).title,...c.filter(l=>l.windowId===n.windowId).map(l=>l.title)].filter(l=>!!l);await F({guiPid:pe(a.socket)??void 0,titles:w})}async listPromptPanes(){const{muxes:e}=await P();return e.flatMap(t=>t.panes.map(n=>({id:`${j(t.socket)}:${n.paneId}`,title:n.title,cwd:n.cwd})))}async locatePane(e){const[t,n]=d.wezterm,a=e[n];if(!e[t]||!a)return null;const{muxes:o}=await P(!0,a);return we(e,o,this.platform)}ownsPaneId(e){return parsePromptPaneId(e)!==null}async locateScreens(e){if(Object.keys(e).length===0)return{};const{muxes:t,candidates:n}=await weztermLiveMuxesCached();return me(e,t,n,this.platform)}async sendPromptText(e,t){const n=parsePromptPaneId(e);if(!n)throw new Error(`Invalid prompt pane "${e}"`);const a=await f(n.muxKey);if(!a)throw new Error("wezterm instance is gone \u2014 cannot deliver prompt");const o=String(n.paneId);if(t){const i=await u(["cli","send-text","--pane-id",o,t],a.socket);if(!i?.ok)throw new Error(h(["cli","send-text","--pane-id",o,"<prompt text>"],a.socket,i))}const s=await u(["cli","send-text","--pane-id",o,"--no-paste","\r"],a.socket);if(!s?.ok)throw new Error(h(["cli","send-text","--pane-id",o,"--no-paste","<CR>"],a.socket,s))}async sendKeys(e,t){const n=parsePromptPaneId(e);if(!n)throw new Error(`Invalid prompt pane "${e}"`);const a=await f(n.muxKey);if(!a)throw new Error("wezterm instance is gone \u2014 cannot send keys to the pane");const o=String(n.paneId),s=await u(["cli","send-text","--pane-id",o,"--no-paste",t],a.socket);if(!s?.ok)throw new Error(h(["cli","send-text","--pane-id",o,"--no-paste","<keys>"],a.socket,s))}async closePane(e){const t=parsePromptPaneId(e);if(!t)throw new Error(`Invalid prompt pane "${e}"`);const n=await f(t.muxKey);if(!n)throw new Error("wezterm instance is gone \u2014 cannot close the pane");const a=String(t.paneId),o=await u(["cli","kill-pane","--pane-id",a],n.socket);if(!o?.ok)throw new Error(h(["cli","kill-pane","--pane-id",a],n.socket,o))}}class fe extends TerminalBackend{parts;constructor(e){super("auto",!0,e,e!=="win32"&&e!=="darwin");const t={win32:["wt","powershell","cmd"],darwin:["terminal","iterm"]}[e]??["gnome","konsole"];this.parts=t.map(n=>new I(n,e,p[n]))}candidates(e,t){return this.parts.flatMap(n=>t&&n.preset==="iterm"?[]:n.candidates(e,t))}attachBackend(){return this.platform==="darwin"?new G(this.platform):this.platform==="win32"?new N(this.platform):new _(this.platform)}countWindows(e){return this.attachBackend().countWindows(e)}listTargets(e){return this.attachBackend().listTargets(e)}runAt(e,t,n){return this.attachBackend().runAt(e,t,n)}listPromptPanes(){return this.attachBackend().listPromptPanes()}locatePane(e){return this.attachBackend().locatePane(e)}locateScreens(e){return this.attachBackend().locateScreens(e)}sendPromptText(e,t){return this.attachBackend().sendPromptText(e,t)}sendKeys(e,t){return this.attachBackend().sendKeys(e,t)}closePane(e){return this.attachBackend().closePane(e)}}const q={auto:(r,e)=>new fe(e),wt:(r,e)=>new N(e),powershell:(r,e)=>new I("powershell",e,p.powershell),cmd:(r,e)=>new I("cmd",e,p.cmd),terminal:(r,e)=>new G(e),iterm:(r,e)=>new ge(e),gnome:(r,e)=>new I("gnome",e,p.gnome),konsole:(r,e)=>new he(e),ghostty:(r,e)=>new ue(e),wezterm:(r,e)=>new _(e),custom:(r,e)=>new de(r,e)};export function terminalBackendFor(r,e=process.platform){return(q[r.preset]??q.auto)(r,e)}export function locatorPresetOf(r){for(const[e,t]of Object.entries(d))if(t.every(n=>r[n]))return e;return null}export function promptTerminalChannel(r){const e=s=>terminalBackendFor({...r(),preset:s}),t=()=>e(r().preset),n=()=>Object.keys(d).map(s=>e(s)),a=s=>{const i=locatorPresetOf(s);return i?e(i):null},o=s=>n().find(i=>i.ownsPaneId(s))??null;return{available:()=>n().some(s=>s.textAddressable),listPanes:async()=>{const s=t();return s.textAddressable?await s.listPromptPanes():[]},locatePane:async s=>await a(s)?.locatePane(s)??null,locateScreens:async s=>{const i={},c=new Map;for(const[w,l]of Object.entries(s)){const m=locatorPresetOf(l);if(!m){i[w]=null;continue}const x=c.get(m)??{};x[w]=l,c.set(m,x)}for(const[w,l]of c){const m=e(w);if(!m.locateScreens){for(const E of Object.keys(l))i[E]=null;continue}const x=await m.locateScreens(l);for(const[E,V]of Object.entries(x))i[E]=V}return i},sendText:async(s,i)=>{const c=o(s);if(!c)throw new Error(`Invalid prompt pane "${s}"`);await c.sendPromptText(s,i)},sendKeys:async(s,i)=>{const c=o(s);if(!c)throw new Error(`Invalid prompt pane "${s}"`);await c.sendKeys(s,i)},closePane:async s=>{const i=o(s);if(!i)throw new Error(`Invalid prompt pane "${s}"`);await i.closePane(s)}}}export async function runInTerminal(r,e,t){await terminalBackendFor(t).run(r,e)}export async function runInWeztermAt(r,e,t,n=process.platform){const a=D(t);if(!a)throw new Error(`Invalid terminal target "${t}"`);const{muxes:o}=await P(),s=o.find(c=>j(c.socket)===a.muxKey);if(!s)throw new Error("wezterm instance is gone \u2014 pick a terminal again");const i=s.panes.filter(c=>c.windowId===a.windowId&&c.tabId===a.tabId);if(i.length===0)throw new Error("terminal tab is gone \u2014 pick a terminal again");if(i.length>=O)throw new Error(`terminal is full (${O} panes) \u2014 pick another terminal or open a new one`);await oe(s.socket,r,e,se(i),s.workspace,n)}export async function countOpenTerminals(r,e){return terminalBackendFor(e).countWindows(r)}export function panesAtDir(r,e,t=process.platform){const n=k(e,t);return r.filter(a=>a.cwd!=null&&k(a.cwd,t)===n)}export async function listProjectPanes(r,e,t=process.platform){const n=terminalBackendFor(e,t),a=panesAtDir(await n.listPromptPanes(),r,t);if(a.length===0&&((await n.countWindows([r])).get(r)??0)>0)throw new Error(`Terminal preset "${n.preset}" cannot close open panes remotely \u2014 pick wezterm in settings`);return a}export async function closeTerminalsIn(r,e,t,n=process.platform){const a=terminalBackendFor(e,n),o=new Set(t),s=(await listProjectPanes(r,e,n)).filter(i=>o.has(i.id));for(const i of s)await a.closePane(i.id);return s.length}export async function readTerminalCounts(r,e=void 0){const t=await Q(),n=await(e?.countTerminals??countOpenTerminals)(r.map(a=>a.path),t.terminal);return Object.fromEntries(r.map(a=>[a.id,n.get(a.path)??0]))}let g=null;export async function weztermLiveMuxesCached(){if(g&&Date.now()-g.at<1e4)return g;const{muxes:r,candidates:e}=await P(!0);return g={at:Date.now(),muxes:r,candidates:e},g}export function resolveTerminalLaunch(r,e,t=process.platform,n){return terminalBackendFor(e,t).candidates(r,n)}export function resolveExplorerLaunch(r,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[r]}:e==="darwin"?{command:"open",args:[r]}:{command:"xdg-open",args:[r]}}export function trySpawn(r){return new Promise(e=>{let t;try{t=H(r.command,r.args,{cwd:r.cwd,shell:r.shell,detached:!0,stdio:"ignore"})}catch{e(!1);return}t.on("error",()=>e(!1)),t.on("spawn",()=>{t.unref(),e(!0)})})}export async function openInExplorer(r){const e=resolveExplorerLaunch(r);if(!await trySpawn(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(r,e){await terminalBackendFor(e).open(r)}class he extends TerminalBackend{constructor(e){super("konsole",!1,e,e==="linux")}candidates(e,t){return p.konsole(e,t,this.platform)}async locatePane(e){return konsolePaneFromEnv(e)}ownsPaneId(e){return parseKonsolePaneId(e)!==null}async sendPromptText(e,t){const n=parseKonsolePaneId(e);if(!n)throw new Error(`Invalid prompt pane "${e}"`);t&&await z(n,"sendText",t),await z(n,"sendKey",String(L))}async sendKeys(e,t){const n=parseKonsolePaneId(e);if(!n)throw new Error(`Invalid prompt pane "${e}"`);for(const a of t)await z(n,"sendKey",String(qtKeyOf(a)))}}export function parseKonsolePaneId(r){const e=/^konsole:([\w.:-]+)\|(\/[\w/]+)$/.exec(r);return e?{service:e[1],session:e[2]}:null}export function konsolePaneFromEnv(r){const[e,t]=d.konsole,n=r[e],a=r[t];if(!n||!a)return null;const o=`konsole:${n}|${a}`;return parseKonsolePaneId(o)?o:null}const L=16777220;export function qtKeyOf(r){switch(r){case"\x1B":return 16777216;case"\r":case`
|
|
2
|
-
`:return L;case" ":return 16777217;case"\b":return 16777219;default:return r.codePointAt(0)??0}}async function z(r,e,t){const n=[...["qdbus6","qdbus5","qdbus"].map(s=>({command:s,args:[r.service,r.session,e,t]})),{command:"dbus-send",args:["--session","--type=method_call",`--dest=${r.service}`,r.session,`org.kde.konsole.Session.${e}`,`string:${t}`]}];let a=null;for(const s of n){const i=await S(s.command,s.args,void 0,5e3);if(i?.ok)return;a=i}const o=a?a.err||a.out||"unknown error":"no qdbus / dbus-send on PATH";throw new Error(`Konsole D-Bus call "${e}" failed: ${o}`)}class ge extends TerminalBackend{constructor(e){super("iterm",!1,e,e==="darwin")}candidates(e,t){return p.iterm(e,t,this.platform)}async locatePane(e){return itermPaneFromEnv(e)}ownsPaneId(e){return parseItermPaneId(e)!==null}async sendPromptText(e,t){const n=parseItermPaneId(e);if(!n)throw new Error(`Invalid prompt pane "${e}"`);await xe(n,t)}}export function parseItermPaneId(r){const e=/^iterm:(w\d+t\d+p\d+:[0-9A-Fa-f-]+)$/.exec(r);return e?e[1]:null}export function itermPaneFromEnv(r){const[e]=d.iterm,t=r[e];if(!t)return null;const n=`iterm:${t}`;return parseItermPaneId(n)?n:null}export function applescriptString(r){return r.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}async function xe(r,e){const t=`tell application "iTerm2"
|
|
3
|
-
repeat with w in windows
|
|
4
|
-
repeat with t in tabs of w
|
|
5
|
-
repeat with s in sessions of t
|
|
6
|
-
if unique id of s is "${r}" then
|
|
7
|
-
tell s to write text "${applescriptString(e)}"
|
|
8
|
-
return "ok"
|
|
9
|
-
end if
|
|
10
|
-
end repeat
|
|
11
|
-
end repeat
|
|
12
|
-
end repeat
|
|
13
|
-
end tell`,n=await S("osascript",["-e",t],void 0,8e3);if(!n)throw new Error("osascript is unavailable \u2014 cannot send text into iTerm2");if(!n.ok||!n.out.includes("ok"))throw new Error(`iTerm2 write text failed: ${n.err||n.out||"unknown error"}`)}class G extends TerminalBackend{constructor(e){super("terminal",e==="darwin",e)}candidates(e,t){return p.terminal(e,t,this.platform)}async run(e,t){if(this.platform==="darwin"){const n=await ee(this.platform),a=re(n,e,this.platform);if(a&&await B(e,t,a.windowId))return}await this.spawnFirst(this.candidates(e,t),`Terminal preset "${this.preset}" is unavailable on this platform`)}async countWindows(e){if(e.length===0||this.platform!=="darwin")return new Map(e.map(n=>[n,0]));const t=await ae(this.platform);return t.length===0?new Map(e.map(n=>[n,0])):T(e,t.flatMap(n=>n.cwd?[{muxKey:"terminal.app",windowId:n.windowId,tabId:n.tabIndex,cwd:n.cwd}]:[]))}listTargets(e){return te(e,this.platform)}async runAt(e,t,n){const a=ne(n);if(!a)throw new Error(`Invalid terminal target "${n}"`);if(!await B(e,t,a.windowId))throw new Error("Terminal window is gone \u2014 pick a terminal again")}}export const defaultProjectOpener={openExplorer:openInExplorer,openTerminal:openInTerminal,runInTerminal,countTerminals:countOpenTerminals,closeTerminals:(r,e,t)=>closeTerminalsIn(r,e,t),listPanes:(r,e)=>listProjectPanes(r,e),listTerminals:(r,e)=>terminalBackendFor(e).listTargets(r),runInTerminalAt:(r,e,t,n)=>terminalBackendFor(n).runAt(r,e,t),focusTerminal:(r,e,t)=>terminalBackendFor(t).focusTarget(r,e)};
|
|
1
|
+
import{TERMINAL_LOCATOR_ENV as h}from"@weavecode/core";import{readDaemonSettings as B}from"./settings.js";import{normalizeDirKey as P}from"./opener/wezterm-mux.js";import{KonsoleBackend as E}from"./opener/backend-konsole.js";import{ItermBackend as A}from"./opener/backend-iterm.js";import{GhosttyBackend as I}from"./opener/backend-ghostty.js";import{TerminalAppBackend as k}from"./opener/backend-terminal-app.js";import{WtBackend as T}from"./opener/backend-wt.js";import{WeztermBackend as x}from"./opener/backend-wezterm.js";import{CandidatesBackend as u,CustomBackend as b,PRESET_CANDIDATES as w,TerminalBackend as S,trySpawn as W}from"./opener/backend.js";export{parseTerminalAppDump,parseTerminalAppTargetId,parsePsRootPids,parseLsofCwds,pickTerminalAppWindow,terminalAppTargets}from"./opener/pty-terminals.js";export{winRaiseEncodedScript}from"./opener/win-raise.js";export{parseWtPaneId,parseWtProcDump,parseWtTargetId,wtInjectEncodedScript,wtPanePidFromEnv,wtPanes,wtWindowSlug}from"./opener/wt.js";export{quotePath}from"./opener/shared.js";export{attachTargetsFromMuxes,countWindowsByDir,listAttachTargets,normalizeDirKey,parseAttachTargetId,parseWeztermPanes,planWeztermNewWindow,planWeztermReuse,sessionScreensFromEnvs,SocketProbeGate,weztermActiveWorkspaceOf,weztermCliArgs,weztermMuxKey,weztermPaneFromEnv,weztermSocketCandidates}from"./opener/wezterm-mux.js";export{planWeztermGrid}from"./opener/wezterm-mux.js";export{konsolePaneFromEnv,parseKonsolePaneId,qtKeyOf}from"./opener/backend-konsole.js";export{applescriptString,itermPaneFromEnv,parseItermPaneId}from"./opener/backend-iterm.js";export{parsePromptPaneId,runInWeztermAt}from"./opener/backend-wezterm.js";export{CandidatesBackend,CustomBackend,PRESET_CANDIDATES,TerminalBackend,trySpawn}from"./opener/backend.js";class z extends S{parts;constructor(e){super("auto",!0,e,e!=="win32"&&e!=="darwin");const a={win32:["wt","powershell","cmd"],darwin:["terminal","iterm"]}[e]??["gnome","konsole"];this.parts=a.map(s=>new u(s,e,w[s]))}candidates(e,n){return this.parts.flatMap(a=>n&&a.preset==="iterm"?[]:a.candidates(e,n))}attachBackend(){return this.platform==="darwin"?new k(this.platform):this.platform==="win32"?new T(this.platform):new x(this.platform)}countWindows(e){return this.attachBackend().countWindows(e)}listTargets(e){return this.attachBackend().listTargets(e)}runAt(e,n,a){return this.attachBackend().runAt(e,n,a)}focusTarget(e,n){return this.attachBackend().focusTarget(e,n)}listPromptPanes(){return this.attachBackend().listPromptPanes()}locatePane(e){return this.attachBackend().locatePane(e)}locateScreens(e){return this.attachBackend().locateScreens(e)}sendPromptText(e,n){return this.attachBackend().sendPromptText(e,n)}sendKeys(e,n){return this.attachBackend().sendKeys(e,n)}getPaneText(e){return this.attachBackend().getPaneText(e)}closePane(e){return this.attachBackend().closePane(e)}}const g={auto:(t,e)=>new z(e),wt:(t,e)=>new T(e),powershell:(t,e)=>new u("powershell",e,w.powershell),cmd:(t,e)=>new u("cmd",e,w.cmd),terminal:(t,e)=>new k(e),iterm:(t,e)=>new A(e),gnome:(t,e)=>new u("gnome",e,w.gnome),konsole:(t,e)=>new E(e),ghostty:(t,e)=>new I(e),wezterm:(t,e)=>new x(e),custom:(t,e)=>new b(t,e)};export function terminalBackendFor(t,e=process.platform){return(g[t.preset]??g.auto)(t,e)}export function locatorPresetOf(t){for(const[e,n]of Object.entries(h))if(n.every(a=>t[a]))return e;return null}export function promptTerminalChannel(t){const e=r=>terminalBackendFor({...t(),preset:r}),n=()=>e(t().preset),a=()=>Object.keys(h).map(r=>e(r)),s=r=>{const o=locatorPresetOf(r);return o?e(o):null},c=r=>a().find(o=>o.ownsPaneId(r))??null;return{available:()=>a().some(r=>r.textAddressable),listPanes:async()=>{const r=n();return r.textAddressable?await r.listPromptPanes():[]},locatePane:async r=>await s(r)?.locatePane(r)??null,locateScreens:async r=>{const o={},i=new Map;for(const[l,m]of Object.entries(r)){const p=locatorPresetOf(m);if(!p){o[l]=null;continue}const d=i.get(p)??{};d[l]=m,i.set(p,d)}for(const[l,m]of i){const p=e(l);if(!p.locateScreens){for(const f of Object.keys(m))o[f]=null;continue}const d=await p.locateScreens(m);for(const[f,y]of Object.entries(d))o[f]=y}return o},sendText:async(r,o)=>{const i=c(r);if(!i)throw new Error(`Invalid prompt pane "${r}"`);await i.sendPromptText(r,o)},sendKeys:async(r,o)=>{const i=c(r);if(!i)throw new Error(`Invalid prompt pane "${r}"`);await i.sendKeys(r,o)},closePane:async r=>{const o=c(r);if(!o)throw new Error(`Invalid prompt pane "${r}"`);await o.closePane(r)}}}export async function runInTerminal(t,e,n){return terminalBackendFor(n).run(t,e)}export async function countOpenTerminals(t,e){return terminalBackendFor(e).countWindows(t)}export function panesAtDir(t,e,n=process.platform){const a=P(e,n);return t.filter(s=>s.cwd!=null&&P(s.cwd,n)===a)}export async function listProjectPanes(t,e,n=process.platform){const a=terminalBackendFor(e,n),s=panesAtDir(await a.listPromptPanes(),t,n);if(s.length===0&&((await a.countWindows([t])).get(t)??0)>0)throw new Error(`Terminal preset "${a.preset}" cannot close open panes remotely \u2014 pick wezterm in settings`);return s}export async function closeTerminalsIn(t,e,n,a=process.platform){const s=terminalBackendFor(e,a),c=new Set(n),r=(await listProjectPanes(t,e,a)).filter(o=>c.has(o.id));for(const o of r)await s.closePane(o.id);return r.length}export async function readTerminalCounts(t,e=void 0){const n=await B(),s=await(e?.countTerminals??countOpenTerminals)(t.map(c=>c.path),n.terminal);return Object.fromEntries(t.map(c=>[c.id,s.get(c.path)??0]))}export function resolveTerminalLaunch(t,e,n=process.platform,a){return terminalBackendFor(e,n).candidates(t,a)}export function resolveExplorerLaunch(t,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[t]}:e==="darwin"?{command:"open",args:[t]}:{command:"xdg-open",args:[t]}}export async function openInExplorer(t){const e=resolveExplorerLaunch(t);if(!await W(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(t,e){await terminalBackendFor(e).open(t)}export const defaultProjectOpener={openExplorer:openInExplorer,openTerminal:openInTerminal,runInTerminal,countTerminals:countOpenTerminals,closeTerminals:(t,e,n)=>closeTerminalsIn(t,e,n),listPanes:(t,e)=>listProjectPanes(t,e),listTerminals:(t,e)=>terminalBackendFor(e).listTargets(t),runInTerminalAt:(t,e,n,a)=>terminalBackendFor(a).runAt(t,e,n),focusTerminal:(t,e,n)=>terminalBackendFor(n).focusTarget(t,e)};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"node:net";export const DEFAULT_PORT=6420,DAEMON_HOST="127.0.0.1",DEFAULT_BIND_HOST="0.0.0.0";export function isPortFree(r,
|
|
1
|
+
import t from"node:net";export const DEFAULT_PORT=6420,DAEMON_HOST="127.0.0.1",DEFAULT_BIND_HOST="0.0.0.0";export function isPortFree(r,o=DAEMON_HOST){return new Promise(e=>{const n=t.createServer();n.once("error",()=>e(!1)),n.once("listening",()=>n.close(()=>e(!0))),n.listen(r,o)})}export async function findFreePort(r,o=100){for(let e=r;e<r+o;e++)if(await isPortFree(e))return e;throw new Error(`No free port found in range ${r}-${r+o-1}`)}
|
|
@@ -10,7 +10,7 @@ import type { PathRefKind } from '@weavecode/harness';
|
|
|
10
10
|
/** 索引条目上限:再大就不是「路径补全」该扛的量了,退化成目录浏览。 */
|
|
11
11
|
export declare const MAX_INDEX_FILES = 300000;
|
|
12
12
|
/** 快照格式版本:作废盘上的旧文件,改形状必须递增。 */
|
|
13
|
-
export declare const INDEX_VERSION =
|
|
13
|
+
export declare const INDEX_VERSION = 2;
|
|
14
14
|
/**
|
|
15
15
|
* 索引的可序列化部分 = **落盘那一份的形状**:枚举结果 + 建它时的根与 git 指纹。
|
|
16
16
|
* 派生出来的东西(小写表、目录子项映射)**不在这层**,读回来现算。
|
|
@@ -28,6 +28,8 @@ export interface FileIndexSnapshot {
|
|
|
28
28
|
files: string[];
|
|
29
29
|
/** 目录集:由文件路径前缀派生 + 子模块的 gitlink(git 不列目录)。 */
|
|
30
30
|
dirs: string[];
|
|
31
|
+
/** 嵌套仓(子模块/嵌套 git 仓)路径 → 实际 HEAD 短 hash(建索引那一拍读的)。 */
|
|
32
|
+
submodules?: Record<string, string>;
|
|
31
33
|
}
|
|
32
34
|
/** 一个目录的直接子项(完整相对路径)。排序**等第一次浏览这个目录时再做**:
|
|
33
35
|
* 30 万条上 `localeCompare({numeric:true})` 是每个比较几微秒,建索引时全排一遍要半分钟。 */
|
|
@@ -42,6 +44,8 @@ export interface FileIndex extends FileIndexSnapshot {
|
|
|
42
44
|
dirLower: string[];
|
|
43
45
|
/** 目录 → 直接子项:浏览面 O(子项数),不再扫全索引。 */
|
|
44
46
|
children: Map<string, DirChildren>;
|
|
47
|
+
/** 嵌套仓 HEAD 短 hash(快照缺省 = 旧快照没有这张表,空)。 */
|
|
48
|
+
submodules: Readonly<Record<string, string>>;
|
|
45
49
|
}
|
|
46
50
|
export interface PathHit {
|
|
47
51
|
path: string;
|
|
@@ -69,14 +73,25 @@ export declare function setFileIndexRoot(dir: string | null): void;
|
|
|
69
73
|
export declare function projectFileIndex(projectId: number, root: string, opts?: {
|
|
70
74
|
fresh?: boolean;
|
|
71
75
|
}): Promise<FileIndex>;
|
|
76
|
+
/**
|
|
77
|
+
* 只读窥视:内存/盘上快照就绪且指纹新鲜才给,miss 返回 null——**绝不触发重建**
|
|
78
|
+
* (全局搜索对十几个项目逐个问,冷项目跳过,不能让一次搜索背起整排索引构建)。
|
|
79
|
+
* `maxStaleMs` 放宽盘上快照的年纪窗(搜索路传 24h:文件名索引陈一天照样能用,
|
|
80
|
+
* git 指纹不符仍会拒——10 分钟硬窗是「粘贴认引用」的保真口径,搜索不需要)。
|
|
81
|
+
*/
|
|
82
|
+
export declare function peekCachedIndex(projectId: number, root: string, opts?: {
|
|
83
|
+
maxStaleMs?: number;
|
|
84
|
+
}): Promise<FileIndex | null>;
|
|
72
85
|
/** 测试用:清空索引缓存。 */
|
|
73
86
|
export declare function clearFileIndexCache(): void;
|
|
74
87
|
/** 删掉已不在库里的项目的快照(大仓库一份按 MB 计),daemon 启动时清一次。 */
|
|
75
88
|
export declare function pruneFileIndexes(projectIds: readonly number[]): void;
|
|
76
|
-
/** 目录浏览:`dir`(相对,'' = 根)的直接子项,目录在前、名字排(自然序)。
|
|
89
|
+
/** 目录浏览:`dir`(相对,'' = 根)的直接子项,目录在前、名字排(自然序)。
|
|
90
|
+
* 嵌套仓目录带 `head`(建索引那一拍的短 hash),前端拿它摆 submodule 徽标。 */
|
|
77
91
|
export declare function listDirOf(index: FileIndex, dir: string): {
|
|
78
92
|
path: string;
|
|
79
93
|
kind: PathRefKind;
|
|
94
|
+
head?: string;
|
|
80
95
|
}[];
|
|
81
96
|
export interface MatchResult {
|
|
82
97
|
hits: PathHit[];
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{execFile as
|
|
1
|
+
import{execFile as X}from"node:child_process";import{lstat as $,mkdir as P,readFile as x,readdir as V,realpath as D,rename as z,stat as A,writeFile as B}from"node:fs/promises";import{readdirSync as G,rmSync as J}from"node:fs";import f from"node:path";import{promisify as Y}from"node:util";import{getIndexDir as I}from"../db/paths.js";const K=Y(X);export const MAX_INDEX_FILES=3e5,INDEX_VERSION=2;const L=3e4,j=10*6e4,Q=3,U=new Set(["node_modules",".git","dist","build","out",".next","target","coverage",".turbo"]);async function b(t,n){try{const{stdout:e}=await K("git",["ls-files","-z",...n],{cwd:t,timeout:1e4,maxBuffer:67108864,windowsHide:!0});return e.split("\0").filter(Boolean)}catch{return null}}async function Z(t){const n=await b(t,["--stage"]);return n?n.filter(e=>e.startsWith("160000 ")).map(e=>e.slice(e.indexOf(" ")+1)):[]}async function q(t){const n=await b(t,["--stage"]);return n?n.filter(e=>e.startsWith("120000 ")).map(e=>e.slice(e.indexOf(" ")+1)):[]}function F(t){return $(f.join(t,".git")).then(()=>!0,()=>!1)}async function tt(t){try{let n=f.join(t,".git");if(!(await $(n)).isDirectory()){const s=/^gitdir:\s*(.+)$/m.exec(await x(n,"utf8"));if(!s)return null;n=f.resolve(t,s[1].trim())}const e=(await x(f.join(n,"HEAD"),"utf8")).trim(),i=e.startsWith("ref: ")?await(async()=>{const s=e.slice(5);try{return(await x(f.join(n,s),"utf8")).trim()}catch{const a=(await x(f.join(n,"packed-refs"),"utf8")).split(`
|
|
2
|
+
`).find(c=>c.endsWith(` ${s}`));return a?a.slice(0,a.indexOf(" ")):null}})():e;return i!==null&&/^[0-9a-f]{40}$/i.test(i)?i.slice(0,7):null}catch{return null}}async function et(t){const n=await b(t,["--others","--ignored","--exclude-standard","--directory"]),e=[];for(const i of n??[]){if(!i.endsWith("/"))continue;const s=i.slice(0,-1);await F(f.join(t,s))&&e.push(s)}return e}async function M(t,n=""){const e=await b(t,["--cached","--others","--exclude-standard"]);if(!e)return null;const i=new Set;for(const o of await Z(t))i.add(o);for(const o of e)o.endsWith("/")&&i.add(o.slice(0,-1));for(const o of await et(t))i.add(o);const s=new Set;for(const o of await q(t))if(!i.has(o))try{(await A(f.join(t,o))).isDirectory()&&s.add(o)}catch{}const r=e.filter(o=>!o.endsWith("/")&&!i.has(o)&&!s.has(o)).map(o=>n+o),a=[...i,...s].map(o=>n+o),c={};for(const o of i){const d=f.join(t,o);if(!await F(d))continue;const w=await tt(d);w&&(c[`${n}${o}`]=w);const l=await M(d,`${n}${o}/`);l&&(r.push(...l.files),a.push(...l.links),Object.assign(c,l.heads))}const u=new Set([await D(t).catch(()=>t)]);for(const o of s){const d=f.join(t,o),w=await D(d).catch(()=>null);if(w===null||u.has(w))continue;u.add(w);const l=`${n}${o}/`;for(let m=r.length-1;m>=0;m--)r[m].startsWith(l)&&r.splice(m,1);const p=await M(d,l)??{files:await W(d),links:[],heads:{}};r.push(...p.files),a.push(...p.links),Object.assign(c,p.heads)}return{files:r,links:a,heads:c}}async function W(t){const n=[],e=new Set([await D(t).catch(()=>t)]),i=async s=>{if(n.length>=MAX_INDEX_FILES)return;let r;try{r=await V(f.join(t,s),{withFileTypes:!0})}catch{return}for(const a of r){if(n.length>=MAX_INDEX_FILES)return;const c=s?`${s}/${a.name}`:a.name;if(a.isDirectory()||a.isSymbolicLink()){if(U.has(a.name))continue;if(a.isSymbolicLink()){let u;try{u=(await A(f.join(t,c))).isDirectory()}catch{u=!1}if(!u){a.name!==".git"&&n.push(c);continue}const o=await D(f.join(t,c)).catch(()=>null);if(o===null||e.has(o))continue;e.add(o);try{await i(c)}finally{e.delete(o)}}else await i(c)}else a.isFile()&&a.name!==".git"&&n.push(c)}};return await i(""),n}function v(t){const n=new Set;for(const e of t){let i=e.lastIndexOf("/");for(;i>0;){const s=e.slice(0,i);if(n.has(s))break;n.add(s),i=s.lastIndexOf("/")}}return[...n].sort()}async function O(t){try{let n=f.join(t,".git");if(!(await $(n)).isDirectory()){const i=/^gitdir:\s*(.+)$/m.exec(await x(n,"utf8"));if(!i)return null;n=f.resolve(t,i[1].trim())}const e=await A(f.join(n,"index"));return`${e.mtimeMs}:${e.size}`}catch{return null}}async function nt(t){const n=await M(t),e=n?.files??await W(t),i=e.length>MAX_INDEX_FILES,s=i?e.slice(0,MAX_INDEX_FILES):e;s.sort();const r=n?.links??[],a=[...new Set([...v(s),...r,...v(r)])].sort();return{v:INDEX_VERSION,root:t,at:Date.now(),stamp:await O(t),truncated:i,files:s,dirs:a,...n&&Object.keys(n.heads).length>0?{submodules:n.heads}:{}}}export function hydrateIndex(t){const n=new Array(t.files.length);for(let r=0;r<t.files.length;r++)n[r]=t.files[r].toLowerCase();const e=new Array(t.dirs.length);for(let r=0;r<t.dirs.length;r++)e[r]=t.dirs[r].toLowerCase();const i=new Map,s=r=>{let a=i.get(r);return a||i.set(r,a={dirs:[],files:[],sorted:!1}),a};for(const r of t.dirs)s(r.slice(0,Math.max(0,r.lastIndexOf("/")))).dirs.push(r);for(const r of t.files)s(r.slice(0,Math.max(0,r.lastIndexOf("/")))).files.push(r);return{...t,lower:n,dirLower:e,children:i,submodules:t.submodules??{}}}export async function buildIndex(t){return hydrateIndex(await nt(t))}const h=new Map,_=new Map;let C=null;export function setFileIndexRoot(t){C=t}function N(t){return f.join(C??I(),`${t}.json`)}function it(t){return{v:t.v,root:t.root,at:t.at,stamp:t.stamp,truncated:t.truncated,files:t.files,dirs:t.dirs,...Object.keys(t.submodules).length>0?{submodules:{...t.submodules}}:{}}}async function st(t,n){const e=N(t),i=`${e}.tmp`;try{await P(f.dirname(e),{recursive:!0}),await B(i,JSON.stringify(it(n)),"utf8"),await z(i,e)}catch{}}async function H(t,n){try{const e=JSON.parse(await x(N(t),"utf8"));return e?.v!==INDEX_VERSION||e.root!==n||!Array.isArray(e.files)||!Array.isArray(e.dirs)?null:e}catch{return null}}function E(t,n){for(h.delete(t),h.set(t,n);h.size>Q;){const e=h.keys().next().value;if(e===void 0)break;h.delete(e)}}function rt(t,n){const e=_.get(t);if(e)return e;const i=buildIndex(n).then(r=>(E(t,r),st(t,r),r));_.set(t,i);const s=()=>{_.delete(t)};return i.then(s,s),i}export async function projectFileIndex(t,n,e={}){const i=h.get(t);if(i&&i.root===n&&!e.fresh){if(Date.now()-i.at<L&&await O(n)===i.stamp)return i;h.delete(t)}else i&&h.delete(t);const s=_.get(t);if(s)return s;if(!i&&!e.fresh){const r=await H(t,n);if(r&&Date.now()-r.at<j&&await O(n)===r.stamp){const a=hydrateIndex(r);return E(t,a),a}}return rt(t,n)}export async function peekCachedIndex(t,n,e={}){const i=h.get(t);if(i&&i.root===n)return Date.now()-i.at<L&&await O(n)===i.stamp?i:(h.delete(t),null);const s=e.maxStaleMs??j,r=await H(t,n);if(r&&Date.now()-r.at<s&&await O(n)===r.stamp){const a=hydrateIndex(r);return E(t,a),a}return null}export function clearFileIndexCache(){h.clear()}export function pruneFileIndexes(t){const n=C??I(),e=new Set(t.map(s=>`${s}.json`));let i;try{i=G(n)}catch{return}for(const s of i)if(!(!s.endsWith(".json")||e.has(s)))try{J(f.join(n,s))}catch{}}const R=new Intl.Collator(void 0,{numeric:!0});export function listDirOf(t,n){const e=t.children.get(n);if(!e)return[];e.sorted||(e.dirs.sort(R.compare),e.files.sort(R.compare),e.sorted=!0);const i=[];for(const s of e.dirs){const r=t.submodules[s];i.push(r?{path:s,kind:"dir",head:r}:{path:s,kind:"dir"})}for(const s of e.files)i.push({path:s,kind:"file"});return i}function at(t,n){return t.startsWith(n)?3:t.includes(n)?2:ot(t,n)?1:-1}function ot(t,n){let e=0;for(let i=0;i<t.length&&e<n.length;i++)t[i]===n[e]&&e++;return e===n.length}function ct(t,n,e){const i=t.lastIndexOf("/")+1,s=t.slice(i).toLowerCase();if(n===3||n===2){const c=s.indexOf(e);return c<0?[]:[[i+c,e.length]]}const r=[];let a=0;for(let c=0;c<s.length&&a<e.length;c++)s[c]===e[a]&&(r.push([i+c,1]),a++);return r}function T(t,n){return n.rank-t.rank||t.len-n.len||t.path.localeCompare(n.path)}const lt=8,ft=1024;function ut(t,n){if(!n)return 0;let e=0,i=t.length;for(;e<i;){const s=e+i>>1;t[s]<n?e=s+1:i=s}return e}export function startMatch(t,n,e,i=""){const s=n.trim().toLowerCase(),r=i?`${i}/`:"",a=[];let c=s&&e>0?"files":"done",u=0,o=0,d=!1;const w=(l,p)=>{const m=l.slice(l.lastIndexOf("/")+1).toLowerCase(),y=at(m,s);if(y<0)return;o++;const g={path:l,kind:p,rank:y,len:l.length};if(a.length===e&&T(g,a[e-1])>=0)return;const S=a.length===e;let k=S?e-1:a.length;for(S?a[e-1]=g:a.push(g);k>0&&T(g,a[k-1])<0;)a[k]=a[k-1],k--;a[k]=g};return{step(l){const p=Date.now()+l;let m=0;for(;c!=="done";){const y=c==="files"?t.files:t.dirs,g=c==="files"?"file":"dir";for(u===0&&(u=ut(y,r));u<y.length;){const S=y[u];if(r&&!S.startsWith(r))break;if(w(S,g),u++,a.length===e&&a[e-1].rank===3)return d=!0,c="done",!0;if((++m&ft-1)===0&&Date.now()>p)return!1}u=0,c=c==="files"?"dirs":"done"}return!0},result(){return{hits:a.map(l=>({path:l.path,kind:l.kind,ranges:ct(l.path,l.rank,s)})),total:d?a.length:o,capped:d}}}}export async function matchPaths(t,n,e,i=""){const s=startMatch(t,n,e,i);for(;!s.step(lt);)await new Promise(r=>setImmediate(r));return s.result()}
|
|
@@ -25,6 +25,8 @@ export interface ProjectHarness {
|
|
|
25
25
|
/** resume 槽的版本下限(UI 据此说明为什么置灰)。 */
|
|
26
26
|
minVersion?: string;
|
|
27
27
|
}
|
|
28
|
+
/** `<bin> --version` 的首个 semver;探不到 null(win32 上 npm shim 是 .cmd,须走 shell)。 */
|
|
29
|
+
export declare function probeBinVersion(bin: string): Promise<string | null>;
|
|
28
30
|
/** 项目的已接入 harness(init 选择结果)+ 各自能否起交互会话(注册表现状)。 */
|
|
29
31
|
export declare function projectHarnesses(projectPath: string, registry?: HarnessRegistry,
|
|
30
32
|
/** 版本探测(测试注入;缺省真跑 `<bin> --version`)。 */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{spawn as c}from"node:child_process";import{readFile as m}from"node:fs/promises";import f from"node:path";import{HARNESS_KEYS as d,isHarness as w}from"@weavecode/core";import{isVersionAtLeast as
|
|
2
|
-
`).find(
|
|
1
|
+
import{spawn as c}from"node:child_process";import{readFile as m}from"node:fs/promises";import f from"node:path";import{HARNESS_KEYS as d,isHarness as w}from"@weavecode/core";import{isVersionAtLeast as h}from"../hooks/toolkit.js";export async function projectHarnessIds(n){const e=[d[0]];let s;try{s=await m(f.join(n,".weave","config.yaml"),"utf-8")}catch{return e}const t=s.split(`
|
|
2
|
+
`).find(o=>o.startsWith("harnesses:"));if(!t)return e;try{const o=JSON.parse(t.slice(t.indexOf(":")+1).trim()),r=Array.isArray(o)?o.filter(w):[];return r.length>0?r:e}catch{return e}}const S=6e5,a=new Map;export function probeBinVersion(n){return new Promise(e=>{let s="";const t=process.platform==="win32"?c(`${n} --version`,{windowsHide:!0,shell:!0,stdio:["ignore","pipe","pipe"]}):c(n,["--version"],{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),o=setTimeout(()=>{t.kill("SIGKILL"),e(null)},5e3);t.stdout?.on("data",r=>s+=r.toString()),t.on("error",()=>{clearTimeout(o),e(null)}),t.on("close",()=>{clearTimeout(o);const r=/(\d+\.\d+\.\d+)/.exec(s);e(r?r[1]:null)})})}function y(n){const e=a.get(n);if(e&&Date.now()-e.at<S)return e.value;const s=probeBinVersion(n).then(t=>(t===null&&a.delete(n),t));return a.set(n,{at:Date.now(),value:s}),s}export async function projectHarnesses(n,e,s=y){const t=await projectHarnessIds(n);return Promise.all(t.map(async o=>{const r=e?.get(o)?.resume;if(!r?.bin)return{id:o,canStartSession:!1};if(!r.minVersion)return{id:o,canStartSession:!0};const i=await s(r.bin),l=r.minVersion.split(".").map(p=>Number.parseInt(p,10)),u=i===null||h(i,l);return{id:o,canStartSession:u,version:i,minVersion:r.minVersion}}))}export async function withProjectHarnesses(n,e,s){return Promise.all(n.map(async t=>({...t,harnesses:await projectHarnesses(t.path,e,s)})))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export class ProjectUpdatesRefresher{snapshot;bus;shouldRun;lastCounts=null;lastFingerprint=null;running=!1;constructor(
|
|
1
|
+
export class ProjectUpdatesRefresher{snapshot;bus;shouldRun;lastCounts=null;lastFingerprint=null;running=!1;constructor(i,s,t,n=()=>!0){this.snapshot=i,this.bus=s,this.shouldRun=n,t.subscribe(r=>{r.kind==="plugin.reloaded"&&this.refreshNow()})}async refreshNow(i=!1){if(!this.running&&!(!i&&!this.shouldRun())){this.running=!0;try{const s=await this.snapshot();this.lastCounts=s;const t=JSON.stringify(s);if(t===this.lastFingerprint)return;this.lastFingerprint=t,this.bus.emit({key:"updates",payload:{counts:s}})}catch{}finally{this.running=!1}}}onSubscriberJoin(){this.lastCounts!==null&&(this.lastFingerprint=JSON.stringify(this.lastCounts),this.bus.emit({key:"updates",payload:{counts:this.lastCounts}})),this.refreshNow(!0)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{imagesSurfaceFor as
|
|
1
|
+
import{imagesSurfaceFor as N}from"../surfaces.js";const d=/\[Image #\d+\]/gi,b=64,I=64*1024*1024,P=12e4,E=t=>t.replace(d,"").replace(/\s+/g," ").trim(),w={"image/png":".png","image/jpeg":".jpg","image/gif":".gif","image/webp":".webp"};function _(t,e,n){const r=t.hookEvents?.listBySession(e,2e3,void 0,["UserPromptSubmit"])??[],o=[];for(const i of r){if(n.get(i.id)?.length)continue;const c=S(i.payload);!c||!c.match(d)||o.push({eventId:i.id,at:i.createdAt,text:E(c)})}return o}function S(t){try{const e=JSON.parse(t).raw;return typeof e?.prompt=="string"&&e.prompt?e.prompt:null}catch{return null}}function O(t,e,n){for(let r=n.length-1;r>=0;r--)try{const o=JSON.parse(n[r].payload).transcriptPath;if(typeof o=="string"&&o)return o}catch{}return t.sessionProbe?.transcriptPathOf(e)??null}export async function importPromptImages(t,e,n){const r=n?N(n):null;if(!r||!t.hookEvents||!t.uploads)return 0;const o=t.uploads.imagesBySession(e),i=_(t,e,o);if(i.length===0)return 0;const c=t.hookEvents.listBySession(e),u=await r.sessionImages({sessionId:e,transcriptPath:O(t,e,c)});if(!u?.length)return 0;let s=0,a=0;for(const l of u){if(s>=b||a>=I)break;const m=x(i,l.text,l.at);if(!m)continue;const p=[];for(const f of l.images){if(s>=b||a>=I)break;const g=w[f.mediaType];if(!g)continue;const h=Buffer.from(f.bytes),y=t.uploads.save({name:`pasted-${s+1}${g}`,mediaType:f.mediaType,bytes:h,dir:t.uploadDir??null});p.includes(y.id)||p.push(y.id),s+=1,a+=h.length}p.length>0&&t.uploads.linkToEvent(m.eventId,p)}return s}function x(t,e,n){const r=E(e),o=r===""?[]:t.filter(a=>a.text===r),i=o.length>0?o:r===""?t.filter(a=>a.text===""):[];if(i.length===0)return null;const c=n?Date.parse(n):NaN;let u=null,s=Number.POSITIVE_INFINITY;for(const a of i){const l=Number.isNaN(c)||!a.at?Number.POSITIVE_INFINITY:Math.abs(Date.parse(a.at)-c);l<s&&(u=a,s=l)}return!u||o.length===0&&!(s<=P)?null:(t.splice(t.indexOf(u),1),u)}export function needsImageImport(t,e){return t.some(n=>{if(n.eventType!=="UserPromptSubmit"||e?.get(n.id)?.length)return!1;const r=S(n.payload);return!!r&&/\[Image #\d+\]/i.test(r)})}const T=new Set;export async function importPromptImagesOnce(t,e,n){if(T.has(e))return!1;T.add(e);try{return await importPromptImages(t,e,n)>0}catch{return!1}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as
|
|
1
|
+
import{z as u}from"zod";import{HandlerConfigSchema as I,HookDispatchStatusSchema as p,HookRuleFilterSchema as R,HookRuleSourceSchema as j}from"@weavecode/core";import{readJson as h,sendJson as r}from"../http.js";import{installPlugin as v,uninstallPlugin as w}from"../../hooks/plugin-installer.js";import{effective as E,setProjectEnabled as S}from"../../hooks/plugin-project-state.js";const y=u.object({name:u.string().min(1),enabled:u.boolean().optional(),priority:u.number().int().optional(),projectId:u.number().int().nullable(),source:j,filter:R.optional(),handler:I,timeoutMs:u.number().int().positive().optional(),record:u.boolean().optional()}),T=y.partial(),H=u.object({enabled:u.boolean()}),B=u.object({enabled:u.boolean(),projectId:u.number().int().optional()}),O=u.object({sessionId:u.string().min(1)}),U=u.object({src:u.string().min(1)});export async function handleHookAdminRoutes(i,o,e,l,d){if(l==="/hooks/rules"){if(!e.hookRegistry)return r(o,503,{error:"Hooks subsystem unavailable"}),!0;if(i.method==="GET"){const t=d.searchParams.get("projectId"),n=t!=null&&t!==""?Number(t):void 0;return r(o,200,{rules:e.hookRegistry.list(n)}),!0}if(i.method==="POST"){try{const t=y.parse(await h(i)),n=e.hookRegistry.create(t);r(o,201,{rule:n})}catch(t){r(o,400,{error:t instanceof Error?t.message:"Invalid rule body"})}return!0}}const g=l.match(/^\/hooks\/rules\/([^/]+)$/);if(g){if(!e.hookRegistry)return r(o,503,{error:"Hooks subsystem unavailable"}),!0;const t=decodeURIComponent(g[1]);if(i.method==="PUT"){try{const n=T.parse(await h(i)),s=e.hookRegistry.update(t,n);if(!s)return r(o,404,{error:"Rule not found"}),!0;r(o,200,{rule:s})}catch(n){r(o,400,{error:n instanceof Error?n.message:"Invalid rule body"})}return!0}if(i.method==="DELETE")return e.hookRegistry.remove(t)?(r(o,200,{ok:!0}),!0):(r(o,404,{error:"Rule not found"}),!0)}const m=l.match(/^\/hooks\/rules\/([^/]+)\/toggle$/);if(m&&i.method==="POST"){if(!e.hookRegistry)return r(o,503,{error:"Hooks subsystem unavailable"}),!0;try{const t=H.parse(await h(i)),n=e.hookRegistry.setEnabled(decodeURIComponent(m[1]),t.enabled);if(!n)return r(o,404,{error:"Rule not found"}),!0;r(o,200,{rule:n})}catch(t){r(o,400,{error:t instanceof Error?t.message:"Invalid body"})}return!0}if(l==="/hooks/plugins"){if(i.method==="GET"){const t=d.searchParams.get("projectId");if(t==null||t==="")return r(o,200,{plugins:e.hookPlugins?.list()??[]}),!0;const n=e.projects.getById(Number(t));if(!n)return r(o,404,{error:"Project not found"}),!0;if(!e.pluginStates)return r(o,503,{error:"Plugin states unavailable"}),!0;const s=e.pluginStates;return r(o,200,{plugins:(e.hookPlugins?.list()??[]).map(a=>{if(a.status==="rejected")return a;const c=E(n,a.id,{states:s})?"active":"disabled";return c===a.status?a:{...a,status:c}})}),!0}if(i.method==="POST"){if(!e.hookPlugins)return r(o,503,{error:"Plugin loader unavailable"}),!0;try{const t=U.parse(await h(i)),n=await v(t.src);await e.hookPlugins.reloadAll(),r(o,201,n)}catch(t){r(o,400,{error:t instanceof Error?t.message:"Install failed"})}return!0}}const f=l.match(/^\/hooks\/plugins\/([^/]+)\/uninstall$/);if(f&&i.method==="POST"){if(!e.hookPlugins)return r(o,503,{error:"Plugin loader unavailable"}),!0;const t=decodeURIComponent(f[1]);return await w(t)?(await e.hookPlugins.reloadAll(),r(o,200,{ok:!0}),!0):(r(o,404,{error:"Plugin directory not found"}),!0)}if(l==="/hooks/plugins/rescan"&&i.method==="POST"){if(!e.hookPlugins)return r(o,503,{error:"Plugin loader unavailable"}),!0;try{await e.hookPlugins.rescan(),r(o,200,{ok:!0,plugins:e.hookPlugins.list().length})}catch(t){r(o,500,{error:t instanceof Error?t.message:"Rescan failed"})}return!0}const b=l.match(/^\/hooks\/plugins\/([^/]+)\/toggle$/);if(b&&i.method==="POST"){if(!e.hookPlugins)return r(o,503,{error:"Plugin loader unavailable"}),!0;try{const t=B.parse(await h(i)),n=decodeURIComponent(b[1]);if(t.projectId!==void 0){const a=e.projects.getById(t.projectId);return a?e.hookPlugins.list().some(c=>c.id===n)?(S(a,n,t.enabled,{projects:e.projects}),r(o,200,{ok:!0}),!0):(r(o,404,{error:"Plugin not found"}),!0):(r(o,404,{error:"Project not found"}),!0)}if(!e.hookPlugins.setPluginEnabled(n,t.enabled))return r(o,404,{error:"Plugin not found"}),!0;r(o,200,{ok:!0})}catch(t){r(o,400,{error:t instanceof Error?t.message:"Invalid body"})}return!0}if(l==="/hooks/dispatches"&&i.method==="GET"){if(!e.hookDispatches)return r(o,503,{error:"Hooks subsystem unavailable"}),!0;const t=d.searchParams.get("ruleId")??void 0,n=d.searchParams.get("status"),s=n?p.parse(n):void 0,a=d.searchParams.get("sessionId")??void 0,c=d.searchParams.get("limit"),P=c?Number(c):void 0;return r(o,200,{dispatches:e.hookDispatches.list({ruleId:t,status:s,sessionId:a,limit:Number.isFinite(P)?P:void 0})}),!0}const k=l.match(/^\/hooks\/dispatches\/(\d+)\/run$/);if(k&&i.method==="POST"){if(!e.hookRunner)return r(o,503,{error:"Resume runner unavailable"}),!0;let t;try{t=O.parse(await h(i)).sessionId}catch(s){return r(o,400,{error:s instanceof Error?s.message:"Invalid body"}),!0}const n=await e.hookRunner.run(Number(k[1]),t);return n.ok?r(o,200,{ok:!0,dispatchId:n.dispatchId}):r(o,n.status,{error:n.error}),!0}return!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{homedir as v}from"node:os";import Q from"node:path";import{checkHarness as X,isHarness as A}from"@weavecode/core";import{readBody as h,sendJson as r}from"../http.js";import{FingerprintCache as z}from"../../install/fingerprint.js";import{installSkill as Y,uninstallSkill as Z,installFileAsset as ee,uninstallFileAsset as te,InstallConflictError as x,AssetNotFoundError as E}from"../../install/installer.js";import{isFileAssetCategory as H}from"../../install/file-assets.js";import{installGlobalSkill as re,uninstallGlobalSkill as ae,readGlobalSkillGroups as ie,resolveGlobalSkillDir as q,listGlobalSkillFiles as se,readGlobalSkillFile as ne,ClaudeJsonCorruptError as oe}from"../../install/global-config.js";import{CodexTomlCorruptError as le}from"../../install/codex-toml.js";import{forgetInstalled as ce,recordInstalled as me}from"../../install/install-ledger.js";import{readProjectFile as ue,readGlobalFile as de,PathEscapeError as pe,FileTooLargeError as fe}from"../../install/reader.js";import{readMcpRows as he}from"../../install/mcp-rows.js";import{setMcpEnableOverride as ge}from"../../install/settings-mcp.js";import{applyUpdate as ye,syncAll as be}from"../../install/apply-update.js";import{buildLibraryIndex as ke}from"../../install/library-index.js";import{detectUpdates as we}from"../../install/updates.js";import{detectPluginTemplateUpdates as Se}from"../../install/plugin-templates.js";import{detectInitFileUpdates as ve,needsInit as Ie}from"../../install/init-files.js";import{getLibraryScan as K,invalidateScan as y}from"../../install/scan-cache.js";import{installCapabilities as Pe}from"../../install/capabilities.js";import{BUILTIN_MCP_SERVERS as je}from"../../install/builtin-mcp.js";import{readPluginRows as Ee}from"../../install/plugin-rows.js";import{installPluginPack as Ne}from"../../install/plugin-install.js";import{importFromDir as Oe,importFromGit as Te,importLibraryIntoMarket as $e}from"../../market/import.js";import{marketDir as N,readManifest as Be}from"../../market/manifest.js";import{marketIdOf as Me}from"../../market/identity.js";import{isInsideDir as O,toRelPosix as Ce}from"../../market/resolve.js";import{checkMarketUpdates as Je}from"../../market/updates.js";import{refreshMarketItems as Re}from"../../market/refresh.js";import{ensureBuiltinMarket as Ge,isBuiltinMarketDir as S}from"../../market/builtin.js";import{removeInstalled as Le}from"../../market/install-link.js";import{syncPlugins as Fe}from"../../hooks/plugin-project-state.js";import{assetSurfaces as De,pluginStateSurfaces as Ue,pluginSurfaces as W,pluginSurfaceFor as _}from"../../surfaces.js";function V(s){return s.scope==="user"||s.category==="plugin"?!1:s.category==="mcp"?!!I(s.agent)?.mcpScopes().includes("project"):!0}function I(s){const t=s??"claude";return De().find(i=>i.harness===t)}function P(s,t){t instanceof x?s.statusCode=409:t instanceof E?s.statusCode=404:t instanceof oe||t instanceof le?s.statusCode=500:s.statusCode=400,s.setHeader("content-type","application/json"),s.end(JSON.stringify({error:t instanceof Error?t.message:"Install failed"}))}function T(s,t){t instanceof pe?s.statusCode=403:t instanceof fe?s.statusCode=413:t instanceof E?s.statusCode=404:s.statusCode=400,s.setHeader("content-type","application/json"),s.end(JSON.stringify({error:t instanceof Error?t.message:"Read failed"}))}async function j(s,t){const i=O(s.path,N(t)),m=i?await Be(s.path):null,p=S(s.path,t);return{id:s.id,kind:s.kind,addedAt:s.addedAt,path:s.path,relPath:O(s.path,t)?Ce(s.path,t):null,resourceId:i?Q.basename(s.path):null,managed:i,builtin:p,namespace:i?Me(s.path,N(t)):void 0,legacy:!m&&!p,source:p?"builtin":m?.source??"legacy",origin:m?.origin??null,importedAt:m?.importedAt??null,commit:m?.commit??null,tags:await xe(s.path)}}const Ae={command:"command",agent:"agent",workflow:"workflow",rule:"rules","output-style":"output-style"};async function ze(s){const{plugins:t,skills:i,mcp:m,files:p}=await K(s),w={},g=(f,b)=>{b>0&&(w[f]=(w[f]??0)+b)};g("skill",i.length),g("mcp",m.length);for(const[f,b]of Object.entries(p))g(Ae[f]??f,b.length);return g("plugin",t.length),g("mods",t.filter(f=>f.kind==="mod"||f.components.includes("mod")).length),w}async function xe(s){try{return await ze(s)}catch{return{}}}export async function handleMarketRoutes(s,t,i,m,p){if(m==="/capabilities"&&s.method==="GET")return r(t,200,Pe()),!0;if(m==="/libraries"&&s.method==="GET")return r(t,200,{libraries:i.libraries?i.libraries.list():[]}),!0;if(m==="/libraries"&&s.method==="POST"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;let a;try{a=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!a.path||!a.kind)return r(t,400,{error:'Missing "path" or "kind"'}),!0;if(!["skill","mcp","both"].includes(a.kind))return r(t,400,{error:'Invalid "kind" (skill|mcp|both)'}),!0;const e=i.libraries.add({path:a.path,kind:a.kind});return i.dataBus?.emit({key:"libraries"}),r(t,201,e),!0}const w=m.match(/^\/libraries\/(\d+)\/assets$/);if(w&&s.method==="GET"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(w[1]));if(!a)return r(t,404,{error:"Library not found"}),!0;const{plugins:e,skills:n,mcp:o,files:l}=await K(a.path),c=a.kind==="skill"||a.kind==="both"?e:[],u=a.kind==="mcp"||a.kind==="both"?o:[],d=a.kind==="skill"||a.kind==="both"?Object.values(l).flat():null;return r(t,200,{library:a,skills:n,mcp:u,files:d,plugins:c}),!0}const g=m.match(/^\/libraries\/(\d+)$/);if(g&&s.method==="DELETE"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;const a=Number(g[1]),e=i.libraries.getById(a);return e&&await y(e.path),i.libraries.remove(a),i.dataBus?.emit({key:"libraries"}),i.dataBus?.emit({key:"market"}),r(t,200,{ok:!0}),!0}if(m==="/market"&&s.method==="GET"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;const a=await Promise.all(i.libraries.list().map(e=>j(e,i.libraries.dataRoot)));return r(t,200,{items:a}),!0}if(m==="/market"&&s.method==="POST"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;let a;try{a=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const e={libraries:i.libraries,dataRoot:i.libraries.dataRoot};try{if(a.kind==="dir"&&a.path){const n=await Oe(a.path,e);n.refreshed&&i.fingerprintCache?.invalidate(n.dir),await y(n.dir),i.dataBus?.emit({key:"market"}),r(t,201,{item:await j(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}else if(a.kind==="git"&&a.url){const n=await Te(a.url,e);n.refreshed&&i.fingerprintCache?.invalidate(n.dir),await y(n.dir),i.dataBus?.emit({key:"market"}),r(t,201,{item:await j(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}else r(t,400,{error:'Invalid body (kind: "dir" + path | "git" + url)'})}catch(n){r(t,400,{error:n instanceof Error?n.message:"Import failed"})}return!0}if(m==="/market/check-updates"&&s.method==="POST"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;let a={};const e=(await h(s)).trim();if(e)try{a=JSON.parse(e)}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const n=i.libraries.list().filter(l=>!S(l.path,i.libraries.dataRoot)).filter(l=>!a.ids?.length||a.ids.includes(l.id));for(const l of n)await y(l.path);const o=await Je(n.map(l=>({id:l.id,dir:l.path})));return i.dataBus?.emit({key:"market"}),r(t,200,{results:o}),!0}if(m==="/market/refresh"&&s.method==="POST"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;let a={};const e=(await h(s)).trim();if(e)try{a=JSON.parse(e)}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const n=i.libraries.list().filter(d=>!a.ids?.length||a.ids.includes(d.id)),o=[];for(const d of n.filter(k=>S(k.path,i.libraries.dataRoot))){const k=await Ge({libraries:i.libraries});o.push({id:d.id,status:k.error?"failed":"refreshed"})}const l=n.filter(d=>!S(d.path,i.libraries.dataRoot)).map(d=>({id:d.id,dir:d.path})),c=[...await Re(l,{libraries:i.libraries,dataRoot:i.libraries.dataRoot}),...o],u=new Map(l.map(d=>[d.id,d.dir]));for(const d of c)if(d.status==="refreshed"){const k=u.get(d.id);k&&(i.fingerprintCache?.invalidate(k),await y(k))}return i.dataBus?.emit({key:"market"}),r(t,200,{results:c}),!0}const f=m.match(/^\/market\/(\d+)$/);if(f&&s.method==="DELETE"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(f[1]));if(!a)return r(t,404,{error:"Library not found"}),!0;if(S(a.path,i.libraries.dataRoot))return r(t,409,{error:"Built-in market is owned by weave and cannot be deleted",note:"It is re-materialized from @weavecode/templates on every daemon start."}),!0;if(!O(a.path,N(i.libraries.dataRoot)))return r(t,400,{error:"Not a market resource (legacy row \u2014 use DELETE /libraries/:id)"}),!0;let e;try{await(i.pluginSurface??_("claude")).removeMarketplace(a.path)}catch(n){e=`Host marketplace deregistration failed: ${n instanceof Error?n.message:String(n)}`}return await Le(a.path),i.libraries.remove(a.id),await y(a.path),i.dataBus?.emit({key:"market"}),i.dataBus?.emit({key:"libraries"}),r(t,200,{ok:!0,removed:a.path,installedCopiesKept:!0,...e?{warning:e}:{},note:"The host cascade-uninstalls plugins installed from this market; other installed copies are kept."}),!0}const b=m.match(/^\/libraries\/(\d+)\/market-import$/);if(b&&s.method==="POST"){if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(b[1]));if(!a)return r(t,404,{error:"Library not found"}),!0;try{const e=a.path,n=await $e(a,{libraries:i.libraries,dataRoot:i.libraries.dataRoot});await y(e),await y(n.dir),r(t,200,{item:await j(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}catch(e){r(t,400,{error:e instanceof Error?e.message:"Import failed"})}return!0}const $=m.match(/^\/projects\/(\d+)\/install$/);if($&&s.method==="POST"){const a=i.projects.getById(Number($[1]));let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!a&&V(e))return r(t,404,{error:"Project not found"}),!0;const n=a?.path??"";try{if(e.category==="skill"){if(!e.name||!e.sourceDir)return r(t,400,{error:'Missing "name" or "sourceDir"'}),!0;const o=e.agent??"claude",l=e.scope==="user"?await re(e.sourceDir,e.name,o):await Y(n,e.sourceDir,e.name,o);r(t,201,{category:"skill",name:e.name,scope:e.scope??"project",agent:o,path:l})}else if(e.category&&H(e.category)){if(!e.name||!e.sourceFile)return r(t,400,{error:'Missing "name" or "sourceFile"'}),!0;const o=e.agent??"claude",l=e.scope??"project",c=await ee(n,e.category,e.name,e.sourceFile,o,l);r(t,201,{category:e.category,name:e.name,scope:l,agent:o,path:c})}else if(e.category==="mcp"){if(!e.name||!e.mcpConfig)return r(t,400,{error:'Missing "name" or "mcpConfig"'}),!0;const o=e.agent??"claude",l=I(o);if(!l)return r(t,400,{error:`Unsupported agent: ${o}`}),!0;const c=l.mcpScopes(),u=e.scope??c[0];if(!u||!c.includes(u))return r(t,400,{error:`MCP servers for ${o} are ${c.join("/")}-level only \u2014 scope "${e.scope}" is not available`}),!0;if(e.name in await l.mcpRead(u,n,v()))return P(t,new x(`MCP server "${e.name}" is already configured`)),!0;await l.mcpWrite(u,n,v(),e.name,e.mcpConfig),u==="project"&&await me(n,{category:"mcp",name:e.name,agent:o}),r(t,201,{category:"mcp",name:e.name,scope:u,agent:o})}else if(e.category==="plugin"){if(!e.name||!e.sourceDir)return r(t,400,{error:'Missing "name" or "sourceDir"'}),!0;if(e.scope&&e.scope!=="user")return r(t,400,{error:'Plugin install currently only supports scope "user"'}),!0;const o=e.agent??"claude",l=W().find(d=>d.harness===o);if(!l)return r(t,400,{error:`No plugin install surface for runtime: ${o}`}),!0;const c=o==="claude"&&i.pluginSurface?i.pluginSurface:l.surface,u=await Ne(c,{dir:e.sourceDir,name:e.name,version:e.version,description:e.description});i.dataBus?.emit({key:"toolkit"}),r(t,201,{category:"plugin",key:u.key,scope:"user",agent:o,alreadyInstalled:u.alreadyInstalled})}else r(t,400,{error:'Invalid "category" (skill|mcp|plugin|command|agent|workflow|rule|output-style)'})}catch(o){P(t,o)}return!0}const B=m.match(/^\/projects\/(\d+)\/mcp\/builtin$/);if(B&&s.method==="POST"){const a=i.projects.getById(Number(B[1]));let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const n=je.find(d=>d.name===e.name);if(!n)return r(t,404,{error:`Unknown built-in MCP server: ${e.name??""}`}),!0;if(!a)return r(t,404,{error:"Project not found"}),!0;const o=e.agent??"claude",l=I(o);if(!l||!l.mcpScopes().includes("user"))return r(t,400,{error:`MCP servers for ${o} have no user scope`}),!0;const c=i.auth?.getLocalToken()??"",u={type:"http",url:`http://127.0.0.1:${i.port}${n.path}`,...c?{headers:{"x-weave-local":c}}:{}};try{await l.mcpWrite("user",a.path,v(),n.name,u),r(t,201,{category:"mcp",name:n.name,scope:"user",agent:o})}catch(d){r(t,400,{error:d instanceof Error?d.message:"Install failed"})}return!0}const M=m.match(/^\/projects\/(\d+)\/uninstall$/);if(M&&s.method==="POST"){const a=i.projects.getById(Number(M[1]));let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!a&&V(e))return r(t,404,{error:"Project not found"}),!0;const n=a?.path??"";try{if(e.category==="skill"){if(!e.name)return r(t,400,{error:'Missing "name"'}),!0;const o=e.agent??"claude";e.scope==="user"?await ae(e.name,o):await Z(n,e.name,o)}else if(e.category&&H(e.category)){if(!e.name)return r(t,400,{error:'Missing "name"'}),!0;await te(n,e.category,e.name,e.agent??"claude",e.scope??"project")}else if(e.category==="mcp"){if(!e.name)return r(t,400,{error:'Missing "name"'}),!0;const o=e.agent??"claude",l=I(o);if(!l)return r(t,400,{error:`Unsupported agent: ${o}`}),!0;const c=l.mcpScopes(),u=e.scope??c[0];if(!u||!c.includes(u))return r(t,400,{error:`MCP servers for ${o} are ${c.join("/")}-level only \u2014 scope "${e.scope}" is not available`}),!0;if(!await l.mcpRemove(u,n,v(),e.name))return P(t,new E(`MCP server "${e.name}" is not configured`)),!0;u==="project"&&await ce(n,{category:"mcp",name:e.name,agent:o})}else return r(t,400,{error:'Invalid "category" (skill|mcp|command|agent|workflow|rule|output-style)'}),!0;r(t,200,{ok:!0})}catch(o){P(t,o)}return!0}const C=m.match(/^\/projects\/(\d+)\/file$/);if(C&&s.method==="GET"){const a=i.projects.getById(Number(C[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;const e=p.searchParams.get("path");if(!e)return r(t,400,{error:'Missing "path" query parameter'}),!0;try{const n=await ue(a.path,e);r(t,200,{path:e,content:n.content,size:n.size})}catch(n){T(t,n)}return!0}if(m==="/global-file"&&s.method==="GET"){const a=p.searchParams.get("path");if(!a)return r(t,400,{error:'Missing "path" query parameter'}),!0;try{const e=await de(a);r(t,200,{path:a,content:e.content,size:e.size})}catch(e){T(t,e)}return!0}const J=m.match(/^\/projects\/(\d+)\/mcp$/);if(J&&s.method==="GET"){const a=i.projects.getById(Number(J[1]));return a?(r(t,200,{rows:await he(a.path)}),!0):(r(t,404,{error:"Project not found"}),!0)}const R=m.match(/^\/projects\/(\d+)\/harness-checks$/);if(R&&s.method==="GET"){const a=i.projects.getById(Number(R[1]));return a?(r(t,200,{checks:await X(a.path)}),!0):(r(t,404,{error:"Project not found"}),!0)}if(m.match(/^\/projects\/(\d+)\/skills\/global$/)&&s.method==="GET")return r(t,200,{groups:await ie()}),!0;if(m.match(/^\/projects\/(\d+)\/skills\/global\/files$/)&&s.method==="GET"){const a=p.searchParams.get("source"),e=p.searchParams.get("name"),n=p.searchParams.get("pluginKey")??void 0;if(!a||!e)return r(t,400,{error:'Missing "source" or "name" query parameter'}),!0;const o=await q(a,e,n);return o?(r(t,200,{files:await se(o)}),!0):(r(t,404,{error:"Skill not found"}),!0)}if(m.match(/^\/projects\/(\d+)\/skills\/global\/file$/)&&s.method==="GET"){const a=p.searchParams.get("source"),e=p.searchParams.get("name"),n=p.searchParams.get("pluginKey")??void 0,o=p.searchParams.get("path");if(!a||!e||!o)return r(t,400,{error:'Missing "source", "name" or "path" query parameter'}),!0;const l=await q(a,e,n);if(!l)return r(t,404,{error:"Skill not found"}),!0;try{const c=await ne(l,o);r(t,200,{path:o,content:c.content,size:c.size})}catch(c){T(t,c)}return!0}const G=m.match(/^\/projects\/(\d+)\/plugins\/state$/);if(G){const a=i.projects.getById(Number(G[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;if(s.method==="GET")return r(t,200,{rows:await Ee(a.path)}),!0;if(s.method==="PUT"){let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!A(e.runtime)||!e.key||!e.scope||!["user","project","local"].includes(e.scope)||!e.state||!["on","off","inherit"].includes(e.state))return r(t,400,{error:'Missing or invalid "runtime"/"key"/"scope" (user|project|local)/"state" (on|off|inherit)'}),!0;const n=e.scope,o=e.state;try{const l=W().find(c=>c.harness===e.runtime);if(l)await(e.runtime==="claude"&&i.pluginSurface?i.pluginSurface:l.surface).setEnabledOverride(a.path,n,e.key,o);else{const c=Ue().find(u=>u.harness===e.runtime);if(!c||n!=="user"||o==="inherit")return r(t,400,{error:"This runtime only supports user-scope on/off overrides"}),!0;await c.state.writeGlobalEnabled(e.key,o==="on")}i.dataBus?.emit({key:"toolkit"}),r(t,200,{ok:!0})}catch(l){r(t,400,{error:l instanceof Error?l.message:"Plugin state write failed"})}return!0}}if(m.match(/^\/projects\/(\d+)\/plugins\/uninstall$/)&&s.method==="POST"){let a;try{a=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!A(a.runtime)||!a.key)return r(t,400,{error:'Missing or invalid "runtime"/"key"'}),!0;try{const e=a.runtime==="claude"&&i.pluginSurface?i.pluginSurface:_(a.runtime),{name:n,market:o}=e.parsePluginKey(a.key);await e.uninstall(n,o),r(t,200,{ok:!0})}catch(e){r(t,400,{error:e instanceof Error?e.message:"Plugin uninstall failed"})}return!0}const L=m.match(/^\/projects\/(\d+)\/mcp\/enable$/);if(L){const a=i.projects.getById(Number(L[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;if(s.method==="PUT"){let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}return!e.name||!e.state?(r(t,400,{error:'Missing "name" or "state"'}),!0):["on","off","inherit"].includes(e.state)?(await ge(a.path,e.name,e.state),r(t,200,{ok:!0}),!0):(r(t,400,{error:'Invalid "state" (on|off|inherit)'}),!0)}}const F=m.match(/^\/projects\/(\d+)\/updates$/);if(F&&s.method==="GET"){const a=i.projects.getById(Number(F[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;const e=i.fingerprintCache??new z;if(!i.libraries){const o=await Se(a.path,e),l=await ve(a.path);return r(t,200,{skills:[],mcp:[],files:[],pluginTemplates:o,initFiles:l,available:o.filter(c=>c.outdated).length+l.filter(c=>c.outdated&&c.syncClass==="auto").length,needsInit:Ie(l)}),!0}const n=await we(a.path,i.libraries.list(),e);return r(t,200,n),!0}const D=m.match(/^\/projects\/(\d+)\/update$/);if(D&&s.method==="POST"){const a=i.projects.getById(Number(D[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;let e;try{e=JSON.parse(await h(s))}catch{return r(t,400,{error:"Invalid JSON body"}),!0}if(!e.category||!e.name||!e.scope)return r(t,400,{error:'Missing "category", "name", or "scope"'}),!0;if(!["skill","mcp","command","agent","workflow","rule","output-style"].includes(e.category))return r(t,400,{error:'Invalid "category"'}),!0;try{const n=await ke(i.libraries.list());await ye(a.path,{category:e.category,name:e.name,scope:e.scope,agent:e.agent},n),r(t,200,{ok:!0,category:e.category,name:e.name,scope:e.scope})}catch(n){r(t,400,{error:n instanceof Error?n.message:"Update failed"})}return!0}const U=m.match(/^\/projects\/(\d+)\/sync-all$/);if(U&&s.method==="POST"){const a=i.projects.getById(Number(U[1]));if(!a)return r(t,404,{error:"Project not found"}),!0;if(!i.libraries)return r(t,503,{error:"Libraries unavailable"}),!0;try{const e=i.fingerprintCache??new z,n=await be(a.path,i.libraries.list(),e);let o=n;try{const l=i.hookPlugins?.list().map(u=>u.id)??[],c=Fe(a,l,{projects:i.projects});o={...n,pluginSync:{syncedAt:c}}}catch{}r(t,200,o),i.updatesRefresher?.refreshNow(!0)}catch(e){r(t,400,{error:e instanceof Error?e.message:"Sync failed"})}return!0}return!1}
|
|
1
|
+
import{homedir as j}from"node:os";import X from"node:path";import{checkHarness as Y,isHarness as A}from"@weavecode/core";import{readBody as g,sendJson as e}from"../http.js";import{FingerprintCache as z}from"../../install/fingerprint.js";import{installSkill as Z,uninstallSkill as q,installFileAsset as tt,uninstallFileAsset as rt,InstallConflictError as x,AssetNotFoundError as M}from"../../install/installer.js";import{isFileAssetCategory as K}from"../../install/file-assets.js";import{installGlobalSkill as et,uninstallGlobalSkill as at,readGlobalSkillGroups as it,resolveGlobalSkillDir as H,listGlobalSkillFiles as ot,readGlobalSkillFile as nt,ClaudeJsonCorruptError as ct}from"../../install/global-config.js";import{CodexTomlCorruptError as lt}from"../../install/codex-toml.js";import{forgetInstalled as st,recordInstalled as ut}from"../../install/install-ledger.js";import{readProjectFile as mt,readGlobalFile as ft,PathEscapeError as dt,FileTooLargeError as pt}from"../../install/reader.js";import{readMcpRows as gt}from"../../install/mcp-rows.js";import{setMcpEnableOverride as ht}from"../../install/settings-mcp.js";import{applyUpdate as bt,syncAll as yt}from"../../install/apply-update.js";import{buildLibraryIndex as kt}from"../../install/library-index.js";import{detectUpdates as wt}from"../../install/updates.js";import{detectPluginTemplateUpdates as St}from"../../install/plugin-templates.js";import{detectInitFileUpdates as jt,needsInit as vt}from"../../install/init-files.js";import{getLibraryScan as _,invalidateScan as b}from"../../install/scan-cache.js";import{installCapabilities as It}from"../../install/capabilities.js";import{BUILTIN_MCP_SERVERS as Pt}from"../../install/builtin-mcp.js";import{readPluginRows as Mt}from"../../install/plugin-rows.js";import{installPluginPack as Et}from"../../install/plugin-install.js";import{importFromDir as Nt,importFromGit as Ot,importLibraryIntoMarket as Tt}from"../../market/import.js";import{marketDir as E,readManifest as Ct}from"../../market/manifest.js";import{marketIdOf as $t}from"../../market/identity.js";import{isInsideDir as N,toRelPosix as Bt}from"../../market/resolve.js";import{checkMarketUpdates as Ft}from"../../market/updates.js";import{refreshMarketItems as Jt}from"../../market/refresh.js";import{ensureBuiltinMarket as Gt,isBuiltinMarketDir as S}from"../../market/builtin.js";import{removeInstalled as Lt}from"../../market/install-link.js";import{syncPlugins as Rt}from"../../hooks/plugin-project-state.js";import{assetSurfaces as Dt,pluginStateSurfaces as Ut,pluginSurfaces as W,pluginSurfaceFor as V}from"../../surfaces.js";function Q(o){return o.scope==="user"||o.category==="plugin"?!1:o.category==="mcp"?!!v(o.agent)?.mcpScopes().includes("project"):!0}function v(o){const r=o??"claude";return Dt().find(i=>i.harness===r)}function I(o,r){r instanceof x?o.statusCode=409:r instanceof M?o.statusCode=404:r instanceof ct||r instanceof lt?o.statusCode=500:o.statusCode=400,o.setHeader("content-type","application/json"),o.end(JSON.stringify({error:r instanceof Error?r.message:"Install failed"}))}function O(o,r){r instanceof dt?o.statusCode=403:r instanceof pt?o.statusCode=413:r instanceof M?o.statusCode=404:o.statusCode=400,o.setHeader("content-type","application/json"),o.end(JSON.stringify({error:r instanceof Error?r.message:"Read failed"}))}async function P(o,r){const i=N(o.path,E(r)),u=i?await Ct(o.path):null,d=S(o.path,r);return{id:o.id,kind:o.kind,addedAt:o.addedAt,path:o.path,relPath:N(o.path,r)?Bt(o.path,r):null,resourceId:i?X.basename(o.path):null,managed:i,builtin:d,namespace:i?$t(o.path,E(r)):void 0,legacy:!u&&!d,source:d?"builtin":u?.source??"legacy",origin:u?.origin??null,importedAt:u?.importedAt??null,commit:u?.commit??null,tags:await xt(o.path)}}const At={command:"command",agent:"agent",workflow:"workflow",rule:"rules","output-style":"output-style"};async function zt(o){const{plugins:r,skills:i,mcp:u,files:d}=await _(o),w={},h=(p,y)=>{y>0&&(w[p]=(w[p]??0)+y)};h("skill",i.length),h("mcp",u.length);for(const[p,y]of Object.entries(d))h(At[p]??p,y.length);return h("plugin",r.length),h("mods",r.filter(p=>p.kind==="mod"||p.components.includes("mod")).length),w}async function xt(o){try{return await zt(o)}catch{return{}}}export async function handleMarketRoutes(o,r,i,u,d){if(u==="/capabilities"&&o.method==="GET")return e(r,200,It()),!0;if(u==="/libraries"&&o.method==="GET")return e(r,200,{libraries:i.libraries?i.libraries.list():[]}),!0;if(u==="/libraries"&&o.method==="POST"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;let a;try{a=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!a.path||!a.kind)return e(r,400,{error:'Missing "path" or "kind"'}),!0;if(!["skill","mcp","both"].includes(a.kind))return e(r,400,{error:'Invalid "kind" (skill|mcp|both)'}),!0;const t=i.libraries.add({path:a.path,kind:a.kind});return i.dataBus?.emit({key:"libraries"}),e(r,201,t),!0}const w=u.match(/^\/libraries\/(\d+)\/assets$/);if(w&&o.method==="GET"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(w[1]));if(!a)return e(r,404,{error:"Library not found"}),!0;const{plugins:t,skills:n,mcp:c,files:l}=await _(a.path),s=a.kind==="skill"||a.kind==="both"?t:[],m=a.kind==="mcp"||a.kind==="both"?c:[],f=a.kind==="skill"||a.kind==="both"?Object.values(l).flat():null;return e(r,200,{library:a,skills:n,mcp:m,files:f,plugins:s}),!0}const h=u.match(/^\/libraries\/(\d+)$/);if(h&&o.method==="DELETE"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;const a=Number(h[1]),t=i.libraries.getById(a);return t&&await b(t.path),i.libraries.remove(a),i.dataBus?.emit({key:"libraries"}),i.dataBus?.emit({key:"market"}),e(r,200,{ok:!0}),!0}if(u==="/market"&&o.method==="GET"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;const a=await Promise.all(i.libraries.list().map(t=>P(t,i.libraries.dataRoot)));return e(r,200,{items:a}),!0}if(u==="/market"&&o.method==="POST"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;let a;try{a=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const t={libraries:i.libraries,dataRoot:i.libraries.dataRoot};try{if(a.kind==="dir"&&a.path){const n=await Nt(a.path,t);n.refreshed&&i.fingerprintCache?.invalidate(n.dir),await b(n.dir),i.dataBus?.emit({key:"market"}),e(r,201,{item:await P(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}else if(a.kind==="git"&&a.url){const n=await Ot(a.url,t);n.refreshed&&i.fingerprintCache?.invalidate(n.dir),await b(n.dir),i.dataBus?.emit({key:"market"}),e(r,201,{item:await P(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}else e(r,400,{error:'Invalid body (kind: "dir" + path | "git" + url)'})}catch(n){e(r,400,{error:n instanceof Error?n.message:"Import failed"})}return!0}if(u==="/market/check-updates"&&o.method==="POST"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;let a={};const t=(await g(o)).trim();if(t)try{a=JSON.parse(t)}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const n=i.libraries.list().filter(l=>!S(l.path,i.libraries.dataRoot)).filter(l=>!a.ids?.length||a.ids.includes(l.id));for(const l of n)await b(l.path);const c=await Ft(n.map(l=>({id:l.id,dir:l.path})));return i.dataBus?.emit({key:"market"}),e(r,200,{results:c}),!0}if(u==="/market/refresh"&&o.method==="POST"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;let a={};const t=(await g(o)).trim();if(t)try{a=JSON.parse(t)}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const n=i.libraries.list().filter(f=>!a.ids?.length||a.ids.includes(f.id)),c=[];for(const f of n.filter(k=>S(k.path,i.libraries.dataRoot))){const k=await Gt({libraries:i.libraries});c.push({id:f.id,status:k.error?"failed":"refreshed"})}const l=n.filter(f=>!S(f.path,i.libraries.dataRoot)).map(f=>({id:f.id,dir:f.path})),s=[...await Jt(l,{libraries:i.libraries,dataRoot:i.libraries.dataRoot}),...c],m=new Map(l.map(f=>[f.id,f.dir]));for(const f of s)if(f.status==="refreshed"){const k=m.get(f.id);k&&(i.fingerprintCache?.invalidate(k),await b(k))}return i.dataBus?.emit({key:"market"}),e(r,200,{results:s}),!0}const p=u.match(/^\/market\/(\d+)$/);if(p&&o.method==="DELETE"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(p[1]));if(!a)return e(r,404,{error:"Library not found"}),!0;if(S(a.path,i.libraries.dataRoot))return e(r,409,{error:"Built-in market is owned by weave and cannot be deleted",note:"It is re-materialized from @weavecode/templates on every daemon start."}),!0;if(!N(a.path,E(i.libraries.dataRoot)))return e(r,400,{error:"Not a market resource (legacy row \u2014 use DELETE /libraries/:id)"}),!0;let t;try{await(i.pluginSurface??V("claude")).removeMarketplace(a.path)}catch(n){t=`Host marketplace deregistration failed: ${n instanceof Error?n.message:String(n)}`}return await Lt(a.path),i.libraries.remove(a.id),await b(a.path),i.dataBus?.emit({key:"market"}),i.dataBus?.emit({key:"libraries"}),e(r,200,{ok:!0,removed:a.path,installedCopiesKept:!0,...t?{warning:t}:{},note:"The host cascade-uninstalls plugins installed from this market; other installed copies are kept."}),!0}const y=u.match(/^\/libraries\/(\d+)\/market-import$/);if(y&&o.method==="POST"){if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;const a=i.libraries.getById(Number(y[1]));if(!a)return e(r,404,{error:"Library not found"}),!0;try{const t=a.path,n=await Tt(a,{libraries:i.libraries,dataRoot:i.libraries.dataRoot});await b(t),await b(n.dir),e(r,200,{item:await P(i.libraries.getById(n.libraryId),i.libraries.dataRoot)})}catch(t){e(r,400,{error:t instanceof Error?t.message:"Import failed"})}return!0}const T=u.match(/^\/projects\/(\d+)\/install$/);if(T&&o.method==="POST"){const a=i.projects.getById(Number(T[1]));let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!a&&Q(t))return e(r,404,{error:"Project not found"}),!0;const n=a?.path??"";try{if(t.category==="skill"){if(!t.name||!t.sourceDir)return e(r,400,{error:'Missing "name" or "sourceDir"'}),!0;const c=t.agent??"claude",l=t.scope==="user"?await et(t.sourceDir,t.name,c):await Z(n,t.sourceDir,t.name,c);e(r,201,{category:"skill",name:t.name,scope:t.scope??"project",agent:c,path:l})}else if(t.category&&K(t.category)){if(!t.name||!t.sourceFile)return e(r,400,{error:'Missing "name" or "sourceFile"'}),!0;const c=t.agent??"claude",l=t.scope??"project",s=await tt(n,t.category,t.name,t.sourceFile,c,l);e(r,201,{category:t.category,name:t.name,scope:l,agent:c,path:s})}else if(t.category==="mcp"){if(!t.name||!t.mcpConfig)return e(r,400,{error:'Missing "name" or "mcpConfig"'}),!0;const c=t.agent??"claude",l=v(c);if(!l)return e(r,400,{error:`Unsupported agent: ${c}`}),!0;const s=l.mcpScopes(),m=t.scope??s[0];if(!m||!s.includes(m))return e(r,400,{error:`MCP servers for ${c} are ${s.join("/")}-level only \u2014 scope "${t.scope}" is not available`}),!0;if(t.name in await l.mcpRead(m,n,j()))return I(r,new x(`MCP server "${t.name}" is already configured`)),!0;await l.mcpWrite(m,n,j(),t.name,t.mcpConfig),m==="project"&&await ut(n,{category:"mcp",name:t.name,agent:c}),e(r,201,{category:"mcp",name:t.name,scope:m,agent:c})}else if(t.category==="plugin"){if(!t.name||!t.sourceDir)return e(r,400,{error:'Missing "name" or "sourceDir"'}),!0;if(t.scope&&t.scope!=="user")return e(r,400,{error:'Plugin install currently only supports scope "user"'}),!0;const c=t.agent??"claude",l=W().find(f=>f.harness===c);if(!l)return e(r,400,{error:`No plugin install surface for runtime: ${c}`}),!0;const s=c==="claude"&&i.pluginSurface?i.pluginSurface:l.surface,m=await Et(s,{dir:t.sourceDir,name:t.name,version:t.version,description:t.description});i.dataBus?.emit({key:"toolkit"}),e(r,201,{category:"plugin",key:m.key,scope:"user",agent:c,alreadyInstalled:m.alreadyInstalled})}else e(r,400,{error:'Invalid "category" (skill|mcp|plugin|command|agent|workflow|rule|output-style)'})}catch(c){I(r,c)}return!0}const C=u.match(/^\/projects\/(\d+)\/mcp\/builtin$/);if(C&&o.method==="POST"){const a=i.projects.getById(Number(C[1]));let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const n=Pt.find(f=>f.name===t.name);if(!n)return e(r,404,{error:`Unknown built-in MCP server: ${t.name??""}`}),!0;if(!a)return e(r,404,{error:"Project not found"}),!0;const c=t.agent??"claude",l=v(c);if(!l||!l.mcpScopes().includes("user"))return e(r,400,{error:`MCP servers for ${c} have no user scope`}),!0;const s=i.auth?.getLocalToken()??"",m={type:"http",url:`http://127.0.0.1:${i.port}${n.path}`,...s?{headers:{"x-weave-local":s}}:{}};try{await l.mcpWrite("user",a.path,j(),n.name,m),e(r,201,{category:"mcp",name:n.name,scope:"user",agent:c})}catch(f){e(r,400,{error:f instanceof Error?f.message:"Install failed"})}return!0}const $=u.match(/^\/projects\/(\d+)\/uninstall$/);if($&&o.method==="POST"){const a=i.projects.getById(Number($[1]));let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!a&&Q(t))return e(r,404,{error:"Project not found"}),!0;const n=a?.path??"";try{if(t.category==="skill"){if(!t.name)return e(r,400,{error:'Missing "name"'}),!0;const c=t.agent??"claude";t.scope==="user"?await at(t.name,c):await q(n,t.name,c)}else if(t.category&&K(t.category)){if(!t.name)return e(r,400,{error:'Missing "name"'}),!0;await rt(n,t.category,t.name,t.agent??"claude",t.scope??"project")}else if(t.category==="mcp"){if(!t.name)return e(r,400,{error:'Missing "name"'}),!0;const c=t.agent??"claude",l=v(c);if(!l)return e(r,400,{error:`Unsupported agent: ${c}`}),!0;const s=l.mcpScopes(),m=t.scope??s[0];if(!m||!s.includes(m))return e(r,400,{error:`MCP servers for ${c} are ${s.join("/")}-level only \u2014 scope "${t.scope}" is not available`}),!0;if(!await l.mcpRemove(m,n,j(),t.name))return I(r,new M(`MCP server "${t.name}" is not configured`)),!0;m==="project"&&await st(n,{category:"mcp",name:t.name,agent:c})}else return e(r,400,{error:'Invalid "category" (skill|mcp|command|agent|workflow|rule|output-style)'}),!0;e(r,200,{ok:!0})}catch(c){I(r,c)}return!0}const B=u.match(/^\/projects\/(\d+)\/asset-file$/);if(B&&o.method==="GET"){const a=i.projects.getById(Number(B[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;const t=d.searchParams.get("path");if(!t)return e(r,400,{error:'Missing "path" query parameter'}),!0;try{const n=await mt(a.path,t);e(r,200,{path:t,content:n.content,size:n.size})}catch(n){O(r,n)}return!0}if(u==="/global-file"&&o.method==="GET"){const a=d.searchParams.get("path");if(!a)return e(r,400,{error:'Missing "path" query parameter'}),!0;try{const t=await ft(a);e(r,200,{path:a,content:t.content,size:t.size})}catch(t){O(r,t)}return!0}const F=u.match(/^\/projects\/(\d+)\/mcp$/);if(F&&o.method==="GET"){const a=i.projects.getById(Number(F[1]));return a?(e(r,200,{rows:await gt(a.path)}),!0):(e(r,404,{error:"Project not found"}),!0)}const J=u.match(/^\/projects\/(\d+)\/harness-checks$/);if(J&&o.method==="GET"){const a=i.projects.getById(Number(J[1]));return a?(e(r,200,{checks:await Y(a.path)}),!0):(e(r,404,{error:"Project not found"}),!0)}if(u.match(/^\/projects\/(\d+)\/skills\/global$/)&&o.method==="GET")return e(r,200,{groups:await it()}),!0;if(u.match(/^\/projects\/(\d+)\/skills\/global\/files$/)&&o.method==="GET"){const a=d.searchParams.get("source"),t=d.searchParams.get("name"),n=d.searchParams.get("pluginKey")??void 0;if(!a||!t)return e(r,400,{error:'Missing "source" or "name" query parameter'}),!0;const c=await H(a,t,n);return c?(e(r,200,{files:await ot(c)}),!0):(e(r,404,{error:"Skill not found"}),!0)}if(u.match(/^\/projects\/(\d+)\/skills\/global\/file$/)&&o.method==="GET"){const a=d.searchParams.get("source"),t=d.searchParams.get("name"),n=d.searchParams.get("pluginKey")??void 0,c=d.searchParams.get("path");if(!a||!t||!c)return e(r,400,{error:'Missing "source", "name" or "path" query parameter'}),!0;const l=await H(a,t,n);if(!l)return e(r,404,{error:"Skill not found"}),!0;try{const s=await nt(l,c);e(r,200,{path:c,content:s.content,size:s.size})}catch(s){O(r,s)}return!0}const G=u.match(/^\/projects\/(\d+)\/plugins\/state$/);if(G){const a=i.projects.getById(Number(G[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;if(o.method==="GET")return e(r,200,{rows:await Mt(a.path)}),!0;if(o.method==="PUT"){let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!A(t.runtime)||!t.key||!t.scope||!["user","project","local"].includes(t.scope)||!t.state||!["on","off","inherit"].includes(t.state))return e(r,400,{error:'Missing or invalid "runtime"/"key"/"scope" (user|project|local)/"state" (on|off|inherit)'}),!0;const n=t.scope,c=t.state;try{const l=W().find(s=>s.harness===t.runtime);if(l)await(t.runtime==="claude"&&i.pluginSurface?i.pluginSurface:l.surface).setEnabledOverride(a.path,n,t.key,c);else{const s=Ut().find(m=>m.harness===t.runtime);if(!s||n!=="user"||c==="inherit")return e(r,400,{error:"This runtime only supports user-scope on/off overrides"}),!0;await s.state.writeGlobalEnabled(t.key,c==="on")}i.dataBus?.emit({key:"toolkit"}),e(r,200,{ok:!0})}catch(l){e(r,400,{error:l instanceof Error?l.message:"Plugin state write failed"})}return!0}}if(u.match(/^\/projects\/(\d+)\/plugins\/uninstall$/)&&o.method==="POST"){let a;try{a=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!A(a.runtime)||!a.key)return e(r,400,{error:'Missing or invalid "runtime"/"key"'}),!0;try{const t=a.runtime==="claude"&&i.pluginSurface?i.pluginSurface:V(a.runtime),{name:n,market:c}=t.parsePluginKey(a.key);await t.uninstall(n,c),e(r,200,{ok:!0})}catch(t){e(r,400,{error:t instanceof Error?t.message:"Plugin uninstall failed"})}return!0}const L=u.match(/^\/projects\/(\d+)\/mcp\/enable$/);if(L){const a=i.projects.getById(Number(L[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;if(o.method==="PUT"){let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}return!t.name||!t.state?(e(r,400,{error:'Missing "name" or "state"'}),!0):["on","off","inherit"].includes(t.state)?(await ht(a.path,t.name,t.state),e(r,200,{ok:!0}),!0):(e(r,400,{error:'Invalid "state" (on|off|inherit)'}),!0)}}const R=u.match(/^\/projects\/(\d+)\/updates$/);if(R&&o.method==="GET"){const a=i.projects.getById(Number(R[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;const t=i.fingerprintCache??new z;if(!i.libraries){const c=await St(a.path,t),l=await jt(a.path);return e(r,200,{skills:[],mcp:[],files:[],pluginTemplates:c,initFiles:l,available:c.filter(s=>s.outdated).length+l.filter(s=>s.outdated&&s.syncClass==="auto").length,needsInit:vt(l)}),!0}const n=await wt(a.path,i.libraries.list(),t);return e(r,200,n),!0}const D=u.match(/^\/projects\/(\d+)\/update$/);if(D&&o.method==="POST"){const a=i.projects.getById(Number(D[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;let t;try{t=JSON.parse(await g(o))}catch{return e(r,400,{error:"Invalid JSON body"}),!0}if(!t.category||!t.name||!t.scope)return e(r,400,{error:'Missing "category", "name", or "scope"'}),!0;if(!["skill","mcp","command","agent","workflow","rule","output-style"].includes(t.category))return e(r,400,{error:'Invalid "category"'}),!0;try{const c=await kt(i.libraries.list());await bt(a.path,{category:t.category,name:t.name,scope:t.scope,agent:t.agent},c),e(r,200,{ok:!0,category:t.category,name:t.name,scope:t.scope})}catch(c){e(r,400,{error:c instanceof Error?c.message:"Update failed"})}return!0}const U=u.match(/^\/projects\/(\d+)\/sync-all$/);if(U&&o.method==="POST"){const a=i.projects.getById(Number(U[1]));if(!a)return e(r,404,{error:"Project not found"}),!0;if(!i.libraries)return e(r,503,{error:"Libraries unavailable"}),!0;try{const t=i.fingerprintCache??new z,n=await yt(a.path,i.libraries.list(),t);let c=n;try{const l=i.hookPlugins?.list().map(m=>m.id)??[],s=Rt(a,l,{projects:i.projects});c={...n,pluginSync:{syncedAt:s}}}catch{}e(r,200,c),i.updatesRefresher?.refreshNow(!0)}catch(t){e(r,400,{error:t instanceof Error?t.message:"Sync failed"})}return!0}return!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as i}from"zod";import{nextRunAt as E,parseCron as
|
|
1
|
+
import{z as i}from"zod";import{nextRunAt as E,parseCron as j}from"../cron.js";import{validateOrchestration as S}from"../../hooks/orchestration-graph.js";import{graphDirections as B,toRunSummary as w}from"../../repositories/orchestrations.js";import{readBody as R,readJson as k,sendJson as o}from"../http.js";const M=i.object({id:i.string().min(1).max(128),kind:i.enum(["session","webhook","trigger"]),webhookToken:i.string().min(1).max(200).optional(),url:i.string().max(2e3).optional(),secret:i.string().max(400).optional(),autoFire:i.boolean().optional()}),T=i.object({name:i.string().min(1).max(200),startText:i.string().max(2e4).optional(),projectId:i.number().int().optional(),nodes:i.array(M).min(1),edges:i.array(i.object({id:i.string().min(1).max(64),from:i.string().min(1),to:i.string().min(1),text:i.string().max(2e4),extract:i.string().max(4e3).optional(),condition:i.string().max(4e3).optional(),when:i.string().max(500).optional()})),cron:i.string().max(200).nullish(),enabled:i.boolean().optional()}),N=T.partial(),O=i.object({text:i.string().min(1).max(2e4).optional(),entries:i.array(i.string().min(1)).optional()}),P=i.object({nodeId:i.string().min(1).max(128)}),$=new Set(["running","done","failed","cancelled","interrupted"]);function m(s,r){const t=s.searchParams.get(r);if(t==null||t==="")return;const c=Number(t);return Number.isFinite(c)?c:void 0}function I(s){const r=s.cron?j(s.cron):null;return{...s,nextRunAt:r?E(r):null}}function v(s,r){const t=r.name.trim();if(!t)return{ok:!1,error:"Name is required"};const c=S(r);if(!c.ok)return{ok:!1,error:c.error};const u=r.cron?.trim()||null;if(u&&!j(u))return{ok:!1,error:`Invalid cron expression: ${u}`};for(const d of r.nodes)if(d.kind==="session"&&!s.hookSessions?.getBySessionId(d.id))return{ok:!1,error:`Unknown session: ${d.id}`};const{entries:g}=B(r.nodes,r.edges),h=g.filter(d=>d.kind==="session");let l=r.projectId??null;if(h.length>0){const d=s.hookSessions.getBySessionId(h[0].id);if(l!=null&&l!==d.projectId)return{ok:!1,error:"projectId must match the entry sessions"};if(l=d.projectId,l==null)return{ok:!1,error:"Entry session has no project"};for(const f of h)if(s.hookSessions.getBySessionId(f.id).projectId!==l)return{ok:!1,error:"All entry sessions must belong to the same project"}}else{const d=r.nodes.find(f=>f.kind==="session");d&&(l=s.hookSessions.getBySessionId(d.id).projectId??l)}return l==null?{ok:!1,error:"projectId is required for webhook-only orchestrations"}:{ok:!0,value:{name:t,projectId:l,startText:(r.startText??"").trim(),nodes:r.nodes,edges:r.edges,cron:u}}}function _(s,r){for(const t of s.orchestrationRuns?.listRunning()??[])t.orchestrationId===r&&s.orchestrationEngine?.cancel(t.id)}export async function handleOrchestrationRoutes(s,r,t,c,u){if(c==="/messaging/orchestrations"){if(!t.orchestrations)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;if(s.method==="GET"){const e=m(u,"projectId"),n=e===void 0?t.orchestrations.list():t.orchestrations.listByProject(e);return o(r,200,{orchestrations:n.map(I)}),!0}if(s.method==="POST"){let e;try{e=T.parse(await k(s))}catch(a){return o(r,400,{error:a instanceof Error?a.message:"Invalid body"}),!0}const n=v(t,e);return n.ok?(o(r,201,{ok:!0,orchestration:I(t.orchestrations.insert({...n.value,enabled:e.enabled}))}),!0):(o(r,400,{error:n.error}),!0)}}const g=c.match(/^\/messaging\/orchestrations\/(\d+)$/);if(g){const e=Number(g[1]);if(s.method==="PUT"){if(!t.orchestrations)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;const n=t.orchestrations.getById(e);if(!n)return o(r,404,{error:"Orchestration not found"}),!0;let a;try{a=N.parse(await k(s))}catch(b){return o(r,400,{error:b instanceof Error?b.message:"Invalid body"}),!0}const y=v(t,{name:a.name??n.name,startText:a.startText??n.startText,projectId:a.projectId??(n.nodes.some(b=>b.kind==="session")?void 0:n.projectId),nodes:a.nodes??n.nodes,edges:a.edges??n.edges,cron:a.cron===void 0?n.cron:a.cron});return y.ok?(o(r,200,{ok:!0,orchestration:I(t.orchestrations.update(e,{...y.value,enabled:a.enabled}))}),!0):(o(r,400,{error:y.error}),!0)}if(s.method==="DELETE")return t.orchestrations?t.orchestrations.getById(e)?(_(t,e),t.orchestrations.deleteById(e),o(r,200,{ok:!0,orchestrationId:e}),!0):(o(r,404,{error:"Orchestration not found"}),!0):(o(r,503,{error:"Messaging subsystem unavailable"}),!0)}const h=c.match(/^\/messaging\/orchestrations\/(\d+)\/trigger$/);if(h&&s.method==="POST"){if(!t.orchestrationEngine||!t.orchestrations)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;let e={};try{const a=(await R(s)).trim();a&&(e=O.parse(JSON.parse(a)))}catch{return o(r,400,{error:"Invalid body"}),!0}const n=await t.orchestrationEngine.start(Number(h[1]),"manual",e.text,e.entries);return n.ok?(o(r,201,{ok:!0,runId:n.runId}),!0):(o(r,n.status,{error:n.error}),!0)}const l=c.match(/^\/messaging\/orchestrations\/(\d+)\/rotate-webhook$/);if(l&&s.method==="POST"){if(!t.orchestrations)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;let e;try{e=P.parse(await k(s))}catch(a){return o(r,400,{error:a instanceof Error?a.message:"Invalid body"}),!0}const n=t.orchestrations.rotateNodeToken(Number(l[1]),e.nodeId);return n?(o(r,200,{ok:!0,webhookToken:n}),!0):(o(r,404,{error:"Webhook entry node not found"}),!0)}const d=c.match(/^\/webhooks\/orchestrate\/([A-Za-z0-9_-]+)$/);if(d&&s.method==="POST"){if(!t.orchestrations||!t.orchestrationEngine)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;const e=t.orchestrations.getByNodeToken(d[1]);if(!e)return o(r,404,{error:"Unknown webhook token"}),!0;const n=(await R(s)).trim().slice(0,2e4),a=await t.orchestrationEngine.start(e.row.id,"webhook",n||void 0,[e.nodeId]);return a.ok?(o(r,202,{ok:!0,runId:a.runId}),!0):(o(r,a.status,{error:a.error}),!0)}if(c==="/messaging/orchestration-runs"){if(!t.orchestrationRuns)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;if(s.method==="GET"){const e=u.searchParams.get("status")||void 0;if(e&&!$.has(e))return o(r,400,{error:`Unknown run status: ${e}`}),!0;const n=t.orchestrationRuns.query({orchestrationId:m(u,"orchestrationId"),projectId:m(u,"projectId"),status:e,text:u.searchParams.get("text")||void 0,before:m(u,"before"),limit:m(u,"limit")});return o(r,200,{runs:n.runs.map(w),nextBefore:n.nextBefore}),!0}if(s.method==="DELETE"){const e=u.searchParams.get("scope")==="all"?"all":"finished",n=m(u,"projectId");if(e==="all")for(const a of t.orchestrationRuns.listRunning())n!=null&&a.projectId!==n||t.orchestrationEngine?.cancel(a.id);return o(r,200,{ok:!0,deleted:t.orchestrationRuns.clear(e,n)}),!0}}const f=c.match(/^\/messaging\/orchestration-runs\/(\d+)$/);if(f&&s.method==="GET"){if(!t.orchestrationRuns)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;const e=t.orchestrationRuns.getById(Number(f[1]));return e?(o(r,200,{run:{...w(e),state:e.state}}),!0):(o(r,404,{error:"Run not found"}),!0)}const x=c.match(/^\/messaging\/orchestration-runs\/(\d+)\/cancel$/);if(x&&s.method==="POST"){if(!t.orchestrationRuns)return o(r,503,{error:"Messaging subsystem unavailable"}),!0;const e=t.orchestrationRuns.getById(Number(x[1]));return e?e.status!=="running"?(o(r,409,{error:`Run already ${e.status}`}),!0):(t.orchestrationEngine?.cancel(e.id)||t.orchestrationRuns.finish(e.id,"cancelled"),o(r,200,{ok:!0,runId:e.id}),!0):(o(r,404,{error:"Run not found"}),!0)}return!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{isHarness as I}from"@weavecode/core";import{readJson as j,sendJson as o}from"../http.js";import{messagingSurfaceFor as P}from"../../surfaces.js";import{projectFileIndex as R}from"../project-files.js";function S(t,e,r){if(!e.hookSessions||!e.hookEvents)return o(t,503,{error:"Hooks subsystem unavailable"}),null;const n=e.hookSessions.getBySessionId(r);if(!n)return o(t,404,{error:"Session not found"}),null;if(n.projectId==null)return o(t,400,{error:"Session is not bound to a project"}),null;const s=e.projects.getById(n.projectId);return s||(o(t,404,{error:"Project not found"}),null)}function b(t,e){if(!t.hookEvents)return null;const r=t.hookEvents.listBySession(e,1),n=r[r.length-1]?.source;return I(n)?n:null}function k(t,e,r){const n=b(e,r),s=n?P(n):null,a=s?.pathRefs??null;return a||(o(t,409,{error:n?s?.unsupportedReasons?.pathRefs??`Harness "${n}" has no path reference syntax`:"Session has no hook events to determine its harness"}),null)}function x(t){if(t==null||t==="")return null;const e=Number(t);return Number.isInteger(e)&&e>0?e:null}function y(t,e){let r=0,n=t.length-1;for(;r<=n;){const s=r+n>>1,a=t[s];if(a===e)return!0;a<e?r=s+1:n=s-1}return!1}export async function handlePathRefRoutes(t,e,r,n,s){const a=n.match(/^\/sessions\/([^/]+)\/ref$/);if(a&&t.method==="GET"){const d=decodeURIComponent(a[1]);if(!S(e,r,d))return!0;const u=k(e,r,d);if(!u)return!0;const c=(s.searchParams.get("path")??"").replace(/^\/+|\/+$/g,"");if(!c)return o(e,400,{error:'Missing "path" query parameter'}),!0;const f=s.searchParams.get("kind")==="dir"?"dir":"file";if(!u.kinds.includes(f))return o(e,409,{error:`Harness does not accept "${f}" references`}),!0;const l=x(s.searchParams.get("start")),h=x(s.searchParams.get("end"));return u.lines?l==null?(o(e,200,{ref:u.expression({path:c,kind:f})}),!0):h!=null&&h<l?(o(e,400,{error:'"end" must not precede "start"'}),!0):(o(e,200,{ref:u.expression({path:c,kind:f,lines:{start:l,end:h??l}})}),!0):(o(e,200,{ref:u.expression({path:c,kind:f})}),!0)}const g=n.match(/^\/sessions\/([^/]+)\/refs\/recognize$/);if(g&&t.method==="POST"){const d=decodeURIComponent(g[1]),u=S(e,r,d);if(!u)return!0;const c=k(e,r,d);if(!c)return!0;let f="";try{const i=await j(t);f=typeof i?.text=="string"?i.text:""}catch{return o(e,400,{error:"Body must be JSON"}),!0}const l=await R(u.id,u.path),h=[];for(const i of c.recognize(f)){const p=i.kind==="dir"&&y(l.dirs,i.path)?"dir":y(l.files,i.path)?"file":null;if(!p||!c.kinds.includes(p))continue;const m=i.lines&&c.lines?i.lines:void 0;h.push({start:i.start,end:i.end,ref:c.expression({path:i.path,kind:p,...m?{lines:m}:{}}),path:i.path,kind:p,...m?{lines:m}:{}})}return o(e,200,{refs:h}),!0}return!1}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { WeaveServerDeps } from '../server.js';
|
|
3
|
+
/**
|
|
4
|
+
* 项目文件数据面路由。返回 true = 本路由认领;false = 未命中,主链继续。
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleProjectFileRoutes(req: IncomingMessage, res: ServerResponse, deps: WeaveServerDeps, pathname: string, url: URL): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{lstat as O,readFile as T,stat as j}from"node:fs/promises";import I from"node:path";import{sendJson as n}from"../http.js";import{listDirOf as E,matchPaths as F,projectFileIndex as S}from"../project-files.js";import{resolveWithinProject as v}from"../../install/reader.js";const N=4*1024*1024,P=1024*1024,_=8192;function k(r){const t=Number(r);return!Number.isFinite(t)||t<=0?100:Math.min(200,Math.floor(t))}function B(r){switch(r.slice(r.lastIndexOf(".")+1).toLowerCase()){case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"webp":return"image/webp";default:return null}}function M(r){switch(r.slice(r.lastIndexOf(".")+1).toLowerCase()){case"html":case"htm":return"text/html; charset=utf-8";case"svg":return"image/svg+xml";case"pdf":return"application/pdf";default:return null}}const z=new Set(["docx","doc","xlsx","xls","pptx","ppt","zip","gz","tar","rar","7z","exe","dll","bin","woff","woff2","ttf","otf","ico","mp4","mp3","wav","mov"]);function L(r){const t=r.slice(r.lastIndexOf(".")+1).toLowerCase();return z.has(t)?"application/octet-stream":null}export async function handleProjectFileRoutes(r,t,x,w,f){const y=w.match(/^\/projects\/(\d+)\/files$/);if(y&&r.method==="GET"){const i=x.projects.getById(Number(y[1]));if(!i)return n(t,404,{error:"Project not found"}),!0;const a=await S(i.id,i.path,{fresh:f.searchParams.get("fresh")==="1"}),u=f.searchParams.get("q")??"",c=(f.searchParams.get("dir")??"").replace(/^\/+|\/+$/g,""),m=k(f.searchParams.get("limit"));if(u.trim()){const{hits:e,total:o,capped:l}=await F(a,u,m,c);return n(t,200,{root:i.path,dir:c,total:o,capped:l,truncated:a.truncated,entries:e.map(s=>({path:s.path,name:s.path.slice(s.path.lastIndexOf("/")+1),kind:s.kind,ranges:s.ranges,...a.submodules[s.path]?{head:a.submodules[s.path]}:{}}))}),!0}const p=E(a,c),d=await Promise.all(p.slice(0,m).map(async e=>{const o={path:e.path,name:e.path.slice(e.path.lastIndexOf("/")+1),kind:e.kind,...e.head?{head:e.head}:{}},l=I.join(i.path,e.path),[s,h]=await Promise.all([O(l).catch(()=>null),e.kind==="file"?j(l).catch(()=>null):Promise.resolve(null)]),g=s?.isSymbolicLink()?{symlink:!0}:null;return h?{...o,...g,size:h.size,mtime:h.mtime.toISOString()}:g?{...o,...g}:o}));return n(t,200,{root:i.path,dir:c,total:p.length,capped:!1,truncated:a.truncated,entries:d}),!0}const b=w.match(/^\/projects\/(\d+)\/file$/);if(b&&r.method==="GET"){const i=x.projects.getById(Number(b[1]));if(!i)return n(t,404,{error:"Project not found"}),!0;const a=f.searchParams.get("path");if(!a)return n(t,400,{error:'Missing "path" query parameter'}),!0;let u;try{u=v(i.path,a)}catch{return n(t,403,{error:"Path escapes the project"}),!0}let c;try{c=await j(u)}catch{return n(t,404,{error:"File not found"}),!0}if(!c.isFile())return n(t,404,{error:"Not a file"}),!0;if(c.size>N)return n(t,413,{error:"File too large to preview"}),!0;const m=B(a),p=M(a),d=L(a);let e=await T(u);if(!m&&!p&&!d){if(e.subarray(0,_).includes(0))return n(t,415,{error:"Binary file"}),!0;if(e.length>P){const o=e.subarray(0,P),l=o.lastIndexOf(10);e=l>0?o.subarray(0,l):o,t.setHeader("x-weave-truncated","1")}}return p&&t.setHeader("content-security-policy","sandbox"),d&&t.setHeader("content-disposition",`attachment; filename*=UTF-8''${encodeURI(I.basename(a))}`),t.writeHead(200,{"content-type":m??p??d??"text/plain; charset=utf-8","content-length":String(e.length),"cache-control":"private, max-age=60"}),t.end(e),!0}return!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import y from"node:fs";import $ from"node:path";import{isHarness as J}from"@weavecode/core";import{messagingSurfaceFor as M}from"../../surfaces.js";import{readBody as p,sendJson as o}from"../http.js";import{readDaemonSettings as j}from"../settings.js";import{closeTerminalsIn as A,defaultProjectOpener as d,readTerminalCounts as x,terminalBackendFor as D}from"../opener.js";import{purgeProjectPipeline as R}from"../hook-pipeline.js";import{hooksRoot as G}from"../../hooks/mirror.js";import{projectHarnesses as H,withProjectHarnesses as E}from"../project-harnesses.js";import{scheduleBootstrapInjection as C}from"../session-open.js";import{getUploadsDir as U}from"../../db/paths.js";export async function handleProjectRoutes(a,e,r,l){const I=l.match(/^\/projects\/(\d+)\/open$/);if(I&&a.method==="POST"){const t=r.projects.getById(Number(I[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;let n;try{n=JSON.parse(await p(a))}catch{return o(e,400,{error:"Invalid JSON body"}),!0}if(n.target!=="explorer"&&n.target!=="terminal")return o(e,400,{error:'Invalid "target" (explorer|terminal)'}),!0;const s=r.opener??d;try{if(!(await y.promises.stat(t.path)).isDirectory())throw new Error(`Not a directory: ${t.path}`);if(n.target==="explorer")await s.openExplorer(t.path);else{const c=await j();await s.openTerminal(t.path,c.terminal),setTimeout(()=>{r.terminalRefresher?.refreshNow()},600)}o(e,200,{ok:!0,target:n.target,path:t.path})}catch(i){o(e,400,{error:i instanceof Error?i.message:"Open failed"})}return!0}const v=l.match(/^\/projects\/(\d+)\/close-terminal$/);if(v&&a.method==="POST"){const t=r.projects.getById(Number(v[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;let n;try{n=JSON.parse(await p(a)||"{}")}catch{return o(e,400,{error:"Invalid JSON body"}),!0}if(!Array.isArray(n.paneIds)||n.paneIds.length===0||n.paneIds.some(c=>typeof c!="string"))return o(e,400,{error:"paneIds must be a non-empty array of strings"}),!0;const s=r.opener??d,i=await j();try{const u=await(s.closeTerminals??A)(t.path,i.terminal,n.paneIds);setTimeout(()=>{r.terminalRefresher?.refreshNow()},600),o(e,200,{ok:!0,closed:u})}catch(c){o(e,400,{error:c instanceof Error?c.message:"Close failed"})}return!0}const b=l.match(/^\/projects\/(\d+)\/focus-terminal$/);if(b&&a.method==="POST"){const t=r.projects.getById(Number(b[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;let n;try{n=JSON.parse(await p(a)||"{}")}catch{return o(e,400,{error:"Invalid JSON body"}),!0}if(typeof n.targetId!="string"||!n.targetId)return o(e,400,{error:"targetId must be a non-empty string"}),!0;const s=r.opener??d,i=await j();try{await(s.focusTerminal??d.focusTerminal)(t.path,n.targetId,i.terminal),o(e,200,{ok:!0,targetId:n.targetId})}catch(c){o(e,409,{error:c instanceof Error?c.message:"Cannot focus terminal"})}return!0}const P=l.match(/^\/projects\/(\d+)\/new-session$/);if(P&&a.method==="POST"){const t=r.projects.getById(Number(P[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;let n;try{n=JSON.parse(await p(a)||"{}")}catch{return o(e,400,{error:"Invalid JSON body"}),!0}const s=await H(t.path,r.harnesses);if(n.harness!==void 0&&!J(n.harness))return o(e,400,{error:'Invalid "harness"'}),!0;const i=n.harness;if(i&&!s.some(m=>m.id===i))return o(e,409,{error:`Harness "${i}" is not integrated in this project`}),!0;const c=i?[i]:s.map(m=>m.id),u=s.find(m=>c.includes(m.id)&&m.canStartSession),f=u?r.harnesses?.get(u.id)?.resume:void 0;if(!f?.bin)return o(e,501,{error:`Harness "${c[0]}" cannot start an interactive session`}),!0;const h=r.opener??d;try{if(!(await y.promises.stat(t.path)).isDirectory())throw new Error(`Not a directory: ${t.path}`);const g=await j(),k=[f.bin,...f.launchArgs??[]],w=await h.runInTerminal(t.path,k,g.terminal);w&&u&&M(u.id).paneEnvSource==="launch"&&r.messageDeliverer?.notePendingOrigin({harness:u.id,projectId:t.id,env:w.env}),w&&u&&f?.bootstrapText&&C(r,w,f.bootstrapText(t.name)),setTimeout(()=>{r.terminalRefresher?.refreshNow()},600),o(e,200,{ok:!0,command:k.join(" "),cwd:t.path})}catch(m){o(e,400,{error:m instanceof Error?m.message:"Open failed"})}return!0}if(l==="/projects"&&a.method==="GET")return o(e,200,{projects:await E(r.projects.list(),r.harnesses)}),!0;if(l==="/projects/archived"&&a.method==="GET")return o(e,200,{projects:await E(r.projects.listArchived(),r.harnesses)}),!0;const T=l.match(/^\/projects\/(\d+)\/archive$/);if(T&&a.method==="POST"){const t=r.projects.getById(Number(T[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;if(t.archivedAt)return o(e,200,{project:t,purged:{events:0,dispatches:0,sessions:0,messages:0}}),!0;const n=r.hookDispatches?.deleteByProject(t.id)??0,s=r.hookEvents?.deleteByProject(t.id)??0;r.uploads?.pruneUnreferenced();const i=r.messageDeliverer?.forgetProject(t.id)??0;r.sessionWatches?.deleteByProject(t.id),r.orchestrations?.deleteByProject(t.id),r.orchestrationRuns?.clear("all",t.id),r.sideQuestions?.repo.deleteByProject(t.id);const c=r.hookSessions?.removeByProject(t.id)??0;return r.projects.setArchived(t.id,!0),R(r.hooksDir??G(),t.token),r.watch?.reconcile(),r.dataBus?.emit({key:"projects"}),o(e,200,{project:r.projects.getById(t.id),purged:{events:s,dispatches:n,sessions:c,messages:i}}),!0}const S=l.match(/^\/projects\/(\d+)\/restore$/);if(S&&a.method==="POST"){const t=r.projects.getById(Number(S[1]));return t?t.archivedAt?(r.projects.setArchived(t.id,!1),r.hookMirror?.syncProject(t.id),r.watch?.reconcile(),r.dataBus?.emit({key:"projects"}),o(e,200,{project:r.projects.getById(t.id)}),!0):(o(e,200,{project:t}),!0):(o(e,404,{error:"Project not found"}),!0)}if(l==="/projects/order"&&a.method==="PUT"){let t;try{t=JSON.parse(await p(a))}catch{return o(e,400,{error:"Invalid JSON body"}),!0}return!Array.isArray(t.ids)||!t.ids.every(n=>Number.isInteger(n))?(o(e,400,{error:'Invalid "ids" (integer array expected)'}),!0):(r.projects.setOrder(t.ids),r.dataBus?.emit({key:"projects"}),o(e,200,{projects:r.projects.list()}),!0)}const N=l.match(/^\/projects\/(\d+)\/panes$/);if(N&&a.method==="GET"){const t=r.projects.getById(Number(N[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;const n=await j(),s=r.opener?.listPanes??d.listPanes;try{o(e,200,{projectId:t.id,panes:await s(t.path,n.terminal)})}catch(i){o(e,409,{error:i instanceof Error?i.message:"Cannot list panes"})}return!0}const B=l.match(/^\/projects\/(\d+)\/terminals$/);if(B&&a.method==="GET"){const t=r.projects.getById(Number(B[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;const n=await j(),s=r.opener?.listTerminals??d.listTerminals,i=D(n.terminal).enumerable?await s(t.path,n.terminal):[];return o(e,200,{projectId:t.id,terminals:i}),!0}if(l==="/terminals/counts"&&a.method==="GET"){if(r.terminalRefresher)o(e,200,{counts:r.terminalRefresher.lastSnapshot?.counts??{}}),r.terminalRefresher.tick(!0);else{const t=r.opener??d;o(e,200,{counts:await x(r.projects.list(),t)})}return!0}const O=l.match(/^\/projects\/(\d+)\/storage$/);if(O){const t=r.projects.getById(Number(O[1]));if(!t)return o(e,404,{error:"Project not found"}),!0;const s=r.projects.getMeta(t.id)?.storage??{},i=r.uploads?.defaultDir??U();if(a.method==="GET")return o(e,200,{storage:s,effective:{images:s.images||i,files:s.files||i}}),!0;if(a.method==="PUT"){let c;try{c=JSON.parse(await p(a))}catch{return o(e,400,{error:"Invalid JSON body"}),!0}const u={};for(const f of["images","files"]){const h=c[f];if(h==null||h===""){u[f]=null;continue}if(typeof h!="string")return o(e,400,{error:`"${f}" must be a string or null`}),!0;const m=h.trim();if(!$.isAbsolute(m))return o(e,400,{error:`"${f}" must be an absolute path`}),!0;try{y.mkdirSync(m,{recursive:!0}),y.accessSync(m,y.constants.W_OK)}catch(g){return o(e,400,{error:`"${f}" is not writable: ${g instanceof Error?g.message:String(g)}`}),!0}u[f]=m}return r.projects.setMeta(t.id,{storage:u}),r.dataBus?.emit({key:"projects"}),o(e,200,{storage:u,effective:{images:u.images||i,files:u.files||i}}),!0}return!1}return!1}
|