terminal-pilot 0.0.30 → 0.0.31
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/dist/cli.js +1375 -435
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js +485 -6
- package/dist/commands/close-session.js.map +4 -4
- package/dist/commands/create-session.js +485 -6
- package/dist/commands/create-session.js.map +4 -4
- package/dist/commands/fill.js +485 -6
- package/dist/commands/fill.js.map +4 -4
- package/dist/commands/get-session.js +485 -6
- package/dist/commands/get-session.js.map +4 -4
- package/dist/commands/index.js +626 -44
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +622 -40
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +68 -17
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js +485 -6
- package/dist/commands/list-sessions.js.map +4 -4
- package/dist/commands/press-key.js +485 -6
- package/dist/commands/press-key.js.map +4 -4
- package/dist/commands/read-history.js +485 -6
- package/dist/commands/read-history.js.map +4 -4
- package/dist/commands/read-screen.js +485 -6
- package/dist/commands/read-screen.js.map +4 -4
- package/dist/commands/resize.js +485 -6
- package/dist/commands/resize.js.map +4 -4
- package/dist/commands/screenshot.js +485 -6
- package/dist/commands/screenshot.js.map +4 -4
- package/dist/commands/send-signal.js +485 -6
- package/dist/commands/send-signal.js.map +4 -4
- package/dist/commands/type.js +485 -6
- package/dist/commands/type.js.map +4 -4
- package/dist/commands/uninstall.js +550 -20
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js +485 -6
- package/dist/commands/wait-for-exit.js.map +4 -4
- package/dist/commands/wait-for.js +485 -6
- package/dist/commands/wait-for.js.map +4 -4
- package/dist/testing/cli-repl.js +1375 -435
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1385 -445
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-defs/README.md +35 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +21 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +18 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/codex.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/codex.js +25 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/cursor.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/cursor.js +15 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.js +16 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/goose.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/goose.js +16 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/index.d.ts +9 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/index.js +9 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/kimi.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +16 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/opencode.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +20 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.d.ts +2 -0
- package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.js +14 -0
- package/node_modules/@poe-code/agent-defs/dist/index.d.ts +5 -0
- package/node_modules/@poe-code/agent-defs/dist/index.js +3 -0
- package/node_modules/@poe-code/agent-defs/dist/registry.d.ts +3 -0
- package/node_modules/@poe-code/agent-defs/dist/registry.js +45 -0
- package/node_modules/@poe-code/agent-defs/dist/specifier.d.ts +7 -0
- package/node_modules/@poe-code/agent-defs/dist/specifier.js +40 -0
- package/node_modules/@poe-code/agent-defs/dist/types.d.ts +28 -0
- package/node_modules/@poe-code/agent-defs/dist/types.js +1 -0
- package/node_modules/@poe-code/agent-defs/package.json +20 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +2 -1
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +37 -18
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +8 -4
- package/node_modules/@poe-code/agent-skill-config/package.json +1 -5
- package/node_modules/@poe-code/config-mutations/README.md +55 -0
- package/node_modules/@poe-code/config-mutations/dist/error-codes.d.ts +1 -0
- package/node_modules/@poe-code/config-mutations/dist/error-codes.js +6 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.d.ts +6 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +829 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.d.ts +17 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.js +64 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.d.ts +7 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.js +39 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/index.d.ts +13 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/index.js +49 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/json.d.ts +32 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/json.js +171 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/object.d.ts +4 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/object.js +27 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/toml.d.ts +2 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/toml.js +75 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/yaml.d.ts +2 -0
- package/node_modules/@poe-code/config-mutations/dist/formats/yaml.js +76 -0
- package/node_modules/@poe-code/config-mutations/dist/fs-utils.d.ts +18 -0
- package/node_modules/@poe-code/config-mutations/dist/fs-utils.js +43 -0
- package/node_modules/@poe-code/config-mutations/dist/index.d.ts +8 -0
- package/node_modules/@poe-code/config-mutations/dist/index.js +8 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.d.ts +47 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.js +34 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.d.ts +62 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.js +55 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.d.ts +40 -0
- package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.js +32 -0
- package/node_modules/@poe-code/config-mutations/dist/template/render.d.ts +6 -0
- package/node_modules/@poe-code/config-mutations/dist/template/render.js +8 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.d.ts +7 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.js +21 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/index.d.ts +3 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/index.js +2 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.d.ts +25 -0
- package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.js +194 -0
- package/node_modules/@poe-code/config-mutations/dist/types.d.ts +168 -0
- package/node_modules/@poe-code/config-mutations/dist/types.js +6 -0
- package/node_modules/@poe-code/config-mutations/package.json +29 -0
- package/node_modules/@poe-code/frontmatter/README.md +35 -0
- package/node_modules/@poe-code/frontmatter/dist/fences.d.ts +25 -0
- package/node_modules/@poe-code/frontmatter/dist/fences.js +100 -0
- package/node_modules/@poe-code/frontmatter/dist/index.d.ts +3 -0
- package/node_modules/@poe-code/frontmatter/dist/index.js +3 -0
- package/node_modules/@poe-code/frontmatter/dist/parse.d.ts +20 -0
- package/node_modules/@poe-code/frontmatter/dist/parse.js +209 -0
- package/node_modules/@poe-code/frontmatter/dist/stringify.d.ts +1 -0
- package/node_modules/@poe-code/frontmatter/dist/stringify.js +48 -0
- package/node_modules/@poe-code/frontmatter/package.json +25 -0
- package/node_modules/toolcraft-design/README.md +160 -0
- package/node_modules/toolcraft-design/dist/acp/components.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/acp/components.js +137 -0
- package/node_modules/toolcraft-design/dist/acp/index.d.ts +3 -0
- package/node_modules/toolcraft-design/dist/acp/index.js +2 -0
- package/node_modules/toolcraft-design/dist/acp/writer.d.ts +13 -0
- package/node_modules/toolcraft-design/dist/acp/writer.js +21 -0
- package/node_modules/toolcraft-design/dist/components/browser.d.ts +15 -0
- package/node_modules/toolcraft-design/dist/components/browser.js +31 -0
- package/node_modules/toolcraft-design/dist/components/catalog.d.ts +26 -0
- package/node_modules/toolcraft-design/dist/components/catalog.js +95 -0
- package/node_modules/toolcraft-design/dist/components/color.d.ts +31 -0
- package/node_modules/toolcraft-design/dist/components/color.js +102 -0
- package/node_modules/toolcraft-design/dist/components/command-errors.d.ts +16 -0
- package/node_modules/toolcraft-design/dist/components/command-errors.js +23 -0
- package/node_modules/toolcraft-design/dist/components/detail-card.d.ts +22 -0
- package/node_modules/toolcraft-design/dist/components/detail-card.js +45 -0
- package/node_modules/toolcraft-design/dist/components/help-formatter-plain.d.ts +5 -0
- package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +132 -0
- package/node_modules/toolcraft-design/dist/components/help-formatter.d.ts +33 -0
- package/node_modules/toolcraft-design/dist/components/help-formatter.js +213 -0
- package/node_modules/toolcraft-design/dist/components/index.d.ts +16 -0
- package/node_modules/toolcraft-design/dist/components/index.js +10 -0
- package/node_modules/toolcraft-design/dist/components/logger.d.ts +11 -0
- package/node_modules/toolcraft-design/dist/components/logger.js +60 -0
- package/node_modules/toolcraft-design/dist/components/symbols.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/components/symbols.js +71 -0
- package/node_modules/toolcraft-design/dist/components/table.d.ts +15 -0
- package/node_modules/toolcraft-design/dist/components/table.js +302 -0
- package/node_modules/toolcraft-design/dist/components/template.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/components/template.js +437 -0
- package/node_modules/toolcraft-design/dist/components/text.d.ts +16 -0
- package/node_modules/toolcraft-design/dist/components/text.js +145 -0
- package/node_modules/toolcraft-design/dist/dashboard/ansi.d.ts +18 -0
- package/node_modules/toolcraft-design/dist/dashboard/ansi.js +343 -0
- package/node_modules/toolcraft-design/dist/dashboard/buffer.d.ts +25 -0
- package/node_modules/toolcraft-design/dist/dashboard/buffer.js +219 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/border.d.ts +9 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/border.js +123 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/footer.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/footer.js +56 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.js +268 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.d.ts +7 -0
- package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.js +107 -0
- package/node_modules/toolcraft-design/dist/dashboard/dashboard.d.ts +20 -0
- package/node_modules/toolcraft-design/dist/dashboard/dashboard.js +167 -0
- package/node_modules/toolcraft-design/dist/dashboard/demo.d.ts +13 -0
- package/node_modules/toolcraft-design/dist/dashboard/demo.js +145 -0
- package/node_modules/toolcraft-design/dist/dashboard/index.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/dashboard/index.js +4 -0
- package/node_modules/toolcraft-design/dist/dashboard/keymap.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/dashboard/keymap.js +233 -0
- package/node_modules/toolcraft-design/dist/dashboard/layout.d.ts +25 -0
- package/node_modules/toolcraft-design/dist/dashboard/layout.js +79 -0
- package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.js +7 -0
- package/node_modules/toolcraft-design/dist/dashboard/snapshot.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/dashboard/snapshot.js +68 -0
- package/node_modules/toolcraft-design/dist/dashboard/store.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/dashboard/store.js +51 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal-width.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal-width.js +71 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal.d.ts +37 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal.js +264 -0
- package/node_modules/toolcraft-design/dist/dashboard/types.d.ts +38 -0
- package/node_modules/toolcraft-design/dist/dashboard/types.js +1 -0
- package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +16 -0
- package/node_modules/toolcraft-design/dist/explorer/actions.js +39 -0
- package/node_modules/toolcraft-design/dist/explorer/demo.d.ts +13 -0
- package/node_modules/toolcraft-design/dist/explorer/demo.js +297 -0
- package/node_modules/toolcraft-design/dist/explorer/events.d.ts +67 -0
- package/node_modules/toolcraft-design/dist/explorer/events.js +1 -0
- package/node_modules/toolcraft-design/dist/explorer/filter.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/explorer/filter.js +95 -0
- package/node_modules/toolcraft-design/dist/explorer/index.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/explorer/index.js +8 -0
- package/node_modules/toolcraft-design/dist/explorer/jobs.d.ts +7 -0
- package/node_modules/toolcraft-design/dist/explorer/jobs.js +59 -0
- package/node_modules/toolcraft-design/dist/explorer/keymap.d.ts +21 -0
- package/node_modules/toolcraft-design/dist/explorer/keymap.js +376 -0
- package/node_modules/toolcraft-design/dist/explorer/layout.d.ts +20 -0
- package/node_modules/toolcraft-design/dist/explorer/layout.js +73 -0
- package/node_modules/toolcraft-design/dist/explorer/reducer.d.ts +9 -0
- package/node_modules/toolcraft-design/dist/explorer/reducer.js +782 -0
- package/node_modules/toolcraft-design/dist/explorer/render/detail.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/render/detail.js +97 -0
- package/node_modules/toolcraft-design/dist/explorer/render/footer.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/render/footer.js +73 -0
- package/node_modules/toolcraft-design/dist/explorer/render/header.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/render/header.js +49 -0
- package/node_modules/toolcraft-design/dist/explorer/render/index.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/explorer/render/index.js +53 -0
- package/node_modules/toolcraft-design/dist/explorer/render/list.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/render/list.js +116 -0
- package/node_modules/toolcraft-design/dist/explorer/render/modal.d.ts +3 -0
- package/node_modules/toolcraft-design/dist/explorer/render/modal.js +87 -0
- package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +156 -0
- package/node_modules/toolcraft-design/dist/explorer/render/text.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/explorer/render/text.js +81 -0
- package/node_modules/toolcraft-design/dist/explorer/runtime.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/explorer/runtime.js +340 -0
- package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.d.ts +50 -0
- package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.js +101 -0
- package/node_modules/toolcraft-design/dist/explorer/state.d.ts +137 -0
- package/node_modules/toolcraft-design/dist/explorer/state.js +86 -0
- package/node_modules/toolcraft-design/dist/explorer/theme.d.ts +27 -0
- package/node_modules/toolcraft-design/dist/explorer/theme.js +29 -0
- package/node_modules/toolcraft-design/dist/index.d.ts +50 -0
- package/node_modules/toolcraft-design/dist/index.js +43 -0
- package/node_modules/toolcraft-design/dist/internal/color-support.d.ts +9 -0
- package/node_modules/toolcraft-design/dist/internal/color-support.js +12 -0
- package/node_modules/toolcraft-design/dist/internal/output-format.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/internal/output-format.js +22 -0
- package/node_modules/toolcraft-design/dist/internal/strip-ansi.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/internal/strip-ansi.js +50 -0
- package/node_modules/toolcraft-design/dist/internal/theme-detect.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/internal/theme-detect.js +71 -0
- package/node_modules/toolcraft-design/dist/internal/theme-state.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/internal/theme-state.js +35 -0
- package/node_modules/toolcraft-design/dist/prompts/index.d.ts +91 -0
- package/node_modules/toolcraft-design/dist/prompts/index.js +137 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.js +4 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.d.ts +9 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.js +47 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/core.d.ts +55 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/core.js +274 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +20 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +53 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/index.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/index.js +6 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/keys.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +28 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.d.ts +13 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +131 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.js +52 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/password.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/password.js +55 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/select.d.ts +18 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/select.js +89 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.d.ts +21 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.js +32 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/text.d.ts +12 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/text.js +60 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.js +18 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.js +9 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/intro.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/intro.js +16 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/log.d.ts +18 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/log.js +104 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/note.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/note.js +39 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/outro.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/outro.js +16 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.js +74 -0
- package/node_modules/toolcraft-design/dist/prompts/theme.d.ts +11 -0
- package/node_modules/toolcraft-design/dist/prompts/theme.js +15 -0
- package/node_modules/toolcraft-design/dist/static/index.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/static/index.js +2 -0
- package/node_modules/toolcraft-design/dist/static/menu.d.ts +11 -0
- package/node_modules/toolcraft-design/dist/static/menu.js +42 -0
- package/node_modules/toolcraft-design/dist/static/spinner.d.ts +14 -0
- package/node_modules/toolcraft-design/dist/static/spinner.js +52 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/ast.d.ts +92 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/ast.js +1 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.js +139 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/index.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/index.js +8 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.d.ts +7 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.js +1495 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.js +36 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.d.ts +10 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.js +1190 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser.d.ts +5 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser.js +42 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.js +615 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
- package/node_modules/toolcraft-design/dist/tokens/brand.d.ts +5 -0
- package/node_modules/toolcraft-design/dist/tokens/brand.js +5 -0
- package/node_modules/toolcraft-design/dist/tokens/colors.d.ts +37 -0
- package/node_modules/toolcraft-design/dist/tokens/colors.js +85 -0
- package/node_modules/toolcraft-design/dist/tokens/index.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/tokens/index.js +5 -0
- package/node_modules/toolcraft-design/dist/tokens/spacing.d.ts +6 -0
- package/node_modules/toolcraft-design/dist/tokens/spacing.js +6 -0
- package/node_modules/toolcraft-design/dist/tokens/typography.d.ts +7 -0
- package/node_modules/toolcraft-design/dist/tokens/typography.js +8 -0
- package/node_modules/toolcraft-design/dist/tokens/widths.d.ts +5 -0
- package/node_modules/toolcraft-design/dist/tokens/widths.js +5 -0
- package/node_modules/toolcraft-design/package.json +44 -0
- package/package.json +15 -5
package/dist/testing/cli-repl.js
CHANGED
|
@@ -79,12 +79,12 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
79
79
|
|
|
80
80
|
// src/cli.ts
|
|
81
81
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
82
|
-
import
|
|
82
|
+
import path24 from "node:path";
|
|
83
83
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
84
84
|
|
|
85
85
|
// ../toolcraft/src/cli.ts
|
|
86
|
-
import { access as access2, lstat as lstat3, readFile as
|
|
87
|
-
import
|
|
86
|
+
import { access as access2, lstat as lstat3, readFile as readFile5, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
87
|
+
import path15 from "node:path";
|
|
88
88
|
import {
|
|
89
89
|
Command as CommanderCommand,
|
|
90
90
|
CommanderError as CommanderError2,
|
|
@@ -450,7 +450,8 @@ function renderMarkdownCode(content) {
|
|
|
450
450
|
currentRun = 0;
|
|
451
451
|
}
|
|
452
452
|
const delimiter = "`".repeat(longestRun + 1);
|
|
453
|
-
|
|
453
|
+
const paddedValue = value.startsWith("`") || value.endsWith("`") ? ` ${value} ` : value;
|
|
454
|
+
return `${delimiter}${paddedValue}${delimiter}`;
|
|
454
455
|
}
|
|
455
456
|
function renderMarkdownLink(content) {
|
|
456
457
|
const value = renderMarkdownInline(content);
|
|
@@ -605,7 +606,54 @@ var symbols = {
|
|
|
605
606
|
|
|
606
607
|
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
607
608
|
function stripAnsi2(value) {
|
|
608
|
-
|
|
609
|
+
let output = "";
|
|
610
|
+
let index = 0;
|
|
611
|
+
while (index < value.length) {
|
|
612
|
+
const char = value[index];
|
|
613
|
+
if (char === "\x1B") {
|
|
614
|
+
index = skipEscapeSequence(value, index);
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
if (char === "\x9B") {
|
|
618
|
+
index = skipCsiSequence(value, index + 1);
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
output += char;
|
|
622
|
+
index += char.length;
|
|
623
|
+
}
|
|
624
|
+
return output;
|
|
625
|
+
}
|
|
626
|
+
function skipEscapeSequence(value, index) {
|
|
627
|
+
const next = value[index + 1];
|
|
628
|
+
if (next === "[") {
|
|
629
|
+
return skipCsiSequence(value, index + 2);
|
|
630
|
+
}
|
|
631
|
+
if (next === "]") {
|
|
632
|
+
return skipOscSequence(value, index + 2);
|
|
633
|
+
}
|
|
634
|
+
return Math.min(value.length, index + 2);
|
|
635
|
+
}
|
|
636
|
+
function skipCsiSequence(value, index) {
|
|
637
|
+
while (index < value.length) {
|
|
638
|
+
const codePoint = value.charCodeAt(index);
|
|
639
|
+
index += 1;
|
|
640
|
+
if (codePoint >= 64 && codePoint <= 126) {
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return index;
|
|
645
|
+
}
|
|
646
|
+
function skipOscSequence(value, index) {
|
|
647
|
+
while (index < value.length) {
|
|
648
|
+
if (value[index] === "\x07") {
|
|
649
|
+
return index + 1;
|
|
650
|
+
}
|
|
651
|
+
if (value[index] === "\x1B" && value[index + 1] === "\\") {
|
|
652
|
+
return index + 2;
|
|
653
|
+
}
|
|
654
|
+
index += 1;
|
|
655
|
+
}
|
|
656
|
+
return index;
|
|
609
657
|
}
|
|
610
658
|
|
|
611
659
|
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
@@ -1394,38 +1442,14 @@ function renderTable(options) {
|
|
|
1394
1442
|
}
|
|
1395
1443
|
|
|
1396
1444
|
// ../toolcraft-design/src/components/detail-card.ts
|
|
1445
|
+
import stringWidth from "fast-string-width";
|
|
1446
|
+
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1397
1447
|
function wrap(value, width) {
|
|
1398
|
-
|
|
1399
|
-
for (const paragraph of value.split("\n")) {
|
|
1400
|
-
let line = "";
|
|
1401
|
-
for (const rawWord of paragraph.split(" ")) {
|
|
1402
|
-
const words = [];
|
|
1403
|
-
let word = rawWord;
|
|
1404
|
-
while (word.length > width) {
|
|
1405
|
-
words.push(word.slice(0, width));
|
|
1406
|
-
word = word.slice(width);
|
|
1407
|
-
}
|
|
1408
|
-
words.push(word);
|
|
1409
|
-
for (const word2 of words) {
|
|
1410
|
-
if (line.length === 0) {
|
|
1411
|
-
line = word2;
|
|
1412
|
-
continue;
|
|
1413
|
-
}
|
|
1414
|
-
if (`${line} ${word2}`.length <= width) {
|
|
1415
|
-
line = `${line} ${word2}`;
|
|
1416
|
-
continue;
|
|
1417
|
-
}
|
|
1418
|
-
lines.push(line);
|
|
1419
|
-
line = word2;
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
lines.push(line);
|
|
1423
|
-
}
|
|
1424
|
-
return lines;
|
|
1448
|
+
return wrapAnsi(value, Math.max(1, width), { hard: true, trim: true }).split("\n");
|
|
1425
1449
|
}
|
|
1426
1450
|
function renderRows(rows, theme, width) {
|
|
1427
1451
|
if (rows.length === 0) return [];
|
|
1428
|
-
const labelWidth = Math.max(...rows.map((row) => row.label
|
|
1452
|
+
const labelWidth = Math.max(...rows.map((row) => stringWidth(row.label)));
|
|
1429
1453
|
const valueWidth = Math.max(20, width - labelWidth - 2);
|
|
1430
1454
|
const continuation = " ".repeat(labelWidth + 2);
|
|
1431
1455
|
return rows.flatMap((row) => {
|
|
@@ -1446,12 +1470,16 @@ function renderDetailCard(options) {
|
|
|
1446
1470
|
${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).toLowerCase()).join(" \xB7 "))}` : identity;
|
|
1447
1471
|
const blocks = [hero];
|
|
1448
1472
|
for (const prose of options.prose ?? []) {
|
|
1449
|
-
blocks.push(
|
|
1473
|
+
blocks.push(
|
|
1474
|
+
prose.title ? [options.theme.header(prose.title), wrap(prose.value, width).join("\n")].join("\n") : wrap(prose.value, width).join("\n")
|
|
1475
|
+
);
|
|
1450
1476
|
}
|
|
1451
1477
|
for (const section of options.sections ?? []) {
|
|
1452
1478
|
if (section.rows.length === 0) continue;
|
|
1453
1479
|
const rows = renderRows(section.rows, options.theme, width);
|
|
1454
|
-
blocks.push(
|
|
1480
|
+
blocks.push(
|
|
1481
|
+
section.title ? [options.theme.header(section.title), ...rows].join("\n") : rows.join("\n")
|
|
1482
|
+
);
|
|
1455
1483
|
}
|
|
1456
1484
|
return blocks.join("\n\n");
|
|
1457
1485
|
}
|
|
@@ -1878,13 +1906,13 @@ import { LineCounter, parse, parseDocument } from "yaml";
|
|
|
1878
1906
|
// ../frontmatter/src/stringify.ts
|
|
1879
1907
|
import { stringify } from "yaml";
|
|
1880
1908
|
|
|
1909
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1910
|
+
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1911
|
+
|
|
1881
1912
|
// ../toolcraft-design/src/acp/writer.ts
|
|
1882
1913
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1883
1914
|
var storage = new AsyncLocalStorage2();
|
|
1884
1915
|
|
|
1885
|
-
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1886
|
-
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1887
|
-
|
|
1888
1916
|
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1889
1917
|
import readline from "node:readline";
|
|
1890
1918
|
import { PassThrough } from "node:stream";
|
|
@@ -1981,8 +2009,8 @@ function mapKey(name, char) {
|
|
|
1981
2009
|
}
|
|
1982
2010
|
|
|
1983
2011
|
// ../toolcraft-design/src/prompts/interactive/wrap.ts
|
|
1984
|
-
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1985
|
-
import
|
|
2012
|
+
import { wrapAnsi as wrapAnsi2 } from "fast-wrap-ansi";
|
|
2013
|
+
import stringWidth2 from "fast-string-width";
|
|
1986
2014
|
function getColumns(output) {
|
|
1987
2015
|
return Math.max(1, output.columns ?? 80);
|
|
1988
2016
|
}
|
|
@@ -1990,7 +2018,7 @@ function getRows(output) {
|
|
|
1990
2018
|
return Math.max(1, output.rows ?? 20);
|
|
1991
2019
|
}
|
|
1992
2020
|
function wrapFrame(output, frame) {
|
|
1993
|
-
return
|
|
2021
|
+
return wrapAnsi2(frame, getColumns(output), { hard: true, trim: false });
|
|
1994
2022
|
}
|
|
1995
2023
|
|
|
1996
2024
|
// ../toolcraft-design/src/prompts/interactive/core.ts
|
|
@@ -2311,7 +2339,7 @@ function confirmPrompt(opts) {
|
|
|
2311
2339
|
}
|
|
2312
2340
|
|
|
2313
2341
|
// ../toolcraft-design/src/prompts/interactive/pagination.ts
|
|
2314
|
-
import { wrapAnsi as
|
|
2342
|
+
import { wrapAnsi as wrapAnsi3 } from "fast-wrap-ansi";
|
|
2315
2343
|
function countLines(values) {
|
|
2316
2344
|
return values.reduce((sum, value) => sum + value.split("\n").length, 0);
|
|
2317
2345
|
}
|
|
@@ -2354,7 +2382,7 @@ function limitOptions(opts) {
|
|
|
2354
2382
|
}
|
|
2355
2383
|
const hasTopMarker = cappedVisibleCount < options.length && start > 0;
|
|
2356
2384
|
const hasBottomMarker = cappedVisibleCount < options.length && start + cappedVisibleCount < options.length;
|
|
2357
|
-
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) =>
|
|
2385
|
+
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) => wrapAnsi3(style(option, start + index === cursor2), columns, { hard: true, trim: false }));
|
|
2358
2386
|
const trimmed = trimToRows(
|
|
2359
2387
|
visible,
|
|
2360
2388
|
Math.max(cursor2 - start, 0),
|
|
@@ -2737,6 +2765,9 @@ function isOptionalSchema(schema) {
|
|
|
2737
2765
|
function getRequiredKeys(schema) {
|
|
2738
2766
|
return Object.keys(schema.shape).filter((key2) => !isOptionalSchema(schema.shape[key2])).sort();
|
|
2739
2767
|
}
|
|
2768
|
+
function getRequiredKeyFingerprint(schema) {
|
|
2769
|
+
return getRequiredKeys(schema).join("+");
|
|
2770
|
+
}
|
|
2740
2771
|
function assertUniqueRequiredKeyFingerprints(branches) {
|
|
2741
2772
|
const fingerprints = /* @__PURE__ */ new Map();
|
|
2742
2773
|
branches.forEach((branch, index) => {
|
|
@@ -2774,6 +2805,451 @@ function Union(branches) {
|
|
|
2774
2805
|
};
|
|
2775
2806
|
}
|
|
2776
2807
|
|
|
2808
|
+
// ../toolcraft-schema/src/validate.ts
|
|
2809
|
+
var missingValue = /* @__PURE__ */ Symbol("missingValue");
|
|
2810
|
+
function validate(schema, value) {
|
|
2811
|
+
const state = { issues: [] };
|
|
2812
|
+
const result = walkSchema(schema, value, [], state);
|
|
2813
|
+
if (state.issues.length > 0) {
|
|
2814
|
+
return { ok: false, issues: state.issues };
|
|
2815
|
+
}
|
|
2816
|
+
return { ok: true, value: result.present ? result.value : void 0 };
|
|
2817
|
+
}
|
|
2818
|
+
function walkSchema(schema, value, path25, state) {
|
|
2819
|
+
if (schema.kind === "optional") {
|
|
2820
|
+
return walkOptional(schema, value, path25, state);
|
|
2821
|
+
}
|
|
2822
|
+
if (value === missingValue) {
|
|
2823
|
+
addIssue(
|
|
2824
|
+
state,
|
|
2825
|
+
path25,
|
|
2826
|
+
expectedFor(schema),
|
|
2827
|
+
"missing",
|
|
2828
|
+
`Expected ${expectedFor(schema)} at ${formatPath(path25)}`
|
|
2829
|
+
);
|
|
2830
|
+
return { present: false };
|
|
2831
|
+
}
|
|
2832
|
+
if (value === null && schema.nullable === true) {
|
|
2833
|
+
return { present: true, value };
|
|
2834
|
+
}
|
|
2835
|
+
switch (schema.kind) {
|
|
2836
|
+
case "string":
|
|
2837
|
+
return walkString(schema, value, path25, state);
|
|
2838
|
+
case "number":
|
|
2839
|
+
return walkNumber(schema, value, path25, state);
|
|
2840
|
+
case "boolean":
|
|
2841
|
+
return walkBoolean(value, path25, state);
|
|
2842
|
+
case "enum":
|
|
2843
|
+
return walkEnum(schema, value, path25, state);
|
|
2844
|
+
case "array":
|
|
2845
|
+
return walkArray(schema, value, path25, state);
|
|
2846
|
+
case "object":
|
|
2847
|
+
return walkObject(schema, value, path25, state);
|
|
2848
|
+
case "oneOf":
|
|
2849
|
+
return walkOneOf(schema, value, path25, state);
|
|
2850
|
+
case "union":
|
|
2851
|
+
return walkUnion(schema, value, path25, state);
|
|
2852
|
+
case "record":
|
|
2853
|
+
return walkRecord(schema, value, path25, state);
|
|
2854
|
+
case "json":
|
|
2855
|
+
return walkJson(value, path25, state);
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
function walkOptional(schema, value, path25, state) {
|
|
2859
|
+
if (value === missingValue || value === void 0) {
|
|
2860
|
+
const defaultValue = getDefault(schema.inner);
|
|
2861
|
+
if (defaultValue.present) {
|
|
2862
|
+
return walkSchema(schema.inner, cloneDefault(defaultValue.value), path25, state);
|
|
2863
|
+
}
|
|
2864
|
+
return { present: false };
|
|
2865
|
+
}
|
|
2866
|
+
return walkSchema(schema.inner, value, path25, state);
|
|
2867
|
+
}
|
|
2868
|
+
function walkString(schema, value, path25, state) {
|
|
2869
|
+
if (typeof value !== "string") {
|
|
2870
|
+
addExpectedIssue(state, path25, "string", value);
|
|
2871
|
+
return { present: true, value };
|
|
2872
|
+
}
|
|
2873
|
+
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
2874
|
+
const expected = `string with length at least ${schema.minLength}`;
|
|
2875
|
+
addIssue(
|
|
2876
|
+
state,
|
|
2877
|
+
path25,
|
|
2878
|
+
expected,
|
|
2879
|
+
`string with length ${value.length}`,
|
|
2880
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
2884
|
+
const expected = `string with length at most ${schema.maxLength}`;
|
|
2885
|
+
addIssue(
|
|
2886
|
+
state,
|
|
2887
|
+
path25,
|
|
2888
|
+
expected,
|
|
2889
|
+
`string with length ${value.length}`,
|
|
2890
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
if (schema.pattern !== void 0) {
|
|
2894
|
+
const pattern = compilePattern(schema.pattern);
|
|
2895
|
+
if (pattern === void 0 || !pattern.test(value)) {
|
|
2896
|
+
const expected = `string matching pattern ${schema.pattern}`;
|
|
2897
|
+
addIssue(state, path25, expected, value, `Expected ${expected} at ${formatPath(path25)}`);
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
return { present: true, value };
|
|
2901
|
+
}
|
|
2902
|
+
function walkNumber(schema, value, path25, state) {
|
|
2903
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
2904
|
+
addExpectedIssue(state, path25, schema.jsonType === "integer" ? "integer" : "number", value);
|
|
2905
|
+
return { present: true, value };
|
|
2906
|
+
}
|
|
2907
|
+
if (schema.jsonType === "integer" && !Number.isInteger(value)) {
|
|
2908
|
+
addExpectedIssue(state, path25, "integer", value);
|
|
2909
|
+
}
|
|
2910
|
+
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
2911
|
+
const expected = `number greater than or equal to ${schema.minimum}`;
|
|
2912
|
+
addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
|
|
2913
|
+
}
|
|
2914
|
+
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
2915
|
+
const expected = `number less than or equal to ${schema.maximum}`;
|
|
2916
|
+
addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
|
|
2917
|
+
}
|
|
2918
|
+
return { present: true, value };
|
|
2919
|
+
}
|
|
2920
|
+
function walkBoolean(value, path25, state) {
|
|
2921
|
+
if (typeof value !== "boolean") {
|
|
2922
|
+
addExpectedIssue(state, path25, "boolean", value);
|
|
2923
|
+
}
|
|
2924
|
+
return { present: true, value };
|
|
2925
|
+
}
|
|
2926
|
+
function walkEnum(schema, value, path25, state) {
|
|
2927
|
+
if (!schema.values.includes(value)) {
|
|
2928
|
+
const expected = `one of ${schema.values.join(", ")}`;
|
|
2929
|
+
addIssue(
|
|
2930
|
+
state,
|
|
2931
|
+
path25,
|
|
2932
|
+
expected,
|
|
2933
|
+
receivedValue(value),
|
|
2934
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2935
|
+
);
|
|
2936
|
+
}
|
|
2937
|
+
return { present: true, value };
|
|
2938
|
+
}
|
|
2939
|
+
function walkArray(schema, value, path25, state) {
|
|
2940
|
+
if (!Array.isArray(value)) {
|
|
2941
|
+
addExpectedIssue(state, path25, "array", value);
|
|
2942
|
+
return { present: true, value };
|
|
2943
|
+
}
|
|
2944
|
+
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
2945
|
+
const expected = `array with at least ${schema.minItems} items`;
|
|
2946
|
+
addIssue(
|
|
2947
|
+
state,
|
|
2948
|
+
path25,
|
|
2949
|
+
expected,
|
|
2950
|
+
`array with ${value.length} items`,
|
|
2951
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2952
|
+
);
|
|
2953
|
+
}
|
|
2954
|
+
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
2955
|
+
const expected = `array with at most ${schema.maxItems} items`;
|
|
2956
|
+
addIssue(
|
|
2957
|
+
state,
|
|
2958
|
+
path25,
|
|
2959
|
+
expected,
|
|
2960
|
+
`array with ${value.length} items`,
|
|
2961
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2962
|
+
);
|
|
2963
|
+
}
|
|
2964
|
+
const nextValue = value.map((item, index) => {
|
|
2965
|
+
const result = walkSchema(schema.item, item, [...path25, String(index)], state);
|
|
2966
|
+
return result.present ? result.value : item;
|
|
2967
|
+
});
|
|
2968
|
+
return { present: true, value: nextValue };
|
|
2969
|
+
}
|
|
2970
|
+
function walkObject(schema, value, path25, state, injectedProperties = {}) {
|
|
2971
|
+
if (!isPlainRecord(value)) {
|
|
2972
|
+
addExpectedIssue(state, path25, "object", value);
|
|
2973
|
+
return { present: true, value };
|
|
2974
|
+
}
|
|
2975
|
+
const nextValue = {};
|
|
2976
|
+
const allowedKeys = /* @__PURE__ */ new Set([...Object.keys(schema.shape), ...Object.keys(injectedProperties)]);
|
|
2977
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
2978
|
+
const propertyValue = Object.hasOwn(value, key2) ? value[key2] : missingValue;
|
|
2979
|
+
const result = walkSchema(propertySchema, propertyValue, [...path25, key2], state);
|
|
2980
|
+
if (result.present) {
|
|
2981
|
+
setOwnValue(nextValue, key2, result.value);
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
for (const [key2, injectedValue] of Object.entries(injectedProperties)) {
|
|
2985
|
+
if (Object.hasOwn(value, key2)) {
|
|
2986
|
+
setOwnValue(nextValue, key2, value[key2]);
|
|
2987
|
+
} else {
|
|
2988
|
+
setOwnValue(nextValue, key2, injectedValue);
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
2992
|
+
if (allowedKeys.has(key2)) {
|
|
2993
|
+
continue;
|
|
2994
|
+
}
|
|
2995
|
+
if (schema.additionalProperties === true) {
|
|
2996
|
+
setOwnValue(nextValue, key2, propertyValue);
|
|
2997
|
+
} else {
|
|
2998
|
+
addUnexpectedPropertyIssue(state, [...path25, key2]);
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
return { present: true, value: nextValue };
|
|
3002
|
+
}
|
|
3003
|
+
function walkOneOf(schema, value, path25, state) {
|
|
3004
|
+
if (!isPlainRecord(value)) {
|
|
3005
|
+
addExpectedIssue(state, path25, "object", value);
|
|
3006
|
+
return { present: true, value };
|
|
3007
|
+
}
|
|
3008
|
+
const discriminatorValue = value[schema.discriminator];
|
|
3009
|
+
const discriminatorPath = [...path25, schema.discriminator];
|
|
3010
|
+
const branchValues = Object.keys(schema.branches);
|
|
3011
|
+
const expected = `one of ${branchValues.join(", ")}`;
|
|
3012
|
+
if (!Object.hasOwn(value, schema.discriminator)) {
|
|
3013
|
+
addIssueWithMessage(
|
|
3014
|
+
state,
|
|
3015
|
+
discriminatorPath,
|
|
3016
|
+
expected,
|
|
3017
|
+
"missing",
|
|
3018
|
+
`Missing discriminator "${schema.discriminator}" at ${formatPath(path25)}. Expected one of: ${branchValues.join(", ")}.`
|
|
3019
|
+
);
|
|
3020
|
+
return { present: true, value };
|
|
3021
|
+
}
|
|
3022
|
+
if (typeof discriminatorValue !== "string" || !Object.hasOwn(schema.branches, discriminatorValue)) {
|
|
3023
|
+
addIssueWithMessage(
|
|
3024
|
+
state,
|
|
3025
|
+
discriminatorPath,
|
|
3026
|
+
expected,
|
|
3027
|
+
receivedValue(discriminatorValue),
|
|
3028
|
+
`Expected ${expected} at ${formatPath(discriminatorPath)}, got ${formatReceivedDiscriminator(discriminatorValue)}`
|
|
3029
|
+
);
|
|
3030
|
+
return { present: true, value };
|
|
3031
|
+
}
|
|
3032
|
+
return walkObject(schema.branches[discriminatorValue], value, path25, state, {
|
|
3033
|
+
[schema.discriminator]: discriminatorValue
|
|
3034
|
+
});
|
|
3035
|
+
}
|
|
3036
|
+
function walkUnion(schema, value, path25, state) {
|
|
3037
|
+
if (isPlainRecord(value)) {
|
|
3038
|
+
const candidateBranches = schema.branches.filter((branch) => hasRequiredKeys(branch, value));
|
|
3039
|
+
if (candidateBranches.length === 1) {
|
|
3040
|
+
return walkObject(candidateBranches[0], value, path25, state);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
const matches = [];
|
|
3044
|
+
for (const branch of schema.branches) {
|
|
3045
|
+
const branchState = { issues: [] };
|
|
3046
|
+
const result = walkObject(branch, value, path25, branchState);
|
|
3047
|
+
if (branchState.issues.length === 0 && result.present) {
|
|
3048
|
+
matches.push({ fingerprint: getRequiredKeyFingerprint(branch), value: result.value });
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
if (matches.length === 1) {
|
|
3052
|
+
return { present: true, value: matches[0].value };
|
|
3053
|
+
}
|
|
3054
|
+
if (matches.length === 0) {
|
|
3055
|
+
const branchDescriptions = schema.branches.map((branch) => getRequiredKeyFingerprint(branch));
|
|
3056
|
+
addIssueWithMessage(
|
|
3057
|
+
state,
|
|
3058
|
+
path25,
|
|
3059
|
+
"exactly one union branch",
|
|
3060
|
+
"0 matching branches",
|
|
3061
|
+
`No union branch matched at ${formatPath(path25)}. Tried ${schema.branches.length} branches. Expected one of: ${branchDescriptions.join(" | ")}.`
|
|
3062
|
+
);
|
|
3063
|
+
return { present: true, value };
|
|
3064
|
+
}
|
|
3065
|
+
addIssueWithMessage(
|
|
3066
|
+
state,
|
|
3067
|
+
path25,
|
|
3068
|
+
"exactly one union branch",
|
|
3069
|
+
`${matches.length} matching branches`,
|
|
3070
|
+
`Expected exactly one union branch at ${formatPath(path25)}, but matched more than one branch: ${matches.map((match) => match.fingerprint).join(" | ")}`
|
|
3071
|
+
);
|
|
3072
|
+
return { present: true, value };
|
|
3073
|
+
}
|
|
3074
|
+
function hasRequiredKeys(schema, value) {
|
|
3075
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
3076
|
+
if (propertySchema.kind !== "optional" && !Object.hasOwn(value, key2)) {
|
|
3077
|
+
return false;
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
return true;
|
|
3081
|
+
}
|
|
3082
|
+
function walkRecord(schema, value, path25, state) {
|
|
3083
|
+
if (!isPlainRecord(value)) {
|
|
3084
|
+
addExpectedIssue(state, path25, "object", value);
|
|
3085
|
+
return { present: true, value };
|
|
3086
|
+
}
|
|
3087
|
+
const nextValue = {};
|
|
3088
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
3089
|
+
const result = walkSchema(schema.value, propertyValue, [...path25, key2], state);
|
|
3090
|
+
if (result.present) {
|
|
3091
|
+
setOwnValue(nextValue, key2, result.value);
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
return { present: true, value: nextValue };
|
|
3095
|
+
}
|
|
3096
|
+
function walkJson(value, path25, state) {
|
|
3097
|
+
if (isJsonValue(value)) {
|
|
3098
|
+
return { present: true, value };
|
|
3099
|
+
}
|
|
3100
|
+
addExpectedIssue(state, path25, "JSON value", value);
|
|
3101
|
+
return { present: true, value };
|
|
3102
|
+
}
|
|
3103
|
+
function getDefault(schema) {
|
|
3104
|
+
if (schema.default !== void 0) {
|
|
3105
|
+
return { present: true, value: schema.default };
|
|
3106
|
+
}
|
|
3107
|
+
if (schema.kind === "optional") {
|
|
3108
|
+
return getDefault(schema.inner);
|
|
3109
|
+
}
|
|
3110
|
+
return { present: false };
|
|
3111
|
+
}
|
|
3112
|
+
function isPlainRecord(value) {
|
|
3113
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3114
|
+
return false;
|
|
3115
|
+
}
|
|
3116
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3117
|
+
return prototype === Object.prototype || prototype === null;
|
|
3118
|
+
}
|
|
3119
|
+
function isJsonValue(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3120
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3121
|
+
return typeof value !== "number" || Number.isFinite(value);
|
|
3122
|
+
}
|
|
3123
|
+
if (Array.isArray(value)) {
|
|
3124
|
+
if (ancestors.has(value)) {
|
|
3125
|
+
return false;
|
|
3126
|
+
}
|
|
3127
|
+
ancestors.add(value);
|
|
3128
|
+
const result = value.every((item) => isJsonValue(item, ancestors));
|
|
3129
|
+
ancestors.delete(value);
|
|
3130
|
+
return result;
|
|
3131
|
+
}
|
|
3132
|
+
if (isPlainRecord(value)) {
|
|
3133
|
+
if (ancestors.has(value)) {
|
|
3134
|
+
return false;
|
|
3135
|
+
}
|
|
3136
|
+
ancestors.add(value);
|
|
3137
|
+
const result = Object.values(value).every((item) => isJsonValue(item, ancestors));
|
|
3138
|
+
ancestors.delete(value);
|
|
3139
|
+
return result;
|
|
3140
|
+
}
|
|
3141
|
+
return false;
|
|
3142
|
+
}
|
|
3143
|
+
function cloneDefault(value) {
|
|
3144
|
+
return structuredClone(value);
|
|
3145
|
+
}
|
|
3146
|
+
function setOwnValue(target, key2, value) {
|
|
3147
|
+
Object.defineProperty(target, key2, {
|
|
3148
|
+
configurable: true,
|
|
3149
|
+
enumerable: true,
|
|
3150
|
+
writable: true,
|
|
3151
|
+
value
|
|
3152
|
+
});
|
|
3153
|
+
}
|
|
3154
|
+
function expectedFor(schema) {
|
|
3155
|
+
switch (schema.kind) {
|
|
3156
|
+
case "string":
|
|
3157
|
+
return "string";
|
|
3158
|
+
case "number":
|
|
3159
|
+
return schema.jsonType === "integer" ? "integer" : "number";
|
|
3160
|
+
case "boolean":
|
|
3161
|
+
return "boolean";
|
|
3162
|
+
case "enum":
|
|
3163
|
+
return `one of ${schema.values.join(", ")}`;
|
|
3164
|
+
case "array":
|
|
3165
|
+
return "array";
|
|
3166
|
+
case "object":
|
|
3167
|
+
case "oneOf":
|
|
3168
|
+
case "record":
|
|
3169
|
+
return "object";
|
|
3170
|
+
case "union":
|
|
3171
|
+
return "exactly one union branch";
|
|
3172
|
+
case "json":
|
|
3173
|
+
return "JSON value";
|
|
3174
|
+
case "optional":
|
|
3175
|
+
return expectedFor(schema.inner);
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
function addExpectedIssue(state, path25, expected, value) {
|
|
3179
|
+
addIssue(
|
|
3180
|
+
state,
|
|
3181
|
+
path25,
|
|
3182
|
+
expected,
|
|
3183
|
+
receivedType(value),
|
|
3184
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
function addUnexpectedPropertyIssue(state, path25) {
|
|
3188
|
+
addIssue(
|
|
3189
|
+
state,
|
|
3190
|
+
path25,
|
|
3191
|
+
"no additional properties",
|
|
3192
|
+
"unknown property",
|
|
3193
|
+
`Unexpected property ${formatPath(path25)}`
|
|
3194
|
+
);
|
|
3195
|
+
}
|
|
3196
|
+
function addIssue(state, path25, expected, received, _message) {
|
|
3197
|
+
state.issues.push({
|
|
3198
|
+
path: path25,
|
|
3199
|
+
expected,
|
|
3200
|
+
received,
|
|
3201
|
+
message: formatIssueMessage(expected, path25, received)
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
function addIssueWithMessage(state, path25, expected, received, message2) {
|
|
3205
|
+
state.issues.push({
|
|
3206
|
+
path: path25,
|
|
3207
|
+
expected,
|
|
3208
|
+
received,
|
|
3209
|
+
message: message2
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
function formatIssueMessage(expected, path25, received) {
|
|
3213
|
+
return `Expected ${expected} at ${formatPath(path25)}, got ${received}`;
|
|
3214
|
+
}
|
|
3215
|
+
function formatPath(path25) {
|
|
3216
|
+
return path25.length === 0 ? "value" : path25.join(".");
|
|
3217
|
+
}
|
|
3218
|
+
function compilePattern(pattern) {
|
|
3219
|
+
try {
|
|
3220
|
+
return new RegExp(pattern);
|
|
3221
|
+
} catch {
|
|
3222
|
+
return void 0;
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
function receivedType(value) {
|
|
3226
|
+
if (value === null) {
|
|
3227
|
+
return "null";
|
|
3228
|
+
}
|
|
3229
|
+
if (Array.isArray(value)) {
|
|
3230
|
+
return "array";
|
|
3231
|
+
}
|
|
3232
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
3233
|
+
return "integer";
|
|
3234
|
+
}
|
|
3235
|
+
return typeof value;
|
|
3236
|
+
}
|
|
3237
|
+
function receivedValue(value) {
|
|
3238
|
+
if (typeof value === "string") {
|
|
3239
|
+
return value;
|
|
3240
|
+
}
|
|
3241
|
+
if (value === void 0) {
|
|
3242
|
+
return "undefined";
|
|
3243
|
+
}
|
|
3244
|
+
return String(value);
|
|
3245
|
+
}
|
|
3246
|
+
function formatReceivedDiscriminator(value) {
|
|
3247
|
+
if (typeof value === "string") {
|
|
3248
|
+
return JSON.stringify(value);
|
|
3249
|
+
}
|
|
3250
|
+
return receivedValue(value);
|
|
3251
|
+
}
|
|
3252
|
+
|
|
2777
3253
|
// ../toolcraft-schema/src/index.ts
|
|
2778
3254
|
function assertValidEnumValues(values) {
|
|
2779
3255
|
if (values.length === 0) {
|
|
@@ -2797,6 +3273,22 @@ function assertFiniteNumber(value, name) {
|
|
|
2797
3273
|
throw new Error(`${name} must be finite`);
|
|
2798
3274
|
}
|
|
2799
3275
|
}
|
|
3276
|
+
function assertMinMaxOrder(minimum, maximum, minimumName, maximumName) {
|
|
3277
|
+
if (minimum !== void 0 && maximum !== void 0 && minimum > maximum) {
|
|
3278
|
+
throw new Error(`${minimumName} must be less than or equal to ${maximumName}`);
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
function assertValidDefault(schema) {
|
|
3282
|
+
if (schema.default === void 0) {
|
|
3283
|
+
return;
|
|
3284
|
+
}
|
|
3285
|
+
const result = validate(schema, schema.default);
|
|
3286
|
+
if (!result.ok) {
|
|
3287
|
+
throw new Error(
|
|
3288
|
+
`default must satisfy schema: ${result.issues[0]?.message ?? "invalid default"}`
|
|
3289
|
+
);
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
2800
3292
|
function assertPattern(pattern) {
|
|
2801
3293
|
if (pattern === void 0) {
|
|
2802
3294
|
return;
|
|
@@ -2811,56 +3303,71 @@ var S = {
|
|
|
2811
3303
|
String(options = {}) {
|
|
2812
3304
|
assertNonNegativeInteger(options.minLength, "minLength");
|
|
2813
3305
|
assertNonNegativeInteger(options.maxLength, "maxLength");
|
|
3306
|
+
assertMinMaxOrder(options.minLength, options.maxLength, "minLength", "maxLength");
|
|
2814
3307
|
assertPattern(options.pattern);
|
|
2815
|
-
|
|
3308
|
+
const schema = {
|
|
2816
3309
|
kind: "string",
|
|
2817
3310
|
...options
|
|
2818
3311
|
};
|
|
3312
|
+
assertValidDefault(schema);
|
|
3313
|
+
return schema;
|
|
2819
3314
|
},
|
|
2820
3315
|
Number(options = {}) {
|
|
2821
3316
|
assertFiniteNumber(options.minimum, "minimum");
|
|
2822
3317
|
assertFiniteNumber(options.maximum, "maximum");
|
|
3318
|
+
assertMinMaxOrder(options.minimum, options.maximum, "minimum", "maximum");
|
|
2823
3319
|
assertFiniteNumber(options.default, "default");
|
|
2824
3320
|
if (options.jsonType === "integer" && options.default !== void 0 && !Number.isInteger(options.default)) {
|
|
2825
3321
|
throw new Error("default must be an integer");
|
|
2826
3322
|
}
|
|
2827
|
-
|
|
3323
|
+
const schema = {
|
|
2828
3324
|
kind: "number",
|
|
2829
3325
|
...options
|
|
2830
3326
|
};
|
|
3327
|
+
assertValidDefault(schema);
|
|
3328
|
+
return schema;
|
|
2831
3329
|
},
|
|
2832
3330
|
Boolean(options = {}) {
|
|
2833
|
-
|
|
3331
|
+
const schema = {
|
|
2834
3332
|
kind: "boolean",
|
|
2835
3333
|
...options
|
|
2836
3334
|
};
|
|
3335
|
+
assertValidDefault(schema);
|
|
3336
|
+
return schema;
|
|
2837
3337
|
},
|
|
2838
3338
|
Enum(values, options = {}) {
|
|
2839
3339
|
assertValidEnumValues(values);
|
|
2840
3340
|
if (options.jsonType === "integer" && values.some((value) => typeof value !== "number" || !Number.isInteger(value))) {
|
|
2841
3341
|
throw new Error("Integer enum values must be integers");
|
|
2842
3342
|
}
|
|
2843
|
-
|
|
3343
|
+
const schema = {
|
|
2844
3344
|
kind: "enum",
|
|
2845
3345
|
values,
|
|
2846
3346
|
...options
|
|
2847
3347
|
};
|
|
3348
|
+
assertValidDefault(schema);
|
|
3349
|
+
return schema;
|
|
2848
3350
|
},
|
|
2849
3351
|
Array(item, options = {}) {
|
|
2850
3352
|
assertNonNegativeInteger(options.minItems, "minItems");
|
|
2851
3353
|
assertNonNegativeInteger(options.maxItems, "maxItems");
|
|
2852
|
-
|
|
3354
|
+
assertMinMaxOrder(options.minItems, options.maxItems, "minItems", "maxItems");
|
|
3355
|
+
const schema = {
|
|
2853
3356
|
kind: "array",
|
|
2854
3357
|
item,
|
|
2855
3358
|
...options
|
|
2856
3359
|
};
|
|
3360
|
+
assertValidDefault(schema);
|
|
3361
|
+
return schema;
|
|
2857
3362
|
},
|
|
2858
3363
|
Object(shape, options = {}) {
|
|
2859
|
-
|
|
3364
|
+
const schema = {
|
|
2860
3365
|
kind: "object",
|
|
2861
3366
|
shape,
|
|
2862
3367
|
...options
|
|
2863
3368
|
};
|
|
3369
|
+
assertValidDefault(schema);
|
|
3370
|
+
return schema;
|
|
2864
3371
|
},
|
|
2865
3372
|
Optional(inner) {
|
|
2866
3373
|
return {
|
|
@@ -3432,6 +3939,9 @@ function isRecord(value) {
|
|
|
3432
3939
|
function isStateList(value) {
|
|
3433
3940
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
3434
3941
|
}
|
|
3942
|
+
function hasVisibleName(value) {
|
|
3943
|
+
return value.trim().length > 0;
|
|
3944
|
+
}
|
|
3435
3945
|
function canFireFromState(event, fromState) {
|
|
3436
3946
|
if (event.from === "*") {
|
|
3437
3947
|
return event.to !== fromState;
|
|
@@ -3446,6 +3956,9 @@ function validateMachine(machine) {
|
|
|
3446
3956
|
throw new TypeError("State machine states must be a string array.");
|
|
3447
3957
|
}
|
|
3448
3958
|
const states = new Set(machine.states);
|
|
3959
|
+
if (machine.states.some((state) => !hasVisibleName(state))) {
|
|
3960
|
+
throw new Error("State names must not be empty.");
|
|
3961
|
+
}
|
|
3449
3962
|
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
3450
3963
|
throw new TypeError("State machine initial must be a string.");
|
|
3451
3964
|
}
|
|
@@ -3456,6 +3969,9 @@ function validateMachine(machine) {
|
|
|
3456
3969
|
throw new TypeError("State machine events must be an object.");
|
|
3457
3970
|
}
|
|
3458
3971
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
3972
|
+
if (!hasVisibleName(eventName)) {
|
|
3973
|
+
throw new Error("Event names must not be empty.");
|
|
3974
|
+
}
|
|
3459
3975
|
if (!isRecord(event)) {
|
|
3460
3976
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
3461
3977
|
}
|
|
@@ -3565,6 +4081,13 @@ import { text as text3 } from "node:stream/consumers";
|
|
|
3565
4081
|
// ../process-runner/src/docker/context.ts
|
|
3566
4082
|
import { execSync } from "node:child_process";
|
|
3567
4083
|
|
|
4084
|
+
// ../process-runner/src/docker/build-context.ts
|
|
4085
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
4086
|
+
import { createRequire } from "node:module";
|
|
4087
|
+
import path2 from "node:path";
|
|
4088
|
+
var require2 = createRequire(import.meta.url);
|
|
4089
|
+
var createIgnore = require2("ignore");
|
|
4090
|
+
|
|
3568
4091
|
// ../process-runner/src/docker/engine.ts
|
|
3569
4092
|
import { execSync as execSync2 } from "node:child_process";
|
|
3570
4093
|
|
|
@@ -3573,19 +4096,19 @@ import * as childProcess from "node:child_process";
|
|
|
3573
4096
|
import { randomBytes } from "node:crypto";
|
|
3574
4097
|
|
|
3575
4098
|
// ../process-runner/src/docker/args.ts
|
|
3576
|
-
import
|
|
4099
|
+
import path3 from "node:path";
|
|
3577
4100
|
|
|
3578
4101
|
// ../process-runner/src/docker/env-file.ts
|
|
3579
4102
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3580
4103
|
import { tmpdir } from "node:os";
|
|
3581
|
-
import
|
|
4104
|
+
import path4 from "node:path";
|
|
3582
4105
|
|
|
3583
4106
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
3584
4107
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
3585
4108
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
3586
|
-
import {
|
|
4109
|
+
import { readFile as readFile2, realpath, writeFile } from "node:fs/promises";
|
|
3587
4110
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
3588
|
-
import
|
|
4111
|
+
import path6 from "node:path";
|
|
3589
4112
|
|
|
3590
4113
|
// ../process-runner/src/host/host-runner.ts
|
|
3591
4114
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
@@ -3718,7 +4241,7 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
3718
4241
|
// ../process-runner/src/workspace-transfer.ts
|
|
3719
4242
|
import { createHash, randomUUID } from "node:crypto";
|
|
3720
4243
|
import { promises as nodeFs } from "node:fs";
|
|
3721
|
-
import
|
|
4244
|
+
import path5 from "node:path";
|
|
3722
4245
|
|
|
3723
4246
|
// ../process-runner/src/testing/mock-runner.ts
|
|
3724
4247
|
import { Readable, Writable } from "node:stream";
|
|
@@ -3790,7 +4313,7 @@ function resolveEndpoint(options = {}) {
|
|
|
3790
4313
|
|
|
3791
4314
|
// ../task-list/src/backends/utils.ts
|
|
3792
4315
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3793
|
-
import
|
|
4316
|
+
import path7 from "node:path";
|
|
3794
4317
|
function compareCreated(left, right) {
|
|
3795
4318
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
3796
4319
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -3822,15 +4345,33 @@ function sortStrings(values) {
|
|
|
3822
4345
|
function sortTasks(tasks) {
|
|
3823
4346
|
return [...tasks].sort((left, right) => left.qualifiedId.localeCompare(right.qualifiedId));
|
|
3824
4347
|
}
|
|
4348
|
+
function isTrimmedPrintableIdentifier(value) {
|
|
4349
|
+
if (value.length === 0 || value !== value.trim()) {
|
|
4350
|
+
return false;
|
|
4351
|
+
}
|
|
4352
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4353
|
+
const code = value.charCodeAt(index);
|
|
4354
|
+
if (code < 32 || code === 127) {
|
|
4355
|
+
return false;
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
return true;
|
|
4359
|
+
}
|
|
3825
4360
|
function validateTaskId(id) {
|
|
3826
|
-
if (id
|
|
4361
|
+
if (!isTrimmedPrintableIdentifier(id) || id.startsWith(".") || id.includes("/") || id.includes("\\") || id.includes("..")) {
|
|
3827
4362
|
throw new Error(`Invalid task id "${id}".`);
|
|
3828
4363
|
}
|
|
3829
4364
|
return id;
|
|
3830
4365
|
}
|
|
3831
|
-
|
|
4366
|
+
function validateTaskName(name) {
|
|
4367
|
+
if (name.trim().length === 0) {
|
|
4368
|
+
throw new Error("Task name must not be empty.");
|
|
4369
|
+
}
|
|
4370
|
+
return name;
|
|
4371
|
+
}
|
|
4372
|
+
async function statIfExists(fs5, filePath) {
|
|
3832
4373
|
try {
|
|
3833
|
-
return await
|
|
4374
|
+
return await fs5.stat(filePath);
|
|
3834
4375
|
} catch (error3) {
|
|
3835
4376
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3836
4377
|
return void 0;
|
|
@@ -3838,15 +4379,18 @@ async function statIfExists(fs4, filePath) {
|
|
|
3838
4379
|
throw error3;
|
|
3839
4380
|
}
|
|
3840
4381
|
}
|
|
3841
|
-
async function rejectSymbolicLinkComponents(
|
|
3842
|
-
const resolvedPath =
|
|
3843
|
-
const rootPath =
|
|
3844
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
4382
|
+
async function rejectSymbolicLinkComponents(fs5, filePath) {
|
|
4383
|
+
const resolvedPath = path7.resolve(filePath);
|
|
4384
|
+
const rootPath = path7.parse(resolvedPath).root;
|
|
4385
|
+
const components = resolvedPath.slice(rootPath.length).split(path7.sep).filter(Boolean);
|
|
3845
4386
|
let currentPath = rootPath;
|
|
3846
4387
|
for (const component of components) {
|
|
3847
|
-
currentPath =
|
|
4388
|
+
currentPath = path7.join(currentPath, component);
|
|
3848
4389
|
try {
|
|
3849
|
-
if ((await
|
|
4390
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
4391
|
+
if (currentPath === "/tmp") {
|
|
4392
|
+
continue;
|
|
4393
|
+
}
|
|
3850
4394
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
3851
4395
|
}
|
|
3852
4396
|
} catch (error3) {
|
|
@@ -3857,19 +4401,19 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
3857
4401
|
}
|
|
3858
4402
|
}
|
|
3859
4403
|
}
|
|
3860
|
-
async function writeAtomically(
|
|
4404
|
+
async function writeAtomically(fs5, filePath, content) {
|
|
3861
4405
|
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3862
4406
|
let tempCreated = false;
|
|
3863
|
-
await
|
|
4407
|
+
await fs5.mkdir(path7.dirname(filePath), { recursive: true });
|
|
3864
4408
|
try {
|
|
3865
|
-
await
|
|
4409
|
+
await fs5.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3866
4410
|
tempCreated = true;
|
|
3867
|
-
await
|
|
4411
|
+
await fs5.rename(tempPath, filePath);
|
|
3868
4412
|
tempCreated = false;
|
|
3869
4413
|
} catch (error3) {
|
|
3870
4414
|
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3871
4415
|
try {
|
|
3872
|
-
await
|
|
4416
|
+
await fs5.unlink(tempPath);
|
|
3873
4417
|
} catch (unlinkError) {
|
|
3874
4418
|
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3875
4419
|
throw unlinkError;
|
|
@@ -3879,18 +4423,18 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
3879
4423
|
throw error3;
|
|
3880
4424
|
}
|
|
3881
4425
|
}
|
|
3882
|
-
async function withFileLock(
|
|
3883
|
-
await
|
|
4426
|
+
async function withFileLock(fs5, lockPath, operation) {
|
|
4427
|
+
await fs5.mkdir(path7.dirname(lockPath), { recursive: true });
|
|
3884
4428
|
for (; ; ) {
|
|
3885
4429
|
try {
|
|
3886
|
-
await
|
|
4430
|
+
await fs5.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
3887
4431
|
break;
|
|
3888
4432
|
} catch (error3) {
|
|
3889
4433
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3890
|
-
await
|
|
4434
|
+
await fs5.unlink(lockPath).catch(() => void 0);
|
|
3891
4435
|
throw error3;
|
|
3892
4436
|
}
|
|
3893
|
-
if (await removeAbandonedLock(
|
|
4437
|
+
if (await removeAbandonedLock(fs5, lockPath)) {
|
|
3894
4438
|
continue;
|
|
3895
4439
|
}
|
|
3896
4440
|
await Promise.resolve();
|
|
@@ -3899,13 +4443,13 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3899
4443
|
try {
|
|
3900
4444
|
return await operation();
|
|
3901
4445
|
} finally {
|
|
3902
|
-
await
|
|
4446
|
+
await fs5.unlink(lockPath);
|
|
3903
4447
|
}
|
|
3904
4448
|
}
|
|
3905
|
-
async function removeAbandonedLock(
|
|
4449
|
+
async function removeAbandonedLock(fs5, lockPath) {
|
|
3906
4450
|
let content;
|
|
3907
4451
|
try {
|
|
3908
|
-
content = await
|
|
4452
|
+
content = await fs5.readFile(lockPath, "utf8");
|
|
3909
4453
|
} catch (error3) {
|
|
3910
4454
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3911
4455
|
return true;
|
|
@@ -3913,11 +4457,11 @@ async function removeAbandonedLock(fs4, lockPath) {
|
|
|
3913
4457
|
throw error3;
|
|
3914
4458
|
}
|
|
3915
4459
|
const owner = Number(content);
|
|
3916
|
-
if (
|
|
4460
|
+
if (Number.isInteger(owner) && owner > 0 && isProcessRunning(owner)) {
|
|
3917
4461
|
return false;
|
|
3918
4462
|
}
|
|
3919
4463
|
try {
|
|
3920
|
-
await
|
|
4464
|
+
await fs5.unlink(lockPath);
|
|
3921
4465
|
return true;
|
|
3922
4466
|
} catch (error3) {
|
|
3923
4467
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
@@ -4185,6 +4729,9 @@ async function ghIssuesBackend(deps) {
|
|
|
4185
4729
|
if (deps.state?.labelPrefix === "") {
|
|
4186
4730
|
throw new Error("gh-issues state.labelPrefix must be a non-empty string when configured.");
|
|
4187
4731
|
}
|
|
4732
|
+
if (deps.stateMachine !== void 0) {
|
|
4733
|
+
validateMachine(deps.stateMachine);
|
|
4734
|
+
}
|
|
4188
4735
|
const client = createGhClient({
|
|
4189
4736
|
token: deps.token,
|
|
4190
4737
|
endpoint: deps.endpoint,
|
|
@@ -4344,7 +4891,9 @@ function createTasksView(name, session, context) {
|
|
|
4344
4891
|
);
|
|
4345
4892
|
projectItemId = added.addProjectV2ItemById?.item?.id ?? void 0;
|
|
4346
4893
|
if (projectItemId === void 0) {
|
|
4347
|
-
throw new Error(
|
|
4894
|
+
throw new Error(
|
|
4895
|
+
"GitHub addProjectV2ItemById response did not include project item id."
|
|
4896
|
+
);
|
|
4348
4897
|
}
|
|
4349
4898
|
}
|
|
4350
4899
|
if (session.labelPrefix === void 0) {
|
|
@@ -4573,12 +5122,15 @@ async function resolveProjectItemId(id, listName, session, context) {
|
|
|
4573
5122
|
const issueNumber = parseIssueNumber(id, listName);
|
|
4574
5123
|
let after;
|
|
4575
5124
|
while (true) {
|
|
4576
|
-
const result = await context.client.graphql(
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
5125
|
+
const result = await context.client.graphql(
|
|
5126
|
+
ISSUE_STATE_LABELS_QUERY,
|
|
5127
|
+
{
|
|
5128
|
+
owner: context.repoOwner,
|
|
5129
|
+
repo: context.repoName,
|
|
5130
|
+
number: issueNumber,
|
|
5131
|
+
after
|
|
5132
|
+
}
|
|
5133
|
+
);
|
|
4582
5134
|
const issue = result.repository?.issue ?? null;
|
|
4583
5135
|
if (issue === null) {
|
|
4584
5136
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
@@ -4855,12 +5407,27 @@ async function fetchIssueTask(id, listName, session, context) {
|
|
|
4855
5407
|
});
|
|
4856
5408
|
}
|
|
4857
5409
|
function parseIssueNumber(id, listName) {
|
|
5410
|
+
if (!isCanonicalDecimalIssueId(id)) {
|
|
5411
|
+
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
5412
|
+
}
|
|
4858
5413
|
const issueNumber = Number(id);
|
|
4859
|
-
if (!Number.
|
|
5414
|
+
if (!Number.isSafeInteger(issueNumber) || issueNumber < 1) {
|
|
4860
5415
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
4861
5416
|
}
|
|
4862
5417
|
return issueNumber;
|
|
4863
5418
|
}
|
|
5419
|
+
function isCanonicalDecimalIssueId(id) {
|
|
5420
|
+
if (id.length === 0 || id[0] === "0") {
|
|
5421
|
+
return false;
|
|
5422
|
+
}
|
|
5423
|
+
for (let index = 0; index < id.length; index += 1) {
|
|
5424
|
+
const charCode = id.charCodeAt(index);
|
|
5425
|
+
if (charCode < 48 || charCode > 57) {
|
|
5426
|
+
return false;
|
|
5427
|
+
}
|
|
5428
|
+
}
|
|
5429
|
+
return true;
|
|
5430
|
+
}
|
|
4864
5431
|
function mapProjectItemToTask(item, listName, session) {
|
|
4865
5432
|
const content = item.content;
|
|
4866
5433
|
if (!isIssueNode(content)) {
|
|
@@ -4968,7 +5535,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
4968
5535
|
}
|
|
4969
5536
|
|
|
4970
5537
|
// ../task-list/src/backends/markdown-dir.ts
|
|
4971
|
-
import
|
|
5538
|
+
import path8 from "node:path";
|
|
4972
5539
|
import { parseDocument as parseDocument2, stringify as stringify2 } from "yaml";
|
|
4973
5540
|
|
|
4974
5541
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -5071,7 +5638,7 @@ function resolveListLayout(deps) {
|
|
|
5071
5638
|
return deps.singleList ? { kind: "single", name: deps.singleList } : { kind: "multi" };
|
|
5072
5639
|
}
|
|
5073
5640
|
function validateListName(name) {
|
|
5074
|
-
if (name
|
|
5641
|
+
if (!isTrimmedPrintableIdentifier(name) || name === ARCHIVE_DIRECTORY_NAME || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
5075
5642
|
throw new Error(`Invalid task list name "${name}".`);
|
|
5076
5643
|
}
|
|
5077
5644
|
return name;
|
|
@@ -5087,16 +5654,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
5087
5654
|
};
|
|
5088
5655
|
}
|
|
5089
5656
|
function listPath(rootPath, layout, list) {
|
|
5090
|
-
return layout.kind === "single" ? rootPath :
|
|
5657
|
+
return layout.kind === "single" ? rootPath : path8.join(rootPath, list);
|
|
5091
5658
|
}
|
|
5092
5659
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
5093
|
-
return layout.kind === "single" ?
|
|
5660
|
+
return layout.kind === "single" ? path8.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path8.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
5094
5661
|
}
|
|
5095
5662
|
function activeTaskFilename(id, order, width) {
|
|
5096
5663
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
5097
5664
|
}
|
|
5098
5665
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
5099
|
-
return
|
|
5666
|
+
return path8.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
5100
5667
|
}
|
|
5101
5668
|
function isMarkdownFile(entryName) {
|
|
5102
5669
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -5198,7 +5765,7 @@ function hasOwnTaskField(frontmatter, key2) {
|
|
|
5198
5765
|
function reservedFrontmatterKeys(mode) {
|
|
5199
5766
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
5200
5767
|
}
|
|
5201
|
-
function
|
|
5768
|
+
function setOwnValue2(record, key2, value) {
|
|
5202
5769
|
Object.defineProperty(record, key2, {
|
|
5203
5770
|
value,
|
|
5204
5771
|
enumerable: true,
|
|
@@ -5211,7 +5778,7 @@ function metadataFromFrontmatter(frontmatter, mode) {
|
|
|
5211
5778
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5212
5779
|
for (const [key2, value] of Object.entries(frontmatter)) {
|
|
5213
5780
|
if (!reservedKeys.has(key2)) {
|
|
5214
|
-
|
|
5781
|
+
setOwnValue2(metadata, key2, value);
|
|
5215
5782
|
}
|
|
5216
5783
|
}
|
|
5217
5784
|
return metadata;
|
|
@@ -5225,7 +5792,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
5225
5792
|
state: frontmatter.state,
|
|
5226
5793
|
description: body,
|
|
5227
5794
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
5228
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5795
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5229
5796
|
};
|
|
5230
5797
|
}
|
|
5231
5798
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -5234,9 +5801,9 @@ ${stringify2(frontmatter)}---
|
|
|
5234
5801
|
|
|
5235
5802
|
${description}`;
|
|
5236
5803
|
}
|
|
5237
|
-
async function readDirectoryNames(
|
|
5804
|
+
async function readDirectoryNames(fs5, directoryPath) {
|
|
5238
5805
|
try {
|
|
5239
|
-
return sortStrings(await
|
|
5806
|
+
return sortStrings(await fs5.readdir(directoryPath));
|
|
5240
5807
|
} catch (error3) {
|
|
5241
5808
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
5242
5809
|
return [];
|
|
@@ -5252,9 +5819,9 @@ async function ensureRootPath(deps) {
|
|
|
5252
5819
|
}
|
|
5253
5820
|
await deps.fs.stat(deps.path);
|
|
5254
5821
|
}
|
|
5255
|
-
async function readTaskFile(
|
|
5256
|
-
await rejectSymbolicLinkComponents(
|
|
5257
|
-
const content = await
|
|
5822
|
+
async function readTaskFile(fs5, list, id, filePath, validStates, initialState, mode) {
|
|
5823
|
+
await rejectSymbolicLinkComponents(fs5, filePath);
|
|
5824
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5258
5825
|
const document = splitTaskDocument(content, filePath, mode);
|
|
5259
5826
|
const frontmatter = mode === "passthrough" && document.frontmatter.trim().length === 0 ? {} : readFrontmatter(document.frontmatter, filePath);
|
|
5260
5827
|
if (mode !== "passthrough") {
|
|
@@ -5265,57 +5832,106 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
5265
5832
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
5266
5833
|
};
|
|
5267
5834
|
}
|
|
5268
|
-
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
5269
|
-
const defaultName = parsedFilename?.id ?? id;
|
|
5270
5835
|
const effectiveFrontmatter = {
|
|
5271
5836
|
...frontmatter,
|
|
5272
|
-
name: typeof frontmatter.name === "string" ? frontmatter.name :
|
|
5837
|
+
name: typeof frontmatter.name === "string" ? frontmatter.name : id,
|
|
5273
5838
|
state: typeof frontmatter.state === "string" && validStates.has(frontmatter.state) ? frontmatter.state : initialState
|
|
5274
5839
|
};
|
|
5275
5840
|
return {
|
|
5276
|
-
path: filePath,
|
|
5277
|
-
frontmatter,
|
|
5278
|
-
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5841
|
+
path: filePath,
|
|
5842
|
+
frontmatter,
|
|
5843
|
+
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5844
|
+
};
|
|
5845
|
+
}
|
|
5846
|
+
async function readPassthroughFrontmatter(fs5, filePath, mode) {
|
|
5847
|
+
if (mode !== "passthrough") {
|
|
5848
|
+
return {};
|
|
5849
|
+
}
|
|
5850
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5851
|
+
const document = splitTaskDocument(content, filePath, mode);
|
|
5852
|
+
if (document.frontmatter.trim().length === 0) {
|
|
5853
|
+
return {};
|
|
5854
|
+
}
|
|
5855
|
+
return readFrontmatter(document.frontmatter, filePath);
|
|
5856
|
+
}
|
|
5857
|
+
async function resolveActiveFilenameEntry(fs5, entryName, entryPath, parsed, mode) {
|
|
5858
|
+
if (mode !== "passthrough" || parsed.order === null) {
|
|
5859
|
+
return parsed;
|
|
5860
|
+
}
|
|
5861
|
+
const frontmatter = await readPassthroughFrontmatter(fs5, entryPath, mode);
|
|
5862
|
+
if (Object.keys(frontmatter).length === 0 && orderedFilenamePrefixLength(entryName) <= MIN_PREFIX_WIDTH) {
|
|
5863
|
+
return parsed;
|
|
5864
|
+
}
|
|
5865
|
+
if (typeof frontmatter.state === "string" || hasOwnTaskField(frontmatter, "$schema") || hasOwnTaskField(frontmatter, "kind") || hasOwnTaskField(frontmatter, "version")) {
|
|
5866
|
+
return parsed;
|
|
5867
|
+
}
|
|
5868
|
+
return {
|
|
5869
|
+
id: entryName.slice(0, -MARKDOWN_EXTENSION.length),
|
|
5870
|
+
order: null,
|
|
5871
|
+
filename: parsed.filename
|
|
5279
5872
|
};
|
|
5280
5873
|
}
|
|
5281
|
-
|
|
5282
|
-
const
|
|
5874
|
+
function orderedFilenamePrefixLength(entryName) {
|
|
5875
|
+
const stem = entryName.slice(0, -MARKDOWN_EXTENSION.length);
|
|
5876
|
+
const separatorIndex = stem.indexOf("-");
|
|
5877
|
+
if (separatorIndex <= 0) {
|
|
5878
|
+
return Number.POSITIVE_INFINITY;
|
|
5879
|
+
}
|
|
5880
|
+
for (let index = 0; index < separatorIndex; index += 1) {
|
|
5881
|
+
const code = stem.charCodeAt(index);
|
|
5882
|
+
if (code < 48 || code > 57) {
|
|
5883
|
+
return Number.POSITIVE_INFINITY;
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
return separatorIndex;
|
|
5887
|
+
}
|
|
5888
|
+
async function findActiveTaskFilename(fs5, listDirectoryPath, id, mode) {
|
|
5889
|
+
const entries = await readDirectoryNames(fs5, listDirectoryPath);
|
|
5283
5890
|
for (const entryName of entries) {
|
|
5284
5891
|
if (isHiddenEntry(entryName)) continue;
|
|
5285
5892
|
const parsed = parseActiveFilename(entryName);
|
|
5286
|
-
if (parsed
|
|
5893
|
+
if (!parsed) continue;
|
|
5894
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5895
|
+
const resolved = await resolveActiveFilenameEntry(
|
|
5896
|
+
fs5,
|
|
5897
|
+
entryName,
|
|
5898
|
+
entryPath,
|
|
5899
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
5900
|
+
mode
|
|
5901
|
+
);
|
|
5902
|
+
if (resolved.id === id) {
|
|
5287
5903
|
return entryName;
|
|
5288
5904
|
}
|
|
5289
5905
|
}
|
|
5290
5906
|
return void 0;
|
|
5291
5907
|
}
|
|
5292
|
-
async function findTaskLocation(
|
|
5908
|
+
async function findTaskLocation(fs5, rootPath, layout, list, id, mode) {
|
|
5293
5909
|
const listDirectoryPath = listPath(rootPath, layout, list);
|
|
5294
|
-
await rejectSymbolicLinkComponents(
|
|
5295
|
-
const activeName = await findActiveTaskFilename(
|
|
5910
|
+
await rejectSymbolicLinkComponents(fs5, listDirectoryPath);
|
|
5911
|
+
const activeName = await findActiveTaskFilename(fs5, listDirectoryPath, id, mode);
|
|
5296
5912
|
if (activeName) {
|
|
5297
|
-
const activePath =
|
|
5298
|
-
await rejectSymbolicLinkComponents(
|
|
5299
|
-
const activeStat = await statIfExists(
|
|
5913
|
+
const activePath = path8.join(listDirectoryPath, activeName);
|
|
5914
|
+
await rejectSymbolicLinkComponents(fs5, activePath);
|
|
5915
|
+
const activeStat = await statIfExists(fs5, activePath);
|
|
5300
5916
|
if (activeStat?.isFile()) {
|
|
5301
5917
|
return { archived: false, path: activePath };
|
|
5302
5918
|
}
|
|
5303
5919
|
}
|
|
5304
5920
|
const archivedPath = archivedTaskPath(rootPath, layout, list, id);
|
|
5305
|
-
await rejectSymbolicLinkComponents(
|
|
5306
|
-
await rejectSymbolicLinkComponents(
|
|
5307
|
-
const archivedStat = await statIfExists(
|
|
5921
|
+
await rejectSymbolicLinkComponents(fs5, archiveDirectoryPath(rootPath, layout, list));
|
|
5922
|
+
await rejectSymbolicLinkComponents(fs5, archivedPath);
|
|
5923
|
+
const archivedStat = await statIfExists(fs5, archivedPath);
|
|
5308
5924
|
if (archivedStat?.isFile()) {
|
|
5309
5925
|
return { archived: true, path: archivedPath };
|
|
5310
5926
|
}
|
|
5311
5927
|
return void 0;
|
|
5312
5928
|
}
|
|
5313
|
-
async function readTaskAtLocation(
|
|
5314
|
-
const location = await findTaskLocation(
|
|
5929
|
+
async function readTaskAtLocation(fs5, rootPath, layout, list, id, validStates, initialState, mode) {
|
|
5930
|
+
const location = await findTaskLocation(fs5, rootPath, layout, list, id, mode);
|
|
5315
5931
|
if (!location) {
|
|
5316
5932
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5317
5933
|
}
|
|
5318
|
-
return readTaskFile(
|
|
5934
|
+
return readTaskFile(fs5, list, id, location.path, validStates, initialState, mode);
|
|
5319
5935
|
}
|
|
5320
5936
|
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
5321
5937
|
const frontmatter = mode !== "passthrough" ? {
|
|
@@ -5331,12 +5947,12 @@ function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
|
5331
5947
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5332
5948
|
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5333
5949
|
if (!reservedKeys.has(key2)) {
|
|
5334
|
-
|
|
5950
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5335
5951
|
}
|
|
5336
5952
|
}
|
|
5337
5953
|
for (const [key2, value] of Object.entries(input.metadata ?? {})) {
|
|
5338
5954
|
if (!reservedKeys.has(key2)) {
|
|
5339
|
-
|
|
5955
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5340
5956
|
}
|
|
5341
5957
|
}
|
|
5342
5958
|
frontmatter.created = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5358,7 +5974,7 @@ function updatedFrontmatter(existingFrontmatter, task, patch, mode) {
|
|
|
5358
5974
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5359
5975
|
for (const [key2, value] of Object.entries(patch.metadata ?? {})) {
|
|
5360
5976
|
if (!reservedKeys.has(key2)) {
|
|
5361
|
-
|
|
5977
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5362
5978
|
}
|
|
5363
5979
|
}
|
|
5364
5980
|
return nextFrontmatter;
|
|
@@ -5382,7 +5998,7 @@ function firedFrontmatter(existingFrontmatter, task, to, mode, metadataPatch) {
|
|
|
5382
5998
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5383
5999
|
for (const [key2, value] of Object.entries(metadataPatch ?? {})) {
|
|
5384
6000
|
if (!reservedKeys.has(key2)) {
|
|
5385
|
-
|
|
6001
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5386
6002
|
}
|
|
5387
6003
|
}
|
|
5388
6004
|
return nextFrontmatter;
|
|
@@ -5416,11 +6032,19 @@ function createTasksView2(deps, layout, list) {
|
|
|
5416
6032
|
if (isHiddenEntry(entryName)) continue;
|
|
5417
6033
|
const parsed = parseActiveFilename(entryName);
|
|
5418
6034
|
if (!parsed) continue;
|
|
5419
|
-
const entryPath =
|
|
6035
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5420
6036
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5421
6037
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5422
6038
|
if (!entryStat?.isFile()) continue;
|
|
5423
|
-
result.push(
|
|
6039
|
+
result.push(
|
|
6040
|
+
await resolveActiveFilenameEntry(
|
|
6041
|
+
deps.fs,
|
|
6042
|
+
entryName,
|
|
6043
|
+
entryPath,
|
|
6044
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
6045
|
+
deps.frontmatterMode
|
|
6046
|
+
)
|
|
6047
|
+
);
|
|
5424
6048
|
}
|
|
5425
6049
|
result.sort((left, right) => {
|
|
5426
6050
|
const leftOrder = left.order ?? Number.POSITIVE_INFINITY;
|
|
@@ -5434,7 +6058,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5434
6058
|
const entries = await readActiveEntries();
|
|
5435
6059
|
const tasks = /* @__PURE__ */ new Map();
|
|
5436
6060
|
for (const entry of entries) {
|
|
5437
|
-
const filePath =
|
|
6061
|
+
const filePath = path8.join(listDirectoryPath, entry.filename);
|
|
5438
6062
|
const file = await readTaskFile(
|
|
5439
6063
|
deps.fs,
|
|
5440
6064
|
list,
|
|
@@ -5455,7 +6079,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5455
6079
|
const result = [];
|
|
5456
6080
|
for (const entryName of entries) {
|
|
5457
6081
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
5458
|
-
const entryPath =
|
|
6082
|
+
const entryPath = path8.join(archivePath, entryName);
|
|
5459
6083
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5460
6084
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5461
6085
|
if (!entryStat?.isFile()) continue;
|
|
@@ -5485,15 +6109,20 @@ function createTasksView2(deps, layout, list) {
|
|
|
5485
6109
|
if (desiredOrder === void 0) continue;
|
|
5486
6110
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
5487
6111
|
if (entry.filename !== desiredFilename) {
|
|
5488
|
-
const fromPath =
|
|
5489
|
-
const stagingPath =
|
|
6112
|
+
const fromPath = path8.join(listDirectoryPath, entry.filename);
|
|
6113
|
+
const stagingPath = path8.join(
|
|
5490
6114
|
listDirectoryPath,
|
|
5491
6115
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
5492
6116
|
);
|
|
5493
|
-
const targetPath =
|
|
6117
|
+
const targetPath = path8.join(listDirectoryPath, desiredFilename);
|
|
5494
6118
|
try {
|
|
5495
6119
|
await deps.fs.rename(fromPath, stagingPath);
|
|
5496
|
-
staged.push({
|
|
6120
|
+
staged.push({
|
|
6121
|
+
original: fromPath,
|
|
6122
|
+
staging: stagingPath,
|
|
6123
|
+
target: targetPath,
|
|
6124
|
+
finalized: false
|
|
6125
|
+
});
|
|
5497
6126
|
} catch (error3) {
|
|
5498
6127
|
for (const stagedEntry of staged.reverse()) {
|
|
5499
6128
|
await deps.fs.rename(stagedEntry.staging, stagedEntry.original);
|
|
@@ -5628,8 +6257,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5628
6257
|
if (filter?.state && entry.task.state !== filter.state) return false;
|
|
5629
6258
|
return true;
|
|
5630
6259
|
});
|
|
5631
|
-
|
|
5632
|
-
return [...orderedActiveTasks, ...filteredArchived.map((entry) => entry.task)];
|
|
6260
|
+
return applyOrder([...orderedActive, ...filteredArchived], filter?.order);
|
|
5633
6261
|
},
|
|
5634
6262
|
async get(id) {
|
|
5635
6263
|
return (await getTaskFile(id)).task;
|
|
@@ -5638,9 +6266,17 @@ function createTasksView2(deps, layout, list) {
|
|
|
5638
6266
|
assertCreateDoesNotSetState(input);
|
|
5639
6267
|
assertCreateHasId(input);
|
|
5640
6268
|
validateTaskId(input.id);
|
|
6269
|
+
validateTaskName(input.name);
|
|
5641
6270
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
5642
|
-
return withFileLock(deps.fs,
|
|
5643
|
-
const existing = await findTaskLocation(
|
|
6271
|
+
return withFileLock(deps.fs, path8.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
6272
|
+
const existing = await findTaskLocation(
|
|
6273
|
+
deps.fs,
|
|
6274
|
+
deps.path,
|
|
6275
|
+
layout,
|
|
6276
|
+
list,
|
|
6277
|
+
input.id,
|
|
6278
|
+
deps.frontmatterMode
|
|
6279
|
+
);
|
|
5644
6280
|
if (existing) {
|
|
5645
6281
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
5646
6282
|
}
|
|
@@ -5652,7 +6288,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5652
6288
|
const nextOrder = maxOrder + 1;
|
|
5653
6289
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
5654
6290
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
5655
|
-
const targetPath =
|
|
6291
|
+
const targetPath = path8.join(listDirectoryPath, filename);
|
|
5656
6292
|
const frontmatter = createdFrontmatter(
|
|
5657
6293
|
deps.defaults,
|
|
5658
6294
|
input,
|
|
@@ -5661,12 +6297,22 @@ function createTasksView2(deps, layout, list) {
|
|
|
5661
6297
|
);
|
|
5662
6298
|
const description = input.description ?? "";
|
|
5663
6299
|
await writeAtomically(deps.fs, targetPath, serializeTaskDocument(frontmatter, description));
|
|
5664
|
-
return createTask(
|
|
6300
|
+
return createTask(
|
|
6301
|
+
list,
|
|
6302
|
+
input.id,
|
|
6303
|
+
frontmatter,
|
|
6304
|
+
description,
|
|
6305
|
+
deps.frontmatterMode,
|
|
6306
|
+
targetPath
|
|
6307
|
+
);
|
|
5665
6308
|
});
|
|
5666
6309
|
},
|
|
5667
6310
|
async update(id, patch) {
|
|
5668
6311
|
assertUpdateDoesNotSetState(patch);
|
|
5669
6312
|
validateTaskId(id);
|
|
6313
|
+
if (patch.name !== void 0) {
|
|
6314
|
+
validateTaskName(patch.name);
|
|
6315
|
+
}
|
|
5670
6316
|
const existing = await getTaskFile(id);
|
|
5671
6317
|
const nextFrontmatter = updatedFrontmatter(
|
|
5672
6318
|
existing.frontmatter,
|
|
@@ -5752,7 +6398,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5752
6398
|
};
|
|
5753
6399
|
if (stateMachine.events[eventName]?.to === "archived") {
|
|
5754
6400
|
validateTaskId(id);
|
|
5755
|
-
const location = await findTaskLocation(
|
|
6401
|
+
const location = await findTaskLocation(
|
|
6402
|
+
deps.fs,
|
|
6403
|
+
deps.path,
|
|
6404
|
+
layout,
|
|
6405
|
+
list,
|
|
6406
|
+
id,
|
|
6407
|
+
deps.frontmatterMode
|
|
6408
|
+
);
|
|
5756
6409
|
if (!location) {
|
|
5757
6410
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5758
6411
|
}
|
|
@@ -5760,7 +6413,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5760
6413
|
validateTaskId(id);
|
|
5761
6414
|
const { event, nextTask } = await withFileLock(
|
|
5762
6415
|
deps.fs,
|
|
5763
|
-
|
|
6416
|
+
path8.join(listDirectoryPath, ".transition.lock"),
|
|
5764
6417
|
fireTask
|
|
5765
6418
|
);
|
|
5766
6419
|
await event.onEnter?.(nextTask);
|
|
@@ -5780,7 +6433,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5780
6433
|
},
|
|
5781
6434
|
async delete(id) {
|
|
5782
6435
|
validateTaskId(id);
|
|
5783
|
-
const location = await findTaskLocation(
|
|
6436
|
+
const location = await findTaskLocation(
|
|
6437
|
+
deps.fs,
|
|
6438
|
+
deps.path,
|
|
6439
|
+
layout,
|
|
6440
|
+
list,
|
|
6441
|
+
id,
|
|
6442
|
+
deps.frontmatterMode
|
|
6443
|
+
);
|
|
5784
6444
|
if (!location) {
|
|
5785
6445
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5786
6446
|
}
|
|
@@ -5853,7 +6513,7 @@ async function markdownDirBackend(deps) {
|
|
|
5853
6513
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
5854
6514
|
continue;
|
|
5855
6515
|
}
|
|
5856
|
-
const entryPath =
|
|
6516
|
+
const entryPath = path8.join(deps.path, entryName);
|
|
5857
6517
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5858
6518
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5859
6519
|
if (entryStat?.isDirectory()) {
|
|
@@ -5895,12 +6555,26 @@ async function markdownDirBackend(deps) {
|
|
|
5895
6555
|
}
|
|
5896
6556
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
5897
6557
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
5898
|
-
return withFileLock(deps.fs,
|
|
5899
|
-
const targetExisting = await findTaskLocation(
|
|
6558
|
+
return withFileLock(deps.fs, path8.join(targetListDir, ".transition.lock"), async () => {
|
|
6559
|
+
const targetExisting = await findTaskLocation(
|
|
6560
|
+
deps.fs,
|
|
6561
|
+
deps.path,
|
|
6562
|
+
layout,
|
|
6563
|
+
targetListName,
|
|
6564
|
+
id,
|
|
6565
|
+
deps.frontmatterMode
|
|
6566
|
+
);
|
|
5900
6567
|
if (targetExisting) {
|
|
5901
6568
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
5902
6569
|
}
|
|
5903
|
-
const sourceLocation = await findTaskLocation(
|
|
6570
|
+
const sourceLocation = await findTaskLocation(
|
|
6571
|
+
deps.fs,
|
|
6572
|
+
deps.path,
|
|
6573
|
+
layout,
|
|
6574
|
+
sourceListName,
|
|
6575
|
+
id,
|
|
6576
|
+
deps.frontmatterMode
|
|
6577
|
+
);
|
|
5904
6578
|
if (!sourceLocation) {
|
|
5905
6579
|
throw new TaskNotFoundError(`Task "${sourceListName}/${id}" not found.`);
|
|
5906
6580
|
}
|
|
@@ -5945,7 +6619,7 @@ async function markdownDirBackend(deps) {
|
|
|
5945
6619
|
);
|
|
5946
6620
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
5947
6621
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
5948
|
-
const targetPath =
|
|
6622
|
+
const targetPath = path8.join(targetListDir, targetFilename);
|
|
5949
6623
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
5950
6624
|
return createTask(
|
|
5951
6625
|
targetListName,
|
|
@@ -5967,7 +6641,7 @@ async function markdownDirBackend(deps) {
|
|
|
5967
6641
|
}
|
|
5968
6642
|
|
|
5969
6643
|
// ../task-list/src/backends/yaml-file.ts
|
|
5970
|
-
import
|
|
6644
|
+
import path9 from "node:path";
|
|
5971
6645
|
import { isMap, parseDocument as parseDocument3 } from "yaml";
|
|
5972
6646
|
|
|
5973
6647
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -6027,7 +6701,7 @@ function malformedTask2(list, id, field) {
|
|
|
6027
6701
|
return new MalformedTaskError(`Malformed task "${list}/${id}": invalid "${field}".`);
|
|
6028
6702
|
}
|
|
6029
6703
|
function validateListName2(name) {
|
|
6030
|
-
if (name
|
|
6704
|
+
if (!isTrimmedPrintableIdentifier(name) || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
6031
6705
|
throw new Error(`Invalid task list name "${name}".`);
|
|
6032
6706
|
}
|
|
6033
6707
|
return name;
|
|
@@ -6064,7 +6738,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
6064
6738
|
state: getOwnEntry(taskRecord, "state"),
|
|
6065
6739
|
description: descriptionFromTaskRecord(taskRecord),
|
|
6066
6740
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
6067
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
6741
|
+
...sourcePath !== void 0 && { sourcePath: path9.resolve(sourcePath) }
|
|
6068
6742
|
};
|
|
6069
6743
|
}
|
|
6070
6744
|
function matchesFilter(task, filter) {
|
|
@@ -6235,8 +6909,8 @@ function serializeDocument(document) {
|
|
|
6235
6909
|
return serialized.endsWith("\n") ? serialized : `${serialized}
|
|
6236
6910
|
`;
|
|
6237
6911
|
}
|
|
6238
|
-
async function readStore(
|
|
6239
|
-
const content = await
|
|
6912
|
+
async function readStore(fs5, filePath, validStates) {
|
|
6913
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
6240
6914
|
const document = parseStoreDocument(filePath, content);
|
|
6241
6915
|
const store = document.toJS();
|
|
6242
6916
|
assertValidStoreRecord(store, filePath);
|
|
@@ -6376,6 +7050,7 @@ function createTasksView3(deps, list) {
|
|
|
6376
7050
|
assertCreateDoesNotSetState2(input);
|
|
6377
7051
|
assertCreateHasId2(input);
|
|
6378
7052
|
validateTaskId(input.id);
|
|
7053
|
+
validateTaskName(input.name);
|
|
6379
7054
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6380
7055
|
if (getTaskRecord(store, list, input.id)) {
|
|
6381
7056
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -6388,6 +7063,9 @@ function createTasksView3(deps, list) {
|
|
|
6388
7063
|
async update(id, patch) {
|
|
6389
7064
|
assertUpdateDoesNotSetState2(patch);
|
|
6390
7065
|
validateTaskId(id);
|
|
7066
|
+
if (patch.name !== void 0) {
|
|
7067
|
+
validateTaskName(patch.name);
|
|
7068
|
+
}
|
|
6391
7069
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6392
7070
|
const existing = getTaskOrThrow(store, list, id);
|
|
6393
7071
|
const nextTaskRecord = buildUpdatedTaskRecord(existing, patch);
|
|
@@ -6479,6 +7157,11 @@ function createTasksView3(deps, list) {
|
|
|
6479
7157
|
insertIndex = anchor.position === "top" ? 0 : listNode.items.length;
|
|
6480
7158
|
} else {
|
|
6481
7159
|
const anchorId = "before" in anchor ? anchor.before : anchor.after;
|
|
7160
|
+
const activeIds = new Set(activeItemIds(listNode, validStates));
|
|
7161
|
+
if (!activeIds.has(anchorId)) {
|
|
7162
|
+
listNode.items.splice(fromIndex, 0, movedPair);
|
|
7163
|
+
throw new AnchorNotFoundError(anchorId);
|
|
7164
|
+
}
|
|
6482
7165
|
const anchorIndex = findItemIndex(listNode, anchorId);
|
|
6483
7166
|
if (anchorIndex < 0) {
|
|
6484
7167
|
listNode.items.splice(fromIndex, 0, movedPair);
|
|
@@ -6663,7 +7346,7 @@ function isRecord4(value) {
|
|
|
6663
7346
|
|
|
6664
7347
|
// ../task-list/src/move.ts
|
|
6665
7348
|
import * as fsPromises2 from "node:fs/promises";
|
|
6666
|
-
import
|
|
7349
|
+
import path10 from "node:path";
|
|
6667
7350
|
|
|
6668
7351
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
6669
7352
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6850,7 +7533,7 @@ function areEqualStrings(left, right) {
|
|
|
6850
7533
|
}
|
|
6851
7534
|
|
|
6852
7535
|
// ../toolcraft/src/human-in-loop/runner.ts
|
|
6853
|
-
import { access, lstat, readFile as
|
|
7536
|
+
import { access, lstat, readFile as readFile3, rename, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
6854
7537
|
|
|
6855
7538
|
// ../toolcraft/src/human-in-loop/default-provider.ts
|
|
6856
7539
|
import process3 from "node:process";
|
|
@@ -6882,7 +7565,7 @@ on error number -128
|
|
|
6882
7565
|
end try`;
|
|
6883
7566
|
}
|
|
6884
7567
|
function parseStdout(out) {
|
|
6885
|
-
const value = out.endsWith("\r\n") ? out.slice(0, -2) : out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
7568
|
+
const value = out.endsWith("\r\n") ? out.slice(0, -2) : out.endsWith("\n") ? out.slice(0, -1) : out.endsWith("\r") ? out.slice(0, -1) : out;
|
|
6886
7569
|
switch (value) {
|
|
6887
7570
|
case "Approve":
|
|
6888
7571
|
case "APPROVED":
|
|
@@ -7162,13 +7845,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
7162
7845
|
}
|
|
7163
7846
|
function enumerateApprovalCommandPaths(root) {
|
|
7164
7847
|
const paths = [];
|
|
7165
|
-
const visit = (node,
|
|
7848
|
+
const visit = (node, path25) => {
|
|
7166
7849
|
if (node.kind === "command") {
|
|
7167
|
-
paths.push(
|
|
7850
|
+
paths.push(path25.join("."));
|
|
7168
7851
|
return;
|
|
7169
7852
|
}
|
|
7170
7853
|
for (const child of getVisibleCliChildren(node)) {
|
|
7171
|
-
visit(child, [...
|
|
7854
|
+
visit(child, [...path25, child.name]);
|
|
7172
7855
|
}
|
|
7173
7856
|
};
|
|
7174
7857
|
if (root.kind === "command") {
|
|
@@ -7203,21 +7886,21 @@ function createHandlerContext(command, params17) {
|
|
|
7203
7886
|
}
|
|
7204
7887
|
function createFs() {
|
|
7205
7888
|
return {
|
|
7206
|
-
readFile: async (
|
|
7207
|
-
writeFile: async (
|
|
7208
|
-
await writeFile2(
|
|
7889
|
+
readFile: async (path25, encoding = "utf8") => readFile3(path25, { encoding }),
|
|
7890
|
+
writeFile: async (path25, contents, options) => {
|
|
7891
|
+
await writeFile2(path25, contents, options);
|
|
7209
7892
|
},
|
|
7210
|
-
exists: async (
|
|
7893
|
+
exists: async (path25) => {
|
|
7211
7894
|
try {
|
|
7212
|
-
await access(
|
|
7895
|
+
await access(path25);
|
|
7213
7896
|
return true;
|
|
7214
7897
|
} catch {
|
|
7215
7898
|
return false;
|
|
7216
7899
|
}
|
|
7217
7900
|
},
|
|
7218
|
-
lstat: async (
|
|
7901
|
+
lstat: async (path25) => lstat(path25),
|
|
7219
7902
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
7220
|
-
unlink: async (
|
|
7903
|
+
unlink: async (path25) => unlink(path25)
|
|
7221
7904
|
};
|
|
7222
7905
|
}
|
|
7223
7906
|
function createEnv(values = process.env) {
|
|
@@ -7496,13 +8179,13 @@ function isMissingStateError(error3) {
|
|
|
7496
8179
|
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
7497
8180
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
7498
8181
|
import os from "node:os";
|
|
7499
|
-
import
|
|
8182
|
+
import path14 from "node:path";
|
|
7500
8183
|
import { CommanderError } from "commander";
|
|
7501
8184
|
|
|
7502
8185
|
// ../toolcraft/src/mcp-proxy.ts
|
|
7503
8186
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7504
|
-
import { lstat as lstat2, mkdir, readFile as
|
|
7505
|
-
import
|
|
8187
|
+
import { lstat as lstat2, mkdir, readFile as readFile4, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
8188
|
+
import path13 from "node:path";
|
|
7506
8189
|
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
7507
8190
|
|
|
7508
8191
|
// ../tiny-mcp-client/src/internal.ts
|
|
@@ -7511,13 +8194,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
7511
8194
|
|
|
7512
8195
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
7513
8196
|
import crypto from "node:crypto";
|
|
7514
|
-
import
|
|
8197
|
+
import path12 from "node:path";
|
|
7515
8198
|
|
|
7516
8199
|
// ../auth-store/src/encrypted-file-store.ts
|
|
7517
8200
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
7518
8201
|
import { promises as fs } from "node:fs";
|
|
7519
8202
|
import { homedir, hostname, userInfo } from "node:os";
|
|
7520
|
-
import
|
|
8203
|
+
import path11 from "node:path";
|
|
7521
8204
|
|
|
7522
8205
|
// ../auth-store/src/error-codes.ts
|
|
7523
8206
|
function hasOwnErrorCode3(error3, code) {
|
|
@@ -7546,10 +8229,13 @@ var EncryptedFileStore = class {
|
|
|
7546
8229
|
if (input.filePath === void 0) {
|
|
7547
8230
|
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
7548
8231
|
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
7549
|
-
|
|
8232
|
+
const defaultFileName = input.defaultFileName ?? "credentials.enc";
|
|
8233
|
+
assertSafeDefaultDirectory(defaultDirectory);
|
|
8234
|
+
assertSafeDefaultFileName(defaultFileName);
|
|
8235
|
+
this.filePath = path11.join(
|
|
7550
8236
|
homeDirectory,
|
|
7551
8237
|
defaultDirectory,
|
|
7552
|
-
|
|
8238
|
+
defaultFileName
|
|
7553
8239
|
);
|
|
7554
8240
|
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
7555
8241
|
homeDirectory,
|
|
@@ -7609,7 +8295,7 @@ var EncryptedFileStore = class {
|
|
|
7609
8295
|
authTag: authTag.toString("base64"),
|
|
7610
8296
|
ciphertext: ciphertext.toString("base64")
|
|
7611
8297
|
};
|
|
7612
|
-
await this.fs.mkdir(
|
|
8298
|
+
await this.fs.mkdir(path11.dirname(this.filePath), { recursive: true });
|
|
7613
8299
|
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
7614
8300
|
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
7615
8301
|
let temporaryCreated = false;
|
|
@@ -7641,7 +8327,7 @@ var EncryptedFileStore = class {
|
|
|
7641
8327
|
}
|
|
7642
8328
|
}
|
|
7643
8329
|
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
7644
|
-
const resolvedPath =
|
|
8330
|
+
const resolvedPath = path11.resolve(targetPath);
|
|
7645
8331
|
const protectedPaths = getProtectedCredentialPaths(
|
|
7646
8332
|
resolvedPath,
|
|
7647
8333
|
this.symbolicLinkCheckStartPath
|
|
@@ -7675,27 +8361,62 @@ var EncryptedFileStore = class {
|
|
|
7675
8361
|
};
|
|
7676
8362
|
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
7677
8363
|
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
7678
|
-
return
|
|
8364
|
+
return path11.resolve(homeDirectory, firstSegment ?? ".");
|
|
7679
8365
|
}
|
|
7680
8366
|
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
7681
8367
|
if (symbolicLinkCheckStartPath === null) {
|
|
7682
|
-
return
|
|
8368
|
+
return getExplicitProtectedCredentialPaths(resolvedPath);
|
|
7683
8369
|
}
|
|
7684
|
-
const resolvedStartPath =
|
|
8370
|
+
const resolvedStartPath = path11.resolve(symbolicLinkCheckStartPath);
|
|
7685
8371
|
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
7686
|
-
return [
|
|
8372
|
+
return [path11.dirname(resolvedPath), resolvedPath];
|
|
7687
8373
|
}
|
|
7688
8374
|
const protectedPaths = [resolvedStartPath];
|
|
7689
8375
|
let currentPath = resolvedStartPath;
|
|
7690
|
-
for (const segment of
|
|
7691
|
-
currentPath =
|
|
8376
|
+
for (const segment of path11.relative(resolvedStartPath, resolvedPath).split(path11.sep).filter(Boolean)) {
|
|
8377
|
+
currentPath = path11.join(currentPath, segment);
|
|
8378
|
+
protectedPaths.push(currentPath);
|
|
8379
|
+
}
|
|
8380
|
+
return protectedPaths;
|
|
8381
|
+
}
|
|
8382
|
+
function assertSafeDefaultDirectory(defaultDirectory) {
|
|
8383
|
+
if (path11.isAbsolute(defaultDirectory) || path11.win32.isAbsolute(defaultDirectory)) {
|
|
8384
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8385
|
+
}
|
|
8386
|
+
for (const segment of splitPathSegments(defaultDirectory)) {
|
|
8387
|
+
if (segment === "..") {
|
|
8388
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8389
|
+
}
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
function assertSafeDefaultFileName(defaultFileName) {
|
|
8393
|
+
if (defaultFileName.trim().length === 0 || defaultFileName === "." || defaultFileName === ".." || splitPathSegments(defaultFileName).length !== 1) {
|
|
8394
|
+
throw new Error("defaultFileName must be a file name without path separators");
|
|
8395
|
+
}
|
|
8396
|
+
}
|
|
8397
|
+
function splitPathSegments(value) {
|
|
8398
|
+
return value.split("/").flatMap((segment) => segment.split("\\")).filter((segment) => segment.length > 0);
|
|
8399
|
+
}
|
|
8400
|
+
function getExplicitProtectedCredentialPaths(resolvedPath) {
|
|
8401
|
+
const parsed = path11.parse(resolvedPath);
|
|
8402
|
+
const segments = resolvedPath.slice(parsed.root.length).split(path11.sep).filter((segment) => segment.length > 0);
|
|
8403
|
+
if (segments.length <= 1) {
|
|
8404
|
+
return [resolvedPath];
|
|
8405
|
+
}
|
|
8406
|
+
const protectedPaths = [];
|
|
8407
|
+
let currentPath = parsed.root;
|
|
8408
|
+
for (const [index, segment] of segments.entries()) {
|
|
8409
|
+
currentPath = path11.join(currentPath, segment);
|
|
8410
|
+
if (index === 0) {
|
|
8411
|
+
continue;
|
|
8412
|
+
}
|
|
7692
8413
|
protectedPaths.push(currentPath);
|
|
7693
8414
|
}
|
|
7694
8415
|
return protectedPaths;
|
|
7695
8416
|
}
|
|
7696
8417
|
function isPathInsideOrEqual(childPath, parentPath) {
|
|
7697
|
-
const relativePath =
|
|
7698
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
8418
|
+
const relativePath = path11.relative(parentPath, childPath);
|
|
8419
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
|
|
7699
8420
|
}
|
|
7700
8421
|
async function removeIfPresent(fileSystem, filePath) {
|
|
7701
8422
|
try {
|
|
@@ -7786,8 +8507,14 @@ var KeychainStore = class {
|
|
|
7786
8507
|
account;
|
|
7787
8508
|
constructor(input) {
|
|
7788
8509
|
this.runCommand = input.runCommand ?? runSecurityCommand;
|
|
7789
|
-
this.service = input.service;
|
|
7790
|
-
this.account = input.account;
|
|
8510
|
+
this.service = input.service.trim();
|
|
8511
|
+
this.account = input.account.trim();
|
|
8512
|
+
if (this.service.length === 0) {
|
|
8513
|
+
throw new Error("Keychain service must not be empty");
|
|
8514
|
+
}
|
|
8515
|
+
if (this.account.length === 0) {
|
|
8516
|
+
throw new Error("Keychain account must not be empty");
|
|
8517
|
+
}
|
|
7791
8518
|
}
|
|
7792
8519
|
async get() {
|
|
7793
8520
|
const result = await this.executeSecurityCommand(
|
|
@@ -7814,10 +8541,10 @@ var KeychainStore = class {
|
|
|
7814
8541
|
"-a",
|
|
7815
8542
|
this.account,
|
|
7816
8543
|
"-U",
|
|
7817
|
-
"-w"
|
|
8544
|
+
"-w",
|
|
8545
|
+
value
|
|
7818
8546
|
],
|
|
7819
|
-
"store secret in macOS Keychain"
|
|
7820
|
-
{ stdin: value }
|
|
8547
|
+
"store secret in macOS Keychain"
|
|
7821
8548
|
);
|
|
7822
8549
|
if (getCommandExitCode(result) !== 0) {
|
|
7823
8550
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
@@ -7962,13 +8689,14 @@ function createSecretStore(input) {
|
|
|
7962
8689
|
function resolveBackend(input) {
|
|
7963
8690
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7964
8691
|
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7965
|
-
|
|
8692
|
+
const backend = configuredBackend?.trim();
|
|
8693
|
+
if (backend === "keychain") {
|
|
7966
8694
|
return "keychain";
|
|
7967
8695
|
}
|
|
7968
|
-
if (
|
|
8696
|
+
if (backend === void 0 || backend === "file") {
|
|
7969
8697
|
return "file";
|
|
7970
8698
|
}
|
|
7971
|
-
throw new Error(`Unsupported auth store backend: ${
|
|
8699
|
+
throw new Error(`Unsupported auth store backend: ${backend}`);
|
|
7972
8700
|
}
|
|
7973
8701
|
function getOwnEnvValue(env, key2) {
|
|
7974
8702
|
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
@@ -7993,6 +8721,7 @@ var DEFAULT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth";
|
|
|
7993
8721
|
var DEFAULT_CLIENT_FILE_SALT = "poe-code:mcp-oauth:clients:v1";
|
|
7994
8722
|
var DEFAULT_CLIENT_FILE_DIRECTORY = ".poe-code/mcp-oauth/clients";
|
|
7995
8723
|
var DEFAULT_CLIENT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth-clients";
|
|
8724
|
+
var MAX_JS_DATE_MS = 864e13;
|
|
7996
8725
|
function createAuthStoreSessionStore(options = {}) {
|
|
7997
8726
|
return {
|
|
7998
8727
|
async load(resource) {
|
|
@@ -8002,10 +8731,10 @@ function createAuthStoreSessionStore(options = {}) {
|
|
|
8002
8731
|
return null;
|
|
8003
8732
|
}
|
|
8004
8733
|
const parsed = JSON.parse(value);
|
|
8005
|
-
if (
|
|
8734
|
+
if (isStoredOAuthSession(parsed)) {
|
|
8006
8735
|
return parsed;
|
|
8007
8736
|
}
|
|
8008
|
-
throw new Error("Stored OAuth session must
|
|
8737
|
+
throw new Error("Stored OAuth session must match the expected shape");
|
|
8009
8738
|
},
|
|
8010
8739
|
async save(resource, session) {
|
|
8011
8740
|
const store = createResourceSecretStore(resource, options);
|
|
@@ -8049,10 +8778,10 @@ function createAuthStoreClientStore(options) {
|
|
|
8049
8778
|
function createNamedSecretStore(key2, options, defaults2) {
|
|
8050
8779
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
8051
8780
|
const configuredFilePath = options.fileStore?.filePath;
|
|
8052
|
-
const parsedFilePath = configuredFilePath === void 0 ? null :
|
|
8781
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path12.parse(configuredFilePath);
|
|
8053
8782
|
const fileStore = {
|
|
8054
8783
|
...options.fileStore,
|
|
8055
|
-
filePath: parsedFilePath === null ? void 0 :
|
|
8784
|
+
filePath: parsedFilePath === null ? void 0 : path12.join(
|
|
8056
8785
|
parsedFilePath.dir,
|
|
8057
8786
|
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
8058
8787
|
),
|
|
@@ -8068,28 +8797,20 @@ function createNamedSecretStore(key2, options, defaults2) {
|
|
|
8068
8797
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
8069
8798
|
}
|
|
8070
8799
|
function createResourceSecretStore(resource, options) {
|
|
8071
|
-
return createNamedSecretStore(
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8078
|
-
accountPrefix: "provider"
|
|
8079
|
-
}
|
|
8080
|
-
);
|
|
8800
|
+
return createNamedSecretStore(canonicalizeResourceIndicator(resource), options, {
|
|
8801
|
+
salt: DEFAULT_FILE_SALT,
|
|
8802
|
+
directory: DEFAULT_FILE_DIRECTORY,
|
|
8803
|
+
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8804
|
+
accountPrefix: "provider"
|
|
8805
|
+
});
|
|
8081
8806
|
}
|
|
8082
8807
|
function createIssuerSecretStore(issuer, options) {
|
|
8083
|
-
return createNamedSecretStore(
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8090
|
-
accountPrefix: "issuer"
|
|
8091
|
-
}
|
|
8092
|
-
);
|
|
8808
|
+
return createNamedSecretStore(issuer, options, {
|
|
8809
|
+
salt: DEFAULT_CLIENT_FILE_SALT,
|
|
8810
|
+
directory: DEFAULT_CLIENT_FILE_DIRECTORY,
|
|
8811
|
+
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8812
|
+
accountPrefix: "issuer"
|
|
8813
|
+
});
|
|
8093
8814
|
}
|
|
8094
8815
|
function isObjectRecord(value) {
|
|
8095
8816
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8101,6 +8822,50 @@ function getOwnString(record, key2) {
|
|
|
8101
8822
|
const value = getOwnEntry4(record, key2);
|
|
8102
8823
|
return typeof value === "string" ? value : void 0;
|
|
8103
8824
|
}
|
|
8825
|
+
function isStoredOAuthSession(value) {
|
|
8826
|
+
if (!isObjectRecord(value)) {
|
|
8827
|
+
return false;
|
|
8828
|
+
}
|
|
8829
|
+
return isNonBlankOwnString(value, "resource") && isNonBlankOwnString(value, "authorizationServer") && isStoredOAuthClient(getOwnEntry4(value, "client")) && isStoredOAuthDiscovery(getOwnEntry4(value, "discovery")) && isStoredOAuthTokensOrMissing(getOwnEntry4(value, "tokens"));
|
|
8830
|
+
}
|
|
8831
|
+
function isStoredOAuthClient(value) {
|
|
8832
|
+
if (!isObjectRecord(value) || !isNonBlankOwnString(value, "clientId")) {
|
|
8833
|
+
return false;
|
|
8834
|
+
}
|
|
8835
|
+
const clientSecret = getOwnEntry4(value, "clientSecret");
|
|
8836
|
+
return clientSecret === void 0 || typeof clientSecret === "string" && clientSecret.trim().length > 0;
|
|
8837
|
+
}
|
|
8838
|
+
function isStoredOAuthDiscovery(value) {
|
|
8839
|
+
if (!isObjectRecord(value)) {
|
|
8840
|
+
return false;
|
|
8841
|
+
}
|
|
8842
|
+
return isNonBlankOwnString(value, "resourceMetadataUrl") && isObjectRecord(getOwnEntry4(value, "resourceMetadata")) && isObjectRecord(getOwnEntry4(value, "authorizationServerMetadata"));
|
|
8843
|
+
}
|
|
8844
|
+
function isStoredOAuthTokensOrMissing(value) {
|
|
8845
|
+
if (value === void 0) {
|
|
8846
|
+
return true;
|
|
8847
|
+
}
|
|
8848
|
+
if (!isObjectRecord(value)) {
|
|
8849
|
+
return false;
|
|
8850
|
+
}
|
|
8851
|
+
if (!isNonBlankOwnString(value, "accessToken") || getOwnString(value, "tokenType") !== "Bearer") {
|
|
8852
|
+
return false;
|
|
8853
|
+
}
|
|
8854
|
+
const expiresAt = getOwnEntry4(value, "expiresAt");
|
|
8855
|
+
if (expiresAt !== null && (typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS || !Number.isFinite(new Date(expiresAt).getTime()))) {
|
|
8856
|
+
return false;
|
|
8857
|
+
}
|
|
8858
|
+
const refreshToken = getOwnEntry4(value, "refreshToken");
|
|
8859
|
+
if (refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
|
|
8860
|
+
return false;
|
|
8861
|
+
}
|
|
8862
|
+
const scope = getOwnEntry4(value, "scope");
|
|
8863
|
+
return scope === void 0 || typeof scope === "string" && scope.trim().length > 0;
|
|
8864
|
+
}
|
|
8865
|
+
function isNonBlankOwnString(record, key2) {
|
|
8866
|
+
const value = getOwnString(record, key2);
|
|
8867
|
+
return value !== void 0 && value.trim().length > 0;
|
|
8868
|
+
}
|
|
8104
8869
|
|
|
8105
8870
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
8106
8871
|
import { URL as URL2 } from "node:url";
|
|
@@ -8211,9 +8976,7 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8211
8976
|
} catch (error3) {
|
|
8212
8977
|
res.writeHead(400);
|
|
8213
8978
|
res.end(error3 instanceof Error ? error3.message : "Invalid OAuth callback");
|
|
8214
|
-
|
|
8215
|
-
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8216
|
-
}
|
|
8979
|
+
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8217
8980
|
return;
|
|
8218
8981
|
}
|
|
8219
8982
|
const authorizationError = callbackParameters.error;
|
|
@@ -8225,7 +8988,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8225
8988
|
return;
|
|
8226
8989
|
}
|
|
8227
8990
|
try {
|
|
8228
|
-
const code = validateAuthorizationCallbackParameters(
|
|
8991
|
+
const code = validateAuthorizationCallbackParameters(
|
|
8992
|
+
callbackParameters,
|
|
8993
|
+
expectedAuthorization
|
|
8994
|
+
);
|
|
8229
8995
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
8230
8996
|
res.end(buildSuccessPage(options.landingPage));
|
|
8231
8997
|
settle(() => resolve(code));
|
|
@@ -8248,7 +9014,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8248
9014
|
const description = callbackParameters.errorDescription ?? callbackParameters.error;
|
|
8249
9015
|
throw createAuthorizationError(callbackParameters.error, description);
|
|
8250
9016
|
}
|
|
8251
|
-
const code = validateAuthorizationCallbackParameters(
|
|
9017
|
+
const code = validateAuthorizationCallbackParameters(
|
|
9018
|
+
callbackParameters,
|
|
9019
|
+
expectedAuthorization
|
|
9020
|
+
);
|
|
8252
9021
|
settle(() => resolve(code));
|
|
8253
9022
|
} catch (error3) {
|
|
8254
9023
|
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
@@ -8353,6 +9122,7 @@ function generateCodeChallenge(verifier) {
|
|
|
8353
9122
|
}
|
|
8354
9123
|
|
|
8355
9124
|
// ../mcp-oauth/src/client/token-endpoint.ts
|
|
9125
|
+
var MAX_JS_DATE_MS2 = 864e13;
|
|
8356
9126
|
var OAuthError = class extends Error {
|
|
8357
9127
|
error;
|
|
8358
9128
|
errorDescription;
|
|
@@ -8430,22 +9200,32 @@ async function requestTokens(input) {
|
|
|
8430
9200
|
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
8431
9201
|
throw new Error("OAuth token response missing access_token");
|
|
8432
9202
|
}
|
|
9203
|
+
const normalizedAccessToken = accessToken.trim();
|
|
8433
9204
|
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
8434
9205
|
if (tokenType === null) {
|
|
8435
9206
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
8436
9207
|
}
|
|
8437
9208
|
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
8438
|
-
|
|
8439
|
-
|
|
9209
|
+
let expiresAt = null;
|
|
9210
|
+
if (expiresIn !== void 0) {
|
|
9211
|
+
if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || !Number.isInteger(expiresIn) || expiresIn < 0) {
|
|
9212
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9213
|
+
}
|
|
9214
|
+
expiresAt = input.now() + expiresIn * 1e3;
|
|
9215
|
+
if (!Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS2 || !Number.isFinite(new Date(expiresAt).getTime())) {
|
|
9216
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9217
|
+
}
|
|
8440
9218
|
}
|
|
8441
9219
|
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
8442
9220
|
const scope = getOwnEntry6(payload, "scope");
|
|
9221
|
+
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
9222
|
+
const normalizedScope = typeof scope === "string" && scope.trim().length > 0 ? scope.trim() : void 0;
|
|
8443
9223
|
return {
|
|
8444
|
-
accessToken,
|
|
8445
|
-
refreshToken:
|
|
9224
|
+
accessToken: normalizedAccessToken,
|
|
9225
|
+
refreshToken: normalizedRefreshToken === void 0 ? void 0 : normalizedRefreshToken,
|
|
8446
9226
|
tokenType,
|
|
8447
|
-
expiresAt
|
|
8448
|
-
scope:
|
|
9227
|
+
expiresAt,
|
|
9228
|
+
scope: normalizedScope === void 0 ? void 0 : normalizedScope
|
|
8449
9229
|
};
|
|
8450
9230
|
}
|
|
8451
9231
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -8496,6 +9276,7 @@ function normalizeBearerTokenType(value) {
|
|
|
8496
9276
|
}
|
|
8497
9277
|
|
|
8498
9278
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
9279
|
+
var MAX_JS_DATE_MS3 = 864e13;
|
|
8499
9280
|
function createOAuthClientProvider(options) {
|
|
8500
9281
|
if (isProviderOptions(options)) {
|
|
8501
9282
|
return options.provider;
|
|
@@ -8660,7 +9441,12 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8660
9441
|
});
|
|
8661
9442
|
let resolvedClient = null;
|
|
8662
9443
|
try {
|
|
8663
|
-
resolvedClient = await resolveClient(
|
|
9444
|
+
resolvedClient = await resolveClient(
|
|
9445
|
+
currentSession,
|
|
9446
|
+
discovery,
|
|
9447
|
+
loopback.redirectUri,
|
|
9448
|
+
fetch2
|
|
9449
|
+
);
|
|
8664
9450
|
const sessionWithoutTokens = {
|
|
8665
9451
|
resource,
|
|
8666
9452
|
authorizationServer: discovery.authorizationServer,
|
|
@@ -8727,28 +9513,26 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8727
9513
|
return finalPromise;
|
|
8728
9514
|
}
|
|
8729
9515
|
async function resolveClient(existingSession, discovery, redirectUri, fetch2) {
|
|
9516
|
+
const configuredClient = normalizeConfiguredClient(options.client);
|
|
8730
9517
|
if (options.client.mode === "static") {
|
|
9518
|
+
if (configuredClient === null) {
|
|
9519
|
+
throw new Error("OAuth client_id must not be blank");
|
|
9520
|
+
}
|
|
8731
9521
|
return {
|
|
8732
9522
|
kind: "static",
|
|
8733
9523
|
fromStoredRegistration: false,
|
|
8734
|
-
client:
|
|
8735
|
-
clientId: options.client.clientId,
|
|
8736
|
-
clientSecret: options.client.clientSecret
|
|
8737
|
-
}
|
|
9524
|
+
client: configuredClient
|
|
8738
9525
|
};
|
|
8739
9526
|
}
|
|
8740
9527
|
const registrationEndpoint = getOwnString2(
|
|
8741
9528
|
discovery.authorizationServerMetadata,
|
|
8742
9529
|
"registration_endpoint"
|
|
8743
9530
|
);
|
|
8744
|
-
if (registrationEndpoint === void 0 &&
|
|
9531
|
+
if (registrationEndpoint === void 0 && configuredClient !== null) {
|
|
8745
9532
|
return {
|
|
8746
9533
|
kind: "static",
|
|
8747
9534
|
fromStoredRegistration: false,
|
|
8748
|
-
client:
|
|
8749
|
-
clientId: options.client.clientId,
|
|
8750
|
-
clientSecret: options.client.clientSecret
|
|
8751
|
-
}
|
|
9535
|
+
client: configuredClient
|
|
8752
9536
|
};
|
|
8753
9537
|
}
|
|
8754
9538
|
const storedClient = await loadRegisteredClient(discovery.authorizationServer);
|
|
@@ -8770,7 +9554,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8770
9554
|
throw new Error("Authorization server metadata is missing registration_endpoint");
|
|
8771
9555
|
}
|
|
8772
9556
|
if (existingSession !== null && existingSession.client.clientId.length > 0) {
|
|
8773
|
-
const isConfiguredStaticFallback =
|
|
9557
|
+
const isConfiguredStaticFallback = configuredClient !== null && existingSession.client.clientId === configuredClient.clientId && existingSession.client.clientSecret === configuredClient.clientSecret;
|
|
8774
9558
|
if (!isConfiguredStaticFallback) {
|
|
8775
9559
|
await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
|
|
8776
9560
|
return {
|
|
@@ -8798,8 +9582,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8798
9582
|
}
|
|
8799
9583
|
const clientSecret = getOwnString2(payload, "client_secret");
|
|
8800
9584
|
const registeredClient = {
|
|
8801
|
-
clientId,
|
|
8802
|
-
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
9585
|
+
clientId: clientId.trim(),
|
|
9586
|
+
clientSecret: clientSecret !== void 0 && clientSecret.trim().length > 0 ? clientSecret.trim() : void 0
|
|
8803
9587
|
};
|
|
8804
9588
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
8805
9589
|
return {
|
|
@@ -8912,14 +9696,16 @@ function normalizeStoredClient(value) {
|
|
|
8912
9696
|
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8913
9697
|
return null;
|
|
8914
9698
|
}
|
|
9699
|
+
const normalizedClientId = clientId.trim();
|
|
8915
9700
|
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8916
9701
|
if (clientSecret === void 0) {
|
|
8917
|
-
return { clientId };
|
|
9702
|
+
return { clientId: normalizedClientId };
|
|
8918
9703
|
}
|
|
8919
9704
|
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8920
9705
|
return null;
|
|
8921
9706
|
}
|
|
8922
|
-
|
|
9707
|
+
const normalizedClientSecret = clientSecret.trim();
|
|
9708
|
+
return { clientId: normalizedClientId, clientSecret: normalizedClientSecret };
|
|
8923
9709
|
}
|
|
8924
9710
|
function normalizeStoredTokens(value) {
|
|
8925
9711
|
if (value === void 0 || !isObjectRecord3(value)) {
|
|
@@ -8930,20 +9716,45 @@ function normalizeStoredTokens(value) {
|
|
|
8930
9716
|
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8931
9717
|
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8932
9718
|
const scope = getOwnString2(value, "scope");
|
|
8933
|
-
const
|
|
8934
|
-
|
|
9719
|
+
const normalizedAccessToken = accessToken?.trim();
|
|
9720
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : void 0;
|
|
9721
|
+
const normalizedScope = scope?.trim();
|
|
9722
|
+
if (accessToken === void 0 || normalizedAccessToken === void 0 || normalizedAccessToken.length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isSafeInteger(expiresAt) && expiresAt <= MAX_JS_DATE_MS3 && Number.isFinite(new Date(expiresAt).getTime())) || refreshToken !== void 0 && (typeof refreshToken !== "string" || normalizedRefreshToken === void 0 || normalizedRefreshToken.length === 0)) {
|
|
8935
9723
|
return void 0;
|
|
8936
9724
|
}
|
|
8937
9725
|
return {
|
|
8938
|
-
accessToken,
|
|
9726
|
+
accessToken: normalizedAccessToken,
|
|
8939
9727
|
tokenType,
|
|
8940
9728
|
expiresAt,
|
|
8941
9729
|
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8942
|
-
...
|
|
9730
|
+
...normalizedScope === void 0 || normalizedScope.length === 0 ? {} : { scope: normalizedScope }
|
|
8943
9731
|
};
|
|
8944
9732
|
}
|
|
8945
9733
|
function getClientMetadata(client) {
|
|
8946
|
-
|
|
9734
|
+
if (client.metadata === void 0) {
|
|
9735
|
+
return void 0;
|
|
9736
|
+
}
|
|
9737
|
+
return {
|
|
9738
|
+
clientName: normalizeOptionalOAuthString(client.metadata.clientName),
|
|
9739
|
+
scope: normalizeOptionalOAuthString(client.metadata.scope),
|
|
9740
|
+
softwareId: normalizeOptionalOAuthString(client.metadata.softwareId),
|
|
9741
|
+
softwareVersion: normalizeOptionalOAuthString(client.metadata.softwareVersion)
|
|
9742
|
+
};
|
|
9743
|
+
}
|
|
9744
|
+
function normalizeConfiguredClient(client) {
|
|
9745
|
+
const clientId = normalizeOptionalOAuthString(client.clientId);
|
|
9746
|
+
if (clientId === void 0) {
|
|
9747
|
+
return null;
|
|
9748
|
+
}
|
|
9749
|
+
const clientSecret = normalizeOptionalOAuthString(client.clientSecret);
|
|
9750
|
+
return clientSecret === void 0 ? { clientId } : { clientId, clientSecret };
|
|
9751
|
+
}
|
|
9752
|
+
function normalizeOptionalOAuthString(value) {
|
|
9753
|
+
if (value === void 0) {
|
|
9754
|
+
return void 0;
|
|
9755
|
+
}
|
|
9756
|
+
const trimmed = value.trim();
|
|
9757
|
+
return trimmed.length === 0 ? void 0 : trimmed;
|
|
8947
9758
|
}
|
|
8948
9759
|
function getOwnEntry7(record, key2) {
|
|
8949
9760
|
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
@@ -8972,11 +9783,7 @@ function buildAuthorizationUrl(input) {
|
|
|
8972
9783
|
"authorization_endpoint",
|
|
8973
9784
|
"Authorization server metadata"
|
|
8974
9785
|
);
|
|
8975
|
-
const issuer = requireOwnString(
|
|
8976
|
-
input.metadata,
|
|
8977
|
-
"issuer",
|
|
8978
|
-
"Authorization server metadata"
|
|
8979
|
-
);
|
|
9786
|
+
const issuer = requireOwnString(input.metadata, "issuer", "Authorization server metadata");
|
|
8980
9787
|
const url = new URL2(authorizationEndpoint);
|
|
8981
9788
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
8982
9789
|
const state = createAuthorizationState({
|
|
@@ -9584,7 +10391,7 @@ var McpClient = class {
|
|
|
9584
10391
|
await onToolsChanged();
|
|
9585
10392
|
});
|
|
9586
10393
|
messageLayer.onNotification("notifications/resources/list_changed", async () => {
|
|
9587
|
-
if (onResourcesChanged === void 0) {
|
|
10394
|
+
if (onResourcesChanged === void 0 || this.currentServerCapabilities?.resources?.listChanged !== true) {
|
|
9588
10395
|
return;
|
|
9589
10396
|
}
|
|
9590
10397
|
await onResourcesChanged();
|
|
@@ -9603,7 +10410,7 @@ var McpClient = class {
|
|
|
9603
10410
|
await onResourceUpdated(uri);
|
|
9604
10411
|
});
|
|
9605
10412
|
messageLayer.onNotification("notifications/prompts/list_changed", async () => {
|
|
9606
|
-
if (onPromptsChanged === void 0) {
|
|
10413
|
+
if (onPromptsChanged === void 0 || this.currentServerCapabilities?.prompts?.listChanged !== true) {
|
|
9607
10414
|
return;
|
|
9608
10415
|
}
|
|
9609
10416
|
await onPromptsChanged();
|
|
@@ -9834,7 +10641,11 @@ var McpClient = class {
|
|
|
9834
10641
|
throw new Error("Server does not support resources");
|
|
9835
10642
|
}
|
|
9836
10643
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9837
|
-
|
|
10644
|
+
const result = await messageLayer.sendRequest("resources/list", requestParams);
|
|
10645
|
+
if (!isResourcesListResult(result)) {
|
|
10646
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/list result");
|
|
10647
|
+
}
|
|
10648
|
+
return result;
|
|
9838
10649
|
}
|
|
9839
10650
|
async listResourceTemplates(params17 = {}) {
|
|
9840
10651
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9843,7 +10654,11 @@ var McpClient = class {
|
|
|
9843
10654
|
throw new Error("Server does not support resources");
|
|
9844
10655
|
}
|
|
9845
10656
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9846
|
-
|
|
10657
|
+
const result = await messageLayer.sendRequest("resources/templates/list", requestParams);
|
|
10658
|
+
if (!isResourceTemplatesListResult(result)) {
|
|
10659
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/templates/list result");
|
|
10660
|
+
}
|
|
10661
|
+
return result;
|
|
9847
10662
|
}
|
|
9848
10663
|
async readResource(params17) {
|
|
9849
10664
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9851,7 +10666,11 @@ var McpClient = class {
|
|
|
9851
10666
|
if (serverCapabilities.resources === void 0) {
|
|
9852
10667
|
throw new Error("Server does not support resources");
|
|
9853
10668
|
}
|
|
9854
|
-
|
|
10669
|
+
const result = await messageLayer.sendRequest("resources/read", params17);
|
|
10670
|
+
if (!isReadResourceResult(result)) {
|
|
10671
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/read result");
|
|
10672
|
+
}
|
|
10673
|
+
return result;
|
|
9855
10674
|
}
|
|
9856
10675
|
async subscribe(uri) {
|
|
9857
10676
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9886,7 +10705,11 @@ var McpClient = class {
|
|
|
9886
10705
|
if (serverCapabilities.prompts === void 0) {
|
|
9887
10706
|
throw new Error("Server does not support prompts");
|
|
9888
10707
|
}
|
|
9889
|
-
|
|
10708
|
+
const result = await messageLayer.sendRequest("prompts/get", params17);
|
|
10709
|
+
if (!isGetPromptResult(result)) {
|
|
10710
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid prompts/get result");
|
|
10711
|
+
}
|
|
10712
|
+
return result;
|
|
9890
10713
|
}
|
|
9891
10714
|
async complete(params17) {
|
|
9892
10715
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9894,7 +10717,11 @@ var McpClient = class {
|
|
|
9894
10717
|
if (serverCapabilities.completions === void 0) {
|
|
9895
10718
|
throw new Error("Server does not support completions");
|
|
9896
10719
|
}
|
|
9897
|
-
|
|
10720
|
+
const result = await messageLayer.sendRequest("completion/complete", params17);
|
|
10721
|
+
if (!isCompleteResult(result)) {
|
|
10722
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid completion/complete result");
|
|
10723
|
+
}
|
|
10724
|
+
return result;
|
|
9898
10725
|
}
|
|
9899
10726
|
async setLogLevel(level) {
|
|
9900
10727
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -10885,6 +11712,44 @@ function isCallToolResult(value) {
|
|
|
10885
11712
|
function isToolsListResult(value) {
|
|
10886
11713
|
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
10887
11714
|
}
|
|
11715
|
+
function isResourcesListResult(value) {
|
|
11716
|
+
return isObjectRecord5(value) && Array.isArray(value.resources) && value.resources.every(isResource) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11717
|
+
}
|
|
11718
|
+
function isResourceTemplatesListResult(value) {
|
|
11719
|
+
return isObjectRecord5(value) && Array.isArray(value.resourceTemplates) && value.resourceTemplates.every(isResourceTemplate) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11720
|
+
}
|
|
11721
|
+
function isReadResourceResult(value) {
|
|
11722
|
+
return isObjectRecord5(value) && Array.isArray(value.contents) && value.contents.every(isResourceContents);
|
|
11723
|
+
}
|
|
11724
|
+
function isGetPromptResult(value) {
|
|
11725
|
+
return isObjectRecord5(value) && (value.description === void 0 || typeof value.description === "string") && Array.isArray(value.messages) && value.messages.every(isPromptMessage);
|
|
11726
|
+
}
|
|
11727
|
+
function isCompleteResult(value) {
|
|
11728
|
+
return isObjectRecord5(value) && isObjectRecord5(value.completion) && Array.isArray(value.completion.values) && value.completion.values.every((candidate) => typeof candidate === "string") && (value.completion.hasMore === void 0 || typeof value.completion.hasMore === "boolean") && (value.completion.total === void 0 || typeof value.completion.total === "number");
|
|
11729
|
+
}
|
|
11730
|
+
function isResource(value) {
|
|
11731
|
+
return isObjectRecord5(value) && typeof value.uri === "string" && typeof value.name === "string" && (value.description === void 0 || typeof value.description === "string") && (value.mimeType === void 0 || typeof value.mimeType === "string") && (value.size === void 0 || typeof value.size === "number");
|
|
11732
|
+
}
|
|
11733
|
+
function isResourceTemplate(value) {
|
|
11734
|
+
return isObjectRecord5(value) && typeof value.uriTemplate === "string" && typeof value.name === "string" && (value.description === void 0 || typeof value.description === "string") && (value.mimeType === void 0 || typeof value.mimeType === "string");
|
|
11735
|
+
}
|
|
11736
|
+
function isResourceContents(value) {
|
|
11737
|
+
if (!isObjectRecord5(value) || typeof value.uri !== "string") {
|
|
11738
|
+
return false;
|
|
11739
|
+
}
|
|
11740
|
+
if (value.mimeType !== void 0 && typeof value.mimeType !== "string") {
|
|
11741
|
+
return false;
|
|
11742
|
+
}
|
|
11743
|
+
const hasText = value.text !== void 0;
|
|
11744
|
+
const hasBlob = value.blob !== void 0;
|
|
11745
|
+
if (!hasText && !hasBlob) {
|
|
11746
|
+
return false;
|
|
11747
|
+
}
|
|
11748
|
+
return (!hasText || typeof value.text === "string") && (!hasBlob || typeof value.blob === "string");
|
|
11749
|
+
}
|
|
11750
|
+
function isPromptMessage(value) {
|
|
11751
|
+
return isObjectRecord5(value) && (value.role === "user" || value.role === "assistant") && isContentItem(value.content);
|
|
11752
|
+
}
|
|
10888
11753
|
function isContentItem(value) {
|
|
10889
11754
|
if (!isObjectRecord5(value)) {
|
|
10890
11755
|
return false;
|
|
@@ -10898,7 +11763,7 @@ function isContentItem(value) {
|
|
|
10898
11763
|
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
10899
11764
|
return false;
|
|
10900
11765
|
}
|
|
10901
|
-
return
|
|
11766
|
+
return isResourceContents(value.resource);
|
|
10902
11767
|
}
|
|
10903
11768
|
function hasOwn(value, property) {
|
|
10904
11769
|
return Object.prototype.hasOwnProperty.call(value, property);
|
|
@@ -11038,13 +11903,13 @@ function convertJsonSchema(schema) {
|
|
|
11038
11903
|
}
|
|
11039
11904
|
return convertSchema(schema, schema, []);
|
|
11040
11905
|
}
|
|
11041
|
-
function convertSchema(schema, root,
|
|
11042
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
11906
|
+
function convertSchema(schema, root, path25) {
|
|
11907
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path25);
|
|
11043
11908
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
11044
11909
|
const composition = getComposition(normalizedSchema.schema);
|
|
11045
11910
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
11046
11911
|
throw new Error(
|
|
11047
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
11912
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
11048
11913
|
normalizedSchema.schema.type
|
|
11049
11914
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
11050
11915
|
);
|
|
@@ -11056,13 +11921,13 @@ function convertSchema(schema, root, path24) {
|
|
|
11056
11921
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
11057
11922
|
}
|
|
11058
11923
|
if (composition !== void 0) {
|
|
11059
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
11924
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path25);
|
|
11060
11925
|
}
|
|
11061
11926
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
11062
11927
|
return applyMetadata(
|
|
11063
11928
|
S.Record(
|
|
11064
11929
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
11065
|
-
...
|
|
11930
|
+
...path25,
|
|
11066
11931
|
"additionalProperties"
|
|
11067
11932
|
])
|
|
11068
11933
|
),
|
|
@@ -11111,12 +11976,12 @@ function convertSchema(schema, root, path24) {
|
|
|
11111
11976
|
if (normalizedSchema.schema.items === void 0) {
|
|
11112
11977
|
throw new Error(
|
|
11113
11978
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11114
|
-
|
|
11979
|
+
path25
|
|
11115
11980
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
11116
11981
|
);
|
|
11117
11982
|
}
|
|
11118
11983
|
return S.Array(
|
|
11119
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
11984
|
+
convertSchema(normalizedSchema.schema.items, root, [...path25, "items"]),
|
|
11120
11985
|
createCommonOptions(
|
|
11121
11986
|
normalizedSchema.schema,
|
|
11122
11987
|
normalizedSchema.nullable,
|
|
@@ -11126,7 +11991,7 @@ function convertSchema(schema, root, path24) {
|
|
|
11126
11991
|
case "object":
|
|
11127
11992
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
11128
11993
|
nullable: normalizedSchema.nullable,
|
|
11129
|
-
path:
|
|
11994
|
+
path: path25
|
|
11130
11995
|
});
|
|
11131
11996
|
case "null":
|
|
11132
11997
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -11141,12 +12006,12 @@ function convertSchema(schema, root, path24) {
|
|
|
11141
12006
|
}
|
|
11142
12007
|
throw new Error(
|
|
11143
12008
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11144
|
-
|
|
12009
|
+
path25
|
|
11145
12010
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
11146
12011
|
);
|
|
11147
12012
|
}
|
|
11148
12013
|
throw new Error(
|
|
11149
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12014
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
11150
12015
|
normalizedSchema.schema.type
|
|
11151
12016
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
11152
12017
|
);
|
|
@@ -11190,21 +12055,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
11190
12055
|
)
|
|
11191
12056
|
});
|
|
11192
12057
|
}
|
|
11193
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
12058
|
+
function convertCompositionSchema(schema, root, nullable, path25) {
|
|
11194
12059
|
const composition = getComposition(schema);
|
|
11195
12060
|
const branchSchemas = composition?.branches ?? [];
|
|
11196
12061
|
const keyword = composition?.keyword ?? "oneOf";
|
|
11197
12062
|
const branches = branchSchemas.map(
|
|
11198
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
12063
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path25, keyword, String(index)])
|
|
11199
12064
|
);
|
|
11200
|
-
const discriminator = findDiscriminator(branches, root,
|
|
12065
|
+
const discriminator = findDiscriminator(branches, root, path25);
|
|
11201
12066
|
if (discriminator !== void 0) {
|
|
11202
12067
|
const convertedBranches = Object.fromEntries(
|
|
11203
12068
|
branches.map((branch, index) => [
|
|
11204
12069
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
11205
12070
|
convertObjectSchema(branch, root, {
|
|
11206
12071
|
omitProperty: discriminator,
|
|
11207
|
-
path: [...
|
|
12072
|
+
path: [...path25, keyword, String(index)]
|
|
11208
12073
|
})
|
|
11209
12074
|
])
|
|
11210
12075
|
);
|
|
@@ -11223,7 +12088,7 @@ function convertCompositionSchema(schema, root, nullable, path24) {
|
|
|
11223
12088
|
S.Union(
|
|
11224
12089
|
branches.map(
|
|
11225
12090
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
11226
|
-
path: [...
|
|
12091
|
+
path: [...path25, keyword, String(index)]
|
|
11227
12092
|
})
|
|
11228
12093
|
)
|
|
11229
12094
|
),
|
|
@@ -11337,11 +12202,11 @@ function getComposition(schema) {
|
|
|
11337
12202
|
}
|
|
11338
12203
|
return void 0;
|
|
11339
12204
|
}
|
|
11340
|
-
function formatJsonSchemaPath(
|
|
11341
|
-
if (
|
|
12205
|
+
function formatJsonSchemaPath(path25) {
|
|
12206
|
+
if (path25.length === 0) {
|
|
11342
12207
|
return "#";
|
|
11343
12208
|
}
|
|
11344
|
-
return `#/${
|
|
12209
|
+
return `#/${path25.map(escapeJsonPointerSegment).join("/")}`;
|
|
11345
12210
|
}
|
|
11346
12211
|
function formatJsonSchemaType(type2) {
|
|
11347
12212
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -11357,11 +12222,11 @@ function isRecordSchema(schema) {
|
|
|
11357
12222
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
11358
12223
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
11359
12224
|
}
|
|
11360
|
-
function findDiscriminator(branches, root,
|
|
12225
|
+
function findDiscriminator(branches, root, path25) {
|
|
11361
12226
|
const [firstBranch] = branches;
|
|
11362
12227
|
if (firstBranch === void 0) {
|
|
11363
12228
|
throw new Error(
|
|
11364
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12229
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
11365
12230
|
);
|
|
11366
12231
|
}
|
|
11367
12232
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -11401,19 +12266,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
11401
12266
|
}
|
|
11402
12267
|
return void 0;
|
|
11403
12268
|
}
|
|
11404
|
-
function resolveReferencedSchema(schema, root,
|
|
12269
|
+
function resolveReferencedSchema(schema, root, path25) {
|
|
11405
12270
|
if (schema.$ref === void 0) {
|
|
11406
12271
|
return schema;
|
|
11407
12272
|
}
|
|
11408
12273
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
11409
12274
|
if (resolvedTarget === void 0) {
|
|
11410
12275
|
throw new Error(
|
|
11411
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12276
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
11412
12277
|
);
|
|
11413
12278
|
}
|
|
11414
12279
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
11415
12280
|
void ignoredRef;
|
|
11416
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
12281
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path25);
|
|
11417
12282
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
11418
12283
|
return resolvedSchema;
|
|
11419
12284
|
}
|
|
@@ -11437,9 +12302,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
11437
12302
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
11438
12303
|
};
|
|
11439
12304
|
}
|
|
11440
|
-
function hasSelfReferencingRef(schema, root,
|
|
12305
|
+
function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
11441
12306
|
const nextActivePaths = new Set(activePaths);
|
|
11442
|
-
nextActivePaths.add(
|
|
12307
|
+
nextActivePaths.add(path25);
|
|
11443
12308
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
11444
12309
|
if (localRefPath !== void 0) {
|
|
11445
12310
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -11450,13 +12315,13 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11450
12315
|
return true;
|
|
11451
12316
|
}
|
|
11452
12317
|
}
|
|
11453
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
12318
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path25}/items`, nextActivePaths)) {
|
|
11454
12319
|
return true;
|
|
11455
12320
|
}
|
|
11456
12321
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
11457
12322
|
schema.additionalProperties,
|
|
11458
12323
|
root,
|
|
11459
|
-
`${
|
|
12324
|
+
`${path25}/additionalProperties`,
|
|
11460
12325
|
nextActivePaths
|
|
11461
12326
|
)) {
|
|
11462
12327
|
return true;
|
|
@@ -11465,7 +12330,7 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11465
12330
|
if (hasSelfReferencingRef(
|
|
11466
12331
|
childSchema,
|
|
11467
12332
|
root,
|
|
11468
|
-
`${
|
|
12333
|
+
`${path25}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
11469
12334
|
nextActivePaths
|
|
11470
12335
|
)) {
|
|
11471
12336
|
return true;
|
|
@@ -11475,24 +12340,24 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11475
12340
|
if (hasSelfReferencingRef(
|
|
11476
12341
|
childSchema,
|
|
11477
12342
|
root,
|
|
11478
|
-
`${
|
|
12343
|
+
`${path25}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
11479
12344
|
nextActivePaths
|
|
11480
12345
|
)) {
|
|
11481
12346
|
return true;
|
|
11482
12347
|
}
|
|
11483
12348
|
}
|
|
11484
12349
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
11485
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12350
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/oneOf/${index}`, nextActivePaths)) {
|
|
11486
12351
|
return true;
|
|
11487
12352
|
}
|
|
11488
12353
|
}
|
|
11489
12354
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
11490
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12355
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/anyOf/${index}`, nextActivePaths)) {
|
|
11491
12356
|
return true;
|
|
11492
12357
|
}
|
|
11493
12358
|
}
|
|
11494
12359
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
11495
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12360
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/allOf/${index}`, nextActivePaths)) {
|
|
11496
12361
|
return true;
|
|
11497
12362
|
}
|
|
11498
12363
|
}
|
|
@@ -11508,14 +12373,14 @@ function getLocalRefPath(ref) {
|
|
|
11508
12373
|
return ref.startsWith("#/") ? ref : void 0;
|
|
11509
12374
|
}
|
|
11510
12375
|
function resolveLocalRef(root, ref) {
|
|
11511
|
-
const
|
|
11512
|
-
if (
|
|
12376
|
+
const path25 = getLocalRefPath(ref);
|
|
12377
|
+
if (path25 === void 0) {
|
|
11513
12378
|
return void 0;
|
|
11514
12379
|
}
|
|
11515
|
-
if (
|
|
12380
|
+
if (path25 === "#") {
|
|
11516
12381
|
return root;
|
|
11517
12382
|
}
|
|
11518
|
-
const segments =
|
|
12383
|
+
const segments = path25.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
11519
12384
|
let current = root;
|
|
11520
12385
|
for (const segment of segments) {
|
|
11521
12386
|
if (Array.isArray(current)) {
|
|
@@ -11561,15 +12426,15 @@ function getBooleanDefault(value) {
|
|
|
11561
12426
|
return typeof value === "boolean" ? value : void 0;
|
|
11562
12427
|
}
|
|
11563
12428
|
function getArrayDefault(value) {
|
|
11564
|
-
return Array.isArray(value) && value.every((item) =>
|
|
12429
|
+
return Array.isArray(value) && value.every((item) => isJsonValue2(item)) ? value : void 0;
|
|
11565
12430
|
}
|
|
11566
12431
|
function getPrimitiveEnumDefault(value, candidates) {
|
|
11567
12432
|
return isPrimitiveEnumValue(value) && candidates.includes(value) ? value : void 0;
|
|
11568
12433
|
}
|
|
11569
12434
|
function getJsonDefault(value) {
|
|
11570
|
-
return
|
|
12435
|
+
return isJsonValue2(value) ? value : void 0;
|
|
11571
12436
|
}
|
|
11572
|
-
function
|
|
12437
|
+
function isJsonValue2(value) {
|
|
11573
12438
|
if (value === null) {
|
|
11574
12439
|
return true;
|
|
11575
12440
|
}
|
|
@@ -11577,12 +12442,12 @@ function isJsonValue(value) {
|
|
|
11577
12442
|
return true;
|
|
11578
12443
|
}
|
|
11579
12444
|
if (Array.isArray(value)) {
|
|
11580
|
-
return value.every((item) =>
|
|
12445
|
+
return value.every((item) => isJsonValue2(item));
|
|
11581
12446
|
}
|
|
11582
12447
|
if (!isPlainObject(value)) {
|
|
11583
12448
|
return false;
|
|
11584
12449
|
}
|
|
11585
|
-
return Object.values(value).every((item) =>
|
|
12450
|
+
return Object.values(value).every((item) => isJsonValue2(item));
|
|
11586
12451
|
}
|
|
11587
12452
|
function isPlainObject(value) {
|
|
11588
12453
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -11772,7 +12637,7 @@ async function ensureConnected(connection) {
|
|
|
11772
12637
|
async function readCache(cachePath) {
|
|
11773
12638
|
try {
|
|
11774
12639
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
11775
|
-
const raw = await
|
|
12640
|
+
const raw = await readFile4(cachePath, "utf8");
|
|
11776
12641
|
const parsed = JSON.parse(raw);
|
|
11777
12642
|
if (parsed === null || typeof parsed !== "object" || !Array.isArray(parsed.tools) || parsed.upstream === void 0 || typeof parsed.upstream.name !== "string" || typeof parsed.upstream.version !== "string") {
|
|
11778
12643
|
return void 0;
|
|
@@ -11793,7 +12658,7 @@ async function readCache(cachePath) {
|
|
|
11793
12658
|
}
|
|
11794
12659
|
}
|
|
11795
12660
|
async function writeCache(cachePath, cache) {
|
|
11796
|
-
const directory =
|
|
12661
|
+
const directory = path13.dirname(cachePath);
|
|
11797
12662
|
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
11798
12663
|
let tempCreated = false;
|
|
11799
12664
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
@@ -11990,13 +12855,13 @@ function collectProxyGroups(root) {
|
|
|
11990
12855
|
function findProjectRoot(from = process.cwd()) {
|
|
11991
12856
|
let current = process.cwd();
|
|
11992
12857
|
if (from !== current) {
|
|
11993
|
-
current =
|
|
12858
|
+
current = path13.resolve(from);
|
|
11994
12859
|
}
|
|
11995
12860
|
while (true) {
|
|
11996
|
-
if (existsSync2(
|
|
12861
|
+
if (existsSync2(path13.join(current, "package.json"))) {
|
|
11997
12862
|
return current;
|
|
11998
12863
|
}
|
|
11999
|
-
const parent =
|
|
12864
|
+
const parent = path13.dirname(current);
|
|
12000
12865
|
if (parent === current) {
|
|
12001
12866
|
return void 0;
|
|
12002
12867
|
}
|
|
@@ -12013,7 +12878,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
12013
12878
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
12014
12879
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
12015
12880
|
}
|
|
12016
|
-
return
|
|
12881
|
+
return path13.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
12017
12882
|
}
|
|
12018
12883
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
12019
12884
|
let currentPath = filePath;
|
|
@@ -12027,10 +12892,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
12027
12892
|
throw error3;
|
|
12028
12893
|
}
|
|
12029
12894
|
}
|
|
12030
|
-
if (
|
|
12895
|
+
if (path13.basename(currentPath) === ".toolcraft") {
|
|
12031
12896
|
return;
|
|
12032
12897
|
}
|
|
12033
|
-
const parentPath =
|
|
12898
|
+
const parentPath = path13.dirname(currentPath);
|
|
12034
12899
|
if (parentPath === currentPath) {
|
|
12035
12900
|
return;
|
|
12036
12901
|
}
|
|
@@ -12176,20 +13041,20 @@ function reportsEnabled(option, env) {
|
|
|
12176
13041
|
function resolveReportDir(option, projectRoot) {
|
|
12177
13042
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12178
13043
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
12179
|
-
return
|
|
13044
|
+
return path14.join(projectRoot, ".toolcraft", "errors");
|
|
12180
13045
|
}
|
|
12181
|
-
return
|
|
13046
|
+
return path14.isAbsolute(configuredDir) ? configuredDir : path14.join(projectRoot, configuredDir);
|
|
12182
13047
|
}
|
|
12183
13048
|
function reportDirMustStayWithinProject(option) {
|
|
12184
13049
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12185
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
13050
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path14.isAbsolute(configuredDir);
|
|
12186
13051
|
}
|
|
12187
13052
|
function isWithinDirectory(parent, child) {
|
|
12188
|
-
const relative =
|
|
12189
|
-
return relative === "" || !
|
|
13053
|
+
const relative = path14.relative(parent, child);
|
|
13054
|
+
return relative === "" || !path14.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path14.sep}`);
|
|
12190
13055
|
}
|
|
12191
13056
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
12192
|
-
if (!isWithinDirectory(
|
|
13057
|
+
if (!isWithinDirectory(path14.resolve(projectRoot), path14.resolve(reportDir))) {
|
|
12193
13058
|
throw new Error("Error report directory resolves outside project root.");
|
|
12194
13059
|
}
|
|
12195
13060
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
@@ -12240,7 +13105,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
12240
13105
|
return output.length === 0 ? "root" : output;
|
|
12241
13106
|
}
|
|
12242
13107
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
12243
|
-
const relative =
|
|
13108
|
+
const relative = path14.relative(projectRoot, absolutePath);
|
|
12244
13109
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
12245
13110
|
}
|
|
12246
13111
|
function redactValue(value) {
|
|
@@ -12560,7 +13425,7 @@ async function writeErrorReport(context) {
|
|
|
12560
13425
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
12561
13426
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
12562
13427
|
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
12563
|
-
const absolutePath =
|
|
13428
|
+
const absolutePath = path14.join(reportDir, fileName);
|
|
12564
13429
|
await mkdir2(reportDir, { recursive: true });
|
|
12565
13430
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
12566
13431
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -13030,7 +13895,7 @@ function inferProgramName(argv) {
|
|
|
13030
13895
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
13031
13896
|
return "toolcraft";
|
|
13032
13897
|
}
|
|
13033
|
-
const parsed =
|
|
13898
|
+
const parsed = path15.parse(entrypoint);
|
|
13034
13899
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
13035
13900
|
}
|
|
13036
13901
|
function normalizeRoots(roots, argv) {
|
|
@@ -13088,11 +13953,11 @@ function formatSegment(segment, casing) {
|
|
|
13088
13953
|
const separator = casing === "snake" ? "_" : "-";
|
|
13089
13954
|
return splitWords3(segment).join(separator);
|
|
13090
13955
|
}
|
|
13091
|
-
function toOptionFlag(
|
|
13092
|
-
return `--${
|
|
13956
|
+
function toOptionFlag(path25, casing) {
|
|
13957
|
+
return `--${path25.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
13093
13958
|
}
|
|
13094
|
-
function toOptionAttribute(
|
|
13095
|
-
return
|
|
13959
|
+
function toOptionAttribute(path25, casing) {
|
|
13960
|
+
return path25.map((segment) => {
|
|
13096
13961
|
const formatted = formatSegment(segment, casing);
|
|
13097
13962
|
if (casing === "snake") {
|
|
13098
13963
|
return formatted;
|
|
@@ -13103,23 +13968,23 @@ function toOptionAttribute(path24, casing) {
|
|
|
13103
13968
|
).join("");
|
|
13104
13969
|
}).join(".");
|
|
13105
13970
|
}
|
|
13106
|
-
function toDisplayPath(
|
|
13107
|
-
return
|
|
13971
|
+
function toDisplayPath(path25) {
|
|
13972
|
+
return path25.join(".");
|
|
13108
13973
|
}
|
|
13109
|
-
function toUnionKindControlPath(
|
|
13110
|
-
if (
|
|
13974
|
+
function toUnionKindControlPath(path25) {
|
|
13975
|
+
if (path25.length === 0) {
|
|
13111
13976
|
return ["kind"];
|
|
13112
13977
|
}
|
|
13113
|
-
const head =
|
|
13114
|
-
const tail =
|
|
13978
|
+
const head = path25.slice(0, -1);
|
|
13979
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
13115
13980
|
return [...head, `${tail}Kind`];
|
|
13116
13981
|
}
|
|
13117
|
-
function toUnionKindDisplayPath(
|
|
13118
|
-
if (
|
|
13982
|
+
function toUnionKindDisplayPath(path25) {
|
|
13983
|
+
if (path25.length === 0) {
|
|
13119
13984
|
return "kind";
|
|
13120
13985
|
}
|
|
13121
|
-
const head =
|
|
13122
|
-
const tail =
|
|
13986
|
+
const head = path25.slice(0, -1);
|
|
13987
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
13123
13988
|
return [...head, `${tail}-kind`].join(".");
|
|
13124
13989
|
}
|
|
13125
13990
|
function createSyntheticEnumSchema(values) {
|
|
@@ -13135,14 +14000,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
13135
14000
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
13136
14001
|
return requiredKeys.join("+");
|
|
13137
14002
|
}
|
|
13138
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
14003
|
+
function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inheritedOptional = false, variantContext) {
|
|
13139
14004
|
const collected = {
|
|
13140
14005
|
dynamicFields: [],
|
|
13141
14006
|
fields: [],
|
|
13142
14007
|
variants: []
|
|
13143
14008
|
};
|
|
13144
14009
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
13145
|
-
const nextPath = [...
|
|
14010
|
+
const nextPath = [...path25, key2];
|
|
13146
14011
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
13147
14012
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
13148
14013
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -13328,9 +14193,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inher
|
|
|
13328
14193
|
}
|
|
13329
14194
|
return collected;
|
|
13330
14195
|
}
|
|
13331
|
-
function toCommanderOptionAttribute(
|
|
13332
|
-
const optionAttribute = toOptionAttribute(
|
|
13333
|
-
const optionFlag = toOptionFlag(
|
|
14196
|
+
function toCommanderOptionAttribute(path25, casing, globalLongOptionFlags) {
|
|
14197
|
+
const optionAttribute = toOptionAttribute(path25, casing);
|
|
14198
|
+
const optionFlag = toOptionFlag(path25, casing);
|
|
13334
14199
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
13335
14200
|
return optionAttribute;
|
|
13336
14201
|
}
|
|
@@ -13603,6 +14468,20 @@ function parseArrayValue(value, schema, label) {
|
|
|
13603
14468
|
(item) => parseScalarValue(item, itemSchema, label)
|
|
13604
14469
|
);
|
|
13605
14470
|
}
|
|
14471
|
+
function isNegativeNumericArrayToken(token, schema) {
|
|
14472
|
+
if (!token.startsWith("-") || token.startsWith("--")) {
|
|
14473
|
+
return false;
|
|
14474
|
+
}
|
|
14475
|
+
const itemSchema = unwrapOptional2(schema.item);
|
|
14476
|
+
if (itemSchema.kind !== "number") {
|
|
14477
|
+
return false;
|
|
14478
|
+
}
|
|
14479
|
+
const items = splitArrayInput(token);
|
|
14480
|
+
return items.length > 0 && items.every((item) => isValidNumberSchemaValue(Number(item), itemSchema));
|
|
14481
|
+
}
|
|
14482
|
+
function isNextArrayOptionToken(token, schema) {
|
|
14483
|
+
return token.startsWith("-") && !isNegativeNumericArrayToken(token, schema);
|
|
14484
|
+
}
|
|
13606
14485
|
function validateArrayBounds(value, schema, label) {
|
|
13607
14486
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
13608
14487
|
throw new UserError(
|
|
@@ -14410,10 +15289,10 @@ function parseDebugStackMode(value) {
|
|
|
14410
15289
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
14411
15290
|
);
|
|
14412
15291
|
}
|
|
14413
|
-
function setNestedValue(target,
|
|
15292
|
+
function setNestedValue(target, path25, value) {
|
|
14414
15293
|
let cursor2 = target;
|
|
14415
|
-
for (let index = 0; index <
|
|
14416
|
-
const segment =
|
|
15294
|
+
for (let index = 0; index < path25.length - 1; index += 1) {
|
|
15295
|
+
const segment = path25[index] ?? "";
|
|
14417
15296
|
const existing = Object.prototype.hasOwnProperty.call(cursor2, segment) ? cursor2[segment] : void 0;
|
|
14418
15297
|
if (typeof existing === "object" && existing !== null) {
|
|
14419
15298
|
cursor2 = existing;
|
|
@@ -14428,7 +15307,7 @@ function setNestedValue(target, path24, value) {
|
|
|
14428
15307
|
});
|
|
14429
15308
|
cursor2 = next;
|
|
14430
15309
|
}
|
|
14431
|
-
const leaf =
|
|
15310
|
+
const leaf = path25[path25.length - 1];
|
|
14432
15311
|
if (leaf !== void 0) {
|
|
14433
15312
|
Object.defineProperty(cursor2, leaf, {
|
|
14434
15313
|
value,
|
|
@@ -14545,21 +15424,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
14545
15424
|
}
|
|
14546
15425
|
function createFs2() {
|
|
14547
15426
|
return {
|
|
14548
|
-
readFile: async (
|
|
14549
|
-
writeFile: async (
|
|
14550
|
-
await writeFile5(
|
|
15427
|
+
readFile: async (path25, encoding = "utf8") => readFile5(path25, { encoding }),
|
|
15428
|
+
writeFile: async (path25, contents, options) => {
|
|
15429
|
+
await writeFile5(path25, contents, options);
|
|
14551
15430
|
},
|
|
14552
|
-
exists: async (
|
|
15431
|
+
exists: async (path25) => {
|
|
14553
15432
|
try {
|
|
14554
|
-
await access2(
|
|
15433
|
+
await access2(path25);
|
|
14555
15434
|
return true;
|
|
14556
15435
|
} catch {
|
|
14557
15436
|
return false;
|
|
14558
15437
|
}
|
|
14559
15438
|
},
|
|
14560
|
-
lstat: async (
|
|
15439
|
+
lstat: async (path25) => lstat3(path25),
|
|
14561
15440
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
14562
|
-
unlink: async (
|
|
15441
|
+
unlink: async (path25) => unlink3(path25)
|
|
14563
15442
|
};
|
|
14564
15443
|
}
|
|
14565
15444
|
function createEnv2(values = process.env) {
|
|
@@ -14575,9 +15454,9 @@ function isPlainObject4(value) {
|
|
|
14575
15454
|
function hasFieldValue(value) {
|
|
14576
15455
|
return value !== void 0;
|
|
14577
15456
|
}
|
|
14578
|
-
function hasNestedField(fields,
|
|
15457
|
+
function hasNestedField(fields, path25) {
|
|
14579
15458
|
return fields.some(
|
|
14580
|
-
(field) =>
|
|
15459
|
+
(field) => path25.length < field.path.length && path25.every((segment, index) => field.path[index] === segment)
|
|
14581
15460
|
);
|
|
14582
15461
|
}
|
|
14583
15462
|
function describeExpectedPresetValue(schema) {
|
|
@@ -14680,7 +15559,7 @@ function validatePresetFieldValue(value, field, presetPath) {
|
|
|
14680
15559
|
async function loadPresetValues(fields, presetPath) {
|
|
14681
15560
|
let rawPreset;
|
|
14682
15561
|
try {
|
|
14683
|
-
rawPreset = await
|
|
15562
|
+
rawPreset = await readFile5(presetPath, {
|
|
14684
15563
|
encoding: "utf8"
|
|
14685
15564
|
});
|
|
14686
15565
|
} catch (error3) {
|
|
@@ -14706,9 +15585,9 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
14706
15585
|
}
|
|
14707
15586
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
14708
15587
|
const presetValues = {};
|
|
14709
|
-
function visitObject(current,
|
|
15588
|
+
function visitObject(current, path25) {
|
|
14710
15589
|
for (const [key2, value] of Object.entries(current)) {
|
|
14711
|
-
const nextPath = [...
|
|
15590
|
+
const nextPath = [...path25, key2];
|
|
14712
15591
|
const displayPath = toDisplayPath(nextPath);
|
|
14713
15592
|
const field = fieldByPath.get(displayPath);
|
|
14714
15593
|
if (field !== void 0) {
|
|
@@ -14915,8 +15794,8 @@ function createFixtureService(definition) {
|
|
|
14915
15794
|
);
|
|
14916
15795
|
}
|
|
14917
15796
|
function resolveFixturePath(commandPath) {
|
|
14918
|
-
const parsed =
|
|
14919
|
-
return
|
|
15797
|
+
const parsed = path15.parse(commandPath);
|
|
15798
|
+
return path15.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
14920
15799
|
}
|
|
14921
15800
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
14922
15801
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -14947,7 +15826,7 @@ async function loadFixtureScenario(command, selector) {
|
|
|
14947
15826
|
const fixturePath = resolveFixturePath(commandPath);
|
|
14948
15827
|
let rawFixture;
|
|
14949
15828
|
try {
|
|
14950
|
-
rawFixture = await
|
|
15829
|
+
rawFixture = await readFile5(fixturePath, {
|
|
14951
15830
|
encoding: "utf8"
|
|
14952
15831
|
});
|
|
14953
15832
|
} catch {
|
|
@@ -15050,8 +15929,8 @@ function validateServices(services) {
|
|
|
15050
15929
|
}
|
|
15051
15930
|
}
|
|
15052
15931
|
}
|
|
15053
|
-
function getNestedValue(target,
|
|
15054
|
-
return
|
|
15932
|
+
function getNestedValue(target, path25) {
|
|
15933
|
+
return path25.reduce(
|
|
15055
15934
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
15056
15935
|
target
|
|
15057
15936
|
);
|
|
@@ -15136,7 +16015,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
|
|
|
15136
16015
|
let cursor2 = index + 1;
|
|
15137
16016
|
while (cursor2 < args.length) {
|
|
15138
16017
|
const token = args[cursor2] ?? "";
|
|
15139
|
-
if (token
|
|
16018
|
+
if (isNextArrayOptionToken(token, schema)) {
|
|
15140
16019
|
break;
|
|
15141
16020
|
}
|
|
15142
16021
|
const parsed = parseArrayValue(token, schema, label);
|
|
@@ -16012,6 +16891,12 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
16012
16891
|
);
|
|
16013
16892
|
return;
|
|
16014
16893
|
}
|
|
16894
|
+
logger2.error(
|
|
16895
|
+
appendUsagePointer(formatCommanderErrorMessage(error3), {
|
|
16896
|
+
rootUsageName: options.rootUsageName,
|
|
16897
|
+
commandPath: options.commandPath.length > 0 ? options.commandPath : findCurrentCommanderCommandPath(options.program, options.argv ?? process.argv)
|
|
16898
|
+
})
|
|
16899
|
+
);
|
|
16015
16900
|
return;
|
|
16016
16901
|
}
|
|
16017
16902
|
if (isHttpErrorLike(error3)) {
|
|
@@ -16029,6 +16914,9 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
16029
16914
|
}
|
|
16030
16915
|
process.exitCode = 1;
|
|
16031
16916
|
}
|
|
16917
|
+
function formatCommanderErrorMessage(error3) {
|
|
16918
|
+
return error3.message.startsWith("error:") ? error3.message : `error: ${error3.message}`;
|
|
16919
|
+
}
|
|
16032
16920
|
function formatInvalidEnumMessage(label, value, values, opts = {}) {
|
|
16033
16921
|
const suggestions = suggest(
|
|
16034
16922
|
value,
|
|
@@ -16353,7 +17241,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
|
|
|
16353
17241
|
// src/terminal-session.ts
|
|
16354
17242
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
16355
17243
|
import { accessSync, chmodSync, constants } from "node:fs";
|
|
16356
|
-
import { createRequire } from "node:module";
|
|
17244
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
16357
17245
|
import { dirname, join } from "node:path";
|
|
16358
17246
|
import * as nodePty from "node-pty";
|
|
16359
17247
|
|
|
@@ -17492,8 +18380,8 @@ var spawnHelperChecked = false;
|
|
|
17492
18380
|
function ensureSpawnHelperExecutable() {
|
|
17493
18381
|
if (spawnHelperChecked) return;
|
|
17494
18382
|
spawnHelperChecked = true;
|
|
17495
|
-
const
|
|
17496
|
-
const nodePtyDir = dirname(
|
|
18383
|
+
const require4 = createRequire2(import.meta.url);
|
|
18384
|
+
const nodePtyDir = dirname(require4.resolve("node-pty"));
|
|
17497
18385
|
const helper = join(nodePtyDir, "..", "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper");
|
|
17498
18386
|
try {
|
|
17499
18387
|
accessSync(helper, constants.X_OK);
|
|
@@ -17913,7 +18801,7 @@ var getSession = defineCommand({
|
|
|
17913
18801
|
|
|
17914
18802
|
// ../agent-skill-config/src/configs.ts
|
|
17915
18803
|
import os2 from "node:os";
|
|
17916
|
-
import
|
|
18804
|
+
import path16 from "node:path";
|
|
17917
18805
|
|
|
17918
18806
|
// ../agent-defs/src/agents/claude-code.ts
|
|
17919
18807
|
var claudeCodeAgent = {
|
|
@@ -18277,7 +19165,7 @@ var templateMutation = {
|
|
|
18277
19165
|
|
|
18278
19166
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
18279
19167
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18280
|
-
import
|
|
19168
|
+
import path18 from "node:path";
|
|
18281
19169
|
|
|
18282
19170
|
// ../config-mutations/src/formats/json.ts
|
|
18283
19171
|
import * as jsonc from "jsonc-parser";
|
|
@@ -18400,22 +19288,22 @@ function prune(obj, shape) {
|
|
|
18400
19288
|
}
|
|
18401
19289
|
return { changed, result };
|
|
18402
19290
|
}
|
|
18403
|
-
function modifyAtPath(content,
|
|
19291
|
+
function modifyAtPath(content, path25, value) {
|
|
18404
19292
|
const indent = detectIndent(content);
|
|
18405
19293
|
const formattingOptions = {
|
|
18406
19294
|
tabSize: indent === " " ? 1 : indent.length,
|
|
18407
19295
|
insertSpaces: indent !== " ",
|
|
18408
19296
|
eol: "\n"
|
|
18409
19297
|
};
|
|
18410
|
-
const edits = jsonc.modify(content,
|
|
19298
|
+
const edits = jsonc.modify(content, path25, value, { formattingOptions });
|
|
18411
19299
|
let result = jsonc.applyEdits(content, edits);
|
|
18412
19300
|
if (!result.endsWith("\n")) {
|
|
18413
19301
|
result += "\n";
|
|
18414
19302
|
}
|
|
18415
19303
|
return result;
|
|
18416
19304
|
}
|
|
18417
|
-
function removeAtPath(content,
|
|
18418
|
-
return modifyAtPath(content,
|
|
19305
|
+
function removeAtPath(content, path25) {
|
|
19306
|
+
return modifyAtPath(content, path25, void 0);
|
|
18419
19307
|
}
|
|
18420
19308
|
function serializeUpdate(content, current, next) {
|
|
18421
19309
|
let result = content || "{}";
|
|
@@ -18425,15 +19313,15 @@ function serializeUpdate(content, current, next) {
|
|
|
18425
19313
|
}
|
|
18426
19314
|
return result;
|
|
18427
19315
|
}
|
|
18428
|
-
function applyObjectUpdate(content,
|
|
19316
|
+
function applyObjectUpdate(content, path25, current, next) {
|
|
18429
19317
|
let result = content;
|
|
18430
19318
|
for (const key2 of Object.keys(current)) {
|
|
18431
19319
|
if (!hasConfigEntry(next, key2)) {
|
|
18432
|
-
result = removeAtPath(result, [...
|
|
19320
|
+
result = removeAtPath(result, [...path25, key2]);
|
|
18433
19321
|
}
|
|
18434
19322
|
}
|
|
18435
19323
|
for (const [key2, nextValue] of Object.entries(next)) {
|
|
18436
|
-
const nextPath = [...
|
|
19324
|
+
const nextPath = [...path25, key2];
|
|
18437
19325
|
const hasCurrent = hasConfigEntry(current, key2);
|
|
18438
19326
|
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
18439
19327
|
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
@@ -18633,20 +19521,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
18633
19521
|
}
|
|
18634
19522
|
return formatRegistry[formatName];
|
|
18635
19523
|
}
|
|
18636
|
-
function detectFormat(
|
|
18637
|
-
const ext = getExtension(
|
|
19524
|
+
function detectFormat(path25) {
|
|
19525
|
+
const ext = getExtension(path25);
|
|
18638
19526
|
return extensionMap[ext];
|
|
18639
19527
|
}
|
|
18640
|
-
function getExtension(
|
|
18641
|
-
const lastDot =
|
|
19528
|
+
function getExtension(path25) {
|
|
19529
|
+
const lastDot = path25.lastIndexOf(".");
|
|
18642
19530
|
if (lastDot === -1) {
|
|
18643
19531
|
return "";
|
|
18644
19532
|
}
|
|
18645
|
-
return
|
|
19533
|
+
return path25.slice(lastDot).toLowerCase();
|
|
18646
19534
|
}
|
|
18647
19535
|
|
|
18648
19536
|
// ../config-mutations/src/execution/path-utils.ts
|
|
18649
|
-
import
|
|
19537
|
+
import path17 from "node:path";
|
|
18650
19538
|
function expandHome(targetPath, homeDir) {
|
|
18651
19539
|
if (!targetPath?.startsWith("~")) {
|
|
18652
19540
|
return targetPath;
|
|
@@ -18663,7 +19551,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
18663
19551
|
remainder = remainder.slice(1);
|
|
18664
19552
|
}
|
|
18665
19553
|
}
|
|
18666
|
-
return remainder.length === 0 ? homeDir :
|
|
19554
|
+
return remainder.length === 0 ? homeDir : path17.join(homeDir, remainder);
|
|
18667
19555
|
}
|
|
18668
19556
|
function validateHomePath(targetPath) {
|
|
18669
19557
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -18678,21 +19566,21 @@ function validateHomePath(targetPath) {
|
|
|
18678
19566
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
18679
19567
|
validateHomePath(rawPath);
|
|
18680
19568
|
const expanded = expandHome(rawPath, homeDir);
|
|
18681
|
-
const canonicalHome =
|
|
18682
|
-
const canonicalExpanded =
|
|
18683
|
-
const relative =
|
|
18684
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
19569
|
+
const canonicalHome = path17.resolve(homeDir);
|
|
19570
|
+
const canonicalExpanded = path17.resolve(expanded);
|
|
19571
|
+
const relative = path17.relative(canonicalHome, canonicalExpanded);
|
|
19572
|
+
if (relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
|
|
18685
19573
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
18686
19574
|
}
|
|
18687
19575
|
if (!pathMapper) {
|
|
18688
19576
|
return canonicalExpanded;
|
|
18689
19577
|
}
|
|
18690
|
-
const rawDirectory =
|
|
19578
|
+
const rawDirectory = path17.dirname(expanded);
|
|
18691
19579
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
18692
19580
|
targetDirectory: rawDirectory
|
|
18693
19581
|
});
|
|
18694
|
-
const filename =
|
|
18695
|
-
return filename.length === 0 ? mappedDirectory :
|
|
19582
|
+
const filename = path17.basename(expanded);
|
|
19583
|
+
return filename.length === 0 ? mappedDirectory : path17.join(mappedDirectory, filename);
|
|
18696
19584
|
}
|
|
18697
19585
|
|
|
18698
19586
|
// ../config-mutations/src/error-codes.ts
|
|
@@ -18704,9 +19592,9 @@ function hasOwnErrorCode5(error3, code) {
|
|
|
18704
19592
|
function isNotFound(error3) {
|
|
18705
19593
|
return hasOwnErrorCode5(error3, "ENOENT");
|
|
18706
19594
|
}
|
|
18707
|
-
async function readFileIfExists(
|
|
19595
|
+
async function readFileIfExists(fs5, target) {
|
|
18708
19596
|
try {
|
|
18709
|
-
return await
|
|
19597
|
+
return await fs5.readFile(target, "utf8");
|
|
18710
19598
|
} catch (error3) {
|
|
18711
19599
|
if (isNotFound(error3)) {
|
|
18712
19600
|
return null;
|
|
@@ -18714,9 +19602,9 @@ async function readFileIfExists(fs4, target) {
|
|
|
18714
19602
|
throw error3;
|
|
18715
19603
|
}
|
|
18716
19604
|
}
|
|
18717
|
-
async function pathExists(
|
|
19605
|
+
async function pathExists(fs5, target) {
|
|
18718
19606
|
try {
|
|
18719
|
-
await
|
|
19607
|
+
await fs5.stat(target);
|
|
18720
19608
|
return true;
|
|
18721
19609
|
} catch (error3) {
|
|
18722
19610
|
if (isNotFound(error3)) {
|
|
@@ -18762,8 +19650,8 @@ function isAlreadyExists(error3) {
|
|
|
18762
19650
|
return hasOwnErrorCode5(error3, "EEXIST");
|
|
18763
19651
|
}
|
|
18764
19652
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
18765
|
-
const boundary =
|
|
18766
|
-
let currentPath =
|
|
19653
|
+
const boundary = path18.dirname(path18.resolve(context.homeDir));
|
|
19654
|
+
let currentPath = path18.resolve(targetPath);
|
|
18767
19655
|
while (currentPath !== boundary) {
|
|
18768
19656
|
try {
|
|
18769
19657
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -18774,7 +19662,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
18774
19662
|
throw error3;
|
|
18775
19663
|
}
|
|
18776
19664
|
}
|
|
18777
|
-
const parentPath =
|
|
19665
|
+
const parentPath = path18.dirname(currentPath);
|
|
18778
19666
|
if (parentPath === currentPath) {
|
|
18779
19667
|
return;
|
|
18780
19668
|
}
|
|
@@ -18839,6 +19727,56 @@ function describeMutation(kind, targetPath) {
|
|
|
18839
19727
|
return "Operation";
|
|
18840
19728
|
}
|
|
18841
19729
|
}
|
|
19730
|
+
function mutationTargetPath(mutation, options) {
|
|
19731
|
+
switch (mutation.kind) {
|
|
19732
|
+
case "ensureDirectory":
|
|
19733
|
+
case "removeDirectory":
|
|
19734
|
+
return resolveValue(mutation.path, options);
|
|
19735
|
+
case "removeFile":
|
|
19736
|
+
case "chmod":
|
|
19737
|
+
case "backup":
|
|
19738
|
+
case "restoreBackup":
|
|
19739
|
+
case "configMerge":
|
|
19740
|
+
case "configPrune":
|
|
19741
|
+
case "configTransform":
|
|
19742
|
+
case "templateWrite":
|
|
19743
|
+
case "templateMergeToml":
|
|
19744
|
+
case "templateMergeJson":
|
|
19745
|
+
return resolveValue(mutation.target, options);
|
|
19746
|
+
default:
|
|
19747
|
+
return void 0;
|
|
19748
|
+
}
|
|
19749
|
+
}
|
|
19750
|
+
function resolveMutationDetails(mutation, context, options) {
|
|
19751
|
+
try {
|
|
19752
|
+
const rawTarget = mutationTargetPath(mutation, options);
|
|
19753
|
+
if (rawTarget === void 0) {
|
|
19754
|
+
return {
|
|
19755
|
+
kind: mutation.kind,
|
|
19756
|
+
label: mutation.label ?? mutation.kind
|
|
19757
|
+
};
|
|
19758
|
+
}
|
|
19759
|
+
try {
|
|
19760
|
+
const targetPath = resolvePath(rawTarget, context.homeDir, context.pathMapper);
|
|
19761
|
+
return {
|
|
19762
|
+
kind: mutation.kind,
|
|
19763
|
+
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19764
|
+
targetPath
|
|
19765
|
+
};
|
|
19766
|
+
} catch {
|
|
19767
|
+
return {
|
|
19768
|
+
kind: mutation.kind,
|
|
19769
|
+
label: mutation.label ?? describeMutation(mutation.kind, rawTarget),
|
|
19770
|
+
targetPath: void 0
|
|
19771
|
+
};
|
|
19772
|
+
}
|
|
19773
|
+
} catch {
|
|
19774
|
+
return {
|
|
19775
|
+
kind: mutation.kind,
|
|
19776
|
+
label: mutation.label ?? mutation.kind
|
|
19777
|
+
};
|
|
19778
|
+
}
|
|
19779
|
+
}
|
|
18842
19780
|
function pruneKeysByPrefix(table, prefix) {
|
|
18843
19781
|
const result = {};
|
|
18844
19782
|
for (const [key2, value] of Object.entries(table)) {
|
|
@@ -18929,6 +19867,7 @@ async function applyEnsureDirectory(mutation, context, options) {
|
|
|
18929
19867
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
18930
19868
|
targetPath
|
|
18931
19869
|
};
|
|
19870
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
18932
19871
|
const existed = await pathExists(context.fs, targetPath);
|
|
18933
19872
|
if (!context.dryRun) {
|
|
18934
19873
|
await context.fs.mkdir(targetPath, { recursive: true });
|
|
@@ -19045,6 +19984,7 @@ async function applyChmod(mutation, context, options) {
|
|
|
19045
19984
|
};
|
|
19046
19985
|
}
|
|
19047
19986
|
try {
|
|
19987
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19048
19988
|
const stat2 = await context.fs.stat(targetPath);
|
|
19049
19989
|
const currentMode = typeof stat2.mode === "number" ? stat2.mode & 511 : null;
|
|
19050
19990
|
if (currentMode === mutation.mode) {
|
|
@@ -19078,6 +20018,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
19078
20018
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19079
20019
|
targetPath
|
|
19080
20020
|
};
|
|
20021
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19081
20022
|
if (mutation.once && await findLatestGeneratedBackup(context.fs, targetPath) !== null) {
|
|
19082
20023
|
return {
|
|
19083
20024
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
@@ -19144,13 +20085,13 @@ async function applyRestoreBackup(mutation, context, options) {
|
|
|
19144
20085
|
}
|
|
19145
20086
|
return { outcome: { changed: true, effect: "copy", detail: "restore" }, details };
|
|
19146
20087
|
}
|
|
19147
|
-
async function findLatestGeneratedBackup(
|
|
20088
|
+
async function findLatestGeneratedBackup(fs5, targetPath) {
|
|
19148
20089
|
const separatorIndex = targetPath.lastIndexOf("/");
|
|
19149
20090
|
const directoryPath = separatorIndex <= 0 ? "/" : targetPath.slice(0, separatorIndex);
|
|
19150
20091
|
const targetName = targetPath.slice(separatorIndex + 1);
|
|
19151
20092
|
let entries;
|
|
19152
20093
|
try {
|
|
19153
|
-
entries = await
|
|
20094
|
+
entries = await fs5.readdir(directoryPath);
|
|
19154
20095
|
} catch (error3) {
|
|
19155
20096
|
if (isNotFound(error3)) {
|
|
19156
20097
|
return null;
|
|
@@ -19214,6 +20155,9 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
19214
20155
|
preserveContent = null;
|
|
19215
20156
|
}
|
|
19216
20157
|
const value = resolveValue(mutation.value, options);
|
|
20158
|
+
if (!isConfigObject4(value)) {
|
|
20159
|
+
throw new Error(`configMerge value must be an object for "${rawPath}".`);
|
|
20160
|
+
}
|
|
19217
20161
|
let merged;
|
|
19218
20162
|
if (mutation.pruneByPrefix) {
|
|
19219
20163
|
merged = mergeWithPruneByPrefix(current, value, mutation.pruneByPrefix);
|
|
@@ -19347,6 +20291,13 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
19347
20291
|
};
|
|
19348
20292
|
}
|
|
19349
20293
|
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
20294
|
+
const serializedChanged = serialized !== rawContent;
|
|
20295
|
+
if (!serializedChanged) {
|
|
20296
|
+
return {
|
|
20297
|
+
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
20298
|
+
details
|
|
20299
|
+
};
|
|
20300
|
+
}
|
|
19350
20301
|
if (!context.dryRun) {
|
|
19351
20302
|
await writeAtomically2(context, targetPath, serialized);
|
|
19352
20303
|
}
|
|
@@ -19463,25 +20414,14 @@ async function runMutations(mutations, context, options) {
|
|
|
19463
20414
|
};
|
|
19464
20415
|
}
|
|
19465
20416
|
async function executeMutation(mutation, context, options) {
|
|
19466
|
-
context
|
|
19467
|
-
|
|
19468
|
-
label: mutation.label ?? mutation.kind,
|
|
19469
|
-
targetPath: void 0
|
|
19470
|
-
// Will be resolved during apply
|
|
19471
|
-
});
|
|
20417
|
+
const pendingDetails = resolveMutationDetails(mutation, context, options);
|
|
20418
|
+
context.observers?.onStart?.(pendingDetails);
|
|
19472
20419
|
try {
|
|
19473
20420
|
const { outcome, details } = await applyMutation(mutation, context, options);
|
|
19474
20421
|
context.observers?.onComplete?.(details, outcome);
|
|
19475
20422
|
return { outcome, details };
|
|
19476
20423
|
} catch (error3) {
|
|
19477
|
-
context.observers?.onError?.(
|
|
19478
|
-
{
|
|
19479
|
-
kind: mutation.kind,
|
|
19480
|
-
label: mutation.label ?? mutation.kind,
|
|
19481
|
-
targetPath: void 0
|
|
19482
|
-
},
|
|
19483
|
-
error3
|
|
19484
|
-
);
|
|
20424
|
+
context.observers?.onError?.(pendingDetails, error3);
|
|
19485
20425
|
throw error3;
|
|
19486
20426
|
}
|
|
19487
20427
|
}
|
|
@@ -19492,8 +20432,8 @@ function hasOwnErrorCode6(error3, code) {
|
|
|
19492
20432
|
}
|
|
19493
20433
|
|
|
19494
20434
|
// ../agent-skill-config/src/templates.ts
|
|
19495
|
-
import { readFile as
|
|
19496
|
-
import
|
|
20435
|
+
import { readFile as readFile6, stat } from "node:fs/promises";
|
|
20436
|
+
import path19 from "node:path";
|
|
19497
20437
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19498
20438
|
|
|
19499
20439
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -19510,9 +20450,9 @@ function toHomeRelative(localSkillDir) {
|
|
|
19510
20450
|
const normalized = localSkillDir.startsWith("./") ? localSkillDir.slice(2) : localSkillDir;
|
|
19511
20451
|
return `~/${normalized}`;
|
|
19512
20452
|
}
|
|
19513
|
-
async function pathExists2(
|
|
20453
|
+
async function pathExists2(fs5, targetPath) {
|
|
19514
20454
|
try {
|
|
19515
|
-
await
|
|
20455
|
+
await fs5.stat(targetPath);
|
|
19516
20456
|
return true;
|
|
19517
20457
|
} catch (error3) {
|
|
19518
20458
|
if (hasOwnErrorCode6(error3, "ENOENT")) {
|
|
@@ -19529,7 +20469,7 @@ async function installSkill(agentId, skill, options) {
|
|
|
19529
20469
|
}
|
|
19530
20470
|
const scope = options.scope ?? "local";
|
|
19531
20471
|
const config2 = support.config;
|
|
19532
|
-
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
20472
|
+
if (skill.name.length === 0 || skill.name !== skill.name.trim() || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
19533
20473
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
19534
20474
|
}
|
|
19535
20475
|
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
@@ -19565,29 +20505,29 @@ async function installSkill(agentId, skill, options) {
|
|
|
19565
20505
|
}
|
|
19566
20506
|
}
|
|
19567
20507
|
);
|
|
19568
|
-
return { skillPath:
|
|
20508
|
+
return { skillPath: absoluteSkillPath, displayPath };
|
|
19569
20509
|
}
|
|
19570
20510
|
|
|
19571
20511
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
19572
|
-
import
|
|
19573
|
-
import
|
|
20512
|
+
import * as fs2 from "node:fs";
|
|
20513
|
+
import path20 from "node:path";
|
|
19574
20514
|
|
|
19575
20515
|
// ../agent-skill-config/src/git-exclude.ts
|
|
19576
20516
|
import { execFileSync } from "node:child_process";
|
|
19577
20517
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
19578
|
-
import * as
|
|
19579
|
-
import
|
|
20518
|
+
import * as fs3 from "node:fs";
|
|
20519
|
+
import path21 from "node:path";
|
|
19580
20520
|
|
|
19581
20521
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
19582
|
-
import * as
|
|
20522
|
+
import * as fs4 from "node:fs";
|
|
19583
20523
|
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
19584
|
-
import
|
|
20524
|
+
import path22 from "node:path";
|
|
19585
20525
|
|
|
19586
20526
|
// src/commands/installer.ts
|
|
19587
20527
|
import os3 from "node:os";
|
|
19588
|
-
import
|
|
20528
|
+
import path23 from "node:path";
|
|
19589
20529
|
import * as nodeFs2 from "node:fs/promises";
|
|
19590
|
-
import { readFile as
|
|
20530
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
19591
20531
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
19592
20532
|
var DEFAULT_INSTALL_SCOPE = "local";
|
|
19593
20533
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
@@ -19637,7 +20577,7 @@ async function loadTerminalPilotTemplate() {
|
|
|
19637
20577
|
];
|
|
19638
20578
|
for (const candidate of candidates) {
|
|
19639
20579
|
try {
|
|
19640
|
-
terminalPilotTemplateCache = await
|
|
20580
|
+
terminalPilotTemplateCache = await readFile7(candidate, "utf8");
|
|
19641
20581
|
return terminalPilotTemplateCache;
|
|
19642
20582
|
} catch (error3) {
|
|
19643
20583
|
if (!isNotFoundError2(error3)) {
|
|
@@ -19652,7 +20592,7 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
19652
20592
|
return homeDir;
|
|
19653
20593
|
}
|
|
19654
20594
|
if (targetPath.startsWith("~/")) {
|
|
19655
|
-
return
|
|
20595
|
+
return path23.join(homeDir, targetPath.slice(2));
|
|
19656
20596
|
}
|
|
19657
20597
|
return targetPath;
|
|
19658
20598
|
}
|
|
@@ -19662,22 +20602,22 @@ function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
|
19662
20602
|
throwUnsupportedAgent(agent);
|
|
19663
20603
|
}
|
|
19664
20604
|
return {
|
|
19665
|
-
displayPath:
|
|
20605
|
+
displayPath: path23.join(
|
|
19666
20606
|
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
19667
20607
|
TERMINAL_PILOT_SKILL_NAME
|
|
19668
20608
|
),
|
|
19669
|
-
fullPath:
|
|
19670
|
-
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) :
|
|
20609
|
+
fullPath: path23.join(
|
|
20610
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path23.resolve(cwd, config2.localSkillDir),
|
|
19671
20611
|
TERMINAL_PILOT_SKILL_NAME
|
|
19672
20612
|
)
|
|
19673
20613
|
};
|
|
19674
20614
|
}
|
|
19675
|
-
async function assertNoSymbolicLinkPath(
|
|
19676
|
-
const rootPath =
|
|
20615
|
+
async function assertNoSymbolicLinkPath(fs5, targetPath) {
|
|
20616
|
+
const rootPath = path23.parse(targetPath).root;
|
|
19677
20617
|
let currentPath = targetPath;
|
|
19678
20618
|
while (currentPath !== rootPath) {
|
|
19679
20619
|
try {
|
|
19680
|
-
if ((await
|
|
20620
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
19681
20621
|
throw new UserError(`Refusing terminal-pilot skill operation through symbolic link: ${currentPath}`);
|
|
19682
20622
|
}
|
|
19683
20623
|
} catch (error3) {
|
|
@@ -19685,7 +20625,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
19685
20625
|
throw error3;
|
|
19686
20626
|
}
|
|
19687
20627
|
}
|
|
19688
|
-
currentPath =
|
|
20628
|
+
currentPath = path23.dirname(currentPath);
|
|
19689
20629
|
}
|
|
19690
20630
|
}
|
|
19691
20631
|
|
|
@@ -20384,11 +21324,11 @@ import { Resvg } from "@resvg/resvg-js";
|
|
|
20384
21324
|
|
|
20385
21325
|
// ../terminal-png/src/font.ts
|
|
20386
21326
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
20387
|
-
import { createRequire as
|
|
21327
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
20388
21328
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
20389
21329
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
20390
|
-
var
|
|
20391
|
-
var fontPackageRoot = dirname2(
|
|
21330
|
+
var require3 = createRequire3(import.meta.url);
|
|
21331
|
+
var fontPackageRoot = dirname2(require3.resolve("jetbrains-mono/package.json"));
|
|
20392
21332
|
var webfontRoot = join2(fontPackageRoot, "fonts/webfonts");
|
|
20393
21333
|
function readWebfontBase64(filename) {
|
|
20394
21334
|
return readFileSync4(join2(webfontRoot, filename)).toString("base64");
|
|
@@ -21098,9 +22038,9 @@ var uninstall = defineCommand({
|
|
|
21098
22038
|
};
|
|
21099
22039
|
}
|
|
21100
22040
|
});
|
|
21101
|
-
async function folderExists(
|
|
22041
|
+
async function folderExists(fs5, folderPath) {
|
|
21102
22042
|
try {
|
|
21103
|
-
await
|
|
22043
|
+
await fs5.stat(folderPath);
|
|
21104
22044
|
return true;
|
|
21105
22045
|
} catch (error3) {
|
|
21106
22046
|
if (hasOwnErrorCode4(error3, "ENOENT")) {
|
|
@@ -21245,7 +22185,7 @@ async function isDirectExecution(argv) {
|
|
|
21245
22185
|
try {
|
|
21246
22186
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
21247
22187
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
21248
|
-
realpath3(
|
|
22188
|
+
realpath3(path24.resolve(entryPoint)),
|
|
21249
22189
|
realpath3(modulePath)
|
|
21250
22190
|
]);
|
|
21251
22191
|
return resolvedEntryPoint === resolvedModulePath;
|