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/qa-cli.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
import assert from "node:assert/strict";
|
|
9
9
|
import { rm as rm2 } from "node:fs/promises";
|
|
10
10
|
import os4 from "node:os";
|
|
11
|
-
import
|
|
11
|
+
import path25 from "node:path";
|
|
12
12
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
13
13
|
|
|
14
14
|
// src/ansi.ts
|
|
@@ -86,12 +86,12 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
86
86
|
|
|
87
87
|
// src/cli.ts
|
|
88
88
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
89
|
-
import
|
|
89
|
+
import path24 from "node:path";
|
|
90
90
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
91
91
|
|
|
92
92
|
// ../toolcraft/src/cli.ts
|
|
93
|
-
import { access as access2, lstat as lstat3, readFile as
|
|
94
|
-
import
|
|
93
|
+
import { access as access2, lstat as lstat3, readFile as readFile5, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
94
|
+
import path15 from "node:path";
|
|
95
95
|
import {
|
|
96
96
|
Command as CommanderCommand,
|
|
97
97
|
CommanderError as CommanderError2,
|
|
@@ -457,7 +457,8 @@ function renderMarkdownCode(content) {
|
|
|
457
457
|
currentRun = 0;
|
|
458
458
|
}
|
|
459
459
|
const delimiter = "`".repeat(longestRun + 1);
|
|
460
|
-
|
|
460
|
+
const paddedValue = value.startsWith("`") || value.endsWith("`") ? ` ${value} ` : value;
|
|
461
|
+
return `${delimiter}${paddedValue}${delimiter}`;
|
|
461
462
|
}
|
|
462
463
|
function renderMarkdownLink(content) {
|
|
463
464
|
const value = renderMarkdownInline(content);
|
|
@@ -612,7 +613,54 @@ var symbols = {
|
|
|
612
613
|
|
|
613
614
|
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
614
615
|
function stripAnsi2(value) {
|
|
615
|
-
|
|
616
|
+
let output = "";
|
|
617
|
+
let index = 0;
|
|
618
|
+
while (index < value.length) {
|
|
619
|
+
const char = value[index];
|
|
620
|
+
if (char === "\x1B") {
|
|
621
|
+
index = skipEscapeSequence(value, index);
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
if (char === "\x9B") {
|
|
625
|
+
index = skipCsiSequence(value, index + 1);
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
output += char;
|
|
629
|
+
index += char.length;
|
|
630
|
+
}
|
|
631
|
+
return output;
|
|
632
|
+
}
|
|
633
|
+
function skipEscapeSequence(value, index) {
|
|
634
|
+
const next = value[index + 1];
|
|
635
|
+
if (next === "[") {
|
|
636
|
+
return skipCsiSequence(value, index + 2);
|
|
637
|
+
}
|
|
638
|
+
if (next === "]") {
|
|
639
|
+
return skipOscSequence(value, index + 2);
|
|
640
|
+
}
|
|
641
|
+
return Math.min(value.length, index + 2);
|
|
642
|
+
}
|
|
643
|
+
function skipCsiSequence(value, index) {
|
|
644
|
+
while (index < value.length) {
|
|
645
|
+
const codePoint = value.charCodeAt(index);
|
|
646
|
+
index += 1;
|
|
647
|
+
if (codePoint >= 64 && codePoint <= 126) {
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return index;
|
|
652
|
+
}
|
|
653
|
+
function skipOscSequence(value, index) {
|
|
654
|
+
while (index < value.length) {
|
|
655
|
+
if (value[index] === "\x07") {
|
|
656
|
+
return index + 1;
|
|
657
|
+
}
|
|
658
|
+
if (value[index] === "\x1B" && value[index + 1] === "\\") {
|
|
659
|
+
return index + 2;
|
|
660
|
+
}
|
|
661
|
+
index += 1;
|
|
662
|
+
}
|
|
663
|
+
return index;
|
|
616
664
|
}
|
|
617
665
|
|
|
618
666
|
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
@@ -1401,38 +1449,14 @@ function renderTable(options) {
|
|
|
1401
1449
|
}
|
|
1402
1450
|
|
|
1403
1451
|
// ../toolcraft-design/src/components/detail-card.ts
|
|
1452
|
+
import stringWidth from "fast-string-width";
|
|
1453
|
+
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1404
1454
|
function wrap(value, width) {
|
|
1405
|
-
|
|
1406
|
-
for (const paragraph of value.split("\n")) {
|
|
1407
|
-
let line = "";
|
|
1408
|
-
for (const rawWord of paragraph.split(" ")) {
|
|
1409
|
-
const words = [];
|
|
1410
|
-
let word = rawWord;
|
|
1411
|
-
while (word.length > width) {
|
|
1412
|
-
words.push(word.slice(0, width));
|
|
1413
|
-
word = word.slice(width);
|
|
1414
|
-
}
|
|
1415
|
-
words.push(word);
|
|
1416
|
-
for (const word2 of words) {
|
|
1417
|
-
if (line.length === 0) {
|
|
1418
|
-
line = word2;
|
|
1419
|
-
continue;
|
|
1420
|
-
}
|
|
1421
|
-
if (`${line} ${word2}`.length <= width) {
|
|
1422
|
-
line = `${line} ${word2}`;
|
|
1423
|
-
continue;
|
|
1424
|
-
}
|
|
1425
|
-
lines.push(line);
|
|
1426
|
-
line = word2;
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
lines.push(line);
|
|
1430
|
-
}
|
|
1431
|
-
return lines;
|
|
1455
|
+
return wrapAnsi(value, Math.max(1, width), { hard: true, trim: true }).split("\n");
|
|
1432
1456
|
}
|
|
1433
1457
|
function renderRows(rows, theme, width) {
|
|
1434
1458
|
if (rows.length === 0) return [];
|
|
1435
|
-
const labelWidth = Math.max(...rows.map((row) => row.label
|
|
1459
|
+
const labelWidth = Math.max(...rows.map((row) => stringWidth(row.label)));
|
|
1436
1460
|
const valueWidth = Math.max(20, width - labelWidth - 2);
|
|
1437
1461
|
const continuation = " ".repeat(labelWidth + 2);
|
|
1438
1462
|
return rows.flatMap((row) => {
|
|
@@ -1453,12 +1477,16 @@ function renderDetailCard(options) {
|
|
|
1453
1477
|
${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).toLowerCase()).join(" \xB7 "))}` : identity;
|
|
1454
1478
|
const blocks = [hero];
|
|
1455
1479
|
for (const prose of options.prose ?? []) {
|
|
1456
|
-
blocks.push(
|
|
1480
|
+
blocks.push(
|
|
1481
|
+
prose.title ? [options.theme.header(prose.title), wrap(prose.value, width).join("\n")].join("\n") : wrap(prose.value, width).join("\n")
|
|
1482
|
+
);
|
|
1457
1483
|
}
|
|
1458
1484
|
for (const section of options.sections ?? []) {
|
|
1459
1485
|
if (section.rows.length === 0) continue;
|
|
1460
1486
|
const rows = renderRows(section.rows, options.theme, width);
|
|
1461
|
-
blocks.push(
|
|
1487
|
+
blocks.push(
|
|
1488
|
+
section.title ? [options.theme.header(section.title), ...rows].join("\n") : rows.join("\n")
|
|
1489
|
+
);
|
|
1462
1490
|
}
|
|
1463
1491
|
return blocks.join("\n\n");
|
|
1464
1492
|
}
|
|
@@ -1885,13 +1913,13 @@ import { LineCounter, parse, parseDocument } from "yaml";
|
|
|
1885
1913
|
// ../frontmatter/src/stringify.ts
|
|
1886
1914
|
import { stringify } from "yaml";
|
|
1887
1915
|
|
|
1916
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1917
|
+
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1918
|
+
|
|
1888
1919
|
// ../toolcraft-design/src/acp/writer.ts
|
|
1889
1920
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1890
1921
|
var storage = new AsyncLocalStorage2();
|
|
1891
1922
|
|
|
1892
|
-
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1893
|
-
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1894
|
-
|
|
1895
1923
|
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1896
1924
|
import readline from "node:readline";
|
|
1897
1925
|
import { PassThrough } from "node:stream";
|
|
@@ -1988,8 +2016,8 @@ function mapKey(name, char) {
|
|
|
1988
2016
|
}
|
|
1989
2017
|
|
|
1990
2018
|
// ../toolcraft-design/src/prompts/interactive/wrap.ts
|
|
1991
|
-
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1992
|
-
import
|
|
2019
|
+
import { wrapAnsi as wrapAnsi2 } from "fast-wrap-ansi";
|
|
2020
|
+
import stringWidth2 from "fast-string-width";
|
|
1993
2021
|
function getColumns(output) {
|
|
1994
2022
|
return Math.max(1, output.columns ?? 80);
|
|
1995
2023
|
}
|
|
@@ -1997,7 +2025,7 @@ function getRows(output) {
|
|
|
1997
2025
|
return Math.max(1, output.rows ?? 20);
|
|
1998
2026
|
}
|
|
1999
2027
|
function wrapFrame(output, frame) {
|
|
2000
|
-
return
|
|
2028
|
+
return wrapAnsi2(frame, getColumns(output), { hard: true, trim: false });
|
|
2001
2029
|
}
|
|
2002
2030
|
|
|
2003
2031
|
// ../toolcraft-design/src/prompts/interactive/core.ts
|
|
@@ -2318,7 +2346,7 @@ function confirmPrompt(opts) {
|
|
|
2318
2346
|
}
|
|
2319
2347
|
|
|
2320
2348
|
// ../toolcraft-design/src/prompts/interactive/pagination.ts
|
|
2321
|
-
import { wrapAnsi as
|
|
2349
|
+
import { wrapAnsi as wrapAnsi3 } from "fast-wrap-ansi";
|
|
2322
2350
|
function countLines(values) {
|
|
2323
2351
|
return values.reduce((sum, value) => sum + value.split("\n").length, 0);
|
|
2324
2352
|
}
|
|
@@ -2361,7 +2389,7 @@ function limitOptions(opts) {
|
|
|
2361
2389
|
}
|
|
2362
2390
|
const hasTopMarker = cappedVisibleCount < options.length && start > 0;
|
|
2363
2391
|
const hasBottomMarker = cappedVisibleCount < options.length && start + cappedVisibleCount < options.length;
|
|
2364
|
-
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) =>
|
|
2392
|
+
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) => wrapAnsi3(style(option, start + index === cursor2), columns, { hard: true, trim: false }));
|
|
2365
2393
|
const trimmed = trimToRows(
|
|
2366
2394
|
visible,
|
|
2367
2395
|
Math.max(cursor2 - start, 0),
|
|
@@ -2744,6 +2772,9 @@ function isOptionalSchema(schema) {
|
|
|
2744
2772
|
function getRequiredKeys(schema) {
|
|
2745
2773
|
return Object.keys(schema.shape).filter((key2) => !isOptionalSchema(schema.shape[key2])).sort();
|
|
2746
2774
|
}
|
|
2775
|
+
function getRequiredKeyFingerprint(schema) {
|
|
2776
|
+
return getRequiredKeys(schema).join("+");
|
|
2777
|
+
}
|
|
2747
2778
|
function assertUniqueRequiredKeyFingerprints(branches) {
|
|
2748
2779
|
const fingerprints = /* @__PURE__ */ new Map();
|
|
2749
2780
|
branches.forEach((branch, index) => {
|
|
@@ -2781,6 +2812,451 @@ function Union(branches) {
|
|
|
2781
2812
|
};
|
|
2782
2813
|
}
|
|
2783
2814
|
|
|
2815
|
+
// ../toolcraft-schema/src/validate.ts
|
|
2816
|
+
var missingValue = /* @__PURE__ */ Symbol("missingValue");
|
|
2817
|
+
function validate(schema, value) {
|
|
2818
|
+
const state = { issues: [] };
|
|
2819
|
+
const result = walkSchema(schema, value, [], state);
|
|
2820
|
+
if (state.issues.length > 0) {
|
|
2821
|
+
return { ok: false, issues: state.issues };
|
|
2822
|
+
}
|
|
2823
|
+
return { ok: true, value: result.present ? result.value : void 0 };
|
|
2824
|
+
}
|
|
2825
|
+
function walkSchema(schema, value, path26, state) {
|
|
2826
|
+
if (schema.kind === "optional") {
|
|
2827
|
+
return walkOptional(schema, value, path26, state);
|
|
2828
|
+
}
|
|
2829
|
+
if (value === missingValue) {
|
|
2830
|
+
addIssue(
|
|
2831
|
+
state,
|
|
2832
|
+
path26,
|
|
2833
|
+
expectedFor(schema),
|
|
2834
|
+
"missing",
|
|
2835
|
+
`Expected ${expectedFor(schema)} at ${formatPath(path26)}`
|
|
2836
|
+
);
|
|
2837
|
+
return { present: false };
|
|
2838
|
+
}
|
|
2839
|
+
if (value === null && schema.nullable === true) {
|
|
2840
|
+
return { present: true, value };
|
|
2841
|
+
}
|
|
2842
|
+
switch (schema.kind) {
|
|
2843
|
+
case "string":
|
|
2844
|
+
return walkString(schema, value, path26, state);
|
|
2845
|
+
case "number":
|
|
2846
|
+
return walkNumber(schema, value, path26, state);
|
|
2847
|
+
case "boolean":
|
|
2848
|
+
return walkBoolean(value, path26, state);
|
|
2849
|
+
case "enum":
|
|
2850
|
+
return walkEnum(schema, value, path26, state);
|
|
2851
|
+
case "array":
|
|
2852
|
+
return walkArray(schema, value, path26, state);
|
|
2853
|
+
case "object":
|
|
2854
|
+
return walkObject(schema, value, path26, state);
|
|
2855
|
+
case "oneOf":
|
|
2856
|
+
return walkOneOf(schema, value, path26, state);
|
|
2857
|
+
case "union":
|
|
2858
|
+
return walkUnion(schema, value, path26, state);
|
|
2859
|
+
case "record":
|
|
2860
|
+
return walkRecord(schema, value, path26, state);
|
|
2861
|
+
case "json":
|
|
2862
|
+
return walkJson(value, path26, state);
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
function walkOptional(schema, value, path26, state) {
|
|
2866
|
+
if (value === missingValue || value === void 0) {
|
|
2867
|
+
const defaultValue = getDefault(schema.inner);
|
|
2868
|
+
if (defaultValue.present) {
|
|
2869
|
+
return walkSchema(schema.inner, cloneDefault(defaultValue.value), path26, state);
|
|
2870
|
+
}
|
|
2871
|
+
return { present: false };
|
|
2872
|
+
}
|
|
2873
|
+
return walkSchema(schema.inner, value, path26, state);
|
|
2874
|
+
}
|
|
2875
|
+
function walkString(schema, value, path26, state) {
|
|
2876
|
+
if (typeof value !== "string") {
|
|
2877
|
+
addExpectedIssue(state, path26, "string", value);
|
|
2878
|
+
return { present: true, value };
|
|
2879
|
+
}
|
|
2880
|
+
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
2881
|
+
const expected = `string with length at least ${schema.minLength}`;
|
|
2882
|
+
addIssue(
|
|
2883
|
+
state,
|
|
2884
|
+
path26,
|
|
2885
|
+
expected,
|
|
2886
|
+
`string with length ${value.length}`,
|
|
2887
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
2888
|
+
);
|
|
2889
|
+
}
|
|
2890
|
+
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
2891
|
+
const expected = `string with length at most ${schema.maxLength}`;
|
|
2892
|
+
addIssue(
|
|
2893
|
+
state,
|
|
2894
|
+
path26,
|
|
2895
|
+
expected,
|
|
2896
|
+
`string with length ${value.length}`,
|
|
2897
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
2898
|
+
);
|
|
2899
|
+
}
|
|
2900
|
+
if (schema.pattern !== void 0) {
|
|
2901
|
+
const pattern = compilePattern(schema.pattern);
|
|
2902
|
+
if (pattern === void 0 || !pattern.test(value)) {
|
|
2903
|
+
const expected = `string matching pattern ${schema.pattern}`;
|
|
2904
|
+
addIssue(state, path26, expected, value, `Expected ${expected} at ${formatPath(path26)}`);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
return { present: true, value };
|
|
2908
|
+
}
|
|
2909
|
+
function walkNumber(schema, value, path26, state) {
|
|
2910
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
2911
|
+
addExpectedIssue(state, path26, schema.jsonType === "integer" ? "integer" : "number", value);
|
|
2912
|
+
return { present: true, value };
|
|
2913
|
+
}
|
|
2914
|
+
if (schema.jsonType === "integer" && !Number.isInteger(value)) {
|
|
2915
|
+
addExpectedIssue(state, path26, "integer", value);
|
|
2916
|
+
}
|
|
2917
|
+
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
2918
|
+
const expected = `number greater than or equal to ${schema.minimum}`;
|
|
2919
|
+
addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
|
|
2920
|
+
}
|
|
2921
|
+
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
2922
|
+
const expected = `number less than or equal to ${schema.maximum}`;
|
|
2923
|
+
addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
|
|
2924
|
+
}
|
|
2925
|
+
return { present: true, value };
|
|
2926
|
+
}
|
|
2927
|
+
function walkBoolean(value, path26, state) {
|
|
2928
|
+
if (typeof value !== "boolean") {
|
|
2929
|
+
addExpectedIssue(state, path26, "boolean", value);
|
|
2930
|
+
}
|
|
2931
|
+
return { present: true, value };
|
|
2932
|
+
}
|
|
2933
|
+
function walkEnum(schema, value, path26, state) {
|
|
2934
|
+
if (!schema.values.includes(value)) {
|
|
2935
|
+
const expected = `one of ${schema.values.join(", ")}`;
|
|
2936
|
+
addIssue(
|
|
2937
|
+
state,
|
|
2938
|
+
path26,
|
|
2939
|
+
expected,
|
|
2940
|
+
receivedValue(value),
|
|
2941
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
2942
|
+
);
|
|
2943
|
+
}
|
|
2944
|
+
return { present: true, value };
|
|
2945
|
+
}
|
|
2946
|
+
function walkArray(schema, value, path26, state) {
|
|
2947
|
+
if (!Array.isArray(value)) {
|
|
2948
|
+
addExpectedIssue(state, path26, "array", value);
|
|
2949
|
+
return { present: true, value };
|
|
2950
|
+
}
|
|
2951
|
+
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
2952
|
+
const expected = `array with at least ${schema.minItems} items`;
|
|
2953
|
+
addIssue(
|
|
2954
|
+
state,
|
|
2955
|
+
path26,
|
|
2956
|
+
expected,
|
|
2957
|
+
`array with ${value.length} items`,
|
|
2958
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
2959
|
+
);
|
|
2960
|
+
}
|
|
2961
|
+
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
2962
|
+
const expected = `array with at most ${schema.maxItems} items`;
|
|
2963
|
+
addIssue(
|
|
2964
|
+
state,
|
|
2965
|
+
path26,
|
|
2966
|
+
expected,
|
|
2967
|
+
`array with ${value.length} items`,
|
|
2968
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
const nextValue = value.map((item, index) => {
|
|
2972
|
+
const result = walkSchema(schema.item, item, [...path26, String(index)], state);
|
|
2973
|
+
return result.present ? result.value : item;
|
|
2974
|
+
});
|
|
2975
|
+
return { present: true, value: nextValue };
|
|
2976
|
+
}
|
|
2977
|
+
function walkObject(schema, value, path26, state, injectedProperties = {}) {
|
|
2978
|
+
if (!isPlainRecord(value)) {
|
|
2979
|
+
addExpectedIssue(state, path26, "object", value);
|
|
2980
|
+
return { present: true, value };
|
|
2981
|
+
}
|
|
2982
|
+
const nextValue = {};
|
|
2983
|
+
const allowedKeys = /* @__PURE__ */ new Set([...Object.keys(schema.shape), ...Object.keys(injectedProperties)]);
|
|
2984
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
2985
|
+
const propertyValue = Object.hasOwn(value, key2) ? value[key2] : missingValue;
|
|
2986
|
+
const result = walkSchema(propertySchema, propertyValue, [...path26, key2], state);
|
|
2987
|
+
if (result.present) {
|
|
2988
|
+
setOwnValue(nextValue, key2, result.value);
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
for (const [key2, injectedValue] of Object.entries(injectedProperties)) {
|
|
2992
|
+
if (Object.hasOwn(value, key2)) {
|
|
2993
|
+
setOwnValue(nextValue, key2, value[key2]);
|
|
2994
|
+
} else {
|
|
2995
|
+
setOwnValue(nextValue, key2, injectedValue);
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
2999
|
+
if (allowedKeys.has(key2)) {
|
|
3000
|
+
continue;
|
|
3001
|
+
}
|
|
3002
|
+
if (schema.additionalProperties === true) {
|
|
3003
|
+
setOwnValue(nextValue, key2, propertyValue);
|
|
3004
|
+
} else {
|
|
3005
|
+
addUnexpectedPropertyIssue(state, [...path26, key2]);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
return { present: true, value: nextValue };
|
|
3009
|
+
}
|
|
3010
|
+
function walkOneOf(schema, value, path26, state) {
|
|
3011
|
+
if (!isPlainRecord(value)) {
|
|
3012
|
+
addExpectedIssue(state, path26, "object", value);
|
|
3013
|
+
return { present: true, value };
|
|
3014
|
+
}
|
|
3015
|
+
const discriminatorValue = value[schema.discriminator];
|
|
3016
|
+
const discriminatorPath = [...path26, schema.discriminator];
|
|
3017
|
+
const branchValues = Object.keys(schema.branches);
|
|
3018
|
+
const expected = `one of ${branchValues.join(", ")}`;
|
|
3019
|
+
if (!Object.hasOwn(value, schema.discriminator)) {
|
|
3020
|
+
addIssueWithMessage(
|
|
3021
|
+
state,
|
|
3022
|
+
discriminatorPath,
|
|
3023
|
+
expected,
|
|
3024
|
+
"missing",
|
|
3025
|
+
`Missing discriminator "${schema.discriminator}" at ${formatPath(path26)}. Expected one of: ${branchValues.join(", ")}.`
|
|
3026
|
+
);
|
|
3027
|
+
return { present: true, value };
|
|
3028
|
+
}
|
|
3029
|
+
if (typeof discriminatorValue !== "string" || !Object.hasOwn(schema.branches, discriminatorValue)) {
|
|
3030
|
+
addIssueWithMessage(
|
|
3031
|
+
state,
|
|
3032
|
+
discriminatorPath,
|
|
3033
|
+
expected,
|
|
3034
|
+
receivedValue(discriminatorValue),
|
|
3035
|
+
`Expected ${expected} at ${formatPath(discriminatorPath)}, got ${formatReceivedDiscriminator(discriminatorValue)}`
|
|
3036
|
+
);
|
|
3037
|
+
return { present: true, value };
|
|
3038
|
+
}
|
|
3039
|
+
return walkObject(schema.branches[discriminatorValue], value, path26, state, {
|
|
3040
|
+
[schema.discriminator]: discriminatorValue
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
function walkUnion(schema, value, path26, state) {
|
|
3044
|
+
if (isPlainRecord(value)) {
|
|
3045
|
+
const candidateBranches = schema.branches.filter((branch) => hasRequiredKeys(branch, value));
|
|
3046
|
+
if (candidateBranches.length === 1) {
|
|
3047
|
+
return walkObject(candidateBranches[0], value, path26, state);
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
const matches = [];
|
|
3051
|
+
for (const branch of schema.branches) {
|
|
3052
|
+
const branchState = { issues: [] };
|
|
3053
|
+
const result = walkObject(branch, value, path26, branchState);
|
|
3054
|
+
if (branchState.issues.length === 0 && result.present) {
|
|
3055
|
+
matches.push({ fingerprint: getRequiredKeyFingerprint(branch), value: result.value });
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
if (matches.length === 1) {
|
|
3059
|
+
return { present: true, value: matches[0].value };
|
|
3060
|
+
}
|
|
3061
|
+
if (matches.length === 0) {
|
|
3062
|
+
const branchDescriptions = schema.branches.map((branch) => getRequiredKeyFingerprint(branch));
|
|
3063
|
+
addIssueWithMessage(
|
|
3064
|
+
state,
|
|
3065
|
+
path26,
|
|
3066
|
+
"exactly one union branch",
|
|
3067
|
+
"0 matching branches",
|
|
3068
|
+
`No union branch matched at ${formatPath(path26)}. Tried ${schema.branches.length} branches. Expected one of: ${branchDescriptions.join(" | ")}.`
|
|
3069
|
+
);
|
|
3070
|
+
return { present: true, value };
|
|
3071
|
+
}
|
|
3072
|
+
addIssueWithMessage(
|
|
3073
|
+
state,
|
|
3074
|
+
path26,
|
|
3075
|
+
"exactly one union branch",
|
|
3076
|
+
`${matches.length} matching branches`,
|
|
3077
|
+
`Expected exactly one union branch at ${formatPath(path26)}, but matched more than one branch: ${matches.map((match) => match.fingerprint).join(" | ")}`
|
|
3078
|
+
);
|
|
3079
|
+
return { present: true, value };
|
|
3080
|
+
}
|
|
3081
|
+
function hasRequiredKeys(schema, value) {
|
|
3082
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
3083
|
+
if (propertySchema.kind !== "optional" && !Object.hasOwn(value, key2)) {
|
|
3084
|
+
return false;
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
return true;
|
|
3088
|
+
}
|
|
3089
|
+
function walkRecord(schema, value, path26, state) {
|
|
3090
|
+
if (!isPlainRecord(value)) {
|
|
3091
|
+
addExpectedIssue(state, path26, "object", value);
|
|
3092
|
+
return { present: true, value };
|
|
3093
|
+
}
|
|
3094
|
+
const nextValue = {};
|
|
3095
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
3096
|
+
const result = walkSchema(schema.value, propertyValue, [...path26, key2], state);
|
|
3097
|
+
if (result.present) {
|
|
3098
|
+
setOwnValue(nextValue, key2, result.value);
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
return { present: true, value: nextValue };
|
|
3102
|
+
}
|
|
3103
|
+
function walkJson(value, path26, state) {
|
|
3104
|
+
if (isJsonValue(value)) {
|
|
3105
|
+
return { present: true, value };
|
|
3106
|
+
}
|
|
3107
|
+
addExpectedIssue(state, path26, "JSON value", value);
|
|
3108
|
+
return { present: true, value };
|
|
3109
|
+
}
|
|
3110
|
+
function getDefault(schema) {
|
|
3111
|
+
if (schema.default !== void 0) {
|
|
3112
|
+
return { present: true, value: schema.default };
|
|
3113
|
+
}
|
|
3114
|
+
if (schema.kind === "optional") {
|
|
3115
|
+
return getDefault(schema.inner);
|
|
3116
|
+
}
|
|
3117
|
+
return { present: false };
|
|
3118
|
+
}
|
|
3119
|
+
function isPlainRecord(value) {
|
|
3120
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3121
|
+
return false;
|
|
3122
|
+
}
|
|
3123
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3124
|
+
return prototype === Object.prototype || prototype === null;
|
|
3125
|
+
}
|
|
3126
|
+
function isJsonValue(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3127
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3128
|
+
return typeof value !== "number" || Number.isFinite(value);
|
|
3129
|
+
}
|
|
3130
|
+
if (Array.isArray(value)) {
|
|
3131
|
+
if (ancestors.has(value)) {
|
|
3132
|
+
return false;
|
|
3133
|
+
}
|
|
3134
|
+
ancestors.add(value);
|
|
3135
|
+
const result = value.every((item) => isJsonValue(item, ancestors));
|
|
3136
|
+
ancestors.delete(value);
|
|
3137
|
+
return result;
|
|
3138
|
+
}
|
|
3139
|
+
if (isPlainRecord(value)) {
|
|
3140
|
+
if (ancestors.has(value)) {
|
|
3141
|
+
return false;
|
|
3142
|
+
}
|
|
3143
|
+
ancestors.add(value);
|
|
3144
|
+
const result = Object.values(value).every((item) => isJsonValue(item, ancestors));
|
|
3145
|
+
ancestors.delete(value);
|
|
3146
|
+
return result;
|
|
3147
|
+
}
|
|
3148
|
+
return false;
|
|
3149
|
+
}
|
|
3150
|
+
function cloneDefault(value) {
|
|
3151
|
+
return structuredClone(value);
|
|
3152
|
+
}
|
|
3153
|
+
function setOwnValue(target, key2, value) {
|
|
3154
|
+
Object.defineProperty(target, key2, {
|
|
3155
|
+
configurable: true,
|
|
3156
|
+
enumerable: true,
|
|
3157
|
+
writable: true,
|
|
3158
|
+
value
|
|
3159
|
+
});
|
|
3160
|
+
}
|
|
3161
|
+
function expectedFor(schema) {
|
|
3162
|
+
switch (schema.kind) {
|
|
3163
|
+
case "string":
|
|
3164
|
+
return "string";
|
|
3165
|
+
case "number":
|
|
3166
|
+
return schema.jsonType === "integer" ? "integer" : "number";
|
|
3167
|
+
case "boolean":
|
|
3168
|
+
return "boolean";
|
|
3169
|
+
case "enum":
|
|
3170
|
+
return `one of ${schema.values.join(", ")}`;
|
|
3171
|
+
case "array":
|
|
3172
|
+
return "array";
|
|
3173
|
+
case "object":
|
|
3174
|
+
case "oneOf":
|
|
3175
|
+
case "record":
|
|
3176
|
+
return "object";
|
|
3177
|
+
case "union":
|
|
3178
|
+
return "exactly one union branch";
|
|
3179
|
+
case "json":
|
|
3180
|
+
return "JSON value";
|
|
3181
|
+
case "optional":
|
|
3182
|
+
return expectedFor(schema.inner);
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
function addExpectedIssue(state, path26, expected, value) {
|
|
3186
|
+
addIssue(
|
|
3187
|
+
state,
|
|
3188
|
+
path26,
|
|
3189
|
+
expected,
|
|
3190
|
+
receivedType(value),
|
|
3191
|
+
`Expected ${expected} at ${formatPath(path26)}`
|
|
3192
|
+
);
|
|
3193
|
+
}
|
|
3194
|
+
function addUnexpectedPropertyIssue(state, path26) {
|
|
3195
|
+
addIssue(
|
|
3196
|
+
state,
|
|
3197
|
+
path26,
|
|
3198
|
+
"no additional properties",
|
|
3199
|
+
"unknown property",
|
|
3200
|
+
`Unexpected property ${formatPath(path26)}`
|
|
3201
|
+
);
|
|
3202
|
+
}
|
|
3203
|
+
function addIssue(state, path26, expected, received, _message) {
|
|
3204
|
+
state.issues.push({
|
|
3205
|
+
path: path26,
|
|
3206
|
+
expected,
|
|
3207
|
+
received,
|
|
3208
|
+
message: formatIssueMessage(expected, path26, received)
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
function addIssueWithMessage(state, path26, expected, received, message2) {
|
|
3212
|
+
state.issues.push({
|
|
3213
|
+
path: path26,
|
|
3214
|
+
expected,
|
|
3215
|
+
received,
|
|
3216
|
+
message: message2
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
function formatIssueMessage(expected, path26, received) {
|
|
3220
|
+
return `Expected ${expected} at ${formatPath(path26)}, got ${received}`;
|
|
3221
|
+
}
|
|
3222
|
+
function formatPath(path26) {
|
|
3223
|
+
return path26.length === 0 ? "value" : path26.join(".");
|
|
3224
|
+
}
|
|
3225
|
+
function compilePattern(pattern) {
|
|
3226
|
+
try {
|
|
3227
|
+
return new RegExp(pattern);
|
|
3228
|
+
} catch {
|
|
3229
|
+
return void 0;
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
function receivedType(value) {
|
|
3233
|
+
if (value === null) {
|
|
3234
|
+
return "null";
|
|
3235
|
+
}
|
|
3236
|
+
if (Array.isArray(value)) {
|
|
3237
|
+
return "array";
|
|
3238
|
+
}
|
|
3239
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
3240
|
+
return "integer";
|
|
3241
|
+
}
|
|
3242
|
+
return typeof value;
|
|
3243
|
+
}
|
|
3244
|
+
function receivedValue(value) {
|
|
3245
|
+
if (typeof value === "string") {
|
|
3246
|
+
return value;
|
|
3247
|
+
}
|
|
3248
|
+
if (value === void 0) {
|
|
3249
|
+
return "undefined";
|
|
3250
|
+
}
|
|
3251
|
+
return String(value);
|
|
3252
|
+
}
|
|
3253
|
+
function formatReceivedDiscriminator(value) {
|
|
3254
|
+
if (typeof value === "string") {
|
|
3255
|
+
return JSON.stringify(value);
|
|
3256
|
+
}
|
|
3257
|
+
return receivedValue(value);
|
|
3258
|
+
}
|
|
3259
|
+
|
|
2784
3260
|
// ../toolcraft-schema/src/index.ts
|
|
2785
3261
|
function assertValidEnumValues(values) {
|
|
2786
3262
|
if (values.length === 0) {
|
|
@@ -2804,6 +3280,22 @@ function assertFiniteNumber(value, name) {
|
|
|
2804
3280
|
throw new Error(`${name} must be finite`);
|
|
2805
3281
|
}
|
|
2806
3282
|
}
|
|
3283
|
+
function assertMinMaxOrder(minimum, maximum, minimumName, maximumName) {
|
|
3284
|
+
if (minimum !== void 0 && maximum !== void 0 && minimum > maximum) {
|
|
3285
|
+
throw new Error(`${minimumName} must be less than or equal to ${maximumName}`);
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
function assertValidDefault(schema) {
|
|
3289
|
+
if (schema.default === void 0) {
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3292
|
+
const result = validate(schema, schema.default);
|
|
3293
|
+
if (!result.ok) {
|
|
3294
|
+
throw new Error(
|
|
3295
|
+
`default must satisfy schema: ${result.issues[0]?.message ?? "invalid default"}`
|
|
3296
|
+
);
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
2807
3299
|
function assertPattern(pattern) {
|
|
2808
3300
|
if (pattern === void 0) {
|
|
2809
3301
|
return;
|
|
@@ -2818,56 +3310,71 @@ var S = {
|
|
|
2818
3310
|
String(options = {}) {
|
|
2819
3311
|
assertNonNegativeInteger(options.minLength, "minLength");
|
|
2820
3312
|
assertNonNegativeInteger(options.maxLength, "maxLength");
|
|
3313
|
+
assertMinMaxOrder(options.minLength, options.maxLength, "minLength", "maxLength");
|
|
2821
3314
|
assertPattern(options.pattern);
|
|
2822
|
-
|
|
3315
|
+
const schema = {
|
|
2823
3316
|
kind: "string",
|
|
2824
3317
|
...options
|
|
2825
3318
|
};
|
|
3319
|
+
assertValidDefault(schema);
|
|
3320
|
+
return schema;
|
|
2826
3321
|
},
|
|
2827
3322
|
Number(options = {}) {
|
|
2828
3323
|
assertFiniteNumber(options.minimum, "minimum");
|
|
2829
3324
|
assertFiniteNumber(options.maximum, "maximum");
|
|
3325
|
+
assertMinMaxOrder(options.minimum, options.maximum, "minimum", "maximum");
|
|
2830
3326
|
assertFiniteNumber(options.default, "default");
|
|
2831
3327
|
if (options.jsonType === "integer" && options.default !== void 0 && !Number.isInteger(options.default)) {
|
|
2832
3328
|
throw new Error("default must be an integer");
|
|
2833
3329
|
}
|
|
2834
|
-
|
|
3330
|
+
const schema = {
|
|
2835
3331
|
kind: "number",
|
|
2836
3332
|
...options
|
|
2837
3333
|
};
|
|
3334
|
+
assertValidDefault(schema);
|
|
3335
|
+
return schema;
|
|
2838
3336
|
},
|
|
2839
3337
|
Boolean(options = {}) {
|
|
2840
|
-
|
|
3338
|
+
const schema = {
|
|
2841
3339
|
kind: "boolean",
|
|
2842
3340
|
...options
|
|
2843
3341
|
};
|
|
3342
|
+
assertValidDefault(schema);
|
|
3343
|
+
return schema;
|
|
2844
3344
|
},
|
|
2845
3345
|
Enum(values, options = {}) {
|
|
2846
3346
|
assertValidEnumValues(values);
|
|
2847
3347
|
if (options.jsonType === "integer" && values.some((value) => typeof value !== "number" || !Number.isInteger(value))) {
|
|
2848
3348
|
throw new Error("Integer enum values must be integers");
|
|
2849
3349
|
}
|
|
2850
|
-
|
|
3350
|
+
const schema = {
|
|
2851
3351
|
kind: "enum",
|
|
2852
3352
|
values,
|
|
2853
3353
|
...options
|
|
2854
3354
|
};
|
|
3355
|
+
assertValidDefault(schema);
|
|
3356
|
+
return schema;
|
|
2855
3357
|
},
|
|
2856
3358
|
Array(item, options = {}) {
|
|
2857
3359
|
assertNonNegativeInteger(options.minItems, "minItems");
|
|
2858
3360
|
assertNonNegativeInteger(options.maxItems, "maxItems");
|
|
2859
|
-
|
|
3361
|
+
assertMinMaxOrder(options.minItems, options.maxItems, "minItems", "maxItems");
|
|
3362
|
+
const schema = {
|
|
2860
3363
|
kind: "array",
|
|
2861
3364
|
item,
|
|
2862
3365
|
...options
|
|
2863
3366
|
};
|
|
3367
|
+
assertValidDefault(schema);
|
|
3368
|
+
return schema;
|
|
2864
3369
|
},
|
|
2865
3370
|
Object(shape, options = {}) {
|
|
2866
|
-
|
|
3371
|
+
const schema = {
|
|
2867
3372
|
kind: "object",
|
|
2868
3373
|
shape,
|
|
2869
3374
|
...options
|
|
2870
3375
|
};
|
|
3376
|
+
assertValidDefault(schema);
|
|
3377
|
+
return schema;
|
|
2871
3378
|
},
|
|
2872
3379
|
Optional(inner) {
|
|
2873
3380
|
return {
|
|
@@ -3439,6 +3946,9 @@ function isRecord(value) {
|
|
|
3439
3946
|
function isStateList(value) {
|
|
3440
3947
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
3441
3948
|
}
|
|
3949
|
+
function hasVisibleName(value) {
|
|
3950
|
+
return value.trim().length > 0;
|
|
3951
|
+
}
|
|
3442
3952
|
function canFireFromState(event, fromState) {
|
|
3443
3953
|
if (event.from === "*") {
|
|
3444
3954
|
return event.to !== fromState;
|
|
@@ -3453,6 +3963,9 @@ function validateMachine(machine) {
|
|
|
3453
3963
|
throw new TypeError("State machine states must be a string array.");
|
|
3454
3964
|
}
|
|
3455
3965
|
const states = new Set(machine.states);
|
|
3966
|
+
if (machine.states.some((state) => !hasVisibleName(state))) {
|
|
3967
|
+
throw new Error("State names must not be empty.");
|
|
3968
|
+
}
|
|
3456
3969
|
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
3457
3970
|
throw new TypeError("State machine initial must be a string.");
|
|
3458
3971
|
}
|
|
@@ -3463,6 +3976,9 @@ function validateMachine(machine) {
|
|
|
3463
3976
|
throw new TypeError("State machine events must be an object.");
|
|
3464
3977
|
}
|
|
3465
3978
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
3979
|
+
if (!hasVisibleName(eventName)) {
|
|
3980
|
+
throw new Error("Event names must not be empty.");
|
|
3981
|
+
}
|
|
3466
3982
|
if (!isRecord(event)) {
|
|
3467
3983
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
3468
3984
|
}
|
|
@@ -3572,6 +4088,13 @@ import { text as text3 } from "node:stream/consumers";
|
|
|
3572
4088
|
// ../process-runner/src/docker/context.ts
|
|
3573
4089
|
import { execSync } from "node:child_process";
|
|
3574
4090
|
|
|
4091
|
+
// ../process-runner/src/docker/build-context.ts
|
|
4092
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
4093
|
+
import { createRequire } from "node:module";
|
|
4094
|
+
import path2 from "node:path";
|
|
4095
|
+
var require2 = createRequire(import.meta.url);
|
|
4096
|
+
var createIgnore = require2("ignore");
|
|
4097
|
+
|
|
3575
4098
|
// ../process-runner/src/docker/engine.ts
|
|
3576
4099
|
import { execSync as execSync2 } from "node:child_process";
|
|
3577
4100
|
|
|
@@ -3580,19 +4103,19 @@ import * as childProcess from "node:child_process";
|
|
|
3580
4103
|
import { randomBytes } from "node:crypto";
|
|
3581
4104
|
|
|
3582
4105
|
// ../process-runner/src/docker/args.ts
|
|
3583
|
-
import
|
|
4106
|
+
import path3 from "node:path";
|
|
3584
4107
|
|
|
3585
4108
|
// ../process-runner/src/docker/env-file.ts
|
|
3586
4109
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3587
4110
|
import { tmpdir } from "node:os";
|
|
3588
|
-
import
|
|
4111
|
+
import path4 from "node:path";
|
|
3589
4112
|
|
|
3590
4113
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
3591
4114
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
3592
4115
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
3593
|
-
import {
|
|
4116
|
+
import { readFile as readFile2, realpath, writeFile } from "node:fs/promises";
|
|
3594
4117
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
3595
|
-
import
|
|
4118
|
+
import path6 from "node:path";
|
|
3596
4119
|
|
|
3597
4120
|
// ../process-runner/src/host/host-runner.ts
|
|
3598
4121
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
@@ -3725,7 +4248,7 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
3725
4248
|
// ../process-runner/src/workspace-transfer.ts
|
|
3726
4249
|
import { createHash, randomUUID } from "node:crypto";
|
|
3727
4250
|
import { promises as nodeFs } from "node:fs";
|
|
3728
|
-
import
|
|
4251
|
+
import path5 from "node:path";
|
|
3729
4252
|
|
|
3730
4253
|
// ../process-runner/src/testing/mock-runner.ts
|
|
3731
4254
|
import { Readable, Writable } from "node:stream";
|
|
@@ -3797,7 +4320,7 @@ function resolveEndpoint(options = {}) {
|
|
|
3797
4320
|
|
|
3798
4321
|
// ../task-list/src/backends/utils.ts
|
|
3799
4322
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3800
|
-
import
|
|
4323
|
+
import path7 from "node:path";
|
|
3801
4324
|
function compareCreated(left, right) {
|
|
3802
4325
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
3803
4326
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -3829,15 +4352,33 @@ function sortStrings(values) {
|
|
|
3829
4352
|
function sortTasks(tasks) {
|
|
3830
4353
|
return [...tasks].sort((left, right) => left.qualifiedId.localeCompare(right.qualifiedId));
|
|
3831
4354
|
}
|
|
4355
|
+
function isTrimmedPrintableIdentifier(value) {
|
|
4356
|
+
if (value.length === 0 || value !== value.trim()) {
|
|
4357
|
+
return false;
|
|
4358
|
+
}
|
|
4359
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4360
|
+
const code = value.charCodeAt(index);
|
|
4361
|
+
if (code < 32 || code === 127) {
|
|
4362
|
+
return false;
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
4365
|
+
return true;
|
|
4366
|
+
}
|
|
3832
4367
|
function validateTaskId(id) {
|
|
3833
|
-
if (id
|
|
4368
|
+
if (!isTrimmedPrintableIdentifier(id) || id.startsWith(".") || id.includes("/") || id.includes("\\") || id.includes("..")) {
|
|
3834
4369
|
throw new Error(`Invalid task id "${id}".`);
|
|
3835
4370
|
}
|
|
3836
4371
|
return id;
|
|
3837
4372
|
}
|
|
3838
|
-
|
|
4373
|
+
function validateTaskName(name) {
|
|
4374
|
+
if (name.trim().length === 0) {
|
|
4375
|
+
throw new Error("Task name must not be empty.");
|
|
4376
|
+
}
|
|
4377
|
+
return name;
|
|
4378
|
+
}
|
|
4379
|
+
async function statIfExists(fs5, filePath) {
|
|
3839
4380
|
try {
|
|
3840
|
-
return await
|
|
4381
|
+
return await fs5.stat(filePath);
|
|
3841
4382
|
} catch (error3) {
|
|
3842
4383
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3843
4384
|
return void 0;
|
|
@@ -3845,15 +4386,18 @@ async function statIfExists(fs4, filePath) {
|
|
|
3845
4386
|
throw error3;
|
|
3846
4387
|
}
|
|
3847
4388
|
}
|
|
3848
|
-
async function rejectSymbolicLinkComponents(
|
|
3849
|
-
const resolvedPath =
|
|
3850
|
-
const rootPath =
|
|
3851
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
4389
|
+
async function rejectSymbolicLinkComponents(fs5, filePath) {
|
|
4390
|
+
const resolvedPath = path7.resolve(filePath);
|
|
4391
|
+
const rootPath = path7.parse(resolvedPath).root;
|
|
4392
|
+
const components = resolvedPath.slice(rootPath.length).split(path7.sep).filter(Boolean);
|
|
3852
4393
|
let currentPath = rootPath;
|
|
3853
4394
|
for (const component of components) {
|
|
3854
|
-
currentPath =
|
|
4395
|
+
currentPath = path7.join(currentPath, component);
|
|
3855
4396
|
try {
|
|
3856
|
-
if ((await
|
|
4397
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
4398
|
+
if (currentPath === "/tmp") {
|
|
4399
|
+
continue;
|
|
4400
|
+
}
|
|
3857
4401
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
3858
4402
|
}
|
|
3859
4403
|
} catch (error3) {
|
|
@@ -3864,19 +4408,19 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
3864
4408
|
}
|
|
3865
4409
|
}
|
|
3866
4410
|
}
|
|
3867
|
-
async function writeAtomically(
|
|
4411
|
+
async function writeAtomically(fs5, filePath, content) {
|
|
3868
4412
|
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3869
4413
|
let tempCreated = false;
|
|
3870
|
-
await
|
|
4414
|
+
await fs5.mkdir(path7.dirname(filePath), { recursive: true });
|
|
3871
4415
|
try {
|
|
3872
|
-
await
|
|
4416
|
+
await fs5.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3873
4417
|
tempCreated = true;
|
|
3874
|
-
await
|
|
4418
|
+
await fs5.rename(tempPath, filePath);
|
|
3875
4419
|
tempCreated = false;
|
|
3876
4420
|
} catch (error3) {
|
|
3877
4421
|
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3878
4422
|
try {
|
|
3879
|
-
await
|
|
4423
|
+
await fs5.unlink(tempPath);
|
|
3880
4424
|
} catch (unlinkError) {
|
|
3881
4425
|
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3882
4426
|
throw unlinkError;
|
|
@@ -3886,18 +4430,18 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
3886
4430
|
throw error3;
|
|
3887
4431
|
}
|
|
3888
4432
|
}
|
|
3889
|
-
async function withFileLock(
|
|
3890
|
-
await
|
|
4433
|
+
async function withFileLock(fs5, lockPath, operation) {
|
|
4434
|
+
await fs5.mkdir(path7.dirname(lockPath), { recursive: true });
|
|
3891
4435
|
for (; ; ) {
|
|
3892
4436
|
try {
|
|
3893
|
-
await
|
|
4437
|
+
await fs5.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
3894
4438
|
break;
|
|
3895
4439
|
} catch (error3) {
|
|
3896
4440
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3897
|
-
await
|
|
4441
|
+
await fs5.unlink(lockPath).catch(() => void 0);
|
|
3898
4442
|
throw error3;
|
|
3899
4443
|
}
|
|
3900
|
-
if (await removeAbandonedLock(
|
|
4444
|
+
if (await removeAbandonedLock(fs5, lockPath)) {
|
|
3901
4445
|
continue;
|
|
3902
4446
|
}
|
|
3903
4447
|
await Promise.resolve();
|
|
@@ -3906,13 +4450,13 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3906
4450
|
try {
|
|
3907
4451
|
return await operation();
|
|
3908
4452
|
} finally {
|
|
3909
|
-
await
|
|
4453
|
+
await fs5.unlink(lockPath);
|
|
3910
4454
|
}
|
|
3911
4455
|
}
|
|
3912
|
-
async function removeAbandonedLock(
|
|
4456
|
+
async function removeAbandonedLock(fs5, lockPath) {
|
|
3913
4457
|
let content;
|
|
3914
4458
|
try {
|
|
3915
|
-
content = await
|
|
4459
|
+
content = await fs5.readFile(lockPath, "utf8");
|
|
3916
4460
|
} catch (error3) {
|
|
3917
4461
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3918
4462
|
return true;
|
|
@@ -3920,11 +4464,11 @@ async function removeAbandonedLock(fs4, lockPath) {
|
|
|
3920
4464
|
throw error3;
|
|
3921
4465
|
}
|
|
3922
4466
|
const owner = Number(content);
|
|
3923
|
-
if (
|
|
4467
|
+
if (Number.isInteger(owner) && owner > 0 && isProcessRunning(owner)) {
|
|
3924
4468
|
return false;
|
|
3925
4469
|
}
|
|
3926
4470
|
try {
|
|
3927
|
-
await
|
|
4471
|
+
await fs5.unlink(lockPath);
|
|
3928
4472
|
return true;
|
|
3929
4473
|
} catch (error3) {
|
|
3930
4474
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
@@ -4192,6 +4736,9 @@ async function ghIssuesBackend(deps) {
|
|
|
4192
4736
|
if (deps.state?.labelPrefix === "") {
|
|
4193
4737
|
throw new Error("gh-issues state.labelPrefix must be a non-empty string when configured.");
|
|
4194
4738
|
}
|
|
4739
|
+
if (deps.stateMachine !== void 0) {
|
|
4740
|
+
validateMachine(deps.stateMachine);
|
|
4741
|
+
}
|
|
4195
4742
|
const client = createGhClient({
|
|
4196
4743
|
token: deps.token,
|
|
4197
4744
|
endpoint: deps.endpoint,
|
|
@@ -4351,7 +4898,9 @@ function createTasksView(name, session, context) {
|
|
|
4351
4898
|
);
|
|
4352
4899
|
projectItemId = added.addProjectV2ItemById?.item?.id ?? void 0;
|
|
4353
4900
|
if (projectItemId === void 0) {
|
|
4354
|
-
throw new Error(
|
|
4901
|
+
throw new Error(
|
|
4902
|
+
"GitHub addProjectV2ItemById response did not include project item id."
|
|
4903
|
+
);
|
|
4355
4904
|
}
|
|
4356
4905
|
}
|
|
4357
4906
|
if (session.labelPrefix === void 0) {
|
|
@@ -4580,12 +5129,15 @@ async function resolveProjectItemId(id, listName, session, context) {
|
|
|
4580
5129
|
const issueNumber = parseIssueNumber(id, listName);
|
|
4581
5130
|
let after;
|
|
4582
5131
|
while (true) {
|
|
4583
|
-
const result = await context.client.graphql(
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
5132
|
+
const result = await context.client.graphql(
|
|
5133
|
+
ISSUE_STATE_LABELS_QUERY,
|
|
5134
|
+
{
|
|
5135
|
+
owner: context.repoOwner,
|
|
5136
|
+
repo: context.repoName,
|
|
5137
|
+
number: issueNumber,
|
|
5138
|
+
after
|
|
5139
|
+
}
|
|
5140
|
+
);
|
|
4589
5141
|
const issue = result.repository?.issue ?? null;
|
|
4590
5142
|
if (issue === null) {
|
|
4591
5143
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
@@ -4862,12 +5414,27 @@ async function fetchIssueTask(id, listName, session, context) {
|
|
|
4862
5414
|
});
|
|
4863
5415
|
}
|
|
4864
5416
|
function parseIssueNumber(id, listName) {
|
|
5417
|
+
if (!isCanonicalDecimalIssueId(id)) {
|
|
5418
|
+
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
5419
|
+
}
|
|
4865
5420
|
const issueNumber = Number(id);
|
|
4866
|
-
if (!Number.
|
|
5421
|
+
if (!Number.isSafeInteger(issueNumber) || issueNumber < 1) {
|
|
4867
5422
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
4868
5423
|
}
|
|
4869
5424
|
return issueNumber;
|
|
4870
5425
|
}
|
|
5426
|
+
function isCanonicalDecimalIssueId(id) {
|
|
5427
|
+
if (id.length === 0 || id[0] === "0") {
|
|
5428
|
+
return false;
|
|
5429
|
+
}
|
|
5430
|
+
for (let index = 0; index < id.length; index += 1) {
|
|
5431
|
+
const charCode = id.charCodeAt(index);
|
|
5432
|
+
if (charCode < 48 || charCode > 57) {
|
|
5433
|
+
return false;
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
return true;
|
|
5437
|
+
}
|
|
4871
5438
|
function mapProjectItemToTask(item, listName, session) {
|
|
4872
5439
|
const content = item.content;
|
|
4873
5440
|
if (!isIssueNode(content)) {
|
|
@@ -4975,7 +5542,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
4975
5542
|
}
|
|
4976
5543
|
|
|
4977
5544
|
// ../task-list/src/backends/markdown-dir.ts
|
|
4978
|
-
import
|
|
5545
|
+
import path8 from "node:path";
|
|
4979
5546
|
import { parseDocument as parseDocument2, stringify as stringify2 } from "yaml";
|
|
4980
5547
|
|
|
4981
5548
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -5078,7 +5645,7 @@ function resolveListLayout(deps) {
|
|
|
5078
5645
|
return deps.singleList ? { kind: "single", name: deps.singleList } : { kind: "multi" };
|
|
5079
5646
|
}
|
|
5080
5647
|
function validateListName(name) {
|
|
5081
|
-
if (name
|
|
5648
|
+
if (!isTrimmedPrintableIdentifier(name) || name === ARCHIVE_DIRECTORY_NAME || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
5082
5649
|
throw new Error(`Invalid task list name "${name}".`);
|
|
5083
5650
|
}
|
|
5084
5651
|
return name;
|
|
@@ -5094,16 +5661,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
5094
5661
|
};
|
|
5095
5662
|
}
|
|
5096
5663
|
function listPath(rootPath, layout, list) {
|
|
5097
|
-
return layout.kind === "single" ? rootPath :
|
|
5664
|
+
return layout.kind === "single" ? rootPath : path8.join(rootPath, list);
|
|
5098
5665
|
}
|
|
5099
5666
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
5100
|
-
return layout.kind === "single" ?
|
|
5667
|
+
return layout.kind === "single" ? path8.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path8.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
5101
5668
|
}
|
|
5102
5669
|
function activeTaskFilename(id, order, width) {
|
|
5103
5670
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
5104
5671
|
}
|
|
5105
5672
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
5106
|
-
return
|
|
5673
|
+
return path8.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
5107
5674
|
}
|
|
5108
5675
|
function isMarkdownFile(entryName) {
|
|
5109
5676
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -5205,7 +5772,7 @@ function hasOwnTaskField(frontmatter, key2) {
|
|
|
5205
5772
|
function reservedFrontmatterKeys(mode) {
|
|
5206
5773
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
5207
5774
|
}
|
|
5208
|
-
function
|
|
5775
|
+
function setOwnValue2(record, key2, value) {
|
|
5209
5776
|
Object.defineProperty(record, key2, {
|
|
5210
5777
|
value,
|
|
5211
5778
|
enumerable: true,
|
|
@@ -5218,7 +5785,7 @@ function metadataFromFrontmatter(frontmatter, mode) {
|
|
|
5218
5785
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5219
5786
|
for (const [key2, value] of Object.entries(frontmatter)) {
|
|
5220
5787
|
if (!reservedKeys.has(key2)) {
|
|
5221
|
-
|
|
5788
|
+
setOwnValue2(metadata, key2, value);
|
|
5222
5789
|
}
|
|
5223
5790
|
}
|
|
5224
5791
|
return metadata;
|
|
@@ -5232,7 +5799,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
5232
5799
|
state: frontmatter.state,
|
|
5233
5800
|
description: body,
|
|
5234
5801
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
5235
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5802
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5236
5803
|
};
|
|
5237
5804
|
}
|
|
5238
5805
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -5241,9 +5808,9 @@ ${stringify2(frontmatter)}---
|
|
|
5241
5808
|
|
|
5242
5809
|
${description}`;
|
|
5243
5810
|
}
|
|
5244
|
-
async function readDirectoryNames(
|
|
5811
|
+
async function readDirectoryNames(fs5, directoryPath) {
|
|
5245
5812
|
try {
|
|
5246
|
-
return sortStrings(await
|
|
5813
|
+
return sortStrings(await fs5.readdir(directoryPath));
|
|
5247
5814
|
} catch (error3) {
|
|
5248
5815
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
5249
5816
|
return [];
|
|
@@ -5259,9 +5826,9 @@ async function ensureRootPath(deps) {
|
|
|
5259
5826
|
}
|
|
5260
5827
|
await deps.fs.stat(deps.path);
|
|
5261
5828
|
}
|
|
5262
|
-
async function readTaskFile(
|
|
5263
|
-
await rejectSymbolicLinkComponents(
|
|
5264
|
-
const content = await
|
|
5829
|
+
async function readTaskFile(fs5, list, id, filePath, validStates, initialState, mode) {
|
|
5830
|
+
await rejectSymbolicLinkComponents(fs5, filePath);
|
|
5831
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5265
5832
|
const document = splitTaskDocument(content, filePath, mode);
|
|
5266
5833
|
const frontmatter = mode === "passthrough" && document.frontmatter.trim().length === 0 ? {} : readFrontmatter(document.frontmatter, filePath);
|
|
5267
5834
|
if (mode !== "passthrough") {
|
|
@@ -5272,57 +5839,106 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
5272
5839
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
5273
5840
|
};
|
|
5274
5841
|
}
|
|
5275
|
-
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
5276
|
-
const defaultName = parsedFilename?.id ?? id;
|
|
5277
5842
|
const effectiveFrontmatter = {
|
|
5278
5843
|
...frontmatter,
|
|
5279
|
-
name: typeof frontmatter.name === "string" ? frontmatter.name :
|
|
5844
|
+
name: typeof frontmatter.name === "string" ? frontmatter.name : id,
|
|
5280
5845
|
state: typeof frontmatter.state === "string" && validStates.has(frontmatter.state) ? frontmatter.state : initialState
|
|
5281
5846
|
};
|
|
5282
5847
|
return {
|
|
5283
|
-
path: filePath,
|
|
5284
|
-
frontmatter,
|
|
5285
|
-
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5848
|
+
path: filePath,
|
|
5849
|
+
frontmatter,
|
|
5850
|
+
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5851
|
+
};
|
|
5852
|
+
}
|
|
5853
|
+
async function readPassthroughFrontmatter(fs5, filePath, mode) {
|
|
5854
|
+
if (mode !== "passthrough") {
|
|
5855
|
+
return {};
|
|
5856
|
+
}
|
|
5857
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5858
|
+
const document = splitTaskDocument(content, filePath, mode);
|
|
5859
|
+
if (document.frontmatter.trim().length === 0) {
|
|
5860
|
+
return {};
|
|
5861
|
+
}
|
|
5862
|
+
return readFrontmatter(document.frontmatter, filePath);
|
|
5863
|
+
}
|
|
5864
|
+
async function resolveActiveFilenameEntry(fs5, entryName, entryPath, parsed, mode) {
|
|
5865
|
+
if (mode !== "passthrough" || parsed.order === null) {
|
|
5866
|
+
return parsed;
|
|
5867
|
+
}
|
|
5868
|
+
const frontmatter = await readPassthroughFrontmatter(fs5, entryPath, mode);
|
|
5869
|
+
if (Object.keys(frontmatter).length === 0 && orderedFilenamePrefixLength(entryName) <= MIN_PREFIX_WIDTH) {
|
|
5870
|
+
return parsed;
|
|
5871
|
+
}
|
|
5872
|
+
if (typeof frontmatter.state === "string" || hasOwnTaskField(frontmatter, "$schema") || hasOwnTaskField(frontmatter, "kind") || hasOwnTaskField(frontmatter, "version")) {
|
|
5873
|
+
return parsed;
|
|
5874
|
+
}
|
|
5875
|
+
return {
|
|
5876
|
+
id: entryName.slice(0, -MARKDOWN_EXTENSION.length),
|
|
5877
|
+
order: null,
|
|
5878
|
+
filename: parsed.filename
|
|
5286
5879
|
};
|
|
5287
5880
|
}
|
|
5288
|
-
|
|
5289
|
-
const
|
|
5881
|
+
function orderedFilenamePrefixLength(entryName) {
|
|
5882
|
+
const stem = entryName.slice(0, -MARKDOWN_EXTENSION.length);
|
|
5883
|
+
const separatorIndex = stem.indexOf("-");
|
|
5884
|
+
if (separatorIndex <= 0) {
|
|
5885
|
+
return Number.POSITIVE_INFINITY;
|
|
5886
|
+
}
|
|
5887
|
+
for (let index = 0; index < separatorIndex; index += 1) {
|
|
5888
|
+
const code = stem.charCodeAt(index);
|
|
5889
|
+
if (code < 48 || code > 57) {
|
|
5890
|
+
return Number.POSITIVE_INFINITY;
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
return separatorIndex;
|
|
5894
|
+
}
|
|
5895
|
+
async function findActiveTaskFilename(fs5, listDirectoryPath, id, mode) {
|
|
5896
|
+
const entries = await readDirectoryNames(fs5, listDirectoryPath);
|
|
5290
5897
|
for (const entryName of entries) {
|
|
5291
5898
|
if (isHiddenEntry(entryName)) continue;
|
|
5292
5899
|
const parsed = parseActiveFilename(entryName);
|
|
5293
|
-
if (parsed
|
|
5900
|
+
if (!parsed) continue;
|
|
5901
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5902
|
+
const resolved = await resolveActiveFilenameEntry(
|
|
5903
|
+
fs5,
|
|
5904
|
+
entryName,
|
|
5905
|
+
entryPath,
|
|
5906
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
5907
|
+
mode
|
|
5908
|
+
);
|
|
5909
|
+
if (resolved.id === id) {
|
|
5294
5910
|
return entryName;
|
|
5295
5911
|
}
|
|
5296
5912
|
}
|
|
5297
5913
|
return void 0;
|
|
5298
5914
|
}
|
|
5299
|
-
async function findTaskLocation(
|
|
5915
|
+
async function findTaskLocation(fs5, rootPath, layout, list, id, mode) {
|
|
5300
5916
|
const listDirectoryPath = listPath(rootPath, layout, list);
|
|
5301
|
-
await rejectSymbolicLinkComponents(
|
|
5302
|
-
const activeName = await findActiveTaskFilename(
|
|
5917
|
+
await rejectSymbolicLinkComponents(fs5, listDirectoryPath);
|
|
5918
|
+
const activeName = await findActiveTaskFilename(fs5, listDirectoryPath, id, mode);
|
|
5303
5919
|
if (activeName) {
|
|
5304
|
-
const activePath =
|
|
5305
|
-
await rejectSymbolicLinkComponents(
|
|
5306
|
-
const activeStat = await statIfExists(
|
|
5920
|
+
const activePath = path8.join(listDirectoryPath, activeName);
|
|
5921
|
+
await rejectSymbolicLinkComponents(fs5, activePath);
|
|
5922
|
+
const activeStat = await statIfExists(fs5, activePath);
|
|
5307
5923
|
if (activeStat?.isFile()) {
|
|
5308
5924
|
return { archived: false, path: activePath };
|
|
5309
5925
|
}
|
|
5310
5926
|
}
|
|
5311
5927
|
const archivedPath = archivedTaskPath(rootPath, layout, list, id);
|
|
5312
|
-
await rejectSymbolicLinkComponents(
|
|
5313
|
-
await rejectSymbolicLinkComponents(
|
|
5314
|
-
const archivedStat = await statIfExists(
|
|
5928
|
+
await rejectSymbolicLinkComponents(fs5, archiveDirectoryPath(rootPath, layout, list));
|
|
5929
|
+
await rejectSymbolicLinkComponents(fs5, archivedPath);
|
|
5930
|
+
const archivedStat = await statIfExists(fs5, archivedPath);
|
|
5315
5931
|
if (archivedStat?.isFile()) {
|
|
5316
5932
|
return { archived: true, path: archivedPath };
|
|
5317
5933
|
}
|
|
5318
5934
|
return void 0;
|
|
5319
5935
|
}
|
|
5320
|
-
async function readTaskAtLocation(
|
|
5321
|
-
const location = await findTaskLocation(
|
|
5936
|
+
async function readTaskAtLocation(fs5, rootPath, layout, list, id, validStates, initialState, mode) {
|
|
5937
|
+
const location = await findTaskLocation(fs5, rootPath, layout, list, id, mode);
|
|
5322
5938
|
if (!location) {
|
|
5323
5939
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5324
5940
|
}
|
|
5325
|
-
return readTaskFile(
|
|
5941
|
+
return readTaskFile(fs5, list, id, location.path, validStates, initialState, mode);
|
|
5326
5942
|
}
|
|
5327
5943
|
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
5328
5944
|
const frontmatter = mode !== "passthrough" ? {
|
|
@@ -5338,12 +5954,12 @@ function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
|
5338
5954
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5339
5955
|
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5340
5956
|
if (!reservedKeys.has(key2)) {
|
|
5341
|
-
|
|
5957
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5342
5958
|
}
|
|
5343
5959
|
}
|
|
5344
5960
|
for (const [key2, value] of Object.entries(input.metadata ?? {})) {
|
|
5345
5961
|
if (!reservedKeys.has(key2)) {
|
|
5346
|
-
|
|
5962
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5347
5963
|
}
|
|
5348
5964
|
}
|
|
5349
5965
|
frontmatter.created = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5365,7 +5981,7 @@ function updatedFrontmatter(existingFrontmatter, task, patch, mode) {
|
|
|
5365
5981
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5366
5982
|
for (const [key2, value] of Object.entries(patch.metadata ?? {})) {
|
|
5367
5983
|
if (!reservedKeys.has(key2)) {
|
|
5368
|
-
|
|
5984
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5369
5985
|
}
|
|
5370
5986
|
}
|
|
5371
5987
|
return nextFrontmatter;
|
|
@@ -5389,7 +6005,7 @@ function firedFrontmatter(existingFrontmatter, task, to, mode, metadataPatch) {
|
|
|
5389
6005
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5390
6006
|
for (const [key2, value] of Object.entries(metadataPatch ?? {})) {
|
|
5391
6007
|
if (!reservedKeys.has(key2)) {
|
|
5392
|
-
|
|
6008
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5393
6009
|
}
|
|
5394
6010
|
}
|
|
5395
6011
|
return nextFrontmatter;
|
|
@@ -5423,11 +6039,19 @@ function createTasksView2(deps, layout, list) {
|
|
|
5423
6039
|
if (isHiddenEntry(entryName)) continue;
|
|
5424
6040
|
const parsed = parseActiveFilename(entryName);
|
|
5425
6041
|
if (!parsed) continue;
|
|
5426
|
-
const entryPath =
|
|
6042
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5427
6043
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5428
6044
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5429
6045
|
if (!entryStat?.isFile()) continue;
|
|
5430
|
-
result.push(
|
|
6046
|
+
result.push(
|
|
6047
|
+
await resolveActiveFilenameEntry(
|
|
6048
|
+
deps.fs,
|
|
6049
|
+
entryName,
|
|
6050
|
+
entryPath,
|
|
6051
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
6052
|
+
deps.frontmatterMode
|
|
6053
|
+
)
|
|
6054
|
+
);
|
|
5431
6055
|
}
|
|
5432
6056
|
result.sort((left, right) => {
|
|
5433
6057
|
const leftOrder = left.order ?? Number.POSITIVE_INFINITY;
|
|
@@ -5441,7 +6065,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5441
6065
|
const entries = await readActiveEntries();
|
|
5442
6066
|
const tasks = /* @__PURE__ */ new Map();
|
|
5443
6067
|
for (const entry of entries) {
|
|
5444
|
-
const filePath =
|
|
6068
|
+
const filePath = path8.join(listDirectoryPath, entry.filename);
|
|
5445
6069
|
const file = await readTaskFile(
|
|
5446
6070
|
deps.fs,
|
|
5447
6071
|
list,
|
|
@@ -5462,7 +6086,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5462
6086
|
const result = [];
|
|
5463
6087
|
for (const entryName of entries) {
|
|
5464
6088
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
5465
|
-
const entryPath =
|
|
6089
|
+
const entryPath = path8.join(archivePath, entryName);
|
|
5466
6090
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5467
6091
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5468
6092
|
if (!entryStat?.isFile()) continue;
|
|
@@ -5492,15 +6116,20 @@ function createTasksView2(deps, layout, list) {
|
|
|
5492
6116
|
if (desiredOrder === void 0) continue;
|
|
5493
6117
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
5494
6118
|
if (entry.filename !== desiredFilename) {
|
|
5495
|
-
const fromPath =
|
|
5496
|
-
const stagingPath =
|
|
6119
|
+
const fromPath = path8.join(listDirectoryPath, entry.filename);
|
|
6120
|
+
const stagingPath = path8.join(
|
|
5497
6121
|
listDirectoryPath,
|
|
5498
6122
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
5499
6123
|
);
|
|
5500
|
-
const targetPath =
|
|
6124
|
+
const targetPath = path8.join(listDirectoryPath, desiredFilename);
|
|
5501
6125
|
try {
|
|
5502
6126
|
await deps.fs.rename(fromPath, stagingPath);
|
|
5503
|
-
staged.push({
|
|
6127
|
+
staged.push({
|
|
6128
|
+
original: fromPath,
|
|
6129
|
+
staging: stagingPath,
|
|
6130
|
+
target: targetPath,
|
|
6131
|
+
finalized: false
|
|
6132
|
+
});
|
|
5504
6133
|
} catch (error3) {
|
|
5505
6134
|
for (const stagedEntry of staged.reverse()) {
|
|
5506
6135
|
await deps.fs.rename(stagedEntry.staging, stagedEntry.original);
|
|
@@ -5635,8 +6264,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5635
6264
|
if (filter?.state && entry.task.state !== filter.state) return false;
|
|
5636
6265
|
return true;
|
|
5637
6266
|
});
|
|
5638
|
-
|
|
5639
|
-
return [...orderedActiveTasks, ...filteredArchived.map((entry) => entry.task)];
|
|
6267
|
+
return applyOrder([...orderedActive, ...filteredArchived], filter?.order);
|
|
5640
6268
|
},
|
|
5641
6269
|
async get(id) {
|
|
5642
6270
|
return (await getTaskFile(id)).task;
|
|
@@ -5645,9 +6273,17 @@ function createTasksView2(deps, layout, list) {
|
|
|
5645
6273
|
assertCreateDoesNotSetState(input);
|
|
5646
6274
|
assertCreateHasId(input);
|
|
5647
6275
|
validateTaskId(input.id);
|
|
6276
|
+
validateTaskName(input.name);
|
|
5648
6277
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
5649
|
-
return withFileLock(deps.fs,
|
|
5650
|
-
const existing = await findTaskLocation(
|
|
6278
|
+
return withFileLock(deps.fs, path8.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
6279
|
+
const existing = await findTaskLocation(
|
|
6280
|
+
deps.fs,
|
|
6281
|
+
deps.path,
|
|
6282
|
+
layout,
|
|
6283
|
+
list,
|
|
6284
|
+
input.id,
|
|
6285
|
+
deps.frontmatterMode
|
|
6286
|
+
);
|
|
5651
6287
|
if (existing) {
|
|
5652
6288
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
5653
6289
|
}
|
|
@@ -5659,7 +6295,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5659
6295
|
const nextOrder = maxOrder + 1;
|
|
5660
6296
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
5661
6297
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
5662
|
-
const targetPath =
|
|
6298
|
+
const targetPath = path8.join(listDirectoryPath, filename);
|
|
5663
6299
|
const frontmatter = createdFrontmatter(
|
|
5664
6300
|
deps.defaults,
|
|
5665
6301
|
input,
|
|
@@ -5668,12 +6304,22 @@ function createTasksView2(deps, layout, list) {
|
|
|
5668
6304
|
);
|
|
5669
6305
|
const description = input.description ?? "";
|
|
5670
6306
|
await writeAtomically(deps.fs, targetPath, serializeTaskDocument(frontmatter, description));
|
|
5671
|
-
return createTask(
|
|
6307
|
+
return createTask(
|
|
6308
|
+
list,
|
|
6309
|
+
input.id,
|
|
6310
|
+
frontmatter,
|
|
6311
|
+
description,
|
|
6312
|
+
deps.frontmatterMode,
|
|
6313
|
+
targetPath
|
|
6314
|
+
);
|
|
5672
6315
|
});
|
|
5673
6316
|
},
|
|
5674
6317
|
async update(id, patch) {
|
|
5675
6318
|
assertUpdateDoesNotSetState(patch);
|
|
5676
6319
|
validateTaskId(id);
|
|
6320
|
+
if (patch.name !== void 0) {
|
|
6321
|
+
validateTaskName(patch.name);
|
|
6322
|
+
}
|
|
5677
6323
|
const existing = await getTaskFile(id);
|
|
5678
6324
|
const nextFrontmatter = updatedFrontmatter(
|
|
5679
6325
|
existing.frontmatter,
|
|
@@ -5759,7 +6405,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5759
6405
|
};
|
|
5760
6406
|
if (stateMachine.events[eventName]?.to === "archived") {
|
|
5761
6407
|
validateTaskId(id);
|
|
5762
|
-
const location = await findTaskLocation(
|
|
6408
|
+
const location = await findTaskLocation(
|
|
6409
|
+
deps.fs,
|
|
6410
|
+
deps.path,
|
|
6411
|
+
layout,
|
|
6412
|
+
list,
|
|
6413
|
+
id,
|
|
6414
|
+
deps.frontmatterMode
|
|
6415
|
+
);
|
|
5763
6416
|
if (!location) {
|
|
5764
6417
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5765
6418
|
}
|
|
@@ -5767,7 +6420,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5767
6420
|
validateTaskId(id);
|
|
5768
6421
|
const { event, nextTask } = await withFileLock(
|
|
5769
6422
|
deps.fs,
|
|
5770
|
-
|
|
6423
|
+
path8.join(listDirectoryPath, ".transition.lock"),
|
|
5771
6424
|
fireTask
|
|
5772
6425
|
);
|
|
5773
6426
|
await event.onEnter?.(nextTask);
|
|
@@ -5787,7 +6440,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5787
6440
|
},
|
|
5788
6441
|
async delete(id) {
|
|
5789
6442
|
validateTaskId(id);
|
|
5790
|
-
const location = await findTaskLocation(
|
|
6443
|
+
const location = await findTaskLocation(
|
|
6444
|
+
deps.fs,
|
|
6445
|
+
deps.path,
|
|
6446
|
+
layout,
|
|
6447
|
+
list,
|
|
6448
|
+
id,
|
|
6449
|
+
deps.frontmatterMode
|
|
6450
|
+
);
|
|
5791
6451
|
if (!location) {
|
|
5792
6452
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5793
6453
|
}
|
|
@@ -5860,7 +6520,7 @@ async function markdownDirBackend(deps) {
|
|
|
5860
6520
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
5861
6521
|
continue;
|
|
5862
6522
|
}
|
|
5863
|
-
const entryPath =
|
|
6523
|
+
const entryPath = path8.join(deps.path, entryName);
|
|
5864
6524
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5865
6525
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5866
6526
|
if (entryStat?.isDirectory()) {
|
|
@@ -5902,12 +6562,26 @@ async function markdownDirBackend(deps) {
|
|
|
5902
6562
|
}
|
|
5903
6563
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
5904
6564
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
5905
|
-
return withFileLock(deps.fs,
|
|
5906
|
-
const targetExisting = await findTaskLocation(
|
|
6565
|
+
return withFileLock(deps.fs, path8.join(targetListDir, ".transition.lock"), async () => {
|
|
6566
|
+
const targetExisting = await findTaskLocation(
|
|
6567
|
+
deps.fs,
|
|
6568
|
+
deps.path,
|
|
6569
|
+
layout,
|
|
6570
|
+
targetListName,
|
|
6571
|
+
id,
|
|
6572
|
+
deps.frontmatterMode
|
|
6573
|
+
);
|
|
5907
6574
|
if (targetExisting) {
|
|
5908
6575
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
5909
6576
|
}
|
|
5910
|
-
const sourceLocation = await findTaskLocation(
|
|
6577
|
+
const sourceLocation = await findTaskLocation(
|
|
6578
|
+
deps.fs,
|
|
6579
|
+
deps.path,
|
|
6580
|
+
layout,
|
|
6581
|
+
sourceListName,
|
|
6582
|
+
id,
|
|
6583
|
+
deps.frontmatterMode
|
|
6584
|
+
);
|
|
5911
6585
|
if (!sourceLocation) {
|
|
5912
6586
|
throw new TaskNotFoundError(`Task "${sourceListName}/${id}" not found.`);
|
|
5913
6587
|
}
|
|
@@ -5952,7 +6626,7 @@ async function markdownDirBackend(deps) {
|
|
|
5952
6626
|
);
|
|
5953
6627
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
5954
6628
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
5955
|
-
const targetPath =
|
|
6629
|
+
const targetPath = path8.join(targetListDir, targetFilename);
|
|
5956
6630
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
5957
6631
|
return createTask(
|
|
5958
6632
|
targetListName,
|
|
@@ -5974,7 +6648,7 @@ async function markdownDirBackend(deps) {
|
|
|
5974
6648
|
}
|
|
5975
6649
|
|
|
5976
6650
|
// ../task-list/src/backends/yaml-file.ts
|
|
5977
|
-
import
|
|
6651
|
+
import path9 from "node:path";
|
|
5978
6652
|
import { isMap, parseDocument as parseDocument3 } from "yaml";
|
|
5979
6653
|
|
|
5980
6654
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -6034,7 +6708,7 @@ function malformedTask2(list, id, field) {
|
|
|
6034
6708
|
return new MalformedTaskError(`Malformed task "${list}/${id}": invalid "${field}".`);
|
|
6035
6709
|
}
|
|
6036
6710
|
function validateListName2(name) {
|
|
6037
|
-
if (name
|
|
6711
|
+
if (!isTrimmedPrintableIdentifier(name) || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
6038
6712
|
throw new Error(`Invalid task list name "${name}".`);
|
|
6039
6713
|
}
|
|
6040
6714
|
return name;
|
|
@@ -6071,7 +6745,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
6071
6745
|
state: getOwnEntry(taskRecord, "state"),
|
|
6072
6746
|
description: descriptionFromTaskRecord(taskRecord),
|
|
6073
6747
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
6074
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
6748
|
+
...sourcePath !== void 0 && { sourcePath: path9.resolve(sourcePath) }
|
|
6075
6749
|
};
|
|
6076
6750
|
}
|
|
6077
6751
|
function matchesFilter(task, filter) {
|
|
@@ -6242,8 +6916,8 @@ function serializeDocument(document) {
|
|
|
6242
6916
|
return serialized.endsWith("\n") ? serialized : `${serialized}
|
|
6243
6917
|
`;
|
|
6244
6918
|
}
|
|
6245
|
-
async function readStore(
|
|
6246
|
-
const content = await
|
|
6919
|
+
async function readStore(fs5, filePath, validStates) {
|
|
6920
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
6247
6921
|
const document = parseStoreDocument(filePath, content);
|
|
6248
6922
|
const store = document.toJS();
|
|
6249
6923
|
assertValidStoreRecord(store, filePath);
|
|
@@ -6383,6 +7057,7 @@ function createTasksView3(deps, list) {
|
|
|
6383
7057
|
assertCreateDoesNotSetState2(input);
|
|
6384
7058
|
assertCreateHasId2(input);
|
|
6385
7059
|
validateTaskId(input.id);
|
|
7060
|
+
validateTaskName(input.name);
|
|
6386
7061
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6387
7062
|
if (getTaskRecord(store, list, input.id)) {
|
|
6388
7063
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -6395,6 +7070,9 @@ function createTasksView3(deps, list) {
|
|
|
6395
7070
|
async update(id, patch) {
|
|
6396
7071
|
assertUpdateDoesNotSetState2(patch);
|
|
6397
7072
|
validateTaskId(id);
|
|
7073
|
+
if (patch.name !== void 0) {
|
|
7074
|
+
validateTaskName(patch.name);
|
|
7075
|
+
}
|
|
6398
7076
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6399
7077
|
const existing = getTaskOrThrow(store, list, id);
|
|
6400
7078
|
const nextTaskRecord = buildUpdatedTaskRecord(existing, patch);
|
|
@@ -6486,6 +7164,11 @@ function createTasksView3(deps, list) {
|
|
|
6486
7164
|
insertIndex = anchor.position === "top" ? 0 : listNode.items.length;
|
|
6487
7165
|
} else {
|
|
6488
7166
|
const anchorId = "before" in anchor ? anchor.before : anchor.after;
|
|
7167
|
+
const activeIds = new Set(activeItemIds(listNode, validStates));
|
|
7168
|
+
if (!activeIds.has(anchorId)) {
|
|
7169
|
+
listNode.items.splice(fromIndex, 0, movedPair);
|
|
7170
|
+
throw new AnchorNotFoundError(anchorId);
|
|
7171
|
+
}
|
|
6489
7172
|
const anchorIndex = findItemIndex(listNode, anchorId);
|
|
6490
7173
|
if (anchorIndex < 0) {
|
|
6491
7174
|
listNode.items.splice(fromIndex, 0, movedPair);
|
|
@@ -6670,7 +7353,7 @@ function isRecord4(value) {
|
|
|
6670
7353
|
|
|
6671
7354
|
// ../task-list/src/move.ts
|
|
6672
7355
|
import * as fsPromises2 from "node:fs/promises";
|
|
6673
|
-
import
|
|
7356
|
+
import path10 from "node:path";
|
|
6674
7357
|
|
|
6675
7358
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
6676
7359
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6857,7 +7540,7 @@ function areEqualStrings(left, right) {
|
|
|
6857
7540
|
}
|
|
6858
7541
|
|
|
6859
7542
|
// ../toolcraft/src/human-in-loop/runner.ts
|
|
6860
|
-
import { access, lstat, readFile as
|
|
7543
|
+
import { access, lstat, readFile as readFile3, rename, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
6861
7544
|
|
|
6862
7545
|
// ../toolcraft/src/human-in-loop/default-provider.ts
|
|
6863
7546
|
import process3 from "node:process";
|
|
@@ -6889,7 +7572,7 @@ on error number -128
|
|
|
6889
7572
|
end try`;
|
|
6890
7573
|
}
|
|
6891
7574
|
function parseStdout(out) {
|
|
6892
|
-
const value = out.endsWith("\r\n") ? out.slice(0, -2) : out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
7575
|
+
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;
|
|
6893
7576
|
switch (value) {
|
|
6894
7577
|
case "Approve":
|
|
6895
7578
|
case "APPROVED":
|
|
@@ -7169,13 +7852,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
7169
7852
|
}
|
|
7170
7853
|
function enumerateApprovalCommandPaths(root) {
|
|
7171
7854
|
const paths = [];
|
|
7172
|
-
const visit = (node,
|
|
7855
|
+
const visit = (node, path26) => {
|
|
7173
7856
|
if (node.kind === "command") {
|
|
7174
|
-
paths.push(
|
|
7857
|
+
paths.push(path26.join("."));
|
|
7175
7858
|
return;
|
|
7176
7859
|
}
|
|
7177
7860
|
for (const child of getVisibleCliChildren(node)) {
|
|
7178
|
-
visit(child, [...
|
|
7861
|
+
visit(child, [...path26, child.name]);
|
|
7179
7862
|
}
|
|
7180
7863
|
};
|
|
7181
7864
|
if (root.kind === "command") {
|
|
@@ -7210,21 +7893,21 @@ function createHandlerContext(command, params17) {
|
|
|
7210
7893
|
}
|
|
7211
7894
|
function createFs() {
|
|
7212
7895
|
return {
|
|
7213
|
-
readFile: async (
|
|
7214
|
-
writeFile: async (
|
|
7215
|
-
await writeFile2(
|
|
7896
|
+
readFile: async (path26, encoding = "utf8") => readFile3(path26, { encoding }),
|
|
7897
|
+
writeFile: async (path26, contents, options) => {
|
|
7898
|
+
await writeFile2(path26, contents, options);
|
|
7216
7899
|
},
|
|
7217
|
-
exists: async (
|
|
7900
|
+
exists: async (path26) => {
|
|
7218
7901
|
try {
|
|
7219
|
-
await access(
|
|
7902
|
+
await access(path26);
|
|
7220
7903
|
return true;
|
|
7221
7904
|
} catch {
|
|
7222
7905
|
return false;
|
|
7223
7906
|
}
|
|
7224
7907
|
},
|
|
7225
|
-
lstat: async (
|
|
7908
|
+
lstat: async (path26) => lstat(path26),
|
|
7226
7909
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
7227
|
-
unlink: async (
|
|
7910
|
+
unlink: async (path26) => unlink(path26)
|
|
7228
7911
|
};
|
|
7229
7912
|
}
|
|
7230
7913
|
function createEnv(values = process.env) {
|
|
@@ -7503,13 +8186,13 @@ function isMissingStateError(error3) {
|
|
|
7503
8186
|
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
7504
8187
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
7505
8188
|
import os from "node:os";
|
|
7506
|
-
import
|
|
8189
|
+
import path14 from "node:path";
|
|
7507
8190
|
import { CommanderError } from "commander";
|
|
7508
8191
|
|
|
7509
8192
|
// ../toolcraft/src/mcp-proxy.ts
|
|
7510
8193
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7511
|
-
import { lstat as lstat2, mkdir, readFile as
|
|
7512
|
-
import
|
|
8194
|
+
import { lstat as lstat2, mkdir, readFile as readFile4, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
8195
|
+
import path13 from "node:path";
|
|
7513
8196
|
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
7514
8197
|
|
|
7515
8198
|
// ../tiny-mcp-client/src/internal.ts
|
|
@@ -7518,13 +8201,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
7518
8201
|
|
|
7519
8202
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
7520
8203
|
import crypto from "node:crypto";
|
|
7521
|
-
import
|
|
8204
|
+
import path12 from "node:path";
|
|
7522
8205
|
|
|
7523
8206
|
// ../auth-store/src/encrypted-file-store.ts
|
|
7524
8207
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
7525
8208
|
import { promises as fs } from "node:fs";
|
|
7526
8209
|
import { homedir, hostname, userInfo } from "node:os";
|
|
7527
|
-
import
|
|
8210
|
+
import path11 from "node:path";
|
|
7528
8211
|
|
|
7529
8212
|
// ../auth-store/src/error-codes.ts
|
|
7530
8213
|
function hasOwnErrorCode3(error3, code) {
|
|
@@ -7553,10 +8236,13 @@ var EncryptedFileStore = class {
|
|
|
7553
8236
|
if (input.filePath === void 0) {
|
|
7554
8237
|
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
7555
8238
|
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
7556
|
-
|
|
8239
|
+
const defaultFileName = input.defaultFileName ?? "credentials.enc";
|
|
8240
|
+
assertSafeDefaultDirectory(defaultDirectory);
|
|
8241
|
+
assertSafeDefaultFileName(defaultFileName);
|
|
8242
|
+
this.filePath = path11.join(
|
|
7557
8243
|
homeDirectory,
|
|
7558
8244
|
defaultDirectory,
|
|
7559
|
-
|
|
8245
|
+
defaultFileName
|
|
7560
8246
|
);
|
|
7561
8247
|
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
7562
8248
|
homeDirectory,
|
|
@@ -7616,7 +8302,7 @@ var EncryptedFileStore = class {
|
|
|
7616
8302
|
authTag: authTag.toString("base64"),
|
|
7617
8303
|
ciphertext: ciphertext.toString("base64")
|
|
7618
8304
|
};
|
|
7619
|
-
await this.fs.mkdir(
|
|
8305
|
+
await this.fs.mkdir(path11.dirname(this.filePath), { recursive: true });
|
|
7620
8306
|
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
7621
8307
|
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
7622
8308
|
let temporaryCreated = false;
|
|
@@ -7648,7 +8334,7 @@ var EncryptedFileStore = class {
|
|
|
7648
8334
|
}
|
|
7649
8335
|
}
|
|
7650
8336
|
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
7651
|
-
const resolvedPath =
|
|
8337
|
+
const resolvedPath = path11.resolve(targetPath);
|
|
7652
8338
|
const protectedPaths = getProtectedCredentialPaths(
|
|
7653
8339
|
resolvedPath,
|
|
7654
8340
|
this.symbolicLinkCheckStartPath
|
|
@@ -7682,27 +8368,62 @@ var EncryptedFileStore = class {
|
|
|
7682
8368
|
};
|
|
7683
8369
|
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
7684
8370
|
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
7685
|
-
return
|
|
8371
|
+
return path11.resolve(homeDirectory, firstSegment ?? ".");
|
|
7686
8372
|
}
|
|
7687
8373
|
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
7688
8374
|
if (symbolicLinkCheckStartPath === null) {
|
|
7689
|
-
return
|
|
8375
|
+
return getExplicitProtectedCredentialPaths(resolvedPath);
|
|
7690
8376
|
}
|
|
7691
|
-
const resolvedStartPath =
|
|
8377
|
+
const resolvedStartPath = path11.resolve(symbolicLinkCheckStartPath);
|
|
7692
8378
|
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
7693
|
-
return [
|
|
8379
|
+
return [path11.dirname(resolvedPath), resolvedPath];
|
|
7694
8380
|
}
|
|
7695
8381
|
const protectedPaths = [resolvedStartPath];
|
|
7696
8382
|
let currentPath = resolvedStartPath;
|
|
7697
|
-
for (const segment of
|
|
7698
|
-
currentPath =
|
|
8383
|
+
for (const segment of path11.relative(resolvedStartPath, resolvedPath).split(path11.sep).filter(Boolean)) {
|
|
8384
|
+
currentPath = path11.join(currentPath, segment);
|
|
8385
|
+
protectedPaths.push(currentPath);
|
|
8386
|
+
}
|
|
8387
|
+
return protectedPaths;
|
|
8388
|
+
}
|
|
8389
|
+
function assertSafeDefaultDirectory(defaultDirectory) {
|
|
8390
|
+
if (path11.isAbsolute(defaultDirectory) || path11.win32.isAbsolute(defaultDirectory)) {
|
|
8391
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8392
|
+
}
|
|
8393
|
+
for (const segment of splitPathSegments(defaultDirectory)) {
|
|
8394
|
+
if (segment === "..") {
|
|
8395
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8398
|
+
}
|
|
8399
|
+
function assertSafeDefaultFileName(defaultFileName) {
|
|
8400
|
+
if (defaultFileName.trim().length === 0 || defaultFileName === "." || defaultFileName === ".." || splitPathSegments(defaultFileName).length !== 1) {
|
|
8401
|
+
throw new Error("defaultFileName must be a file name without path separators");
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
function splitPathSegments(value) {
|
|
8405
|
+
return value.split("/").flatMap((segment) => segment.split("\\")).filter((segment) => segment.length > 0);
|
|
8406
|
+
}
|
|
8407
|
+
function getExplicitProtectedCredentialPaths(resolvedPath) {
|
|
8408
|
+
const parsed = path11.parse(resolvedPath);
|
|
8409
|
+
const segments = resolvedPath.slice(parsed.root.length).split(path11.sep).filter((segment) => segment.length > 0);
|
|
8410
|
+
if (segments.length <= 1) {
|
|
8411
|
+
return [resolvedPath];
|
|
8412
|
+
}
|
|
8413
|
+
const protectedPaths = [];
|
|
8414
|
+
let currentPath = parsed.root;
|
|
8415
|
+
for (const [index, segment] of segments.entries()) {
|
|
8416
|
+
currentPath = path11.join(currentPath, segment);
|
|
8417
|
+
if (index === 0) {
|
|
8418
|
+
continue;
|
|
8419
|
+
}
|
|
7699
8420
|
protectedPaths.push(currentPath);
|
|
7700
8421
|
}
|
|
7701
8422
|
return protectedPaths;
|
|
7702
8423
|
}
|
|
7703
8424
|
function isPathInsideOrEqual(childPath, parentPath) {
|
|
7704
|
-
const relativePath =
|
|
7705
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
8425
|
+
const relativePath = path11.relative(parentPath, childPath);
|
|
8426
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
|
|
7706
8427
|
}
|
|
7707
8428
|
async function removeIfPresent(fileSystem, filePath) {
|
|
7708
8429
|
try {
|
|
@@ -7793,8 +8514,14 @@ var KeychainStore = class {
|
|
|
7793
8514
|
account;
|
|
7794
8515
|
constructor(input) {
|
|
7795
8516
|
this.runCommand = input.runCommand ?? runSecurityCommand;
|
|
7796
|
-
this.service = input.service;
|
|
7797
|
-
this.account = input.account;
|
|
8517
|
+
this.service = input.service.trim();
|
|
8518
|
+
this.account = input.account.trim();
|
|
8519
|
+
if (this.service.length === 0) {
|
|
8520
|
+
throw new Error("Keychain service must not be empty");
|
|
8521
|
+
}
|
|
8522
|
+
if (this.account.length === 0) {
|
|
8523
|
+
throw new Error("Keychain account must not be empty");
|
|
8524
|
+
}
|
|
7798
8525
|
}
|
|
7799
8526
|
async get() {
|
|
7800
8527
|
const result = await this.executeSecurityCommand(
|
|
@@ -7821,10 +8548,10 @@ var KeychainStore = class {
|
|
|
7821
8548
|
"-a",
|
|
7822
8549
|
this.account,
|
|
7823
8550
|
"-U",
|
|
7824
|
-
"-w"
|
|
8551
|
+
"-w",
|
|
8552
|
+
value
|
|
7825
8553
|
],
|
|
7826
|
-
"store secret in macOS Keychain"
|
|
7827
|
-
{ stdin: value }
|
|
8554
|
+
"store secret in macOS Keychain"
|
|
7828
8555
|
);
|
|
7829
8556
|
if (getCommandExitCode(result) !== 0) {
|
|
7830
8557
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
@@ -7969,13 +8696,14 @@ function createSecretStore(input) {
|
|
|
7969
8696
|
function resolveBackend(input) {
|
|
7970
8697
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7971
8698
|
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7972
|
-
|
|
8699
|
+
const backend = configuredBackend?.trim();
|
|
8700
|
+
if (backend === "keychain") {
|
|
7973
8701
|
return "keychain";
|
|
7974
8702
|
}
|
|
7975
|
-
if (
|
|
8703
|
+
if (backend === void 0 || backend === "file") {
|
|
7976
8704
|
return "file";
|
|
7977
8705
|
}
|
|
7978
|
-
throw new Error(`Unsupported auth store backend: ${
|
|
8706
|
+
throw new Error(`Unsupported auth store backend: ${backend}`);
|
|
7979
8707
|
}
|
|
7980
8708
|
function getOwnEnvValue(env, key2) {
|
|
7981
8709
|
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
@@ -8000,6 +8728,7 @@ var DEFAULT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth";
|
|
|
8000
8728
|
var DEFAULT_CLIENT_FILE_SALT = "poe-code:mcp-oauth:clients:v1";
|
|
8001
8729
|
var DEFAULT_CLIENT_FILE_DIRECTORY = ".poe-code/mcp-oauth/clients";
|
|
8002
8730
|
var DEFAULT_CLIENT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth-clients";
|
|
8731
|
+
var MAX_JS_DATE_MS = 864e13;
|
|
8003
8732
|
function createAuthStoreSessionStore(options = {}) {
|
|
8004
8733
|
return {
|
|
8005
8734
|
async load(resource) {
|
|
@@ -8009,10 +8738,10 @@ function createAuthStoreSessionStore(options = {}) {
|
|
|
8009
8738
|
return null;
|
|
8010
8739
|
}
|
|
8011
8740
|
const parsed = JSON.parse(value);
|
|
8012
|
-
if (
|
|
8741
|
+
if (isStoredOAuthSession(parsed)) {
|
|
8013
8742
|
return parsed;
|
|
8014
8743
|
}
|
|
8015
|
-
throw new Error("Stored OAuth session must
|
|
8744
|
+
throw new Error("Stored OAuth session must match the expected shape");
|
|
8016
8745
|
},
|
|
8017
8746
|
async save(resource, session) {
|
|
8018
8747
|
const store = createResourceSecretStore(resource, options);
|
|
@@ -8056,10 +8785,10 @@ function createAuthStoreClientStore(options) {
|
|
|
8056
8785
|
function createNamedSecretStore(key2, options, defaults2) {
|
|
8057
8786
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
8058
8787
|
const configuredFilePath = options.fileStore?.filePath;
|
|
8059
|
-
const parsedFilePath = configuredFilePath === void 0 ? null :
|
|
8788
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path12.parse(configuredFilePath);
|
|
8060
8789
|
const fileStore = {
|
|
8061
8790
|
...options.fileStore,
|
|
8062
|
-
filePath: parsedFilePath === null ? void 0 :
|
|
8791
|
+
filePath: parsedFilePath === null ? void 0 : path12.join(
|
|
8063
8792
|
parsedFilePath.dir,
|
|
8064
8793
|
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
8065
8794
|
),
|
|
@@ -8075,28 +8804,20 @@ function createNamedSecretStore(key2, options, defaults2) {
|
|
|
8075
8804
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
8076
8805
|
}
|
|
8077
8806
|
function createResourceSecretStore(resource, options) {
|
|
8078
|
-
return createNamedSecretStore(
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8085
|
-
accountPrefix: "provider"
|
|
8086
|
-
}
|
|
8087
|
-
);
|
|
8807
|
+
return createNamedSecretStore(canonicalizeResourceIndicator(resource), options, {
|
|
8808
|
+
salt: DEFAULT_FILE_SALT,
|
|
8809
|
+
directory: DEFAULT_FILE_DIRECTORY,
|
|
8810
|
+
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8811
|
+
accountPrefix: "provider"
|
|
8812
|
+
});
|
|
8088
8813
|
}
|
|
8089
8814
|
function createIssuerSecretStore(issuer, options) {
|
|
8090
|
-
return createNamedSecretStore(
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8097
|
-
accountPrefix: "issuer"
|
|
8098
|
-
}
|
|
8099
|
-
);
|
|
8815
|
+
return createNamedSecretStore(issuer, options, {
|
|
8816
|
+
salt: DEFAULT_CLIENT_FILE_SALT,
|
|
8817
|
+
directory: DEFAULT_CLIENT_FILE_DIRECTORY,
|
|
8818
|
+
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8819
|
+
accountPrefix: "issuer"
|
|
8820
|
+
});
|
|
8100
8821
|
}
|
|
8101
8822
|
function isObjectRecord(value) {
|
|
8102
8823
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8108,6 +8829,50 @@ function getOwnString(record, key2) {
|
|
|
8108
8829
|
const value = getOwnEntry4(record, key2);
|
|
8109
8830
|
return typeof value === "string" ? value : void 0;
|
|
8110
8831
|
}
|
|
8832
|
+
function isStoredOAuthSession(value) {
|
|
8833
|
+
if (!isObjectRecord(value)) {
|
|
8834
|
+
return false;
|
|
8835
|
+
}
|
|
8836
|
+
return isNonBlankOwnString(value, "resource") && isNonBlankOwnString(value, "authorizationServer") && isStoredOAuthClient(getOwnEntry4(value, "client")) && isStoredOAuthDiscovery(getOwnEntry4(value, "discovery")) && isStoredOAuthTokensOrMissing(getOwnEntry4(value, "tokens"));
|
|
8837
|
+
}
|
|
8838
|
+
function isStoredOAuthClient(value) {
|
|
8839
|
+
if (!isObjectRecord(value) || !isNonBlankOwnString(value, "clientId")) {
|
|
8840
|
+
return false;
|
|
8841
|
+
}
|
|
8842
|
+
const clientSecret = getOwnEntry4(value, "clientSecret");
|
|
8843
|
+
return clientSecret === void 0 || typeof clientSecret === "string" && clientSecret.trim().length > 0;
|
|
8844
|
+
}
|
|
8845
|
+
function isStoredOAuthDiscovery(value) {
|
|
8846
|
+
if (!isObjectRecord(value)) {
|
|
8847
|
+
return false;
|
|
8848
|
+
}
|
|
8849
|
+
return isNonBlankOwnString(value, "resourceMetadataUrl") && isObjectRecord(getOwnEntry4(value, "resourceMetadata")) && isObjectRecord(getOwnEntry4(value, "authorizationServerMetadata"));
|
|
8850
|
+
}
|
|
8851
|
+
function isStoredOAuthTokensOrMissing(value) {
|
|
8852
|
+
if (value === void 0) {
|
|
8853
|
+
return true;
|
|
8854
|
+
}
|
|
8855
|
+
if (!isObjectRecord(value)) {
|
|
8856
|
+
return false;
|
|
8857
|
+
}
|
|
8858
|
+
if (!isNonBlankOwnString(value, "accessToken") || getOwnString(value, "tokenType") !== "Bearer") {
|
|
8859
|
+
return false;
|
|
8860
|
+
}
|
|
8861
|
+
const expiresAt = getOwnEntry4(value, "expiresAt");
|
|
8862
|
+
if (expiresAt !== null && (typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS || !Number.isFinite(new Date(expiresAt).getTime()))) {
|
|
8863
|
+
return false;
|
|
8864
|
+
}
|
|
8865
|
+
const refreshToken = getOwnEntry4(value, "refreshToken");
|
|
8866
|
+
if (refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
|
|
8867
|
+
return false;
|
|
8868
|
+
}
|
|
8869
|
+
const scope = getOwnEntry4(value, "scope");
|
|
8870
|
+
return scope === void 0 || typeof scope === "string" && scope.trim().length > 0;
|
|
8871
|
+
}
|
|
8872
|
+
function isNonBlankOwnString(record, key2) {
|
|
8873
|
+
const value = getOwnString(record, key2);
|
|
8874
|
+
return value !== void 0 && value.trim().length > 0;
|
|
8875
|
+
}
|
|
8111
8876
|
|
|
8112
8877
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
8113
8878
|
import { URL as URL2 } from "node:url";
|
|
@@ -8218,9 +8983,7 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8218
8983
|
} catch (error3) {
|
|
8219
8984
|
res.writeHead(400);
|
|
8220
8985
|
res.end(error3 instanceof Error ? error3.message : "Invalid OAuth callback");
|
|
8221
|
-
|
|
8222
|
-
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8223
|
-
}
|
|
8986
|
+
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8224
8987
|
return;
|
|
8225
8988
|
}
|
|
8226
8989
|
const authorizationError = callbackParameters.error;
|
|
@@ -8232,7 +8995,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8232
8995
|
return;
|
|
8233
8996
|
}
|
|
8234
8997
|
try {
|
|
8235
|
-
const code = validateAuthorizationCallbackParameters(
|
|
8998
|
+
const code = validateAuthorizationCallbackParameters(
|
|
8999
|
+
callbackParameters,
|
|
9000
|
+
expectedAuthorization
|
|
9001
|
+
);
|
|
8236
9002
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
8237
9003
|
res.end(buildSuccessPage(options.landingPage));
|
|
8238
9004
|
settle(() => resolve(code));
|
|
@@ -8255,7 +9021,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8255
9021
|
const description = callbackParameters.errorDescription ?? callbackParameters.error;
|
|
8256
9022
|
throw createAuthorizationError(callbackParameters.error, description);
|
|
8257
9023
|
}
|
|
8258
|
-
const code = validateAuthorizationCallbackParameters(
|
|
9024
|
+
const code = validateAuthorizationCallbackParameters(
|
|
9025
|
+
callbackParameters,
|
|
9026
|
+
expectedAuthorization
|
|
9027
|
+
);
|
|
8259
9028
|
settle(() => resolve(code));
|
|
8260
9029
|
} catch (error3) {
|
|
8261
9030
|
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
@@ -8360,6 +9129,7 @@ function generateCodeChallenge(verifier) {
|
|
|
8360
9129
|
}
|
|
8361
9130
|
|
|
8362
9131
|
// ../mcp-oauth/src/client/token-endpoint.ts
|
|
9132
|
+
var MAX_JS_DATE_MS2 = 864e13;
|
|
8363
9133
|
var OAuthError = class extends Error {
|
|
8364
9134
|
error;
|
|
8365
9135
|
errorDescription;
|
|
@@ -8437,22 +9207,32 @@ async function requestTokens(input) {
|
|
|
8437
9207
|
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
8438
9208
|
throw new Error("OAuth token response missing access_token");
|
|
8439
9209
|
}
|
|
9210
|
+
const normalizedAccessToken = accessToken.trim();
|
|
8440
9211
|
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
8441
9212
|
if (tokenType === null) {
|
|
8442
9213
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
8443
9214
|
}
|
|
8444
9215
|
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
8445
|
-
|
|
8446
|
-
|
|
9216
|
+
let expiresAt = null;
|
|
9217
|
+
if (expiresIn !== void 0) {
|
|
9218
|
+
if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || !Number.isInteger(expiresIn) || expiresIn < 0) {
|
|
9219
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9220
|
+
}
|
|
9221
|
+
expiresAt = input.now() + expiresIn * 1e3;
|
|
9222
|
+
if (!Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS2 || !Number.isFinite(new Date(expiresAt).getTime())) {
|
|
9223
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9224
|
+
}
|
|
8447
9225
|
}
|
|
8448
9226
|
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
8449
9227
|
const scope = getOwnEntry6(payload, "scope");
|
|
9228
|
+
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
9229
|
+
const normalizedScope = typeof scope === "string" && scope.trim().length > 0 ? scope.trim() : void 0;
|
|
8450
9230
|
return {
|
|
8451
|
-
accessToken,
|
|
8452
|
-
refreshToken:
|
|
9231
|
+
accessToken: normalizedAccessToken,
|
|
9232
|
+
refreshToken: normalizedRefreshToken === void 0 ? void 0 : normalizedRefreshToken,
|
|
8453
9233
|
tokenType,
|
|
8454
|
-
expiresAt
|
|
8455
|
-
scope:
|
|
9234
|
+
expiresAt,
|
|
9235
|
+
scope: normalizedScope === void 0 ? void 0 : normalizedScope
|
|
8456
9236
|
};
|
|
8457
9237
|
}
|
|
8458
9238
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -8503,6 +9283,7 @@ function normalizeBearerTokenType(value) {
|
|
|
8503
9283
|
}
|
|
8504
9284
|
|
|
8505
9285
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
9286
|
+
var MAX_JS_DATE_MS3 = 864e13;
|
|
8506
9287
|
function createOAuthClientProvider(options) {
|
|
8507
9288
|
if (isProviderOptions(options)) {
|
|
8508
9289
|
return options.provider;
|
|
@@ -8667,7 +9448,12 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8667
9448
|
});
|
|
8668
9449
|
let resolvedClient = null;
|
|
8669
9450
|
try {
|
|
8670
|
-
resolvedClient = await resolveClient(
|
|
9451
|
+
resolvedClient = await resolveClient(
|
|
9452
|
+
currentSession,
|
|
9453
|
+
discovery,
|
|
9454
|
+
loopback.redirectUri,
|
|
9455
|
+
fetch2
|
|
9456
|
+
);
|
|
8671
9457
|
const sessionWithoutTokens = {
|
|
8672
9458
|
resource,
|
|
8673
9459
|
authorizationServer: discovery.authorizationServer,
|
|
@@ -8734,28 +9520,26 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8734
9520
|
return finalPromise;
|
|
8735
9521
|
}
|
|
8736
9522
|
async function resolveClient(existingSession, discovery, redirectUri, fetch2) {
|
|
9523
|
+
const configuredClient = normalizeConfiguredClient(options.client);
|
|
8737
9524
|
if (options.client.mode === "static") {
|
|
9525
|
+
if (configuredClient === null) {
|
|
9526
|
+
throw new Error("OAuth client_id must not be blank");
|
|
9527
|
+
}
|
|
8738
9528
|
return {
|
|
8739
9529
|
kind: "static",
|
|
8740
9530
|
fromStoredRegistration: false,
|
|
8741
|
-
client:
|
|
8742
|
-
clientId: options.client.clientId,
|
|
8743
|
-
clientSecret: options.client.clientSecret
|
|
8744
|
-
}
|
|
9531
|
+
client: configuredClient
|
|
8745
9532
|
};
|
|
8746
9533
|
}
|
|
8747
9534
|
const registrationEndpoint = getOwnString2(
|
|
8748
9535
|
discovery.authorizationServerMetadata,
|
|
8749
9536
|
"registration_endpoint"
|
|
8750
9537
|
);
|
|
8751
|
-
if (registrationEndpoint === void 0 &&
|
|
9538
|
+
if (registrationEndpoint === void 0 && configuredClient !== null) {
|
|
8752
9539
|
return {
|
|
8753
9540
|
kind: "static",
|
|
8754
9541
|
fromStoredRegistration: false,
|
|
8755
|
-
client:
|
|
8756
|
-
clientId: options.client.clientId,
|
|
8757
|
-
clientSecret: options.client.clientSecret
|
|
8758
|
-
}
|
|
9542
|
+
client: configuredClient
|
|
8759
9543
|
};
|
|
8760
9544
|
}
|
|
8761
9545
|
const storedClient = await loadRegisteredClient(discovery.authorizationServer);
|
|
@@ -8777,7 +9561,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8777
9561
|
throw new Error("Authorization server metadata is missing registration_endpoint");
|
|
8778
9562
|
}
|
|
8779
9563
|
if (existingSession !== null && existingSession.client.clientId.length > 0) {
|
|
8780
|
-
const isConfiguredStaticFallback =
|
|
9564
|
+
const isConfiguredStaticFallback = configuredClient !== null && existingSession.client.clientId === configuredClient.clientId && existingSession.client.clientSecret === configuredClient.clientSecret;
|
|
8781
9565
|
if (!isConfiguredStaticFallback) {
|
|
8782
9566
|
await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
|
|
8783
9567
|
return {
|
|
@@ -8805,8 +9589,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8805
9589
|
}
|
|
8806
9590
|
const clientSecret = getOwnString2(payload, "client_secret");
|
|
8807
9591
|
const registeredClient = {
|
|
8808
|
-
clientId,
|
|
8809
|
-
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
9592
|
+
clientId: clientId.trim(),
|
|
9593
|
+
clientSecret: clientSecret !== void 0 && clientSecret.trim().length > 0 ? clientSecret.trim() : void 0
|
|
8810
9594
|
};
|
|
8811
9595
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
8812
9596
|
return {
|
|
@@ -8919,14 +9703,16 @@ function normalizeStoredClient(value) {
|
|
|
8919
9703
|
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8920
9704
|
return null;
|
|
8921
9705
|
}
|
|
9706
|
+
const normalizedClientId = clientId.trim();
|
|
8922
9707
|
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8923
9708
|
if (clientSecret === void 0) {
|
|
8924
|
-
return { clientId };
|
|
9709
|
+
return { clientId: normalizedClientId };
|
|
8925
9710
|
}
|
|
8926
9711
|
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8927
9712
|
return null;
|
|
8928
9713
|
}
|
|
8929
|
-
|
|
9714
|
+
const normalizedClientSecret = clientSecret.trim();
|
|
9715
|
+
return { clientId: normalizedClientId, clientSecret: normalizedClientSecret };
|
|
8930
9716
|
}
|
|
8931
9717
|
function normalizeStoredTokens(value) {
|
|
8932
9718
|
if (value === void 0 || !isObjectRecord3(value)) {
|
|
@@ -8937,20 +9723,45 @@ function normalizeStoredTokens(value) {
|
|
|
8937
9723
|
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8938
9724
|
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8939
9725
|
const scope = getOwnString2(value, "scope");
|
|
8940
|
-
const
|
|
8941
|
-
|
|
9726
|
+
const normalizedAccessToken = accessToken?.trim();
|
|
9727
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : void 0;
|
|
9728
|
+
const normalizedScope = scope?.trim();
|
|
9729
|
+
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)) {
|
|
8942
9730
|
return void 0;
|
|
8943
9731
|
}
|
|
8944
9732
|
return {
|
|
8945
|
-
accessToken,
|
|
9733
|
+
accessToken: normalizedAccessToken,
|
|
8946
9734
|
tokenType,
|
|
8947
9735
|
expiresAt,
|
|
8948
9736
|
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8949
|
-
...
|
|
9737
|
+
...normalizedScope === void 0 || normalizedScope.length === 0 ? {} : { scope: normalizedScope }
|
|
8950
9738
|
};
|
|
8951
9739
|
}
|
|
8952
9740
|
function getClientMetadata(client) {
|
|
8953
|
-
|
|
9741
|
+
if (client.metadata === void 0) {
|
|
9742
|
+
return void 0;
|
|
9743
|
+
}
|
|
9744
|
+
return {
|
|
9745
|
+
clientName: normalizeOptionalOAuthString(client.metadata.clientName),
|
|
9746
|
+
scope: normalizeOptionalOAuthString(client.metadata.scope),
|
|
9747
|
+
softwareId: normalizeOptionalOAuthString(client.metadata.softwareId),
|
|
9748
|
+
softwareVersion: normalizeOptionalOAuthString(client.metadata.softwareVersion)
|
|
9749
|
+
};
|
|
9750
|
+
}
|
|
9751
|
+
function normalizeConfiguredClient(client) {
|
|
9752
|
+
const clientId = normalizeOptionalOAuthString(client.clientId);
|
|
9753
|
+
if (clientId === void 0) {
|
|
9754
|
+
return null;
|
|
9755
|
+
}
|
|
9756
|
+
const clientSecret = normalizeOptionalOAuthString(client.clientSecret);
|
|
9757
|
+
return clientSecret === void 0 ? { clientId } : { clientId, clientSecret };
|
|
9758
|
+
}
|
|
9759
|
+
function normalizeOptionalOAuthString(value) {
|
|
9760
|
+
if (value === void 0) {
|
|
9761
|
+
return void 0;
|
|
9762
|
+
}
|
|
9763
|
+
const trimmed = value.trim();
|
|
9764
|
+
return trimmed.length === 0 ? void 0 : trimmed;
|
|
8954
9765
|
}
|
|
8955
9766
|
function getOwnEntry7(record, key2) {
|
|
8956
9767
|
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
@@ -8979,11 +9790,7 @@ function buildAuthorizationUrl(input) {
|
|
|
8979
9790
|
"authorization_endpoint",
|
|
8980
9791
|
"Authorization server metadata"
|
|
8981
9792
|
);
|
|
8982
|
-
const issuer = requireOwnString(
|
|
8983
|
-
input.metadata,
|
|
8984
|
-
"issuer",
|
|
8985
|
-
"Authorization server metadata"
|
|
8986
|
-
);
|
|
9793
|
+
const issuer = requireOwnString(input.metadata, "issuer", "Authorization server metadata");
|
|
8987
9794
|
const url = new URL2(authorizationEndpoint);
|
|
8988
9795
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
8989
9796
|
const state = createAuthorizationState({
|
|
@@ -9591,7 +10398,7 @@ var McpClient = class {
|
|
|
9591
10398
|
await onToolsChanged();
|
|
9592
10399
|
});
|
|
9593
10400
|
messageLayer.onNotification("notifications/resources/list_changed", async () => {
|
|
9594
|
-
if (onResourcesChanged === void 0) {
|
|
10401
|
+
if (onResourcesChanged === void 0 || this.currentServerCapabilities?.resources?.listChanged !== true) {
|
|
9595
10402
|
return;
|
|
9596
10403
|
}
|
|
9597
10404
|
await onResourcesChanged();
|
|
@@ -9610,7 +10417,7 @@ var McpClient = class {
|
|
|
9610
10417
|
await onResourceUpdated(uri);
|
|
9611
10418
|
});
|
|
9612
10419
|
messageLayer.onNotification("notifications/prompts/list_changed", async () => {
|
|
9613
|
-
if (onPromptsChanged === void 0) {
|
|
10420
|
+
if (onPromptsChanged === void 0 || this.currentServerCapabilities?.prompts?.listChanged !== true) {
|
|
9614
10421
|
return;
|
|
9615
10422
|
}
|
|
9616
10423
|
await onPromptsChanged();
|
|
@@ -9841,7 +10648,11 @@ var McpClient = class {
|
|
|
9841
10648
|
throw new Error("Server does not support resources");
|
|
9842
10649
|
}
|
|
9843
10650
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9844
|
-
|
|
10651
|
+
const result = await messageLayer.sendRequest("resources/list", requestParams);
|
|
10652
|
+
if (!isResourcesListResult(result)) {
|
|
10653
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/list result");
|
|
10654
|
+
}
|
|
10655
|
+
return result;
|
|
9845
10656
|
}
|
|
9846
10657
|
async listResourceTemplates(params17 = {}) {
|
|
9847
10658
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9850,7 +10661,11 @@ var McpClient = class {
|
|
|
9850
10661
|
throw new Error("Server does not support resources");
|
|
9851
10662
|
}
|
|
9852
10663
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9853
|
-
|
|
10664
|
+
const result = await messageLayer.sendRequest("resources/templates/list", requestParams);
|
|
10665
|
+
if (!isResourceTemplatesListResult(result)) {
|
|
10666
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/templates/list result");
|
|
10667
|
+
}
|
|
10668
|
+
return result;
|
|
9854
10669
|
}
|
|
9855
10670
|
async readResource(params17) {
|
|
9856
10671
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9858,7 +10673,11 @@ var McpClient = class {
|
|
|
9858
10673
|
if (serverCapabilities.resources === void 0) {
|
|
9859
10674
|
throw new Error("Server does not support resources");
|
|
9860
10675
|
}
|
|
9861
|
-
|
|
10676
|
+
const result = await messageLayer.sendRequest("resources/read", params17);
|
|
10677
|
+
if (!isReadResourceResult(result)) {
|
|
10678
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/read result");
|
|
10679
|
+
}
|
|
10680
|
+
return result;
|
|
9862
10681
|
}
|
|
9863
10682
|
async subscribe(uri) {
|
|
9864
10683
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9893,7 +10712,11 @@ var McpClient = class {
|
|
|
9893
10712
|
if (serverCapabilities.prompts === void 0) {
|
|
9894
10713
|
throw new Error("Server does not support prompts");
|
|
9895
10714
|
}
|
|
9896
|
-
|
|
10715
|
+
const result = await messageLayer.sendRequest("prompts/get", params17);
|
|
10716
|
+
if (!isGetPromptResult(result)) {
|
|
10717
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid prompts/get result");
|
|
10718
|
+
}
|
|
10719
|
+
return result;
|
|
9897
10720
|
}
|
|
9898
10721
|
async complete(params17) {
|
|
9899
10722
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9901,7 +10724,11 @@ var McpClient = class {
|
|
|
9901
10724
|
if (serverCapabilities.completions === void 0) {
|
|
9902
10725
|
throw new Error("Server does not support completions");
|
|
9903
10726
|
}
|
|
9904
|
-
|
|
10727
|
+
const result = await messageLayer.sendRequest("completion/complete", params17);
|
|
10728
|
+
if (!isCompleteResult(result)) {
|
|
10729
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid completion/complete result");
|
|
10730
|
+
}
|
|
10731
|
+
return result;
|
|
9905
10732
|
}
|
|
9906
10733
|
async setLogLevel(level) {
|
|
9907
10734
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -10892,6 +11719,44 @@ function isCallToolResult(value) {
|
|
|
10892
11719
|
function isToolsListResult(value) {
|
|
10893
11720
|
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
10894
11721
|
}
|
|
11722
|
+
function isResourcesListResult(value) {
|
|
11723
|
+
return isObjectRecord5(value) && Array.isArray(value.resources) && value.resources.every(isResource) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11724
|
+
}
|
|
11725
|
+
function isResourceTemplatesListResult(value) {
|
|
11726
|
+
return isObjectRecord5(value) && Array.isArray(value.resourceTemplates) && value.resourceTemplates.every(isResourceTemplate) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11727
|
+
}
|
|
11728
|
+
function isReadResourceResult(value) {
|
|
11729
|
+
return isObjectRecord5(value) && Array.isArray(value.contents) && value.contents.every(isResourceContents);
|
|
11730
|
+
}
|
|
11731
|
+
function isGetPromptResult(value) {
|
|
11732
|
+
return isObjectRecord5(value) && (value.description === void 0 || typeof value.description === "string") && Array.isArray(value.messages) && value.messages.every(isPromptMessage);
|
|
11733
|
+
}
|
|
11734
|
+
function isCompleteResult(value) {
|
|
11735
|
+
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");
|
|
11736
|
+
}
|
|
11737
|
+
function isResource(value) {
|
|
11738
|
+
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");
|
|
11739
|
+
}
|
|
11740
|
+
function isResourceTemplate(value) {
|
|
11741
|
+
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");
|
|
11742
|
+
}
|
|
11743
|
+
function isResourceContents(value) {
|
|
11744
|
+
if (!isObjectRecord5(value) || typeof value.uri !== "string") {
|
|
11745
|
+
return false;
|
|
11746
|
+
}
|
|
11747
|
+
if (value.mimeType !== void 0 && typeof value.mimeType !== "string") {
|
|
11748
|
+
return false;
|
|
11749
|
+
}
|
|
11750
|
+
const hasText = value.text !== void 0;
|
|
11751
|
+
const hasBlob = value.blob !== void 0;
|
|
11752
|
+
if (!hasText && !hasBlob) {
|
|
11753
|
+
return false;
|
|
11754
|
+
}
|
|
11755
|
+
return (!hasText || typeof value.text === "string") && (!hasBlob || typeof value.blob === "string");
|
|
11756
|
+
}
|
|
11757
|
+
function isPromptMessage(value) {
|
|
11758
|
+
return isObjectRecord5(value) && (value.role === "user" || value.role === "assistant") && isContentItem(value.content);
|
|
11759
|
+
}
|
|
10895
11760
|
function isContentItem(value) {
|
|
10896
11761
|
if (!isObjectRecord5(value)) {
|
|
10897
11762
|
return false;
|
|
@@ -10905,7 +11770,7 @@ function isContentItem(value) {
|
|
|
10905
11770
|
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
10906
11771
|
return false;
|
|
10907
11772
|
}
|
|
10908
|
-
return
|
|
11773
|
+
return isResourceContents(value.resource);
|
|
10909
11774
|
}
|
|
10910
11775
|
function hasOwn(value, property) {
|
|
10911
11776
|
return Object.prototype.hasOwnProperty.call(value, property);
|
|
@@ -11045,13 +11910,13 @@ function convertJsonSchema(schema) {
|
|
|
11045
11910
|
}
|
|
11046
11911
|
return convertSchema(schema, schema, []);
|
|
11047
11912
|
}
|
|
11048
|
-
function convertSchema(schema, root,
|
|
11049
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
11913
|
+
function convertSchema(schema, root, path26) {
|
|
11914
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path26);
|
|
11050
11915
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
11051
11916
|
const composition = getComposition(normalizedSchema.schema);
|
|
11052
11917
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
11053
11918
|
throw new Error(
|
|
11054
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
11919
|
+
`JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
|
|
11055
11920
|
normalizedSchema.schema.type
|
|
11056
11921
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
11057
11922
|
);
|
|
@@ -11063,13 +11928,13 @@ function convertSchema(schema, root, path25) {
|
|
|
11063
11928
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
11064
11929
|
}
|
|
11065
11930
|
if (composition !== void 0) {
|
|
11066
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
11931
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path26);
|
|
11067
11932
|
}
|
|
11068
11933
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
11069
11934
|
return applyMetadata(
|
|
11070
11935
|
S.Record(
|
|
11071
11936
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
11072
|
-
...
|
|
11937
|
+
...path26,
|
|
11073
11938
|
"additionalProperties"
|
|
11074
11939
|
])
|
|
11075
11940
|
),
|
|
@@ -11118,12 +11983,12 @@ function convertSchema(schema, root, path25) {
|
|
|
11118
11983
|
if (normalizedSchema.schema.items === void 0) {
|
|
11119
11984
|
throw new Error(
|
|
11120
11985
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11121
|
-
|
|
11986
|
+
path26
|
|
11122
11987
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
11123
11988
|
);
|
|
11124
11989
|
}
|
|
11125
11990
|
return S.Array(
|
|
11126
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
11991
|
+
convertSchema(normalizedSchema.schema.items, root, [...path26, "items"]),
|
|
11127
11992
|
createCommonOptions(
|
|
11128
11993
|
normalizedSchema.schema,
|
|
11129
11994
|
normalizedSchema.nullable,
|
|
@@ -11133,7 +11998,7 @@ function convertSchema(schema, root, path25) {
|
|
|
11133
11998
|
case "object":
|
|
11134
11999
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
11135
12000
|
nullable: normalizedSchema.nullable,
|
|
11136
|
-
path:
|
|
12001
|
+
path: path26
|
|
11137
12002
|
});
|
|
11138
12003
|
case "null":
|
|
11139
12004
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -11148,12 +12013,12 @@ function convertSchema(schema, root, path25) {
|
|
|
11148
12013
|
}
|
|
11149
12014
|
throw new Error(
|
|
11150
12015
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11151
|
-
|
|
12016
|
+
path26
|
|
11152
12017
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
11153
12018
|
);
|
|
11154
12019
|
}
|
|
11155
12020
|
throw new Error(
|
|
11156
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12021
|
+
`JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
|
|
11157
12022
|
normalizedSchema.schema.type
|
|
11158
12023
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
11159
12024
|
);
|
|
@@ -11197,21 +12062,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
11197
12062
|
)
|
|
11198
12063
|
});
|
|
11199
12064
|
}
|
|
11200
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
12065
|
+
function convertCompositionSchema(schema, root, nullable, path26) {
|
|
11201
12066
|
const composition = getComposition(schema);
|
|
11202
12067
|
const branchSchemas = composition?.branches ?? [];
|
|
11203
12068
|
const keyword = composition?.keyword ?? "oneOf";
|
|
11204
12069
|
const branches = branchSchemas.map(
|
|
11205
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
12070
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path26, keyword, String(index)])
|
|
11206
12071
|
);
|
|
11207
|
-
const discriminator = findDiscriminator(branches, root,
|
|
12072
|
+
const discriminator = findDiscriminator(branches, root, path26);
|
|
11208
12073
|
if (discriminator !== void 0) {
|
|
11209
12074
|
const convertedBranches = Object.fromEntries(
|
|
11210
12075
|
branches.map((branch, index) => [
|
|
11211
12076
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
11212
12077
|
convertObjectSchema(branch, root, {
|
|
11213
12078
|
omitProperty: discriminator,
|
|
11214
|
-
path: [...
|
|
12079
|
+
path: [...path26, keyword, String(index)]
|
|
11215
12080
|
})
|
|
11216
12081
|
])
|
|
11217
12082
|
);
|
|
@@ -11230,7 +12095,7 @@ function convertCompositionSchema(schema, root, nullable, path25) {
|
|
|
11230
12095
|
S.Union(
|
|
11231
12096
|
branches.map(
|
|
11232
12097
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
11233
|
-
path: [...
|
|
12098
|
+
path: [...path26, keyword, String(index)]
|
|
11234
12099
|
})
|
|
11235
12100
|
)
|
|
11236
12101
|
),
|
|
@@ -11344,11 +12209,11 @@ function getComposition(schema) {
|
|
|
11344
12209
|
}
|
|
11345
12210
|
return void 0;
|
|
11346
12211
|
}
|
|
11347
|
-
function formatJsonSchemaPath(
|
|
11348
|
-
if (
|
|
12212
|
+
function formatJsonSchemaPath(path26) {
|
|
12213
|
+
if (path26.length === 0) {
|
|
11349
12214
|
return "#";
|
|
11350
12215
|
}
|
|
11351
|
-
return `#/${
|
|
12216
|
+
return `#/${path26.map(escapeJsonPointerSegment).join("/")}`;
|
|
11352
12217
|
}
|
|
11353
12218
|
function formatJsonSchemaType(type2) {
|
|
11354
12219
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -11364,11 +12229,11 @@ function isRecordSchema(schema) {
|
|
|
11364
12229
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
11365
12230
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
11366
12231
|
}
|
|
11367
|
-
function findDiscriminator(branches, root,
|
|
12232
|
+
function findDiscriminator(branches, root, path26) {
|
|
11368
12233
|
const [firstBranch] = branches;
|
|
11369
12234
|
if (firstBranch === void 0) {
|
|
11370
12235
|
throw new Error(
|
|
11371
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12236
|
+
`JSON Schema "${formatJsonSchemaPath(path26)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
11372
12237
|
);
|
|
11373
12238
|
}
|
|
11374
12239
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -11408,19 +12273,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
11408
12273
|
}
|
|
11409
12274
|
return void 0;
|
|
11410
12275
|
}
|
|
11411
|
-
function resolveReferencedSchema(schema, root,
|
|
12276
|
+
function resolveReferencedSchema(schema, root, path26) {
|
|
11412
12277
|
if (schema.$ref === void 0) {
|
|
11413
12278
|
return schema;
|
|
11414
12279
|
}
|
|
11415
12280
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
11416
12281
|
if (resolvedTarget === void 0) {
|
|
11417
12282
|
throw new Error(
|
|
11418
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12283
|
+
`JSON Schema "${formatJsonSchemaPath(path26)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
11419
12284
|
);
|
|
11420
12285
|
}
|
|
11421
12286
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
11422
12287
|
void ignoredRef;
|
|
11423
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
12288
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path26);
|
|
11424
12289
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
11425
12290
|
return resolvedSchema;
|
|
11426
12291
|
}
|
|
@@ -11444,9 +12309,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
11444
12309
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
11445
12310
|
};
|
|
11446
12311
|
}
|
|
11447
|
-
function hasSelfReferencingRef(schema, root,
|
|
12312
|
+
function hasSelfReferencingRef(schema, root, path26 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
11448
12313
|
const nextActivePaths = new Set(activePaths);
|
|
11449
|
-
nextActivePaths.add(
|
|
12314
|
+
nextActivePaths.add(path26);
|
|
11450
12315
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
11451
12316
|
if (localRefPath !== void 0) {
|
|
11452
12317
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -11457,13 +12322,13 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
|
|
|
11457
12322
|
return true;
|
|
11458
12323
|
}
|
|
11459
12324
|
}
|
|
11460
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
12325
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path26}/items`, nextActivePaths)) {
|
|
11461
12326
|
return true;
|
|
11462
12327
|
}
|
|
11463
12328
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
11464
12329
|
schema.additionalProperties,
|
|
11465
12330
|
root,
|
|
11466
|
-
`${
|
|
12331
|
+
`${path26}/additionalProperties`,
|
|
11467
12332
|
nextActivePaths
|
|
11468
12333
|
)) {
|
|
11469
12334
|
return true;
|
|
@@ -11472,7 +12337,7 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
|
|
|
11472
12337
|
if (hasSelfReferencingRef(
|
|
11473
12338
|
childSchema,
|
|
11474
12339
|
root,
|
|
11475
|
-
`${
|
|
12340
|
+
`${path26}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
11476
12341
|
nextActivePaths
|
|
11477
12342
|
)) {
|
|
11478
12343
|
return true;
|
|
@@ -11482,24 +12347,24 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
|
|
|
11482
12347
|
if (hasSelfReferencingRef(
|
|
11483
12348
|
childSchema,
|
|
11484
12349
|
root,
|
|
11485
|
-
`${
|
|
12350
|
+
`${path26}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
11486
12351
|
nextActivePaths
|
|
11487
12352
|
)) {
|
|
11488
12353
|
return true;
|
|
11489
12354
|
}
|
|
11490
12355
|
}
|
|
11491
12356
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
11492
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12357
|
+
if (hasSelfReferencingRef(childSchema, root, `${path26}/oneOf/${index}`, nextActivePaths)) {
|
|
11493
12358
|
return true;
|
|
11494
12359
|
}
|
|
11495
12360
|
}
|
|
11496
12361
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
11497
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12362
|
+
if (hasSelfReferencingRef(childSchema, root, `${path26}/anyOf/${index}`, nextActivePaths)) {
|
|
11498
12363
|
return true;
|
|
11499
12364
|
}
|
|
11500
12365
|
}
|
|
11501
12366
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
11502
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12367
|
+
if (hasSelfReferencingRef(childSchema, root, `${path26}/allOf/${index}`, nextActivePaths)) {
|
|
11503
12368
|
return true;
|
|
11504
12369
|
}
|
|
11505
12370
|
}
|
|
@@ -11515,14 +12380,14 @@ function getLocalRefPath(ref) {
|
|
|
11515
12380
|
return ref.startsWith("#/") ? ref : void 0;
|
|
11516
12381
|
}
|
|
11517
12382
|
function resolveLocalRef(root, ref) {
|
|
11518
|
-
const
|
|
11519
|
-
if (
|
|
12383
|
+
const path26 = getLocalRefPath(ref);
|
|
12384
|
+
if (path26 === void 0) {
|
|
11520
12385
|
return void 0;
|
|
11521
12386
|
}
|
|
11522
|
-
if (
|
|
12387
|
+
if (path26 === "#") {
|
|
11523
12388
|
return root;
|
|
11524
12389
|
}
|
|
11525
|
-
const segments =
|
|
12390
|
+
const segments = path26.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
11526
12391
|
let current = root;
|
|
11527
12392
|
for (const segment of segments) {
|
|
11528
12393
|
if (Array.isArray(current)) {
|
|
@@ -11568,15 +12433,15 @@ function getBooleanDefault(value) {
|
|
|
11568
12433
|
return typeof value === "boolean" ? value : void 0;
|
|
11569
12434
|
}
|
|
11570
12435
|
function getArrayDefault(value) {
|
|
11571
|
-
return Array.isArray(value) && value.every((item) =>
|
|
12436
|
+
return Array.isArray(value) && value.every((item) => isJsonValue2(item)) ? value : void 0;
|
|
11572
12437
|
}
|
|
11573
12438
|
function getPrimitiveEnumDefault(value, candidates) {
|
|
11574
12439
|
return isPrimitiveEnumValue(value) && candidates.includes(value) ? value : void 0;
|
|
11575
12440
|
}
|
|
11576
12441
|
function getJsonDefault(value) {
|
|
11577
|
-
return
|
|
12442
|
+
return isJsonValue2(value) ? value : void 0;
|
|
11578
12443
|
}
|
|
11579
|
-
function
|
|
12444
|
+
function isJsonValue2(value) {
|
|
11580
12445
|
if (value === null) {
|
|
11581
12446
|
return true;
|
|
11582
12447
|
}
|
|
@@ -11584,12 +12449,12 @@ function isJsonValue(value) {
|
|
|
11584
12449
|
return true;
|
|
11585
12450
|
}
|
|
11586
12451
|
if (Array.isArray(value)) {
|
|
11587
|
-
return value.every((item) =>
|
|
12452
|
+
return value.every((item) => isJsonValue2(item));
|
|
11588
12453
|
}
|
|
11589
12454
|
if (!isPlainObject(value)) {
|
|
11590
12455
|
return false;
|
|
11591
12456
|
}
|
|
11592
|
-
return Object.values(value).every((item) =>
|
|
12457
|
+
return Object.values(value).every((item) => isJsonValue2(item));
|
|
11593
12458
|
}
|
|
11594
12459
|
function isPlainObject(value) {
|
|
11595
12460
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -11779,7 +12644,7 @@ async function ensureConnected(connection) {
|
|
|
11779
12644
|
async function readCache(cachePath) {
|
|
11780
12645
|
try {
|
|
11781
12646
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
11782
|
-
const raw = await
|
|
12647
|
+
const raw = await readFile4(cachePath, "utf8");
|
|
11783
12648
|
const parsed = JSON.parse(raw);
|
|
11784
12649
|
if (parsed === null || typeof parsed !== "object" || !Array.isArray(parsed.tools) || parsed.upstream === void 0 || typeof parsed.upstream.name !== "string" || typeof parsed.upstream.version !== "string") {
|
|
11785
12650
|
return void 0;
|
|
@@ -11800,7 +12665,7 @@ async function readCache(cachePath) {
|
|
|
11800
12665
|
}
|
|
11801
12666
|
}
|
|
11802
12667
|
async function writeCache(cachePath, cache) {
|
|
11803
|
-
const directory =
|
|
12668
|
+
const directory = path13.dirname(cachePath);
|
|
11804
12669
|
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
11805
12670
|
let tempCreated = false;
|
|
11806
12671
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
@@ -11997,13 +12862,13 @@ function collectProxyGroups(root) {
|
|
|
11997
12862
|
function findProjectRoot(from = process.cwd()) {
|
|
11998
12863
|
let current = process.cwd();
|
|
11999
12864
|
if (from !== current) {
|
|
12000
|
-
current =
|
|
12865
|
+
current = path13.resolve(from);
|
|
12001
12866
|
}
|
|
12002
12867
|
while (true) {
|
|
12003
|
-
if (existsSync2(
|
|
12868
|
+
if (existsSync2(path13.join(current, "package.json"))) {
|
|
12004
12869
|
return current;
|
|
12005
12870
|
}
|
|
12006
|
-
const parent =
|
|
12871
|
+
const parent = path13.dirname(current);
|
|
12007
12872
|
if (parent === current) {
|
|
12008
12873
|
return void 0;
|
|
12009
12874
|
}
|
|
@@ -12020,7 +12885,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
12020
12885
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
12021
12886
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
12022
12887
|
}
|
|
12023
|
-
return
|
|
12888
|
+
return path13.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
12024
12889
|
}
|
|
12025
12890
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
12026
12891
|
let currentPath = filePath;
|
|
@@ -12034,10 +12899,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
12034
12899
|
throw error3;
|
|
12035
12900
|
}
|
|
12036
12901
|
}
|
|
12037
|
-
if (
|
|
12902
|
+
if (path13.basename(currentPath) === ".toolcraft") {
|
|
12038
12903
|
return;
|
|
12039
12904
|
}
|
|
12040
|
-
const parentPath =
|
|
12905
|
+
const parentPath = path13.dirname(currentPath);
|
|
12041
12906
|
if (parentPath === currentPath) {
|
|
12042
12907
|
return;
|
|
12043
12908
|
}
|
|
@@ -12183,20 +13048,20 @@ function reportsEnabled(option, env) {
|
|
|
12183
13048
|
function resolveReportDir(option, projectRoot) {
|
|
12184
13049
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12185
13050
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
12186
|
-
return
|
|
13051
|
+
return path14.join(projectRoot, ".toolcraft", "errors");
|
|
12187
13052
|
}
|
|
12188
|
-
return
|
|
13053
|
+
return path14.isAbsolute(configuredDir) ? configuredDir : path14.join(projectRoot, configuredDir);
|
|
12189
13054
|
}
|
|
12190
13055
|
function reportDirMustStayWithinProject(option) {
|
|
12191
13056
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12192
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
13057
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path14.isAbsolute(configuredDir);
|
|
12193
13058
|
}
|
|
12194
13059
|
function isWithinDirectory(parent, child) {
|
|
12195
|
-
const relative =
|
|
12196
|
-
return relative === "" || !
|
|
13060
|
+
const relative = path14.relative(parent, child);
|
|
13061
|
+
return relative === "" || !path14.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path14.sep}`);
|
|
12197
13062
|
}
|
|
12198
13063
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
12199
|
-
if (!isWithinDirectory(
|
|
13064
|
+
if (!isWithinDirectory(path14.resolve(projectRoot), path14.resolve(reportDir))) {
|
|
12200
13065
|
throw new Error("Error report directory resolves outside project root.");
|
|
12201
13066
|
}
|
|
12202
13067
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
@@ -12247,7 +13112,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
12247
13112
|
return output.length === 0 ? "root" : output;
|
|
12248
13113
|
}
|
|
12249
13114
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
12250
|
-
const relative =
|
|
13115
|
+
const relative = path14.relative(projectRoot, absolutePath);
|
|
12251
13116
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
12252
13117
|
}
|
|
12253
13118
|
function redactValue(value) {
|
|
@@ -12567,7 +13432,7 @@ async function writeErrorReport(context) {
|
|
|
12567
13432
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
12568
13433
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
12569
13434
|
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
12570
|
-
const absolutePath =
|
|
13435
|
+
const absolutePath = path14.join(reportDir, fileName);
|
|
12571
13436
|
await mkdir2(reportDir, { recursive: true });
|
|
12572
13437
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
12573
13438
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -13037,7 +13902,7 @@ function inferProgramName(argv) {
|
|
|
13037
13902
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
13038
13903
|
return "toolcraft";
|
|
13039
13904
|
}
|
|
13040
|
-
const parsed =
|
|
13905
|
+
const parsed = path15.parse(entrypoint);
|
|
13041
13906
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
13042
13907
|
}
|
|
13043
13908
|
function normalizeRoots(roots, argv) {
|
|
@@ -13095,11 +13960,11 @@ function formatSegment(segment, casing) {
|
|
|
13095
13960
|
const separator = casing === "snake" ? "_" : "-";
|
|
13096
13961
|
return splitWords3(segment).join(separator);
|
|
13097
13962
|
}
|
|
13098
|
-
function toOptionFlag(
|
|
13099
|
-
return `--${
|
|
13963
|
+
function toOptionFlag(path26, casing) {
|
|
13964
|
+
return `--${path26.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
13100
13965
|
}
|
|
13101
|
-
function toOptionAttribute(
|
|
13102
|
-
return
|
|
13966
|
+
function toOptionAttribute(path26, casing) {
|
|
13967
|
+
return path26.map((segment) => {
|
|
13103
13968
|
const formatted = formatSegment(segment, casing);
|
|
13104
13969
|
if (casing === "snake") {
|
|
13105
13970
|
return formatted;
|
|
@@ -13110,23 +13975,23 @@ function toOptionAttribute(path25, casing) {
|
|
|
13110
13975
|
).join("");
|
|
13111
13976
|
}).join(".");
|
|
13112
13977
|
}
|
|
13113
|
-
function toDisplayPath(
|
|
13114
|
-
return
|
|
13978
|
+
function toDisplayPath(path26) {
|
|
13979
|
+
return path26.join(".");
|
|
13115
13980
|
}
|
|
13116
|
-
function toUnionKindControlPath(
|
|
13117
|
-
if (
|
|
13981
|
+
function toUnionKindControlPath(path26) {
|
|
13982
|
+
if (path26.length === 0) {
|
|
13118
13983
|
return ["kind"];
|
|
13119
13984
|
}
|
|
13120
|
-
const head =
|
|
13121
|
-
const tail =
|
|
13985
|
+
const head = path26.slice(0, -1);
|
|
13986
|
+
const tail = path26[path26.length - 1] ?? "";
|
|
13122
13987
|
return [...head, `${tail}Kind`];
|
|
13123
13988
|
}
|
|
13124
|
-
function toUnionKindDisplayPath(
|
|
13125
|
-
if (
|
|
13989
|
+
function toUnionKindDisplayPath(path26) {
|
|
13990
|
+
if (path26.length === 0) {
|
|
13126
13991
|
return "kind";
|
|
13127
13992
|
}
|
|
13128
|
-
const head =
|
|
13129
|
-
const tail =
|
|
13993
|
+
const head = path26.slice(0, -1);
|
|
13994
|
+
const tail = path26[path26.length - 1] ?? "";
|
|
13130
13995
|
return [...head, `${tail}-kind`].join(".");
|
|
13131
13996
|
}
|
|
13132
13997
|
function createSyntheticEnumSchema(values) {
|
|
@@ -13142,14 +14007,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
13142
14007
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
13143
14008
|
return requiredKeys.join("+");
|
|
13144
14009
|
}
|
|
13145
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
14010
|
+
function collectFields(schema, casing, globalLongOptionFlags, path26 = [], inheritedOptional = false, variantContext) {
|
|
13146
14011
|
const collected = {
|
|
13147
14012
|
dynamicFields: [],
|
|
13148
14013
|
fields: [],
|
|
13149
14014
|
variants: []
|
|
13150
14015
|
};
|
|
13151
14016
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
13152
|
-
const nextPath = [...
|
|
14017
|
+
const nextPath = [...path26, key2];
|
|
13153
14018
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
13154
14019
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
13155
14020
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -13335,9 +14200,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inher
|
|
|
13335
14200
|
}
|
|
13336
14201
|
return collected;
|
|
13337
14202
|
}
|
|
13338
|
-
function toCommanderOptionAttribute(
|
|
13339
|
-
const optionAttribute = toOptionAttribute(
|
|
13340
|
-
const optionFlag = toOptionFlag(
|
|
14203
|
+
function toCommanderOptionAttribute(path26, casing, globalLongOptionFlags) {
|
|
14204
|
+
const optionAttribute = toOptionAttribute(path26, casing);
|
|
14205
|
+
const optionFlag = toOptionFlag(path26, casing);
|
|
13341
14206
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
13342
14207
|
return optionAttribute;
|
|
13343
14208
|
}
|
|
@@ -13610,6 +14475,20 @@ function parseArrayValue(value, schema, label) {
|
|
|
13610
14475
|
(item) => parseScalarValue(item, itemSchema, label)
|
|
13611
14476
|
);
|
|
13612
14477
|
}
|
|
14478
|
+
function isNegativeNumericArrayToken(token, schema) {
|
|
14479
|
+
if (!token.startsWith("-") || token.startsWith("--")) {
|
|
14480
|
+
return false;
|
|
14481
|
+
}
|
|
14482
|
+
const itemSchema = unwrapOptional2(schema.item);
|
|
14483
|
+
if (itemSchema.kind !== "number") {
|
|
14484
|
+
return false;
|
|
14485
|
+
}
|
|
14486
|
+
const items = splitArrayInput(token);
|
|
14487
|
+
return items.length > 0 && items.every((item) => isValidNumberSchemaValue(Number(item), itemSchema));
|
|
14488
|
+
}
|
|
14489
|
+
function isNextArrayOptionToken(token, schema) {
|
|
14490
|
+
return token.startsWith("-") && !isNegativeNumericArrayToken(token, schema);
|
|
14491
|
+
}
|
|
13613
14492
|
function validateArrayBounds(value, schema, label) {
|
|
13614
14493
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
13615
14494
|
throw new UserError(
|
|
@@ -14417,10 +15296,10 @@ function parseDebugStackMode(value) {
|
|
|
14417
15296
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
14418
15297
|
);
|
|
14419
15298
|
}
|
|
14420
|
-
function setNestedValue(target,
|
|
15299
|
+
function setNestedValue(target, path26, value) {
|
|
14421
15300
|
let cursor2 = target;
|
|
14422
|
-
for (let index = 0; index <
|
|
14423
|
-
const segment =
|
|
15301
|
+
for (let index = 0; index < path26.length - 1; index += 1) {
|
|
15302
|
+
const segment = path26[index] ?? "";
|
|
14424
15303
|
const existing = Object.prototype.hasOwnProperty.call(cursor2, segment) ? cursor2[segment] : void 0;
|
|
14425
15304
|
if (typeof existing === "object" && existing !== null) {
|
|
14426
15305
|
cursor2 = existing;
|
|
@@ -14435,7 +15314,7 @@ function setNestedValue(target, path25, value) {
|
|
|
14435
15314
|
});
|
|
14436
15315
|
cursor2 = next;
|
|
14437
15316
|
}
|
|
14438
|
-
const leaf =
|
|
15317
|
+
const leaf = path26[path26.length - 1];
|
|
14439
15318
|
if (leaf !== void 0) {
|
|
14440
15319
|
Object.defineProperty(cursor2, leaf, {
|
|
14441
15320
|
value,
|
|
@@ -14552,21 +15431,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
14552
15431
|
}
|
|
14553
15432
|
function createFs2() {
|
|
14554
15433
|
return {
|
|
14555
|
-
readFile: async (
|
|
14556
|
-
writeFile: async (
|
|
14557
|
-
await writeFile5(
|
|
15434
|
+
readFile: async (path26, encoding = "utf8") => readFile5(path26, { encoding }),
|
|
15435
|
+
writeFile: async (path26, contents, options) => {
|
|
15436
|
+
await writeFile5(path26, contents, options);
|
|
14558
15437
|
},
|
|
14559
|
-
exists: async (
|
|
15438
|
+
exists: async (path26) => {
|
|
14560
15439
|
try {
|
|
14561
|
-
await access2(
|
|
15440
|
+
await access2(path26);
|
|
14562
15441
|
return true;
|
|
14563
15442
|
} catch {
|
|
14564
15443
|
return false;
|
|
14565
15444
|
}
|
|
14566
15445
|
},
|
|
14567
|
-
lstat: async (
|
|
15446
|
+
lstat: async (path26) => lstat3(path26),
|
|
14568
15447
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
14569
|
-
unlink: async (
|
|
15448
|
+
unlink: async (path26) => unlink3(path26)
|
|
14570
15449
|
};
|
|
14571
15450
|
}
|
|
14572
15451
|
function createEnv2(values = process.env) {
|
|
@@ -14582,9 +15461,9 @@ function isPlainObject4(value) {
|
|
|
14582
15461
|
function hasFieldValue(value) {
|
|
14583
15462
|
return value !== void 0;
|
|
14584
15463
|
}
|
|
14585
|
-
function hasNestedField(fields,
|
|
15464
|
+
function hasNestedField(fields, path26) {
|
|
14586
15465
|
return fields.some(
|
|
14587
|
-
(field) =>
|
|
15466
|
+
(field) => path26.length < field.path.length && path26.every((segment, index) => field.path[index] === segment)
|
|
14588
15467
|
);
|
|
14589
15468
|
}
|
|
14590
15469
|
function describeExpectedPresetValue(schema) {
|
|
@@ -14687,7 +15566,7 @@ function validatePresetFieldValue(value, field, presetPath) {
|
|
|
14687
15566
|
async function loadPresetValues(fields, presetPath) {
|
|
14688
15567
|
let rawPreset;
|
|
14689
15568
|
try {
|
|
14690
|
-
rawPreset = await
|
|
15569
|
+
rawPreset = await readFile5(presetPath, {
|
|
14691
15570
|
encoding: "utf8"
|
|
14692
15571
|
});
|
|
14693
15572
|
} catch (error3) {
|
|
@@ -14713,9 +15592,9 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
14713
15592
|
}
|
|
14714
15593
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
14715
15594
|
const presetValues = {};
|
|
14716
|
-
function visitObject(current,
|
|
15595
|
+
function visitObject(current, path26) {
|
|
14717
15596
|
for (const [key2, value] of Object.entries(current)) {
|
|
14718
|
-
const nextPath = [...
|
|
15597
|
+
const nextPath = [...path26, key2];
|
|
14719
15598
|
const displayPath = toDisplayPath(nextPath);
|
|
14720
15599
|
const field = fieldByPath.get(displayPath);
|
|
14721
15600
|
if (field !== void 0) {
|
|
@@ -14922,8 +15801,8 @@ function createFixtureService(definition) {
|
|
|
14922
15801
|
);
|
|
14923
15802
|
}
|
|
14924
15803
|
function resolveFixturePath(commandPath) {
|
|
14925
|
-
const parsed =
|
|
14926
|
-
return
|
|
15804
|
+
const parsed = path15.parse(commandPath);
|
|
15805
|
+
return path15.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
14927
15806
|
}
|
|
14928
15807
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
14929
15808
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -14954,7 +15833,7 @@ async function loadFixtureScenario(command, selector) {
|
|
|
14954
15833
|
const fixturePath = resolveFixturePath(commandPath);
|
|
14955
15834
|
let rawFixture;
|
|
14956
15835
|
try {
|
|
14957
|
-
rawFixture = await
|
|
15836
|
+
rawFixture = await readFile5(fixturePath, {
|
|
14958
15837
|
encoding: "utf8"
|
|
14959
15838
|
});
|
|
14960
15839
|
} catch {
|
|
@@ -15057,8 +15936,8 @@ function validateServices(services) {
|
|
|
15057
15936
|
}
|
|
15058
15937
|
}
|
|
15059
15938
|
}
|
|
15060
|
-
function getNestedValue(target,
|
|
15061
|
-
return
|
|
15939
|
+
function getNestedValue(target, path26) {
|
|
15940
|
+
return path26.reduce(
|
|
15062
15941
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
15063
15942
|
target
|
|
15064
15943
|
);
|
|
@@ -15143,7 +16022,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
|
|
|
15143
16022
|
let cursor2 = index + 1;
|
|
15144
16023
|
while (cursor2 < args.length) {
|
|
15145
16024
|
const token = args[cursor2] ?? "";
|
|
15146
|
-
if (token
|
|
16025
|
+
if (isNextArrayOptionToken(token, schema)) {
|
|
15147
16026
|
break;
|
|
15148
16027
|
}
|
|
15149
16028
|
const parsed = parseArrayValue(token, schema, label);
|
|
@@ -16019,6 +16898,12 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
16019
16898
|
);
|
|
16020
16899
|
return;
|
|
16021
16900
|
}
|
|
16901
|
+
logger2.error(
|
|
16902
|
+
appendUsagePointer(formatCommanderErrorMessage(error3), {
|
|
16903
|
+
rootUsageName: options.rootUsageName,
|
|
16904
|
+
commandPath: options.commandPath.length > 0 ? options.commandPath : findCurrentCommanderCommandPath(options.program, options.argv ?? process.argv)
|
|
16905
|
+
})
|
|
16906
|
+
);
|
|
16022
16907
|
return;
|
|
16023
16908
|
}
|
|
16024
16909
|
if (isHttpErrorLike(error3)) {
|
|
@@ -16036,6 +16921,9 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
16036
16921
|
}
|
|
16037
16922
|
process.exitCode = 1;
|
|
16038
16923
|
}
|
|
16924
|
+
function formatCommanderErrorMessage(error3) {
|
|
16925
|
+
return error3.message.startsWith("error:") ? error3.message : `error: ${error3.message}`;
|
|
16926
|
+
}
|
|
16039
16927
|
function formatInvalidEnumMessage(label, value, values, opts = {}) {
|
|
16040
16928
|
const suggestions = suggest(
|
|
16041
16929
|
value,
|
|
@@ -16360,7 +17248,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
|
|
|
16360
17248
|
// src/terminal-session.ts
|
|
16361
17249
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
16362
17250
|
import { accessSync, chmodSync, constants } from "node:fs";
|
|
16363
|
-
import { createRequire } from "node:module";
|
|
17251
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
16364
17252
|
import { dirname, join } from "node:path";
|
|
16365
17253
|
import * as nodePty from "node-pty";
|
|
16366
17254
|
|
|
@@ -17499,8 +18387,8 @@ var spawnHelperChecked = false;
|
|
|
17499
18387
|
function ensureSpawnHelperExecutable() {
|
|
17500
18388
|
if (spawnHelperChecked) return;
|
|
17501
18389
|
spawnHelperChecked = true;
|
|
17502
|
-
const
|
|
17503
|
-
const nodePtyDir = dirname(
|
|
18390
|
+
const require4 = createRequire2(import.meta.url);
|
|
18391
|
+
const nodePtyDir = dirname(require4.resolve("node-pty"));
|
|
17504
18392
|
const helper = join(nodePtyDir, "..", "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper");
|
|
17505
18393
|
try {
|
|
17506
18394
|
accessSync(helper, constants.X_OK);
|
|
@@ -17920,7 +18808,7 @@ var getSession = defineCommand({
|
|
|
17920
18808
|
|
|
17921
18809
|
// ../agent-skill-config/src/configs.ts
|
|
17922
18810
|
import os2 from "node:os";
|
|
17923
|
-
import
|
|
18811
|
+
import path16 from "node:path";
|
|
17924
18812
|
|
|
17925
18813
|
// ../agent-defs/src/agents/claude-code.ts
|
|
17926
18814
|
var claudeCodeAgent = {
|
|
@@ -18284,7 +19172,7 @@ var templateMutation = {
|
|
|
18284
19172
|
|
|
18285
19173
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
18286
19174
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18287
|
-
import
|
|
19175
|
+
import path18 from "node:path";
|
|
18288
19176
|
|
|
18289
19177
|
// ../config-mutations/src/formats/json.ts
|
|
18290
19178
|
import * as jsonc from "jsonc-parser";
|
|
@@ -18407,22 +19295,22 @@ function prune(obj, shape) {
|
|
|
18407
19295
|
}
|
|
18408
19296
|
return { changed, result };
|
|
18409
19297
|
}
|
|
18410
|
-
function modifyAtPath(content,
|
|
19298
|
+
function modifyAtPath(content, path26, value) {
|
|
18411
19299
|
const indent = detectIndent(content);
|
|
18412
19300
|
const formattingOptions = {
|
|
18413
19301
|
tabSize: indent === " " ? 1 : indent.length,
|
|
18414
19302
|
insertSpaces: indent !== " ",
|
|
18415
19303
|
eol: "\n"
|
|
18416
19304
|
};
|
|
18417
|
-
const edits = jsonc.modify(content,
|
|
19305
|
+
const edits = jsonc.modify(content, path26, value, { formattingOptions });
|
|
18418
19306
|
let result = jsonc.applyEdits(content, edits);
|
|
18419
19307
|
if (!result.endsWith("\n")) {
|
|
18420
19308
|
result += "\n";
|
|
18421
19309
|
}
|
|
18422
19310
|
return result;
|
|
18423
19311
|
}
|
|
18424
|
-
function removeAtPath(content,
|
|
18425
|
-
return modifyAtPath(content,
|
|
19312
|
+
function removeAtPath(content, path26) {
|
|
19313
|
+
return modifyAtPath(content, path26, void 0);
|
|
18426
19314
|
}
|
|
18427
19315
|
function serializeUpdate(content, current, next) {
|
|
18428
19316
|
let result = content || "{}";
|
|
@@ -18432,15 +19320,15 @@ function serializeUpdate(content, current, next) {
|
|
|
18432
19320
|
}
|
|
18433
19321
|
return result;
|
|
18434
19322
|
}
|
|
18435
|
-
function applyObjectUpdate(content,
|
|
19323
|
+
function applyObjectUpdate(content, path26, current, next) {
|
|
18436
19324
|
let result = content;
|
|
18437
19325
|
for (const key2 of Object.keys(current)) {
|
|
18438
19326
|
if (!hasConfigEntry(next, key2)) {
|
|
18439
|
-
result = removeAtPath(result, [...
|
|
19327
|
+
result = removeAtPath(result, [...path26, key2]);
|
|
18440
19328
|
}
|
|
18441
19329
|
}
|
|
18442
19330
|
for (const [key2, nextValue] of Object.entries(next)) {
|
|
18443
|
-
const nextPath = [...
|
|
19331
|
+
const nextPath = [...path26, key2];
|
|
18444
19332
|
const hasCurrent = hasConfigEntry(current, key2);
|
|
18445
19333
|
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
18446
19334
|
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
@@ -18640,20 +19528,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
18640
19528
|
}
|
|
18641
19529
|
return formatRegistry[formatName];
|
|
18642
19530
|
}
|
|
18643
|
-
function detectFormat(
|
|
18644
|
-
const ext = getExtension(
|
|
19531
|
+
function detectFormat(path26) {
|
|
19532
|
+
const ext = getExtension(path26);
|
|
18645
19533
|
return extensionMap[ext];
|
|
18646
19534
|
}
|
|
18647
|
-
function getExtension(
|
|
18648
|
-
const lastDot =
|
|
19535
|
+
function getExtension(path26) {
|
|
19536
|
+
const lastDot = path26.lastIndexOf(".");
|
|
18649
19537
|
if (lastDot === -1) {
|
|
18650
19538
|
return "";
|
|
18651
19539
|
}
|
|
18652
|
-
return
|
|
19540
|
+
return path26.slice(lastDot).toLowerCase();
|
|
18653
19541
|
}
|
|
18654
19542
|
|
|
18655
19543
|
// ../config-mutations/src/execution/path-utils.ts
|
|
18656
|
-
import
|
|
19544
|
+
import path17 from "node:path";
|
|
18657
19545
|
function expandHome(targetPath, homeDir) {
|
|
18658
19546
|
if (!targetPath?.startsWith("~")) {
|
|
18659
19547
|
return targetPath;
|
|
@@ -18670,7 +19558,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
18670
19558
|
remainder = remainder.slice(1);
|
|
18671
19559
|
}
|
|
18672
19560
|
}
|
|
18673
|
-
return remainder.length === 0 ? homeDir :
|
|
19561
|
+
return remainder.length === 0 ? homeDir : path17.join(homeDir, remainder);
|
|
18674
19562
|
}
|
|
18675
19563
|
function validateHomePath(targetPath) {
|
|
18676
19564
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -18685,21 +19573,21 @@ function validateHomePath(targetPath) {
|
|
|
18685
19573
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
18686
19574
|
validateHomePath(rawPath);
|
|
18687
19575
|
const expanded = expandHome(rawPath, homeDir);
|
|
18688
|
-
const canonicalHome =
|
|
18689
|
-
const canonicalExpanded =
|
|
18690
|
-
const relative =
|
|
18691
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
19576
|
+
const canonicalHome = path17.resolve(homeDir);
|
|
19577
|
+
const canonicalExpanded = path17.resolve(expanded);
|
|
19578
|
+
const relative = path17.relative(canonicalHome, canonicalExpanded);
|
|
19579
|
+
if (relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
|
|
18692
19580
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
18693
19581
|
}
|
|
18694
19582
|
if (!pathMapper) {
|
|
18695
19583
|
return canonicalExpanded;
|
|
18696
19584
|
}
|
|
18697
|
-
const rawDirectory =
|
|
19585
|
+
const rawDirectory = path17.dirname(expanded);
|
|
18698
19586
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
18699
19587
|
targetDirectory: rawDirectory
|
|
18700
19588
|
});
|
|
18701
|
-
const filename =
|
|
18702
|
-
return filename.length === 0 ? mappedDirectory :
|
|
19589
|
+
const filename = path17.basename(expanded);
|
|
19590
|
+
return filename.length === 0 ? mappedDirectory : path17.join(mappedDirectory, filename);
|
|
18703
19591
|
}
|
|
18704
19592
|
|
|
18705
19593
|
// ../config-mutations/src/error-codes.ts
|
|
@@ -18711,9 +19599,9 @@ function hasOwnErrorCode5(error3, code) {
|
|
|
18711
19599
|
function isNotFound(error3) {
|
|
18712
19600
|
return hasOwnErrorCode5(error3, "ENOENT");
|
|
18713
19601
|
}
|
|
18714
|
-
async function readFileIfExists(
|
|
19602
|
+
async function readFileIfExists(fs5, target) {
|
|
18715
19603
|
try {
|
|
18716
|
-
return await
|
|
19604
|
+
return await fs5.readFile(target, "utf8");
|
|
18717
19605
|
} catch (error3) {
|
|
18718
19606
|
if (isNotFound(error3)) {
|
|
18719
19607
|
return null;
|
|
@@ -18721,9 +19609,9 @@ async function readFileIfExists(fs4, target) {
|
|
|
18721
19609
|
throw error3;
|
|
18722
19610
|
}
|
|
18723
19611
|
}
|
|
18724
|
-
async function pathExists(
|
|
19612
|
+
async function pathExists(fs5, target) {
|
|
18725
19613
|
try {
|
|
18726
|
-
await
|
|
19614
|
+
await fs5.stat(target);
|
|
18727
19615
|
return true;
|
|
18728
19616
|
} catch (error3) {
|
|
18729
19617
|
if (isNotFound(error3)) {
|
|
@@ -18769,8 +19657,8 @@ function isAlreadyExists(error3) {
|
|
|
18769
19657
|
return hasOwnErrorCode5(error3, "EEXIST");
|
|
18770
19658
|
}
|
|
18771
19659
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
18772
|
-
const boundary =
|
|
18773
|
-
let currentPath =
|
|
19660
|
+
const boundary = path18.dirname(path18.resolve(context.homeDir));
|
|
19661
|
+
let currentPath = path18.resolve(targetPath);
|
|
18774
19662
|
while (currentPath !== boundary) {
|
|
18775
19663
|
try {
|
|
18776
19664
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -18781,7 +19669,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
18781
19669
|
throw error3;
|
|
18782
19670
|
}
|
|
18783
19671
|
}
|
|
18784
|
-
const parentPath =
|
|
19672
|
+
const parentPath = path18.dirname(currentPath);
|
|
18785
19673
|
if (parentPath === currentPath) {
|
|
18786
19674
|
return;
|
|
18787
19675
|
}
|
|
@@ -18846,6 +19734,56 @@ function describeMutation(kind, targetPath) {
|
|
|
18846
19734
|
return "Operation";
|
|
18847
19735
|
}
|
|
18848
19736
|
}
|
|
19737
|
+
function mutationTargetPath(mutation, options) {
|
|
19738
|
+
switch (mutation.kind) {
|
|
19739
|
+
case "ensureDirectory":
|
|
19740
|
+
case "removeDirectory":
|
|
19741
|
+
return resolveValue(mutation.path, options);
|
|
19742
|
+
case "removeFile":
|
|
19743
|
+
case "chmod":
|
|
19744
|
+
case "backup":
|
|
19745
|
+
case "restoreBackup":
|
|
19746
|
+
case "configMerge":
|
|
19747
|
+
case "configPrune":
|
|
19748
|
+
case "configTransform":
|
|
19749
|
+
case "templateWrite":
|
|
19750
|
+
case "templateMergeToml":
|
|
19751
|
+
case "templateMergeJson":
|
|
19752
|
+
return resolveValue(mutation.target, options);
|
|
19753
|
+
default:
|
|
19754
|
+
return void 0;
|
|
19755
|
+
}
|
|
19756
|
+
}
|
|
19757
|
+
function resolveMutationDetails(mutation, context, options) {
|
|
19758
|
+
try {
|
|
19759
|
+
const rawTarget = mutationTargetPath(mutation, options);
|
|
19760
|
+
if (rawTarget === void 0) {
|
|
19761
|
+
return {
|
|
19762
|
+
kind: mutation.kind,
|
|
19763
|
+
label: mutation.label ?? mutation.kind
|
|
19764
|
+
};
|
|
19765
|
+
}
|
|
19766
|
+
try {
|
|
19767
|
+
const targetPath = resolvePath(rawTarget, context.homeDir, context.pathMapper);
|
|
19768
|
+
return {
|
|
19769
|
+
kind: mutation.kind,
|
|
19770
|
+
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19771
|
+
targetPath
|
|
19772
|
+
};
|
|
19773
|
+
} catch {
|
|
19774
|
+
return {
|
|
19775
|
+
kind: mutation.kind,
|
|
19776
|
+
label: mutation.label ?? describeMutation(mutation.kind, rawTarget),
|
|
19777
|
+
targetPath: void 0
|
|
19778
|
+
};
|
|
19779
|
+
}
|
|
19780
|
+
} catch {
|
|
19781
|
+
return {
|
|
19782
|
+
kind: mutation.kind,
|
|
19783
|
+
label: mutation.label ?? mutation.kind
|
|
19784
|
+
};
|
|
19785
|
+
}
|
|
19786
|
+
}
|
|
18849
19787
|
function pruneKeysByPrefix(table, prefix) {
|
|
18850
19788
|
const result = {};
|
|
18851
19789
|
for (const [key2, value] of Object.entries(table)) {
|
|
@@ -18936,6 +19874,7 @@ async function applyEnsureDirectory(mutation, context, options) {
|
|
|
18936
19874
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
18937
19875
|
targetPath
|
|
18938
19876
|
};
|
|
19877
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
18939
19878
|
const existed = await pathExists(context.fs, targetPath);
|
|
18940
19879
|
if (!context.dryRun) {
|
|
18941
19880
|
await context.fs.mkdir(targetPath, { recursive: true });
|
|
@@ -19052,6 +19991,7 @@ async function applyChmod(mutation, context, options) {
|
|
|
19052
19991
|
};
|
|
19053
19992
|
}
|
|
19054
19993
|
try {
|
|
19994
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19055
19995
|
const stat2 = await context.fs.stat(targetPath);
|
|
19056
19996
|
const currentMode = typeof stat2.mode === "number" ? stat2.mode & 511 : null;
|
|
19057
19997
|
if (currentMode === mutation.mode) {
|
|
@@ -19085,6 +20025,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
19085
20025
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19086
20026
|
targetPath
|
|
19087
20027
|
};
|
|
20028
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19088
20029
|
if (mutation.once && await findLatestGeneratedBackup(context.fs, targetPath) !== null) {
|
|
19089
20030
|
return {
|
|
19090
20031
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
@@ -19151,13 +20092,13 @@ async function applyRestoreBackup(mutation, context, options) {
|
|
|
19151
20092
|
}
|
|
19152
20093
|
return { outcome: { changed: true, effect: "copy", detail: "restore" }, details };
|
|
19153
20094
|
}
|
|
19154
|
-
async function findLatestGeneratedBackup(
|
|
20095
|
+
async function findLatestGeneratedBackup(fs5, targetPath) {
|
|
19155
20096
|
const separatorIndex = targetPath.lastIndexOf("/");
|
|
19156
20097
|
const directoryPath = separatorIndex <= 0 ? "/" : targetPath.slice(0, separatorIndex);
|
|
19157
20098
|
const targetName = targetPath.slice(separatorIndex + 1);
|
|
19158
20099
|
let entries;
|
|
19159
20100
|
try {
|
|
19160
|
-
entries = await
|
|
20101
|
+
entries = await fs5.readdir(directoryPath);
|
|
19161
20102
|
} catch (error3) {
|
|
19162
20103
|
if (isNotFound(error3)) {
|
|
19163
20104
|
return null;
|
|
@@ -19221,6 +20162,9 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
19221
20162
|
preserveContent = null;
|
|
19222
20163
|
}
|
|
19223
20164
|
const value = resolveValue(mutation.value, options);
|
|
20165
|
+
if (!isConfigObject4(value)) {
|
|
20166
|
+
throw new Error(`configMerge value must be an object for "${rawPath}".`);
|
|
20167
|
+
}
|
|
19224
20168
|
let merged;
|
|
19225
20169
|
if (mutation.pruneByPrefix) {
|
|
19226
20170
|
merged = mergeWithPruneByPrefix(current, value, mutation.pruneByPrefix);
|
|
@@ -19354,6 +20298,13 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
19354
20298
|
};
|
|
19355
20299
|
}
|
|
19356
20300
|
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
20301
|
+
const serializedChanged = serialized !== rawContent;
|
|
20302
|
+
if (!serializedChanged) {
|
|
20303
|
+
return {
|
|
20304
|
+
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
20305
|
+
details
|
|
20306
|
+
};
|
|
20307
|
+
}
|
|
19357
20308
|
if (!context.dryRun) {
|
|
19358
20309
|
await writeAtomically2(context, targetPath, serialized);
|
|
19359
20310
|
}
|
|
@@ -19470,25 +20421,14 @@ async function runMutations(mutations, context, options) {
|
|
|
19470
20421
|
};
|
|
19471
20422
|
}
|
|
19472
20423
|
async function executeMutation(mutation, context, options) {
|
|
19473
|
-
context
|
|
19474
|
-
|
|
19475
|
-
label: mutation.label ?? mutation.kind,
|
|
19476
|
-
targetPath: void 0
|
|
19477
|
-
// Will be resolved during apply
|
|
19478
|
-
});
|
|
20424
|
+
const pendingDetails = resolveMutationDetails(mutation, context, options);
|
|
20425
|
+
context.observers?.onStart?.(pendingDetails);
|
|
19479
20426
|
try {
|
|
19480
20427
|
const { outcome, details } = await applyMutation(mutation, context, options);
|
|
19481
20428
|
context.observers?.onComplete?.(details, outcome);
|
|
19482
20429
|
return { outcome, details };
|
|
19483
20430
|
} catch (error3) {
|
|
19484
|
-
context.observers?.onError?.(
|
|
19485
|
-
{
|
|
19486
|
-
kind: mutation.kind,
|
|
19487
|
-
label: mutation.label ?? mutation.kind,
|
|
19488
|
-
targetPath: void 0
|
|
19489
|
-
},
|
|
19490
|
-
error3
|
|
19491
|
-
);
|
|
20431
|
+
context.observers?.onError?.(pendingDetails, error3);
|
|
19492
20432
|
throw error3;
|
|
19493
20433
|
}
|
|
19494
20434
|
}
|
|
@@ -19499,8 +20439,8 @@ function hasOwnErrorCode6(error3, code) {
|
|
|
19499
20439
|
}
|
|
19500
20440
|
|
|
19501
20441
|
// ../agent-skill-config/src/templates.ts
|
|
19502
|
-
import { readFile as
|
|
19503
|
-
import
|
|
20442
|
+
import { readFile as readFile6, stat } from "node:fs/promises";
|
|
20443
|
+
import path19 from "node:path";
|
|
19504
20444
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19505
20445
|
|
|
19506
20446
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -19517,9 +20457,9 @@ function toHomeRelative(localSkillDir) {
|
|
|
19517
20457
|
const normalized = localSkillDir.startsWith("./") ? localSkillDir.slice(2) : localSkillDir;
|
|
19518
20458
|
return `~/${normalized}`;
|
|
19519
20459
|
}
|
|
19520
|
-
async function pathExists2(
|
|
20460
|
+
async function pathExists2(fs5, targetPath) {
|
|
19521
20461
|
try {
|
|
19522
|
-
await
|
|
20462
|
+
await fs5.stat(targetPath);
|
|
19523
20463
|
return true;
|
|
19524
20464
|
} catch (error3) {
|
|
19525
20465
|
if (hasOwnErrorCode6(error3, "ENOENT")) {
|
|
@@ -19536,7 +20476,7 @@ async function installSkill(agentId, skill, options) {
|
|
|
19536
20476
|
}
|
|
19537
20477
|
const scope = options.scope ?? "local";
|
|
19538
20478
|
const config2 = support.config;
|
|
19539
|
-
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
20479
|
+
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")) {
|
|
19540
20480
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
19541
20481
|
}
|
|
19542
20482
|
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
@@ -19572,29 +20512,29 @@ async function installSkill(agentId, skill, options) {
|
|
|
19572
20512
|
}
|
|
19573
20513
|
}
|
|
19574
20514
|
);
|
|
19575
|
-
return { skillPath:
|
|
20515
|
+
return { skillPath: absoluteSkillPath, displayPath };
|
|
19576
20516
|
}
|
|
19577
20517
|
|
|
19578
20518
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
19579
|
-
import
|
|
19580
|
-
import
|
|
20519
|
+
import * as fs2 from "node:fs";
|
|
20520
|
+
import path20 from "node:path";
|
|
19581
20521
|
|
|
19582
20522
|
// ../agent-skill-config/src/git-exclude.ts
|
|
19583
20523
|
import { execFileSync } from "node:child_process";
|
|
19584
20524
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
19585
|
-
import * as
|
|
19586
|
-
import
|
|
20525
|
+
import * as fs3 from "node:fs";
|
|
20526
|
+
import path21 from "node:path";
|
|
19587
20527
|
|
|
19588
20528
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
19589
|
-
import * as
|
|
20529
|
+
import * as fs4 from "node:fs";
|
|
19590
20530
|
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
19591
|
-
import
|
|
20531
|
+
import path22 from "node:path";
|
|
19592
20532
|
|
|
19593
20533
|
// src/commands/installer.ts
|
|
19594
20534
|
import os3 from "node:os";
|
|
19595
|
-
import
|
|
20535
|
+
import path23 from "node:path";
|
|
19596
20536
|
import * as nodeFs2 from "node:fs/promises";
|
|
19597
|
-
import { readFile as
|
|
20537
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
19598
20538
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
19599
20539
|
var DEFAULT_INSTALL_SCOPE = "local";
|
|
19600
20540
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
@@ -19644,7 +20584,7 @@ async function loadTerminalPilotTemplate() {
|
|
|
19644
20584
|
];
|
|
19645
20585
|
for (const candidate of candidates) {
|
|
19646
20586
|
try {
|
|
19647
|
-
terminalPilotTemplateCache = await
|
|
20587
|
+
terminalPilotTemplateCache = await readFile7(candidate, "utf8");
|
|
19648
20588
|
return terminalPilotTemplateCache;
|
|
19649
20589
|
} catch (error3) {
|
|
19650
20590
|
if (!isNotFoundError2(error3)) {
|
|
@@ -19659,7 +20599,7 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
19659
20599
|
return homeDir;
|
|
19660
20600
|
}
|
|
19661
20601
|
if (targetPath.startsWith("~/")) {
|
|
19662
|
-
return
|
|
20602
|
+
return path23.join(homeDir, targetPath.slice(2));
|
|
19663
20603
|
}
|
|
19664
20604
|
return targetPath;
|
|
19665
20605
|
}
|
|
@@ -19669,22 +20609,22 @@ function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
|
19669
20609
|
throwUnsupportedAgent(agent);
|
|
19670
20610
|
}
|
|
19671
20611
|
return {
|
|
19672
|
-
displayPath:
|
|
20612
|
+
displayPath: path23.join(
|
|
19673
20613
|
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
19674
20614
|
TERMINAL_PILOT_SKILL_NAME
|
|
19675
20615
|
),
|
|
19676
|
-
fullPath:
|
|
19677
|
-
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) :
|
|
20616
|
+
fullPath: path23.join(
|
|
20617
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path23.resolve(cwd, config2.localSkillDir),
|
|
19678
20618
|
TERMINAL_PILOT_SKILL_NAME
|
|
19679
20619
|
)
|
|
19680
20620
|
};
|
|
19681
20621
|
}
|
|
19682
|
-
async function assertNoSymbolicLinkPath(
|
|
19683
|
-
const rootPath =
|
|
20622
|
+
async function assertNoSymbolicLinkPath(fs5, targetPath) {
|
|
20623
|
+
const rootPath = path23.parse(targetPath).root;
|
|
19684
20624
|
let currentPath = targetPath;
|
|
19685
20625
|
while (currentPath !== rootPath) {
|
|
19686
20626
|
try {
|
|
19687
|
-
if ((await
|
|
20627
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
19688
20628
|
throw new UserError(`Refusing terminal-pilot skill operation through symbolic link: ${currentPath}`);
|
|
19689
20629
|
}
|
|
19690
20630
|
} catch (error3) {
|
|
@@ -19692,7 +20632,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
19692
20632
|
throw error3;
|
|
19693
20633
|
}
|
|
19694
20634
|
}
|
|
19695
|
-
currentPath =
|
|
20635
|
+
currentPath = path23.dirname(currentPath);
|
|
19696
20636
|
}
|
|
19697
20637
|
}
|
|
19698
20638
|
|
|
@@ -20391,11 +21331,11 @@ import { Resvg } from "@resvg/resvg-js";
|
|
|
20391
21331
|
|
|
20392
21332
|
// ../terminal-png/src/font.ts
|
|
20393
21333
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
20394
|
-
import { createRequire as
|
|
21334
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
20395
21335
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
20396
21336
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
20397
|
-
var
|
|
20398
|
-
var fontPackageRoot = dirname2(
|
|
21337
|
+
var require3 = createRequire3(import.meta.url);
|
|
21338
|
+
var fontPackageRoot = dirname2(require3.resolve("jetbrains-mono/package.json"));
|
|
20399
21339
|
var webfontRoot = join2(fontPackageRoot, "fonts/webfonts");
|
|
20400
21340
|
function readWebfontBase64(filename) {
|
|
20401
21341
|
return readFileSync4(join2(webfontRoot, filename)).toString("base64");
|
|
@@ -21105,9 +22045,9 @@ var uninstall = defineCommand({
|
|
|
21105
22045
|
};
|
|
21106
22046
|
}
|
|
21107
22047
|
});
|
|
21108
|
-
async function folderExists(
|
|
22048
|
+
async function folderExists(fs5, folderPath) {
|
|
21109
22049
|
try {
|
|
21110
|
-
await
|
|
22050
|
+
await fs5.stat(folderPath);
|
|
21111
22051
|
return true;
|
|
21112
22052
|
} catch (error3) {
|
|
21113
22053
|
if (hasOwnErrorCode4(error3, "ENOENT")) {
|
|
@@ -21252,7 +22192,7 @@ async function isDirectExecution(argv) {
|
|
|
21252
22192
|
try {
|
|
21253
22193
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
21254
22194
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
21255
|
-
realpath3(
|
|
22195
|
+
realpath3(path24.resolve(entryPoint)),
|
|
21256
22196
|
realpath3(modulePath)
|
|
21257
22197
|
]);
|
|
21258
22198
|
return resolvedEntryPoint === resolvedModulePath;
|
|
@@ -21364,13 +22304,13 @@ function createTerminalPilotCliRepl() {
|
|
|
21364
22304
|
}
|
|
21365
22305
|
|
|
21366
22306
|
// src/testing/qa-cli.ts
|
|
21367
|
-
var testingDirectory =
|
|
21368
|
-
var repoRoot =
|
|
21369
|
-
var tsxPath =
|
|
21370
|
-
var testCliPath =
|
|
21371
|
-
var menuCliPath =
|
|
21372
|
-
var vimSavedFile =
|
|
21373
|
-
var vimDiscardFile =
|
|
22307
|
+
var testingDirectory = path25.dirname(fileURLToPath6(import.meta.url));
|
|
22308
|
+
var repoRoot = path25.resolve(testingDirectory, "../../../..");
|
|
22309
|
+
var tsxPath = path25.join(repoRoot, "node_modules", ".bin", "tsx");
|
|
22310
|
+
var testCliPath = path25.join(repoRoot, "packages/terminal-pilot/src/testing/test-cli.js");
|
|
22311
|
+
var menuCliPath = path25.join(repoRoot, "packages/terminal-pilot/src/testing/menu-cli.js");
|
|
22312
|
+
var vimSavedFile = path25.join(os4.tmpdir(), "terminal-pilot-qa-test.txt");
|
|
22313
|
+
var vimDiscardFile = path25.join(os4.tmpdir(), "terminal-pilot-qa-discard.txt");
|
|
21374
22314
|
var QaContext = class {
|
|
21375
22315
|
repl = createTerminalPilotCliRepl();
|
|
21376
22316
|
async close() {
|
|
@@ -22116,7 +23056,7 @@ var cases = [
|
|
|
22116
23056
|
"VIM",
|
|
22117
23057
|
"-t",
|
|
22118
23058
|
"5000",
|
|
22119
|
-
|
|
23059
|
+
path25.basename(vimSavedFile)
|
|
22120
23060
|
]);
|
|
22121
23061
|
await ctx.expectOk(["press-key", "-s", "VIM", "i"]);
|
|
22122
23062
|
await ctx.expectOk(["type", "-s", "VIM", "hello from terminal-pilot"]);
|
|
@@ -22171,7 +23111,7 @@ var cases = [
|
|
|
22171
23111
|
"VIM2",
|
|
22172
23112
|
"-t",
|
|
22173
23113
|
"5000",
|
|
22174
|
-
|
|
23114
|
+
path25.basename(vimDiscardFile)
|
|
22175
23115
|
]);
|
|
22176
23116
|
await ctx.expectOk(["press-key", "-s", "VIM2", "i"]);
|
|
22177
23117
|
await ctx.expectOk(["type", "-s", "VIM2", "this should not be saved"]);
|