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/cli.js
CHANGED
|
@@ -7,12 +7,12 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
10
|
-
import
|
|
10
|
+
import path24 from "node:path";
|
|
11
11
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
12
12
|
|
|
13
13
|
// ../toolcraft/src/cli.ts
|
|
14
|
-
import { access as access2, lstat as lstat3, readFile as
|
|
15
|
-
import
|
|
14
|
+
import { access as access2, lstat as lstat3, readFile as readFile5, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
15
|
+
import path15 from "node:path";
|
|
16
16
|
import {
|
|
17
17
|
Command as CommanderCommand,
|
|
18
18
|
CommanderError as CommanderError2,
|
|
@@ -378,7 +378,8 @@ function renderMarkdownCode(content) {
|
|
|
378
378
|
currentRun = 0;
|
|
379
379
|
}
|
|
380
380
|
const delimiter = "`".repeat(longestRun + 1);
|
|
381
|
-
|
|
381
|
+
const paddedValue = value.startsWith("`") || value.endsWith("`") ? ` ${value} ` : value;
|
|
382
|
+
return `${delimiter}${paddedValue}${delimiter}`;
|
|
382
383
|
}
|
|
383
384
|
function renderMarkdownLink(content) {
|
|
384
385
|
const value = renderMarkdownInline(content);
|
|
@@ -533,7 +534,54 @@ var symbols = {
|
|
|
533
534
|
|
|
534
535
|
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
535
536
|
function stripAnsi(value) {
|
|
536
|
-
|
|
537
|
+
let output = "";
|
|
538
|
+
let index = 0;
|
|
539
|
+
while (index < value.length) {
|
|
540
|
+
const char = value[index];
|
|
541
|
+
if (char === "\x1B") {
|
|
542
|
+
index = skipEscapeSequence(value, index);
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
if (char === "\x9B") {
|
|
546
|
+
index = skipCsiSequence(value, index + 1);
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
output += char;
|
|
550
|
+
index += char.length;
|
|
551
|
+
}
|
|
552
|
+
return output;
|
|
553
|
+
}
|
|
554
|
+
function skipEscapeSequence(value, index) {
|
|
555
|
+
const next = value[index + 1];
|
|
556
|
+
if (next === "[") {
|
|
557
|
+
return skipCsiSequence(value, index + 2);
|
|
558
|
+
}
|
|
559
|
+
if (next === "]") {
|
|
560
|
+
return skipOscSequence(value, index + 2);
|
|
561
|
+
}
|
|
562
|
+
return Math.min(value.length, index + 2);
|
|
563
|
+
}
|
|
564
|
+
function skipCsiSequence(value, index) {
|
|
565
|
+
while (index < value.length) {
|
|
566
|
+
const codePoint = value.charCodeAt(index);
|
|
567
|
+
index += 1;
|
|
568
|
+
if (codePoint >= 64 && codePoint <= 126) {
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return index;
|
|
573
|
+
}
|
|
574
|
+
function skipOscSequence(value, index) {
|
|
575
|
+
while (index < value.length) {
|
|
576
|
+
if (value[index] === "\x07") {
|
|
577
|
+
return index + 1;
|
|
578
|
+
}
|
|
579
|
+
if (value[index] === "\x1B" && value[index + 1] === "\\") {
|
|
580
|
+
return index + 2;
|
|
581
|
+
}
|
|
582
|
+
index += 1;
|
|
583
|
+
}
|
|
584
|
+
return index;
|
|
537
585
|
}
|
|
538
586
|
|
|
539
587
|
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
@@ -1322,38 +1370,14 @@ function renderTable(options) {
|
|
|
1322
1370
|
}
|
|
1323
1371
|
|
|
1324
1372
|
// ../toolcraft-design/src/components/detail-card.ts
|
|
1373
|
+
import stringWidth from "fast-string-width";
|
|
1374
|
+
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1325
1375
|
function wrap(value, width) {
|
|
1326
|
-
|
|
1327
|
-
for (const paragraph of value.split("\n")) {
|
|
1328
|
-
let line = "";
|
|
1329
|
-
for (const rawWord of paragraph.split(" ")) {
|
|
1330
|
-
const words = [];
|
|
1331
|
-
let word = rawWord;
|
|
1332
|
-
while (word.length > width) {
|
|
1333
|
-
words.push(word.slice(0, width));
|
|
1334
|
-
word = word.slice(width);
|
|
1335
|
-
}
|
|
1336
|
-
words.push(word);
|
|
1337
|
-
for (const word2 of words) {
|
|
1338
|
-
if (line.length === 0) {
|
|
1339
|
-
line = word2;
|
|
1340
|
-
continue;
|
|
1341
|
-
}
|
|
1342
|
-
if (`${line} ${word2}`.length <= width) {
|
|
1343
|
-
line = `${line} ${word2}`;
|
|
1344
|
-
continue;
|
|
1345
|
-
}
|
|
1346
|
-
lines.push(line);
|
|
1347
|
-
line = word2;
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
lines.push(line);
|
|
1351
|
-
}
|
|
1352
|
-
return lines;
|
|
1376
|
+
return wrapAnsi(value, Math.max(1, width), { hard: true, trim: true }).split("\n");
|
|
1353
1377
|
}
|
|
1354
1378
|
function renderRows(rows, theme, width) {
|
|
1355
1379
|
if (rows.length === 0) return [];
|
|
1356
|
-
const labelWidth = Math.max(...rows.map((row) => row.label
|
|
1380
|
+
const labelWidth = Math.max(...rows.map((row) => stringWidth(row.label)));
|
|
1357
1381
|
const valueWidth = Math.max(20, width - labelWidth - 2);
|
|
1358
1382
|
const continuation = " ".repeat(labelWidth + 2);
|
|
1359
1383
|
return rows.flatMap((row) => {
|
|
@@ -1374,12 +1398,16 @@ function renderDetailCard(options) {
|
|
|
1374
1398
|
${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).toLowerCase()).join(" \xB7 "))}` : identity;
|
|
1375
1399
|
const blocks = [hero];
|
|
1376
1400
|
for (const prose of options.prose ?? []) {
|
|
1377
|
-
blocks.push(
|
|
1401
|
+
blocks.push(
|
|
1402
|
+
prose.title ? [options.theme.header(prose.title), wrap(prose.value, width).join("\n")].join("\n") : wrap(prose.value, width).join("\n")
|
|
1403
|
+
);
|
|
1378
1404
|
}
|
|
1379
1405
|
for (const section of options.sections ?? []) {
|
|
1380
1406
|
if (section.rows.length === 0) continue;
|
|
1381
1407
|
const rows = renderRows(section.rows, options.theme, width);
|
|
1382
|
-
blocks.push(
|
|
1408
|
+
blocks.push(
|
|
1409
|
+
section.title ? [options.theme.header(section.title), ...rows].join("\n") : rows.join("\n")
|
|
1410
|
+
);
|
|
1383
1411
|
}
|
|
1384
1412
|
return blocks.join("\n\n");
|
|
1385
1413
|
}
|
|
@@ -1806,13 +1834,13 @@ import { LineCounter, parse, parseDocument } from "yaml";
|
|
|
1806
1834
|
// ../frontmatter/src/stringify.ts
|
|
1807
1835
|
import { stringify } from "yaml";
|
|
1808
1836
|
|
|
1837
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1838
|
+
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1839
|
+
|
|
1809
1840
|
// ../toolcraft-design/src/acp/writer.ts
|
|
1810
1841
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1811
1842
|
var storage = new AsyncLocalStorage2();
|
|
1812
1843
|
|
|
1813
|
-
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1814
|
-
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1815
|
-
|
|
1816
1844
|
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1817
1845
|
import readline from "node:readline";
|
|
1818
1846
|
import { PassThrough } from "node:stream";
|
|
@@ -1909,8 +1937,8 @@ function mapKey(name, char) {
|
|
|
1909
1937
|
}
|
|
1910
1938
|
|
|
1911
1939
|
// ../toolcraft-design/src/prompts/interactive/wrap.ts
|
|
1912
|
-
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1913
|
-
import
|
|
1940
|
+
import { wrapAnsi as wrapAnsi2 } from "fast-wrap-ansi";
|
|
1941
|
+
import stringWidth2 from "fast-string-width";
|
|
1914
1942
|
function getColumns(output) {
|
|
1915
1943
|
return Math.max(1, output.columns ?? 80);
|
|
1916
1944
|
}
|
|
@@ -1918,7 +1946,7 @@ function getRows(output) {
|
|
|
1918
1946
|
return Math.max(1, output.rows ?? 20);
|
|
1919
1947
|
}
|
|
1920
1948
|
function wrapFrame(output, frame) {
|
|
1921
|
-
return
|
|
1949
|
+
return wrapAnsi2(frame, getColumns(output), { hard: true, trim: false });
|
|
1922
1950
|
}
|
|
1923
1951
|
|
|
1924
1952
|
// ../toolcraft-design/src/prompts/interactive/core.ts
|
|
@@ -2239,7 +2267,7 @@ function confirmPrompt(opts) {
|
|
|
2239
2267
|
}
|
|
2240
2268
|
|
|
2241
2269
|
// ../toolcraft-design/src/prompts/interactive/pagination.ts
|
|
2242
|
-
import { wrapAnsi as
|
|
2270
|
+
import { wrapAnsi as wrapAnsi3 } from "fast-wrap-ansi";
|
|
2243
2271
|
function countLines(values) {
|
|
2244
2272
|
return values.reduce((sum, value) => sum + value.split("\n").length, 0);
|
|
2245
2273
|
}
|
|
@@ -2282,7 +2310,7 @@ function limitOptions(opts) {
|
|
|
2282
2310
|
}
|
|
2283
2311
|
const hasTopMarker = cappedVisibleCount < options.length && start > 0;
|
|
2284
2312
|
const hasBottomMarker = cappedVisibleCount < options.length && start + cappedVisibleCount < options.length;
|
|
2285
|
-
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) =>
|
|
2313
|
+
const visible = options.slice(start, start + cappedVisibleCount).map((option, index) => wrapAnsi3(style(option, start + index === cursor2), columns, { hard: true, trim: false }));
|
|
2286
2314
|
const trimmed = trimToRows(
|
|
2287
2315
|
visible,
|
|
2288
2316
|
Math.max(cursor2 - start, 0),
|
|
@@ -2665,6 +2693,9 @@ function isOptionalSchema(schema) {
|
|
|
2665
2693
|
function getRequiredKeys(schema) {
|
|
2666
2694
|
return Object.keys(schema.shape).filter((key2) => !isOptionalSchema(schema.shape[key2])).sort();
|
|
2667
2695
|
}
|
|
2696
|
+
function getRequiredKeyFingerprint(schema) {
|
|
2697
|
+
return getRequiredKeys(schema).join("+");
|
|
2698
|
+
}
|
|
2668
2699
|
function assertUniqueRequiredKeyFingerprints(branches) {
|
|
2669
2700
|
const fingerprints = /* @__PURE__ */ new Map();
|
|
2670
2701
|
branches.forEach((branch, index) => {
|
|
@@ -2702,6 +2733,451 @@ function Union(branches) {
|
|
|
2702
2733
|
};
|
|
2703
2734
|
}
|
|
2704
2735
|
|
|
2736
|
+
// ../toolcraft-schema/src/validate.ts
|
|
2737
|
+
var missingValue = /* @__PURE__ */ Symbol("missingValue");
|
|
2738
|
+
function validate(schema, value) {
|
|
2739
|
+
const state = { issues: [] };
|
|
2740
|
+
const result = walkSchema(schema, value, [], state);
|
|
2741
|
+
if (state.issues.length > 0) {
|
|
2742
|
+
return { ok: false, issues: state.issues };
|
|
2743
|
+
}
|
|
2744
|
+
return { ok: true, value: result.present ? result.value : void 0 };
|
|
2745
|
+
}
|
|
2746
|
+
function walkSchema(schema, value, path25, state) {
|
|
2747
|
+
if (schema.kind === "optional") {
|
|
2748
|
+
return walkOptional(schema, value, path25, state);
|
|
2749
|
+
}
|
|
2750
|
+
if (value === missingValue) {
|
|
2751
|
+
addIssue(
|
|
2752
|
+
state,
|
|
2753
|
+
path25,
|
|
2754
|
+
expectedFor(schema),
|
|
2755
|
+
"missing",
|
|
2756
|
+
`Expected ${expectedFor(schema)} at ${formatPath(path25)}`
|
|
2757
|
+
);
|
|
2758
|
+
return { present: false };
|
|
2759
|
+
}
|
|
2760
|
+
if (value === null && schema.nullable === true) {
|
|
2761
|
+
return { present: true, value };
|
|
2762
|
+
}
|
|
2763
|
+
switch (schema.kind) {
|
|
2764
|
+
case "string":
|
|
2765
|
+
return walkString(schema, value, path25, state);
|
|
2766
|
+
case "number":
|
|
2767
|
+
return walkNumber(schema, value, path25, state);
|
|
2768
|
+
case "boolean":
|
|
2769
|
+
return walkBoolean(value, path25, state);
|
|
2770
|
+
case "enum":
|
|
2771
|
+
return walkEnum(schema, value, path25, state);
|
|
2772
|
+
case "array":
|
|
2773
|
+
return walkArray(schema, value, path25, state);
|
|
2774
|
+
case "object":
|
|
2775
|
+
return walkObject(schema, value, path25, state);
|
|
2776
|
+
case "oneOf":
|
|
2777
|
+
return walkOneOf(schema, value, path25, state);
|
|
2778
|
+
case "union":
|
|
2779
|
+
return walkUnion(schema, value, path25, state);
|
|
2780
|
+
case "record":
|
|
2781
|
+
return walkRecord(schema, value, path25, state);
|
|
2782
|
+
case "json":
|
|
2783
|
+
return walkJson(value, path25, state);
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
function walkOptional(schema, value, path25, state) {
|
|
2787
|
+
if (value === missingValue || value === void 0) {
|
|
2788
|
+
const defaultValue = getDefault(schema.inner);
|
|
2789
|
+
if (defaultValue.present) {
|
|
2790
|
+
return walkSchema(schema.inner, cloneDefault(defaultValue.value), path25, state);
|
|
2791
|
+
}
|
|
2792
|
+
return { present: false };
|
|
2793
|
+
}
|
|
2794
|
+
return walkSchema(schema.inner, value, path25, state);
|
|
2795
|
+
}
|
|
2796
|
+
function walkString(schema, value, path25, state) {
|
|
2797
|
+
if (typeof value !== "string") {
|
|
2798
|
+
addExpectedIssue(state, path25, "string", value);
|
|
2799
|
+
return { present: true, value };
|
|
2800
|
+
}
|
|
2801
|
+
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
2802
|
+
const expected = `string with length at least ${schema.minLength}`;
|
|
2803
|
+
addIssue(
|
|
2804
|
+
state,
|
|
2805
|
+
path25,
|
|
2806
|
+
expected,
|
|
2807
|
+
`string with length ${value.length}`,
|
|
2808
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2809
|
+
);
|
|
2810
|
+
}
|
|
2811
|
+
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
2812
|
+
const expected = `string with length at most ${schema.maxLength}`;
|
|
2813
|
+
addIssue(
|
|
2814
|
+
state,
|
|
2815
|
+
path25,
|
|
2816
|
+
expected,
|
|
2817
|
+
`string with length ${value.length}`,
|
|
2818
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2819
|
+
);
|
|
2820
|
+
}
|
|
2821
|
+
if (schema.pattern !== void 0) {
|
|
2822
|
+
const pattern = compilePattern(schema.pattern);
|
|
2823
|
+
if (pattern === void 0 || !pattern.test(value)) {
|
|
2824
|
+
const expected = `string matching pattern ${schema.pattern}`;
|
|
2825
|
+
addIssue(state, path25, expected, value, `Expected ${expected} at ${formatPath(path25)}`);
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
return { present: true, value };
|
|
2829
|
+
}
|
|
2830
|
+
function walkNumber(schema, value, path25, state) {
|
|
2831
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
2832
|
+
addExpectedIssue(state, path25, schema.jsonType === "integer" ? "integer" : "number", value);
|
|
2833
|
+
return { present: true, value };
|
|
2834
|
+
}
|
|
2835
|
+
if (schema.jsonType === "integer" && !Number.isInteger(value)) {
|
|
2836
|
+
addExpectedIssue(state, path25, "integer", value);
|
|
2837
|
+
}
|
|
2838
|
+
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
2839
|
+
const expected = `number greater than or equal to ${schema.minimum}`;
|
|
2840
|
+
addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
|
|
2841
|
+
}
|
|
2842
|
+
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
2843
|
+
const expected = `number less than or equal to ${schema.maximum}`;
|
|
2844
|
+
addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
|
|
2845
|
+
}
|
|
2846
|
+
return { present: true, value };
|
|
2847
|
+
}
|
|
2848
|
+
function walkBoolean(value, path25, state) {
|
|
2849
|
+
if (typeof value !== "boolean") {
|
|
2850
|
+
addExpectedIssue(state, path25, "boolean", value);
|
|
2851
|
+
}
|
|
2852
|
+
return { present: true, value };
|
|
2853
|
+
}
|
|
2854
|
+
function walkEnum(schema, value, path25, state) {
|
|
2855
|
+
if (!schema.values.includes(value)) {
|
|
2856
|
+
const expected = `one of ${schema.values.join(", ")}`;
|
|
2857
|
+
addIssue(
|
|
2858
|
+
state,
|
|
2859
|
+
path25,
|
|
2860
|
+
expected,
|
|
2861
|
+
receivedValue(value),
|
|
2862
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
return { present: true, value };
|
|
2866
|
+
}
|
|
2867
|
+
function walkArray(schema, value, path25, state) {
|
|
2868
|
+
if (!Array.isArray(value)) {
|
|
2869
|
+
addExpectedIssue(state, path25, "array", value);
|
|
2870
|
+
return { present: true, value };
|
|
2871
|
+
}
|
|
2872
|
+
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
2873
|
+
const expected = `array with at least ${schema.minItems} items`;
|
|
2874
|
+
addIssue(
|
|
2875
|
+
state,
|
|
2876
|
+
path25,
|
|
2877
|
+
expected,
|
|
2878
|
+
`array with ${value.length} items`,
|
|
2879
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2880
|
+
);
|
|
2881
|
+
}
|
|
2882
|
+
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
2883
|
+
const expected = `array with at most ${schema.maxItems} items`;
|
|
2884
|
+
addIssue(
|
|
2885
|
+
state,
|
|
2886
|
+
path25,
|
|
2887
|
+
expected,
|
|
2888
|
+
`array with ${value.length} items`,
|
|
2889
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
2890
|
+
);
|
|
2891
|
+
}
|
|
2892
|
+
const nextValue = value.map((item, index) => {
|
|
2893
|
+
const result = walkSchema(schema.item, item, [...path25, String(index)], state);
|
|
2894
|
+
return result.present ? result.value : item;
|
|
2895
|
+
});
|
|
2896
|
+
return { present: true, value: nextValue };
|
|
2897
|
+
}
|
|
2898
|
+
function walkObject(schema, value, path25, state, injectedProperties = {}) {
|
|
2899
|
+
if (!isPlainRecord(value)) {
|
|
2900
|
+
addExpectedIssue(state, path25, "object", value);
|
|
2901
|
+
return { present: true, value };
|
|
2902
|
+
}
|
|
2903
|
+
const nextValue = {};
|
|
2904
|
+
const allowedKeys = /* @__PURE__ */ new Set([...Object.keys(schema.shape), ...Object.keys(injectedProperties)]);
|
|
2905
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
2906
|
+
const propertyValue = Object.hasOwn(value, key2) ? value[key2] : missingValue;
|
|
2907
|
+
const result = walkSchema(propertySchema, propertyValue, [...path25, key2], state);
|
|
2908
|
+
if (result.present) {
|
|
2909
|
+
setOwnValue(nextValue, key2, result.value);
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
for (const [key2, injectedValue] of Object.entries(injectedProperties)) {
|
|
2913
|
+
if (Object.hasOwn(value, key2)) {
|
|
2914
|
+
setOwnValue(nextValue, key2, value[key2]);
|
|
2915
|
+
} else {
|
|
2916
|
+
setOwnValue(nextValue, key2, injectedValue);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
2920
|
+
if (allowedKeys.has(key2)) {
|
|
2921
|
+
continue;
|
|
2922
|
+
}
|
|
2923
|
+
if (schema.additionalProperties === true) {
|
|
2924
|
+
setOwnValue(nextValue, key2, propertyValue);
|
|
2925
|
+
} else {
|
|
2926
|
+
addUnexpectedPropertyIssue(state, [...path25, key2]);
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
return { present: true, value: nextValue };
|
|
2930
|
+
}
|
|
2931
|
+
function walkOneOf(schema, value, path25, state) {
|
|
2932
|
+
if (!isPlainRecord(value)) {
|
|
2933
|
+
addExpectedIssue(state, path25, "object", value);
|
|
2934
|
+
return { present: true, value };
|
|
2935
|
+
}
|
|
2936
|
+
const discriminatorValue = value[schema.discriminator];
|
|
2937
|
+
const discriminatorPath = [...path25, schema.discriminator];
|
|
2938
|
+
const branchValues = Object.keys(schema.branches);
|
|
2939
|
+
const expected = `one of ${branchValues.join(", ")}`;
|
|
2940
|
+
if (!Object.hasOwn(value, schema.discriminator)) {
|
|
2941
|
+
addIssueWithMessage(
|
|
2942
|
+
state,
|
|
2943
|
+
discriminatorPath,
|
|
2944
|
+
expected,
|
|
2945
|
+
"missing",
|
|
2946
|
+
`Missing discriminator "${schema.discriminator}" at ${formatPath(path25)}. Expected one of: ${branchValues.join(", ")}.`
|
|
2947
|
+
);
|
|
2948
|
+
return { present: true, value };
|
|
2949
|
+
}
|
|
2950
|
+
if (typeof discriminatorValue !== "string" || !Object.hasOwn(schema.branches, discriminatorValue)) {
|
|
2951
|
+
addIssueWithMessage(
|
|
2952
|
+
state,
|
|
2953
|
+
discriminatorPath,
|
|
2954
|
+
expected,
|
|
2955
|
+
receivedValue(discriminatorValue),
|
|
2956
|
+
`Expected ${expected} at ${formatPath(discriminatorPath)}, got ${formatReceivedDiscriminator(discriminatorValue)}`
|
|
2957
|
+
);
|
|
2958
|
+
return { present: true, value };
|
|
2959
|
+
}
|
|
2960
|
+
return walkObject(schema.branches[discriminatorValue], value, path25, state, {
|
|
2961
|
+
[schema.discriminator]: discriminatorValue
|
|
2962
|
+
});
|
|
2963
|
+
}
|
|
2964
|
+
function walkUnion(schema, value, path25, state) {
|
|
2965
|
+
if (isPlainRecord(value)) {
|
|
2966
|
+
const candidateBranches = schema.branches.filter((branch) => hasRequiredKeys(branch, value));
|
|
2967
|
+
if (candidateBranches.length === 1) {
|
|
2968
|
+
return walkObject(candidateBranches[0], value, path25, state);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
const matches = [];
|
|
2972
|
+
for (const branch of schema.branches) {
|
|
2973
|
+
const branchState = { issues: [] };
|
|
2974
|
+
const result = walkObject(branch, value, path25, branchState);
|
|
2975
|
+
if (branchState.issues.length === 0 && result.present) {
|
|
2976
|
+
matches.push({ fingerprint: getRequiredKeyFingerprint(branch), value: result.value });
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
if (matches.length === 1) {
|
|
2980
|
+
return { present: true, value: matches[0].value };
|
|
2981
|
+
}
|
|
2982
|
+
if (matches.length === 0) {
|
|
2983
|
+
const branchDescriptions = schema.branches.map((branch) => getRequiredKeyFingerprint(branch));
|
|
2984
|
+
addIssueWithMessage(
|
|
2985
|
+
state,
|
|
2986
|
+
path25,
|
|
2987
|
+
"exactly one union branch",
|
|
2988
|
+
"0 matching branches",
|
|
2989
|
+
`No union branch matched at ${formatPath(path25)}. Tried ${schema.branches.length} branches. Expected one of: ${branchDescriptions.join(" | ")}.`
|
|
2990
|
+
);
|
|
2991
|
+
return { present: true, value };
|
|
2992
|
+
}
|
|
2993
|
+
addIssueWithMessage(
|
|
2994
|
+
state,
|
|
2995
|
+
path25,
|
|
2996
|
+
"exactly one union branch",
|
|
2997
|
+
`${matches.length} matching branches`,
|
|
2998
|
+
`Expected exactly one union branch at ${formatPath(path25)}, but matched more than one branch: ${matches.map((match) => match.fingerprint).join(" | ")}`
|
|
2999
|
+
);
|
|
3000
|
+
return { present: true, value };
|
|
3001
|
+
}
|
|
3002
|
+
function hasRequiredKeys(schema, value) {
|
|
3003
|
+
for (const [key2, propertySchema] of Object.entries(schema.shape)) {
|
|
3004
|
+
if (propertySchema.kind !== "optional" && !Object.hasOwn(value, key2)) {
|
|
3005
|
+
return false;
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
return true;
|
|
3009
|
+
}
|
|
3010
|
+
function walkRecord(schema, value, path25, state) {
|
|
3011
|
+
if (!isPlainRecord(value)) {
|
|
3012
|
+
addExpectedIssue(state, path25, "object", value);
|
|
3013
|
+
return { present: true, value };
|
|
3014
|
+
}
|
|
3015
|
+
const nextValue = {};
|
|
3016
|
+
for (const [key2, propertyValue] of Object.entries(value)) {
|
|
3017
|
+
const result = walkSchema(schema.value, propertyValue, [...path25, key2], state);
|
|
3018
|
+
if (result.present) {
|
|
3019
|
+
setOwnValue(nextValue, key2, result.value);
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
return { present: true, value: nextValue };
|
|
3023
|
+
}
|
|
3024
|
+
function walkJson(value, path25, state) {
|
|
3025
|
+
if (isJsonValue(value)) {
|
|
3026
|
+
return { present: true, value };
|
|
3027
|
+
}
|
|
3028
|
+
addExpectedIssue(state, path25, "JSON value", value);
|
|
3029
|
+
return { present: true, value };
|
|
3030
|
+
}
|
|
3031
|
+
function getDefault(schema) {
|
|
3032
|
+
if (schema.default !== void 0) {
|
|
3033
|
+
return { present: true, value: schema.default };
|
|
3034
|
+
}
|
|
3035
|
+
if (schema.kind === "optional") {
|
|
3036
|
+
return getDefault(schema.inner);
|
|
3037
|
+
}
|
|
3038
|
+
return { present: false };
|
|
3039
|
+
}
|
|
3040
|
+
function isPlainRecord(value) {
|
|
3041
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3042
|
+
return false;
|
|
3043
|
+
}
|
|
3044
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3045
|
+
return prototype === Object.prototype || prototype === null;
|
|
3046
|
+
}
|
|
3047
|
+
function isJsonValue(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3048
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3049
|
+
return typeof value !== "number" || Number.isFinite(value);
|
|
3050
|
+
}
|
|
3051
|
+
if (Array.isArray(value)) {
|
|
3052
|
+
if (ancestors.has(value)) {
|
|
3053
|
+
return false;
|
|
3054
|
+
}
|
|
3055
|
+
ancestors.add(value);
|
|
3056
|
+
const result = value.every((item) => isJsonValue(item, ancestors));
|
|
3057
|
+
ancestors.delete(value);
|
|
3058
|
+
return result;
|
|
3059
|
+
}
|
|
3060
|
+
if (isPlainRecord(value)) {
|
|
3061
|
+
if (ancestors.has(value)) {
|
|
3062
|
+
return false;
|
|
3063
|
+
}
|
|
3064
|
+
ancestors.add(value);
|
|
3065
|
+
const result = Object.values(value).every((item) => isJsonValue(item, ancestors));
|
|
3066
|
+
ancestors.delete(value);
|
|
3067
|
+
return result;
|
|
3068
|
+
}
|
|
3069
|
+
return false;
|
|
3070
|
+
}
|
|
3071
|
+
function cloneDefault(value) {
|
|
3072
|
+
return structuredClone(value);
|
|
3073
|
+
}
|
|
3074
|
+
function setOwnValue(target, key2, value) {
|
|
3075
|
+
Object.defineProperty(target, key2, {
|
|
3076
|
+
configurable: true,
|
|
3077
|
+
enumerable: true,
|
|
3078
|
+
writable: true,
|
|
3079
|
+
value
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
function expectedFor(schema) {
|
|
3083
|
+
switch (schema.kind) {
|
|
3084
|
+
case "string":
|
|
3085
|
+
return "string";
|
|
3086
|
+
case "number":
|
|
3087
|
+
return schema.jsonType === "integer" ? "integer" : "number";
|
|
3088
|
+
case "boolean":
|
|
3089
|
+
return "boolean";
|
|
3090
|
+
case "enum":
|
|
3091
|
+
return `one of ${schema.values.join(", ")}`;
|
|
3092
|
+
case "array":
|
|
3093
|
+
return "array";
|
|
3094
|
+
case "object":
|
|
3095
|
+
case "oneOf":
|
|
3096
|
+
case "record":
|
|
3097
|
+
return "object";
|
|
3098
|
+
case "union":
|
|
3099
|
+
return "exactly one union branch";
|
|
3100
|
+
case "json":
|
|
3101
|
+
return "JSON value";
|
|
3102
|
+
case "optional":
|
|
3103
|
+
return expectedFor(schema.inner);
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
function addExpectedIssue(state, path25, expected, value) {
|
|
3107
|
+
addIssue(
|
|
3108
|
+
state,
|
|
3109
|
+
path25,
|
|
3110
|
+
expected,
|
|
3111
|
+
receivedType(value),
|
|
3112
|
+
`Expected ${expected} at ${formatPath(path25)}`
|
|
3113
|
+
);
|
|
3114
|
+
}
|
|
3115
|
+
function addUnexpectedPropertyIssue(state, path25) {
|
|
3116
|
+
addIssue(
|
|
3117
|
+
state,
|
|
3118
|
+
path25,
|
|
3119
|
+
"no additional properties",
|
|
3120
|
+
"unknown property",
|
|
3121
|
+
`Unexpected property ${formatPath(path25)}`
|
|
3122
|
+
);
|
|
3123
|
+
}
|
|
3124
|
+
function addIssue(state, path25, expected, received, _message) {
|
|
3125
|
+
state.issues.push({
|
|
3126
|
+
path: path25,
|
|
3127
|
+
expected,
|
|
3128
|
+
received,
|
|
3129
|
+
message: formatIssueMessage(expected, path25, received)
|
|
3130
|
+
});
|
|
3131
|
+
}
|
|
3132
|
+
function addIssueWithMessage(state, path25, expected, received, message2) {
|
|
3133
|
+
state.issues.push({
|
|
3134
|
+
path: path25,
|
|
3135
|
+
expected,
|
|
3136
|
+
received,
|
|
3137
|
+
message: message2
|
|
3138
|
+
});
|
|
3139
|
+
}
|
|
3140
|
+
function formatIssueMessage(expected, path25, received) {
|
|
3141
|
+
return `Expected ${expected} at ${formatPath(path25)}, got ${received}`;
|
|
3142
|
+
}
|
|
3143
|
+
function formatPath(path25) {
|
|
3144
|
+
return path25.length === 0 ? "value" : path25.join(".");
|
|
3145
|
+
}
|
|
3146
|
+
function compilePattern(pattern) {
|
|
3147
|
+
try {
|
|
3148
|
+
return new RegExp(pattern);
|
|
3149
|
+
} catch {
|
|
3150
|
+
return void 0;
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
function receivedType(value) {
|
|
3154
|
+
if (value === null) {
|
|
3155
|
+
return "null";
|
|
3156
|
+
}
|
|
3157
|
+
if (Array.isArray(value)) {
|
|
3158
|
+
return "array";
|
|
3159
|
+
}
|
|
3160
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
3161
|
+
return "integer";
|
|
3162
|
+
}
|
|
3163
|
+
return typeof value;
|
|
3164
|
+
}
|
|
3165
|
+
function receivedValue(value) {
|
|
3166
|
+
if (typeof value === "string") {
|
|
3167
|
+
return value;
|
|
3168
|
+
}
|
|
3169
|
+
if (value === void 0) {
|
|
3170
|
+
return "undefined";
|
|
3171
|
+
}
|
|
3172
|
+
return String(value);
|
|
3173
|
+
}
|
|
3174
|
+
function formatReceivedDiscriminator(value) {
|
|
3175
|
+
if (typeof value === "string") {
|
|
3176
|
+
return JSON.stringify(value);
|
|
3177
|
+
}
|
|
3178
|
+
return receivedValue(value);
|
|
3179
|
+
}
|
|
3180
|
+
|
|
2705
3181
|
// ../toolcraft-schema/src/index.ts
|
|
2706
3182
|
function assertValidEnumValues(values) {
|
|
2707
3183
|
if (values.length === 0) {
|
|
@@ -2725,6 +3201,22 @@ function assertFiniteNumber(value, name) {
|
|
|
2725
3201
|
throw new Error(`${name} must be finite`);
|
|
2726
3202
|
}
|
|
2727
3203
|
}
|
|
3204
|
+
function assertMinMaxOrder(minimum, maximum, minimumName, maximumName) {
|
|
3205
|
+
if (minimum !== void 0 && maximum !== void 0 && minimum > maximum) {
|
|
3206
|
+
throw new Error(`${minimumName} must be less than or equal to ${maximumName}`);
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
function assertValidDefault(schema) {
|
|
3210
|
+
if (schema.default === void 0) {
|
|
3211
|
+
return;
|
|
3212
|
+
}
|
|
3213
|
+
const result = validate(schema, schema.default);
|
|
3214
|
+
if (!result.ok) {
|
|
3215
|
+
throw new Error(
|
|
3216
|
+
`default must satisfy schema: ${result.issues[0]?.message ?? "invalid default"}`
|
|
3217
|
+
);
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
2728
3220
|
function assertPattern(pattern) {
|
|
2729
3221
|
if (pattern === void 0) {
|
|
2730
3222
|
return;
|
|
@@ -2739,56 +3231,71 @@ var S = {
|
|
|
2739
3231
|
String(options = {}) {
|
|
2740
3232
|
assertNonNegativeInteger(options.minLength, "minLength");
|
|
2741
3233
|
assertNonNegativeInteger(options.maxLength, "maxLength");
|
|
3234
|
+
assertMinMaxOrder(options.minLength, options.maxLength, "minLength", "maxLength");
|
|
2742
3235
|
assertPattern(options.pattern);
|
|
2743
|
-
|
|
3236
|
+
const schema = {
|
|
2744
3237
|
kind: "string",
|
|
2745
3238
|
...options
|
|
2746
3239
|
};
|
|
3240
|
+
assertValidDefault(schema);
|
|
3241
|
+
return schema;
|
|
2747
3242
|
},
|
|
2748
3243
|
Number(options = {}) {
|
|
2749
3244
|
assertFiniteNumber(options.minimum, "minimum");
|
|
2750
3245
|
assertFiniteNumber(options.maximum, "maximum");
|
|
3246
|
+
assertMinMaxOrder(options.minimum, options.maximum, "minimum", "maximum");
|
|
2751
3247
|
assertFiniteNumber(options.default, "default");
|
|
2752
3248
|
if (options.jsonType === "integer" && options.default !== void 0 && !Number.isInteger(options.default)) {
|
|
2753
3249
|
throw new Error("default must be an integer");
|
|
2754
3250
|
}
|
|
2755
|
-
|
|
3251
|
+
const schema = {
|
|
2756
3252
|
kind: "number",
|
|
2757
3253
|
...options
|
|
2758
3254
|
};
|
|
3255
|
+
assertValidDefault(schema);
|
|
3256
|
+
return schema;
|
|
2759
3257
|
},
|
|
2760
3258
|
Boolean(options = {}) {
|
|
2761
|
-
|
|
3259
|
+
const schema = {
|
|
2762
3260
|
kind: "boolean",
|
|
2763
3261
|
...options
|
|
2764
3262
|
};
|
|
3263
|
+
assertValidDefault(schema);
|
|
3264
|
+
return schema;
|
|
2765
3265
|
},
|
|
2766
3266
|
Enum(values, options = {}) {
|
|
2767
3267
|
assertValidEnumValues(values);
|
|
2768
3268
|
if (options.jsonType === "integer" && values.some((value) => typeof value !== "number" || !Number.isInteger(value))) {
|
|
2769
3269
|
throw new Error("Integer enum values must be integers");
|
|
2770
3270
|
}
|
|
2771
|
-
|
|
3271
|
+
const schema = {
|
|
2772
3272
|
kind: "enum",
|
|
2773
3273
|
values,
|
|
2774
3274
|
...options
|
|
2775
3275
|
};
|
|
3276
|
+
assertValidDefault(schema);
|
|
3277
|
+
return schema;
|
|
2776
3278
|
},
|
|
2777
3279
|
Array(item, options = {}) {
|
|
2778
3280
|
assertNonNegativeInteger(options.minItems, "minItems");
|
|
2779
3281
|
assertNonNegativeInteger(options.maxItems, "maxItems");
|
|
2780
|
-
|
|
3282
|
+
assertMinMaxOrder(options.minItems, options.maxItems, "minItems", "maxItems");
|
|
3283
|
+
const schema = {
|
|
2781
3284
|
kind: "array",
|
|
2782
3285
|
item,
|
|
2783
3286
|
...options
|
|
2784
3287
|
};
|
|
3288
|
+
assertValidDefault(schema);
|
|
3289
|
+
return schema;
|
|
2785
3290
|
},
|
|
2786
3291
|
Object(shape, options = {}) {
|
|
2787
|
-
|
|
3292
|
+
const schema = {
|
|
2788
3293
|
kind: "object",
|
|
2789
3294
|
shape,
|
|
2790
3295
|
...options
|
|
2791
3296
|
};
|
|
3297
|
+
assertValidDefault(schema);
|
|
3298
|
+
return schema;
|
|
2792
3299
|
},
|
|
2793
3300
|
Optional(inner) {
|
|
2794
3301
|
return {
|
|
@@ -3360,6 +3867,9 @@ function isRecord(value) {
|
|
|
3360
3867
|
function isStateList(value) {
|
|
3361
3868
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
3362
3869
|
}
|
|
3870
|
+
function hasVisibleName(value) {
|
|
3871
|
+
return value.trim().length > 0;
|
|
3872
|
+
}
|
|
3363
3873
|
function canFireFromState(event, fromState) {
|
|
3364
3874
|
if (event.from === "*") {
|
|
3365
3875
|
return event.to !== fromState;
|
|
@@ -3374,6 +3884,9 @@ function validateMachine(machine) {
|
|
|
3374
3884
|
throw new TypeError("State machine states must be a string array.");
|
|
3375
3885
|
}
|
|
3376
3886
|
const states = new Set(machine.states);
|
|
3887
|
+
if (machine.states.some((state) => !hasVisibleName(state))) {
|
|
3888
|
+
throw new Error("State names must not be empty.");
|
|
3889
|
+
}
|
|
3377
3890
|
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
3378
3891
|
throw new TypeError("State machine initial must be a string.");
|
|
3379
3892
|
}
|
|
@@ -3384,6 +3897,9 @@ function validateMachine(machine) {
|
|
|
3384
3897
|
throw new TypeError("State machine events must be an object.");
|
|
3385
3898
|
}
|
|
3386
3899
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
3900
|
+
if (!hasVisibleName(eventName)) {
|
|
3901
|
+
throw new Error("Event names must not be empty.");
|
|
3902
|
+
}
|
|
3387
3903
|
if (!isRecord(event)) {
|
|
3388
3904
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
3389
3905
|
}
|
|
@@ -3493,6 +4009,13 @@ import { text as text3 } from "node:stream/consumers";
|
|
|
3493
4009
|
// ../process-runner/src/docker/context.ts
|
|
3494
4010
|
import { execSync } from "node:child_process";
|
|
3495
4011
|
|
|
4012
|
+
// ../process-runner/src/docker/build-context.ts
|
|
4013
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
4014
|
+
import { createRequire } from "node:module";
|
|
4015
|
+
import path2 from "node:path";
|
|
4016
|
+
var require2 = createRequire(import.meta.url);
|
|
4017
|
+
var createIgnore = require2("ignore");
|
|
4018
|
+
|
|
3496
4019
|
// ../process-runner/src/docker/engine.ts
|
|
3497
4020
|
import { execSync as execSync2 } from "node:child_process";
|
|
3498
4021
|
|
|
@@ -3501,19 +4024,19 @@ import * as childProcess from "node:child_process";
|
|
|
3501
4024
|
import { randomBytes } from "node:crypto";
|
|
3502
4025
|
|
|
3503
4026
|
// ../process-runner/src/docker/args.ts
|
|
3504
|
-
import
|
|
4027
|
+
import path3 from "node:path";
|
|
3505
4028
|
|
|
3506
4029
|
// ../process-runner/src/docker/env-file.ts
|
|
3507
4030
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3508
4031
|
import { tmpdir } from "node:os";
|
|
3509
|
-
import
|
|
4032
|
+
import path4 from "node:path";
|
|
3510
4033
|
|
|
3511
4034
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
3512
4035
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
3513
4036
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
3514
|
-
import {
|
|
4037
|
+
import { readFile as readFile2, realpath, writeFile } from "node:fs/promises";
|
|
3515
4038
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
3516
|
-
import
|
|
4039
|
+
import path6 from "node:path";
|
|
3517
4040
|
|
|
3518
4041
|
// ../process-runner/src/host/host-runner.ts
|
|
3519
4042
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
@@ -3646,7 +4169,7 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
3646
4169
|
// ../process-runner/src/workspace-transfer.ts
|
|
3647
4170
|
import { createHash, randomUUID } from "node:crypto";
|
|
3648
4171
|
import { promises as nodeFs } from "node:fs";
|
|
3649
|
-
import
|
|
4172
|
+
import path5 from "node:path";
|
|
3650
4173
|
|
|
3651
4174
|
// ../process-runner/src/testing/mock-runner.ts
|
|
3652
4175
|
import { Readable, Writable } from "node:stream";
|
|
@@ -3718,7 +4241,7 @@ function resolveEndpoint(options = {}) {
|
|
|
3718
4241
|
|
|
3719
4242
|
// ../task-list/src/backends/utils.ts
|
|
3720
4243
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3721
|
-
import
|
|
4244
|
+
import path7 from "node:path";
|
|
3722
4245
|
function compareCreated(left, right) {
|
|
3723
4246
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
3724
4247
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -3750,15 +4273,33 @@ function sortStrings(values) {
|
|
|
3750
4273
|
function sortTasks(tasks) {
|
|
3751
4274
|
return [...tasks].sort((left, right) => left.qualifiedId.localeCompare(right.qualifiedId));
|
|
3752
4275
|
}
|
|
4276
|
+
function isTrimmedPrintableIdentifier(value) {
|
|
4277
|
+
if (value.length === 0 || value !== value.trim()) {
|
|
4278
|
+
return false;
|
|
4279
|
+
}
|
|
4280
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4281
|
+
const code = value.charCodeAt(index);
|
|
4282
|
+
if (code < 32 || code === 127) {
|
|
4283
|
+
return false;
|
|
4284
|
+
}
|
|
4285
|
+
}
|
|
4286
|
+
return true;
|
|
4287
|
+
}
|
|
3753
4288
|
function validateTaskId(id) {
|
|
3754
|
-
if (id
|
|
4289
|
+
if (!isTrimmedPrintableIdentifier(id) || id.startsWith(".") || id.includes("/") || id.includes("\\") || id.includes("..")) {
|
|
3755
4290
|
throw new Error(`Invalid task id "${id}".`);
|
|
3756
4291
|
}
|
|
3757
4292
|
return id;
|
|
3758
4293
|
}
|
|
3759
|
-
|
|
4294
|
+
function validateTaskName(name) {
|
|
4295
|
+
if (name.trim().length === 0) {
|
|
4296
|
+
throw new Error("Task name must not be empty.");
|
|
4297
|
+
}
|
|
4298
|
+
return name;
|
|
4299
|
+
}
|
|
4300
|
+
async function statIfExists(fs5, filePath) {
|
|
3760
4301
|
try {
|
|
3761
|
-
return await
|
|
4302
|
+
return await fs5.stat(filePath);
|
|
3762
4303
|
} catch (error3) {
|
|
3763
4304
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3764
4305
|
return void 0;
|
|
@@ -3766,15 +4307,18 @@ async function statIfExists(fs4, filePath) {
|
|
|
3766
4307
|
throw error3;
|
|
3767
4308
|
}
|
|
3768
4309
|
}
|
|
3769
|
-
async function rejectSymbolicLinkComponents(
|
|
3770
|
-
const resolvedPath =
|
|
3771
|
-
const rootPath =
|
|
3772
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
4310
|
+
async function rejectSymbolicLinkComponents(fs5, filePath) {
|
|
4311
|
+
const resolvedPath = path7.resolve(filePath);
|
|
4312
|
+
const rootPath = path7.parse(resolvedPath).root;
|
|
4313
|
+
const components = resolvedPath.slice(rootPath.length).split(path7.sep).filter(Boolean);
|
|
3773
4314
|
let currentPath = rootPath;
|
|
3774
4315
|
for (const component of components) {
|
|
3775
|
-
currentPath =
|
|
4316
|
+
currentPath = path7.join(currentPath, component);
|
|
3776
4317
|
try {
|
|
3777
|
-
if ((await
|
|
4318
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
4319
|
+
if (currentPath === "/tmp") {
|
|
4320
|
+
continue;
|
|
4321
|
+
}
|
|
3778
4322
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
3779
4323
|
}
|
|
3780
4324
|
} catch (error3) {
|
|
@@ -3785,19 +4329,19 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
3785
4329
|
}
|
|
3786
4330
|
}
|
|
3787
4331
|
}
|
|
3788
|
-
async function writeAtomically(
|
|
4332
|
+
async function writeAtomically(fs5, filePath, content) {
|
|
3789
4333
|
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3790
4334
|
let tempCreated = false;
|
|
3791
|
-
await
|
|
4335
|
+
await fs5.mkdir(path7.dirname(filePath), { recursive: true });
|
|
3792
4336
|
try {
|
|
3793
|
-
await
|
|
4337
|
+
await fs5.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3794
4338
|
tempCreated = true;
|
|
3795
|
-
await
|
|
4339
|
+
await fs5.rename(tempPath, filePath);
|
|
3796
4340
|
tempCreated = false;
|
|
3797
4341
|
} catch (error3) {
|
|
3798
4342
|
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3799
4343
|
try {
|
|
3800
|
-
await
|
|
4344
|
+
await fs5.unlink(tempPath);
|
|
3801
4345
|
} catch (unlinkError) {
|
|
3802
4346
|
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3803
4347
|
throw unlinkError;
|
|
@@ -3807,18 +4351,18 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
3807
4351
|
throw error3;
|
|
3808
4352
|
}
|
|
3809
4353
|
}
|
|
3810
|
-
async function withFileLock(
|
|
3811
|
-
await
|
|
4354
|
+
async function withFileLock(fs5, lockPath, operation) {
|
|
4355
|
+
await fs5.mkdir(path7.dirname(lockPath), { recursive: true });
|
|
3812
4356
|
for (; ; ) {
|
|
3813
4357
|
try {
|
|
3814
|
-
await
|
|
4358
|
+
await fs5.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
3815
4359
|
break;
|
|
3816
4360
|
} catch (error3) {
|
|
3817
4361
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3818
|
-
await
|
|
4362
|
+
await fs5.unlink(lockPath).catch(() => void 0);
|
|
3819
4363
|
throw error3;
|
|
3820
4364
|
}
|
|
3821
|
-
if (await removeAbandonedLock(
|
|
4365
|
+
if (await removeAbandonedLock(fs5, lockPath)) {
|
|
3822
4366
|
continue;
|
|
3823
4367
|
}
|
|
3824
4368
|
await Promise.resolve();
|
|
@@ -3827,13 +4371,13 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3827
4371
|
try {
|
|
3828
4372
|
return await operation();
|
|
3829
4373
|
} finally {
|
|
3830
|
-
await
|
|
4374
|
+
await fs5.unlink(lockPath);
|
|
3831
4375
|
}
|
|
3832
4376
|
}
|
|
3833
|
-
async function removeAbandonedLock(
|
|
4377
|
+
async function removeAbandonedLock(fs5, lockPath) {
|
|
3834
4378
|
let content;
|
|
3835
4379
|
try {
|
|
3836
|
-
content = await
|
|
4380
|
+
content = await fs5.readFile(lockPath, "utf8");
|
|
3837
4381
|
} catch (error3) {
|
|
3838
4382
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
3839
4383
|
return true;
|
|
@@ -3841,11 +4385,11 @@ async function removeAbandonedLock(fs4, lockPath) {
|
|
|
3841
4385
|
throw error3;
|
|
3842
4386
|
}
|
|
3843
4387
|
const owner = Number(content);
|
|
3844
|
-
if (
|
|
4388
|
+
if (Number.isInteger(owner) && owner > 0 && isProcessRunning(owner)) {
|
|
3845
4389
|
return false;
|
|
3846
4390
|
}
|
|
3847
4391
|
try {
|
|
3848
|
-
await
|
|
4392
|
+
await fs5.unlink(lockPath);
|
|
3849
4393
|
return true;
|
|
3850
4394
|
} catch (error3) {
|
|
3851
4395
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
@@ -4113,6 +4657,9 @@ async function ghIssuesBackend(deps) {
|
|
|
4113
4657
|
if (deps.state?.labelPrefix === "") {
|
|
4114
4658
|
throw new Error("gh-issues state.labelPrefix must be a non-empty string when configured.");
|
|
4115
4659
|
}
|
|
4660
|
+
if (deps.stateMachine !== void 0) {
|
|
4661
|
+
validateMachine(deps.stateMachine);
|
|
4662
|
+
}
|
|
4116
4663
|
const client = createGhClient({
|
|
4117
4664
|
token: deps.token,
|
|
4118
4665
|
endpoint: deps.endpoint,
|
|
@@ -4272,7 +4819,9 @@ function createTasksView(name, session, context) {
|
|
|
4272
4819
|
);
|
|
4273
4820
|
projectItemId = added.addProjectV2ItemById?.item?.id ?? void 0;
|
|
4274
4821
|
if (projectItemId === void 0) {
|
|
4275
|
-
throw new Error(
|
|
4822
|
+
throw new Error(
|
|
4823
|
+
"GitHub addProjectV2ItemById response did not include project item id."
|
|
4824
|
+
);
|
|
4276
4825
|
}
|
|
4277
4826
|
}
|
|
4278
4827
|
if (session.labelPrefix === void 0) {
|
|
@@ -4501,12 +5050,15 @@ async function resolveProjectItemId(id, listName, session, context) {
|
|
|
4501
5050
|
const issueNumber = parseIssueNumber(id, listName);
|
|
4502
5051
|
let after;
|
|
4503
5052
|
while (true) {
|
|
4504
|
-
const result = await context.client.graphql(
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
5053
|
+
const result = await context.client.graphql(
|
|
5054
|
+
ISSUE_STATE_LABELS_QUERY,
|
|
5055
|
+
{
|
|
5056
|
+
owner: context.repoOwner,
|
|
5057
|
+
repo: context.repoName,
|
|
5058
|
+
number: issueNumber,
|
|
5059
|
+
after
|
|
5060
|
+
}
|
|
5061
|
+
);
|
|
4510
5062
|
const issue = result.repository?.issue ?? null;
|
|
4511
5063
|
if (issue === null) {
|
|
4512
5064
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
@@ -4783,12 +5335,27 @@ async function fetchIssueTask(id, listName, session, context) {
|
|
|
4783
5335
|
});
|
|
4784
5336
|
}
|
|
4785
5337
|
function parseIssueNumber(id, listName) {
|
|
5338
|
+
if (!isCanonicalDecimalIssueId(id)) {
|
|
5339
|
+
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
5340
|
+
}
|
|
4786
5341
|
const issueNumber = Number(id);
|
|
4787
|
-
if (!Number.
|
|
5342
|
+
if (!Number.isSafeInteger(issueNumber) || issueNumber < 1) {
|
|
4788
5343
|
throw new TaskNotFoundError(`Task "${listName}/${id}" not found.`);
|
|
4789
5344
|
}
|
|
4790
5345
|
return issueNumber;
|
|
4791
5346
|
}
|
|
5347
|
+
function isCanonicalDecimalIssueId(id) {
|
|
5348
|
+
if (id.length === 0 || id[0] === "0") {
|
|
5349
|
+
return false;
|
|
5350
|
+
}
|
|
5351
|
+
for (let index = 0; index < id.length; index += 1) {
|
|
5352
|
+
const charCode = id.charCodeAt(index);
|
|
5353
|
+
if (charCode < 48 || charCode > 57) {
|
|
5354
|
+
return false;
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
return true;
|
|
5358
|
+
}
|
|
4792
5359
|
function mapProjectItemToTask(item, listName, session) {
|
|
4793
5360
|
const content = item.content;
|
|
4794
5361
|
if (!isIssueNode(content)) {
|
|
@@ -4896,7 +5463,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
4896
5463
|
}
|
|
4897
5464
|
|
|
4898
5465
|
// ../task-list/src/backends/markdown-dir.ts
|
|
4899
|
-
import
|
|
5466
|
+
import path8 from "node:path";
|
|
4900
5467
|
import { parseDocument as parseDocument2, stringify as stringify2 } from "yaml";
|
|
4901
5468
|
|
|
4902
5469
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -4999,7 +5566,7 @@ function resolveListLayout(deps) {
|
|
|
4999
5566
|
return deps.singleList ? { kind: "single", name: deps.singleList } : { kind: "multi" };
|
|
5000
5567
|
}
|
|
5001
5568
|
function validateListName(name) {
|
|
5002
|
-
if (name
|
|
5569
|
+
if (!isTrimmedPrintableIdentifier(name) || name === ARCHIVE_DIRECTORY_NAME || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
5003
5570
|
throw new Error(`Invalid task list name "${name}".`);
|
|
5004
5571
|
}
|
|
5005
5572
|
return name;
|
|
@@ -5015,16 +5582,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
5015
5582
|
};
|
|
5016
5583
|
}
|
|
5017
5584
|
function listPath(rootPath, layout, list) {
|
|
5018
|
-
return layout.kind === "single" ? rootPath :
|
|
5585
|
+
return layout.kind === "single" ? rootPath : path8.join(rootPath, list);
|
|
5019
5586
|
}
|
|
5020
5587
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
5021
|
-
return layout.kind === "single" ?
|
|
5588
|
+
return layout.kind === "single" ? path8.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path8.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
5022
5589
|
}
|
|
5023
5590
|
function activeTaskFilename(id, order, width) {
|
|
5024
5591
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
5025
5592
|
}
|
|
5026
5593
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
5027
|
-
return
|
|
5594
|
+
return path8.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
5028
5595
|
}
|
|
5029
5596
|
function isMarkdownFile(entryName) {
|
|
5030
5597
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -5126,7 +5693,7 @@ function hasOwnTaskField(frontmatter, key2) {
|
|
|
5126
5693
|
function reservedFrontmatterKeys(mode) {
|
|
5127
5694
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
5128
5695
|
}
|
|
5129
|
-
function
|
|
5696
|
+
function setOwnValue2(record, key2, value) {
|
|
5130
5697
|
Object.defineProperty(record, key2, {
|
|
5131
5698
|
value,
|
|
5132
5699
|
enumerable: true,
|
|
@@ -5139,7 +5706,7 @@ function metadataFromFrontmatter(frontmatter, mode) {
|
|
|
5139
5706
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5140
5707
|
for (const [key2, value] of Object.entries(frontmatter)) {
|
|
5141
5708
|
if (!reservedKeys.has(key2)) {
|
|
5142
|
-
|
|
5709
|
+
setOwnValue2(metadata, key2, value);
|
|
5143
5710
|
}
|
|
5144
5711
|
}
|
|
5145
5712
|
return metadata;
|
|
@@ -5153,7 +5720,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
5153
5720
|
state: frontmatter.state,
|
|
5154
5721
|
description: body,
|
|
5155
5722
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
5156
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5723
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5157
5724
|
};
|
|
5158
5725
|
}
|
|
5159
5726
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -5162,9 +5729,9 @@ ${stringify2(frontmatter)}---
|
|
|
5162
5729
|
|
|
5163
5730
|
${description}`;
|
|
5164
5731
|
}
|
|
5165
|
-
async function readDirectoryNames(
|
|
5732
|
+
async function readDirectoryNames(fs5, directoryPath) {
|
|
5166
5733
|
try {
|
|
5167
|
-
return sortStrings(await
|
|
5734
|
+
return sortStrings(await fs5.readdir(directoryPath));
|
|
5168
5735
|
} catch (error3) {
|
|
5169
5736
|
if (hasErrorCode(error3, "ENOENT")) {
|
|
5170
5737
|
return [];
|
|
@@ -5180,9 +5747,9 @@ async function ensureRootPath(deps) {
|
|
|
5180
5747
|
}
|
|
5181
5748
|
await deps.fs.stat(deps.path);
|
|
5182
5749
|
}
|
|
5183
|
-
async function readTaskFile(
|
|
5184
|
-
await rejectSymbolicLinkComponents(
|
|
5185
|
-
const content = await
|
|
5750
|
+
async function readTaskFile(fs5, list, id, filePath, validStates, initialState, mode) {
|
|
5751
|
+
await rejectSymbolicLinkComponents(fs5, filePath);
|
|
5752
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5186
5753
|
const document = splitTaskDocument(content, filePath, mode);
|
|
5187
5754
|
const frontmatter = mode === "passthrough" && document.frontmatter.trim().length === 0 ? {} : readFrontmatter(document.frontmatter, filePath);
|
|
5188
5755
|
if (mode !== "passthrough") {
|
|
@@ -5193,57 +5760,106 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
5193
5760
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
5194
5761
|
};
|
|
5195
5762
|
}
|
|
5196
|
-
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
5197
|
-
const defaultName = parsedFilename?.id ?? id;
|
|
5198
5763
|
const effectiveFrontmatter = {
|
|
5199
5764
|
...frontmatter,
|
|
5200
|
-
name: typeof frontmatter.name === "string" ? frontmatter.name :
|
|
5765
|
+
name: typeof frontmatter.name === "string" ? frontmatter.name : id,
|
|
5201
5766
|
state: typeof frontmatter.state === "string" && validStates.has(frontmatter.state) ? frontmatter.state : initialState
|
|
5202
5767
|
};
|
|
5203
5768
|
return {
|
|
5204
|
-
path: filePath,
|
|
5205
|
-
frontmatter,
|
|
5206
|
-
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5769
|
+
path: filePath,
|
|
5770
|
+
frontmatter,
|
|
5771
|
+
task: createTask(list, id, effectiveFrontmatter, document.body, mode, filePath)
|
|
5772
|
+
};
|
|
5773
|
+
}
|
|
5774
|
+
async function readPassthroughFrontmatter(fs5, filePath, mode) {
|
|
5775
|
+
if (mode !== "passthrough") {
|
|
5776
|
+
return {};
|
|
5777
|
+
}
|
|
5778
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
5779
|
+
const document = splitTaskDocument(content, filePath, mode);
|
|
5780
|
+
if (document.frontmatter.trim().length === 0) {
|
|
5781
|
+
return {};
|
|
5782
|
+
}
|
|
5783
|
+
return readFrontmatter(document.frontmatter, filePath);
|
|
5784
|
+
}
|
|
5785
|
+
async function resolveActiveFilenameEntry(fs5, entryName, entryPath, parsed, mode) {
|
|
5786
|
+
if (mode !== "passthrough" || parsed.order === null) {
|
|
5787
|
+
return parsed;
|
|
5788
|
+
}
|
|
5789
|
+
const frontmatter = await readPassthroughFrontmatter(fs5, entryPath, mode);
|
|
5790
|
+
if (Object.keys(frontmatter).length === 0 && orderedFilenamePrefixLength(entryName) <= MIN_PREFIX_WIDTH) {
|
|
5791
|
+
return parsed;
|
|
5792
|
+
}
|
|
5793
|
+
if (typeof frontmatter.state === "string" || hasOwnTaskField(frontmatter, "$schema") || hasOwnTaskField(frontmatter, "kind") || hasOwnTaskField(frontmatter, "version")) {
|
|
5794
|
+
return parsed;
|
|
5795
|
+
}
|
|
5796
|
+
return {
|
|
5797
|
+
id: entryName.slice(0, -MARKDOWN_EXTENSION.length),
|
|
5798
|
+
order: null,
|
|
5799
|
+
filename: parsed.filename
|
|
5207
5800
|
};
|
|
5208
5801
|
}
|
|
5209
|
-
|
|
5210
|
-
const
|
|
5802
|
+
function orderedFilenamePrefixLength(entryName) {
|
|
5803
|
+
const stem = entryName.slice(0, -MARKDOWN_EXTENSION.length);
|
|
5804
|
+
const separatorIndex = stem.indexOf("-");
|
|
5805
|
+
if (separatorIndex <= 0) {
|
|
5806
|
+
return Number.POSITIVE_INFINITY;
|
|
5807
|
+
}
|
|
5808
|
+
for (let index = 0; index < separatorIndex; index += 1) {
|
|
5809
|
+
const code = stem.charCodeAt(index);
|
|
5810
|
+
if (code < 48 || code > 57) {
|
|
5811
|
+
return Number.POSITIVE_INFINITY;
|
|
5812
|
+
}
|
|
5813
|
+
}
|
|
5814
|
+
return separatorIndex;
|
|
5815
|
+
}
|
|
5816
|
+
async function findActiveTaskFilename(fs5, listDirectoryPath, id, mode) {
|
|
5817
|
+
const entries = await readDirectoryNames(fs5, listDirectoryPath);
|
|
5211
5818
|
for (const entryName of entries) {
|
|
5212
5819
|
if (isHiddenEntry(entryName)) continue;
|
|
5213
5820
|
const parsed = parseActiveFilename(entryName);
|
|
5214
|
-
if (parsed
|
|
5821
|
+
if (!parsed) continue;
|
|
5822
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5823
|
+
const resolved = await resolveActiveFilenameEntry(
|
|
5824
|
+
fs5,
|
|
5825
|
+
entryName,
|
|
5826
|
+
entryPath,
|
|
5827
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
5828
|
+
mode
|
|
5829
|
+
);
|
|
5830
|
+
if (resolved.id === id) {
|
|
5215
5831
|
return entryName;
|
|
5216
5832
|
}
|
|
5217
5833
|
}
|
|
5218
5834
|
return void 0;
|
|
5219
5835
|
}
|
|
5220
|
-
async function findTaskLocation(
|
|
5836
|
+
async function findTaskLocation(fs5, rootPath, layout, list, id, mode) {
|
|
5221
5837
|
const listDirectoryPath = listPath(rootPath, layout, list);
|
|
5222
|
-
await rejectSymbolicLinkComponents(
|
|
5223
|
-
const activeName = await findActiveTaskFilename(
|
|
5838
|
+
await rejectSymbolicLinkComponents(fs5, listDirectoryPath);
|
|
5839
|
+
const activeName = await findActiveTaskFilename(fs5, listDirectoryPath, id, mode);
|
|
5224
5840
|
if (activeName) {
|
|
5225
|
-
const activePath =
|
|
5226
|
-
await rejectSymbolicLinkComponents(
|
|
5227
|
-
const activeStat = await statIfExists(
|
|
5841
|
+
const activePath = path8.join(listDirectoryPath, activeName);
|
|
5842
|
+
await rejectSymbolicLinkComponents(fs5, activePath);
|
|
5843
|
+
const activeStat = await statIfExists(fs5, activePath);
|
|
5228
5844
|
if (activeStat?.isFile()) {
|
|
5229
5845
|
return { archived: false, path: activePath };
|
|
5230
5846
|
}
|
|
5231
5847
|
}
|
|
5232
5848
|
const archivedPath = archivedTaskPath(rootPath, layout, list, id);
|
|
5233
|
-
await rejectSymbolicLinkComponents(
|
|
5234
|
-
await rejectSymbolicLinkComponents(
|
|
5235
|
-
const archivedStat = await statIfExists(
|
|
5849
|
+
await rejectSymbolicLinkComponents(fs5, archiveDirectoryPath(rootPath, layout, list));
|
|
5850
|
+
await rejectSymbolicLinkComponents(fs5, archivedPath);
|
|
5851
|
+
const archivedStat = await statIfExists(fs5, archivedPath);
|
|
5236
5852
|
if (archivedStat?.isFile()) {
|
|
5237
5853
|
return { archived: true, path: archivedPath };
|
|
5238
5854
|
}
|
|
5239
5855
|
return void 0;
|
|
5240
5856
|
}
|
|
5241
|
-
async function readTaskAtLocation(
|
|
5242
|
-
const location = await findTaskLocation(
|
|
5857
|
+
async function readTaskAtLocation(fs5, rootPath, layout, list, id, validStates, initialState, mode) {
|
|
5858
|
+
const location = await findTaskLocation(fs5, rootPath, layout, list, id, mode);
|
|
5243
5859
|
if (!location) {
|
|
5244
5860
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5245
5861
|
}
|
|
5246
|
-
return readTaskFile(
|
|
5862
|
+
return readTaskFile(fs5, list, id, location.path, validStates, initialState, mode);
|
|
5247
5863
|
}
|
|
5248
5864
|
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
5249
5865
|
const frontmatter = mode !== "passthrough" ? {
|
|
@@ -5259,12 +5875,12 @@ function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
|
5259
5875
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5260
5876
|
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5261
5877
|
if (!reservedKeys.has(key2)) {
|
|
5262
|
-
|
|
5878
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5263
5879
|
}
|
|
5264
5880
|
}
|
|
5265
5881
|
for (const [key2, value] of Object.entries(input.metadata ?? {})) {
|
|
5266
5882
|
if (!reservedKeys.has(key2)) {
|
|
5267
|
-
|
|
5883
|
+
setOwnValue2(frontmatter, key2, value);
|
|
5268
5884
|
}
|
|
5269
5885
|
}
|
|
5270
5886
|
frontmatter.created = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5286,7 +5902,7 @@ function updatedFrontmatter(existingFrontmatter, task, patch, mode) {
|
|
|
5286
5902
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5287
5903
|
for (const [key2, value] of Object.entries(patch.metadata ?? {})) {
|
|
5288
5904
|
if (!reservedKeys.has(key2)) {
|
|
5289
|
-
|
|
5905
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5290
5906
|
}
|
|
5291
5907
|
}
|
|
5292
5908
|
return nextFrontmatter;
|
|
@@ -5310,7 +5926,7 @@ function firedFrontmatter(existingFrontmatter, task, to, mode, metadataPatch) {
|
|
|
5310
5926
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
5311
5927
|
for (const [key2, value] of Object.entries(metadataPatch ?? {})) {
|
|
5312
5928
|
if (!reservedKeys.has(key2)) {
|
|
5313
|
-
|
|
5929
|
+
setOwnValue2(nextFrontmatter, key2, value);
|
|
5314
5930
|
}
|
|
5315
5931
|
}
|
|
5316
5932
|
return nextFrontmatter;
|
|
@@ -5344,11 +5960,19 @@ function createTasksView2(deps, layout, list) {
|
|
|
5344
5960
|
if (isHiddenEntry(entryName)) continue;
|
|
5345
5961
|
const parsed = parseActiveFilename(entryName);
|
|
5346
5962
|
if (!parsed) continue;
|
|
5347
|
-
const entryPath =
|
|
5963
|
+
const entryPath = path8.join(listDirectoryPath, entryName);
|
|
5348
5964
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5349
5965
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5350
5966
|
if (!entryStat?.isFile()) continue;
|
|
5351
|
-
result.push(
|
|
5967
|
+
result.push(
|
|
5968
|
+
await resolveActiveFilenameEntry(
|
|
5969
|
+
deps.fs,
|
|
5970
|
+
entryName,
|
|
5971
|
+
entryPath,
|
|
5972
|
+
{ id: parsed.id, order: parsed.order, filename: entryName },
|
|
5973
|
+
deps.frontmatterMode
|
|
5974
|
+
)
|
|
5975
|
+
);
|
|
5352
5976
|
}
|
|
5353
5977
|
result.sort((left, right) => {
|
|
5354
5978
|
const leftOrder = left.order ?? Number.POSITIVE_INFINITY;
|
|
@@ -5362,7 +5986,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5362
5986
|
const entries = await readActiveEntries();
|
|
5363
5987
|
const tasks = /* @__PURE__ */ new Map();
|
|
5364
5988
|
for (const entry of entries) {
|
|
5365
|
-
const filePath =
|
|
5989
|
+
const filePath = path8.join(listDirectoryPath, entry.filename);
|
|
5366
5990
|
const file = await readTaskFile(
|
|
5367
5991
|
deps.fs,
|
|
5368
5992
|
list,
|
|
@@ -5383,7 +6007,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5383
6007
|
const result = [];
|
|
5384
6008
|
for (const entryName of entries) {
|
|
5385
6009
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
5386
|
-
const entryPath =
|
|
6010
|
+
const entryPath = path8.join(archivePath, entryName);
|
|
5387
6011
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5388
6012
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5389
6013
|
if (!entryStat?.isFile()) continue;
|
|
@@ -5413,15 +6037,20 @@ function createTasksView2(deps, layout, list) {
|
|
|
5413
6037
|
if (desiredOrder === void 0) continue;
|
|
5414
6038
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
5415
6039
|
if (entry.filename !== desiredFilename) {
|
|
5416
|
-
const fromPath =
|
|
5417
|
-
const stagingPath =
|
|
6040
|
+
const fromPath = path8.join(listDirectoryPath, entry.filename);
|
|
6041
|
+
const stagingPath = path8.join(
|
|
5418
6042
|
listDirectoryPath,
|
|
5419
6043
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
5420
6044
|
);
|
|
5421
|
-
const targetPath =
|
|
6045
|
+
const targetPath = path8.join(listDirectoryPath, desiredFilename);
|
|
5422
6046
|
try {
|
|
5423
6047
|
await deps.fs.rename(fromPath, stagingPath);
|
|
5424
|
-
staged.push({
|
|
6048
|
+
staged.push({
|
|
6049
|
+
original: fromPath,
|
|
6050
|
+
staging: stagingPath,
|
|
6051
|
+
target: targetPath,
|
|
6052
|
+
finalized: false
|
|
6053
|
+
});
|
|
5425
6054
|
} catch (error3) {
|
|
5426
6055
|
for (const stagedEntry of staged.reverse()) {
|
|
5427
6056
|
await deps.fs.rename(stagedEntry.staging, stagedEntry.original);
|
|
@@ -5556,8 +6185,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5556
6185
|
if (filter?.state && entry.task.state !== filter.state) return false;
|
|
5557
6186
|
return true;
|
|
5558
6187
|
});
|
|
5559
|
-
|
|
5560
|
-
return [...orderedActiveTasks, ...filteredArchived.map((entry) => entry.task)];
|
|
6188
|
+
return applyOrder([...orderedActive, ...filteredArchived], filter?.order);
|
|
5561
6189
|
},
|
|
5562
6190
|
async get(id) {
|
|
5563
6191
|
return (await getTaskFile(id)).task;
|
|
@@ -5566,9 +6194,17 @@ function createTasksView2(deps, layout, list) {
|
|
|
5566
6194
|
assertCreateDoesNotSetState(input);
|
|
5567
6195
|
assertCreateHasId(input);
|
|
5568
6196
|
validateTaskId(input.id);
|
|
6197
|
+
validateTaskName(input.name);
|
|
5569
6198
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
5570
|
-
return withFileLock(deps.fs,
|
|
5571
|
-
const existing = await findTaskLocation(
|
|
6199
|
+
return withFileLock(deps.fs, path8.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
6200
|
+
const existing = await findTaskLocation(
|
|
6201
|
+
deps.fs,
|
|
6202
|
+
deps.path,
|
|
6203
|
+
layout,
|
|
6204
|
+
list,
|
|
6205
|
+
input.id,
|
|
6206
|
+
deps.frontmatterMode
|
|
6207
|
+
);
|
|
5572
6208
|
if (existing) {
|
|
5573
6209
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
5574
6210
|
}
|
|
@@ -5580,7 +6216,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5580
6216
|
const nextOrder = maxOrder + 1;
|
|
5581
6217
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
5582
6218
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
5583
|
-
const targetPath =
|
|
6219
|
+
const targetPath = path8.join(listDirectoryPath, filename);
|
|
5584
6220
|
const frontmatter = createdFrontmatter(
|
|
5585
6221
|
deps.defaults,
|
|
5586
6222
|
input,
|
|
@@ -5589,12 +6225,22 @@ function createTasksView2(deps, layout, list) {
|
|
|
5589
6225
|
);
|
|
5590
6226
|
const description = input.description ?? "";
|
|
5591
6227
|
await writeAtomically(deps.fs, targetPath, serializeTaskDocument(frontmatter, description));
|
|
5592
|
-
return createTask(
|
|
6228
|
+
return createTask(
|
|
6229
|
+
list,
|
|
6230
|
+
input.id,
|
|
6231
|
+
frontmatter,
|
|
6232
|
+
description,
|
|
6233
|
+
deps.frontmatterMode,
|
|
6234
|
+
targetPath
|
|
6235
|
+
);
|
|
5593
6236
|
});
|
|
5594
6237
|
},
|
|
5595
6238
|
async update(id, patch) {
|
|
5596
6239
|
assertUpdateDoesNotSetState(patch);
|
|
5597
6240
|
validateTaskId(id);
|
|
6241
|
+
if (patch.name !== void 0) {
|
|
6242
|
+
validateTaskName(patch.name);
|
|
6243
|
+
}
|
|
5598
6244
|
const existing = await getTaskFile(id);
|
|
5599
6245
|
const nextFrontmatter = updatedFrontmatter(
|
|
5600
6246
|
existing.frontmatter,
|
|
@@ -5680,7 +6326,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5680
6326
|
};
|
|
5681
6327
|
if (stateMachine.events[eventName]?.to === "archived") {
|
|
5682
6328
|
validateTaskId(id);
|
|
5683
|
-
const location = await findTaskLocation(
|
|
6329
|
+
const location = await findTaskLocation(
|
|
6330
|
+
deps.fs,
|
|
6331
|
+
deps.path,
|
|
6332
|
+
layout,
|
|
6333
|
+
list,
|
|
6334
|
+
id,
|
|
6335
|
+
deps.frontmatterMode
|
|
6336
|
+
);
|
|
5684
6337
|
if (!location) {
|
|
5685
6338
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5686
6339
|
}
|
|
@@ -5688,7 +6341,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
5688
6341
|
validateTaskId(id);
|
|
5689
6342
|
const { event, nextTask } = await withFileLock(
|
|
5690
6343
|
deps.fs,
|
|
5691
|
-
|
|
6344
|
+
path8.join(listDirectoryPath, ".transition.lock"),
|
|
5692
6345
|
fireTask
|
|
5693
6346
|
);
|
|
5694
6347
|
await event.onEnter?.(nextTask);
|
|
@@ -5708,7 +6361,14 @@ function createTasksView2(deps, layout, list) {
|
|
|
5708
6361
|
},
|
|
5709
6362
|
async delete(id) {
|
|
5710
6363
|
validateTaskId(id);
|
|
5711
|
-
const location = await findTaskLocation(
|
|
6364
|
+
const location = await findTaskLocation(
|
|
6365
|
+
deps.fs,
|
|
6366
|
+
deps.path,
|
|
6367
|
+
layout,
|
|
6368
|
+
list,
|
|
6369
|
+
id,
|
|
6370
|
+
deps.frontmatterMode
|
|
6371
|
+
);
|
|
5712
6372
|
if (!location) {
|
|
5713
6373
|
throw new TaskNotFoundError(`Task "${list}/${id}" not found.`);
|
|
5714
6374
|
}
|
|
@@ -5781,7 +6441,7 @@ async function markdownDirBackend(deps) {
|
|
|
5781
6441
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
5782
6442
|
continue;
|
|
5783
6443
|
}
|
|
5784
|
-
const entryPath =
|
|
6444
|
+
const entryPath = path8.join(deps.path, entryName);
|
|
5785
6445
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
5786
6446
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
5787
6447
|
if (entryStat?.isDirectory()) {
|
|
@@ -5823,12 +6483,26 @@ async function markdownDirBackend(deps) {
|
|
|
5823
6483
|
}
|
|
5824
6484
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
5825
6485
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
5826
|
-
return withFileLock(deps.fs,
|
|
5827
|
-
const targetExisting = await findTaskLocation(
|
|
6486
|
+
return withFileLock(deps.fs, path8.join(targetListDir, ".transition.lock"), async () => {
|
|
6487
|
+
const targetExisting = await findTaskLocation(
|
|
6488
|
+
deps.fs,
|
|
6489
|
+
deps.path,
|
|
6490
|
+
layout,
|
|
6491
|
+
targetListName,
|
|
6492
|
+
id,
|
|
6493
|
+
deps.frontmatterMode
|
|
6494
|
+
);
|
|
5828
6495
|
if (targetExisting) {
|
|
5829
6496
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
5830
6497
|
}
|
|
5831
|
-
const sourceLocation = await findTaskLocation(
|
|
6498
|
+
const sourceLocation = await findTaskLocation(
|
|
6499
|
+
deps.fs,
|
|
6500
|
+
deps.path,
|
|
6501
|
+
layout,
|
|
6502
|
+
sourceListName,
|
|
6503
|
+
id,
|
|
6504
|
+
deps.frontmatterMode
|
|
6505
|
+
);
|
|
5832
6506
|
if (!sourceLocation) {
|
|
5833
6507
|
throw new TaskNotFoundError(`Task "${sourceListName}/${id}" not found.`);
|
|
5834
6508
|
}
|
|
@@ -5873,7 +6547,7 @@ async function markdownDirBackend(deps) {
|
|
|
5873
6547
|
);
|
|
5874
6548
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
5875
6549
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
5876
|
-
const targetPath =
|
|
6550
|
+
const targetPath = path8.join(targetListDir, targetFilename);
|
|
5877
6551
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
5878
6552
|
return createTask(
|
|
5879
6553
|
targetListName,
|
|
@@ -5895,7 +6569,7 @@ async function markdownDirBackend(deps) {
|
|
|
5895
6569
|
}
|
|
5896
6570
|
|
|
5897
6571
|
// ../task-list/src/backends/yaml-file.ts
|
|
5898
|
-
import
|
|
6572
|
+
import path9 from "node:path";
|
|
5899
6573
|
import { isMap, parseDocument as parseDocument3 } from "yaml";
|
|
5900
6574
|
|
|
5901
6575
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -5955,7 +6629,7 @@ function malformedTask2(list, id, field) {
|
|
|
5955
6629
|
return new MalformedTaskError(`Malformed task "${list}/${id}": invalid "${field}".`);
|
|
5956
6630
|
}
|
|
5957
6631
|
function validateListName2(name) {
|
|
5958
|
-
if (name
|
|
6632
|
+
if (!isTrimmedPrintableIdentifier(name) || name.startsWith(".") || name.includes("/") || name.includes("\\") || name.includes("..")) {
|
|
5959
6633
|
throw new Error(`Invalid task list name "${name}".`);
|
|
5960
6634
|
}
|
|
5961
6635
|
return name;
|
|
@@ -5992,7 +6666,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5992
6666
|
state: getOwnEntry(taskRecord, "state"),
|
|
5993
6667
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5994
6668
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5995
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
6669
|
+
...sourcePath !== void 0 && { sourcePath: path9.resolve(sourcePath) }
|
|
5996
6670
|
};
|
|
5997
6671
|
}
|
|
5998
6672
|
function matchesFilter(task, filter) {
|
|
@@ -6163,8 +6837,8 @@ function serializeDocument(document) {
|
|
|
6163
6837
|
return serialized.endsWith("\n") ? serialized : `${serialized}
|
|
6164
6838
|
`;
|
|
6165
6839
|
}
|
|
6166
|
-
async function readStore(
|
|
6167
|
-
const content = await
|
|
6840
|
+
async function readStore(fs5, filePath, validStates) {
|
|
6841
|
+
const content = await fs5.readFile(filePath, "utf8");
|
|
6168
6842
|
const document = parseStoreDocument(filePath, content);
|
|
6169
6843
|
const store = document.toJS();
|
|
6170
6844
|
assertValidStoreRecord(store, filePath);
|
|
@@ -6304,6 +6978,7 @@ function createTasksView3(deps, list) {
|
|
|
6304
6978
|
assertCreateDoesNotSetState2(input);
|
|
6305
6979
|
assertCreateHasId2(input);
|
|
6306
6980
|
validateTaskId(input.id);
|
|
6981
|
+
validateTaskName(input.name);
|
|
6307
6982
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6308
6983
|
if (getTaskRecord(store, list, input.id)) {
|
|
6309
6984
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -6316,6 +6991,9 @@ function createTasksView3(deps, list) {
|
|
|
6316
6991
|
async update(id, patch) {
|
|
6317
6992
|
assertUpdateDoesNotSetState2(patch);
|
|
6318
6993
|
validateTaskId(id);
|
|
6994
|
+
if (patch.name !== void 0) {
|
|
6995
|
+
validateTaskName(patch.name);
|
|
6996
|
+
}
|
|
6319
6997
|
const { document, store } = await readStore(deps.fs, deps.path, validStates);
|
|
6320
6998
|
const existing = getTaskOrThrow(store, list, id);
|
|
6321
6999
|
const nextTaskRecord = buildUpdatedTaskRecord(existing, patch);
|
|
@@ -6407,6 +7085,11 @@ function createTasksView3(deps, list) {
|
|
|
6407
7085
|
insertIndex = anchor.position === "top" ? 0 : listNode.items.length;
|
|
6408
7086
|
} else {
|
|
6409
7087
|
const anchorId = "before" in anchor ? anchor.before : anchor.after;
|
|
7088
|
+
const activeIds = new Set(activeItemIds(listNode, validStates));
|
|
7089
|
+
if (!activeIds.has(anchorId)) {
|
|
7090
|
+
listNode.items.splice(fromIndex, 0, movedPair);
|
|
7091
|
+
throw new AnchorNotFoundError(anchorId);
|
|
7092
|
+
}
|
|
6410
7093
|
const anchorIndex = findItemIndex(listNode, anchorId);
|
|
6411
7094
|
if (anchorIndex < 0) {
|
|
6412
7095
|
listNode.items.splice(fromIndex, 0, movedPair);
|
|
@@ -6591,7 +7274,7 @@ function isRecord4(value) {
|
|
|
6591
7274
|
|
|
6592
7275
|
// ../task-list/src/move.ts
|
|
6593
7276
|
import * as fsPromises2 from "node:fs/promises";
|
|
6594
|
-
import
|
|
7277
|
+
import path10 from "node:path";
|
|
6595
7278
|
|
|
6596
7279
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
6597
7280
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6778,7 +7461,7 @@ function areEqualStrings(left, right) {
|
|
|
6778
7461
|
}
|
|
6779
7462
|
|
|
6780
7463
|
// ../toolcraft/src/human-in-loop/runner.ts
|
|
6781
|
-
import { access, lstat, readFile as
|
|
7464
|
+
import { access, lstat, readFile as readFile3, rename, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
6782
7465
|
|
|
6783
7466
|
// ../toolcraft/src/human-in-loop/default-provider.ts
|
|
6784
7467
|
import process3 from "node:process";
|
|
@@ -6810,7 +7493,7 @@ on error number -128
|
|
|
6810
7493
|
end try`;
|
|
6811
7494
|
}
|
|
6812
7495
|
function parseStdout(out) {
|
|
6813
|
-
const value = out.endsWith("\r\n") ? out.slice(0, -2) : out.endsWith("\n") ? out.slice(0, -1) : out;
|
|
7496
|
+
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;
|
|
6814
7497
|
switch (value) {
|
|
6815
7498
|
case "Approve":
|
|
6816
7499
|
case "APPROVED":
|
|
@@ -7090,13 +7773,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
7090
7773
|
}
|
|
7091
7774
|
function enumerateApprovalCommandPaths(root) {
|
|
7092
7775
|
const paths = [];
|
|
7093
|
-
const visit = (node,
|
|
7776
|
+
const visit = (node, path25) => {
|
|
7094
7777
|
if (node.kind === "command") {
|
|
7095
|
-
paths.push(
|
|
7778
|
+
paths.push(path25.join("."));
|
|
7096
7779
|
return;
|
|
7097
7780
|
}
|
|
7098
7781
|
for (const child of getVisibleCliChildren(node)) {
|
|
7099
|
-
visit(child, [...
|
|
7782
|
+
visit(child, [...path25, child.name]);
|
|
7100
7783
|
}
|
|
7101
7784
|
};
|
|
7102
7785
|
if (root.kind === "command") {
|
|
@@ -7131,21 +7814,21 @@ function createHandlerContext(command, params17) {
|
|
|
7131
7814
|
}
|
|
7132
7815
|
function createFs() {
|
|
7133
7816
|
return {
|
|
7134
|
-
readFile: async (
|
|
7135
|
-
writeFile: async (
|
|
7136
|
-
await writeFile2(
|
|
7817
|
+
readFile: async (path25, encoding = "utf8") => readFile3(path25, { encoding }),
|
|
7818
|
+
writeFile: async (path25, contents, options) => {
|
|
7819
|
+
await writeFile2(path25, contents, options);
|
|
7137
7820
|
},
|
|
7138
|
-
exists: async (
|
|
7821
|
+
exists: async (path25) => {
|
|
7139
7822
|
try {
|
|
7140
|
-
await access(
|
|
7823
|
+
await access(path25);
|
|
7141
7824
|
return true;
|
|
7142
7825
|
} catch {
|
|
7143
7826
|
return false;
|
|
7144
7827
|
}
|
|
7145
7828
|
},
|
|
7146
|
-
lstat: async (
|
|
7829
|
+
lstat: async (path25) => lstat(path25),
|
|
7147
7830
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
7148
|
-
unlink: async (
|
|
7831
|
+
unlink: async (path25) => unlink(path25)
|
|
7149
7832
|
};
|
|
7150
7833
|
}
|
|
7151
7834
|
function createEnv(values = process.env) {
|
|
@@ -7424,13 +8107,13 @@ function isMissingStateError(error3) {
|
|
|
7424
8107
|
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
7425
8108
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
7426
8109
|
import os from "node:os";
|
|
7427
|
-
import
|
|
8110
|
+
import path14 from "node:path";
|
|
7428
8111
|
import { CommanderError } from "commander";
|
|
7429
8112
|
|
|
7430
8113
|
// ../toolcraft/src/mcp-proxy.ts
|
|
7431
8114
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7432
|
-
import { lstat as lstat2, mkdir, readFile as
|
|
7433
|
-
import
|
|
8115
|
+
import { lstat as lstat2, mkdir, readFile as readFile4, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
8116
|
+
import path13 from "node:path";
|
|
7434
8117
|
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
7435
8118
|
|
|
7436
8119
|
// ../tiny-mcp-client/src/internal.ts
|
|
@@ -7439,13 +8122,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
7439
8122
|
|
|
7440
8123
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
7441
8124
|
import crypto from "node:crypto";
|
|
7442
|
-
import
|
|
8125
|
+
import path12 from "node:path";
|
|
7443
8126
|
|
|
7444
8127
|
// ../auth-store/src/encrypted-file-store.ts
|
|
7445
8128
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
7446
8129
|
import { promises as fs } from "node:fs";
|
|
7447
8130
|
import { homedir, hostname, userInfo } from "node:os";
|
|
7448
|
-
import
|
|
8131
|
+
import path11 from "node:path";
|
|
7449
8132
|
|
|
7450
8133
|
// ../auth-store/src/error-codes.ts
|
|
7451
8134
|
function hasOwnErrorCode3(error3, code) {
|
|
@@ -7474,10 +8157,13 @@ var EncryptedFileStore = class {
|
|
|
7474
8157
|
if (input.filePath === void 0) {
|
|
7475
8158
|
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
7476
8159
|
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
7477
|
-
|
|
8160
|
+
const defaultFileName = input.defaultFileName ?? "credentials.enc";
|
|
8161
|
+
assertSafeDefaultDirectory(defaultDirectory);
|
|
8162
|
+
assertSafeDefaultFileName(defaultFileName);
|
|
8163
|
+
this.filePath = path11.join(
|
|
7478
8164
|
homeDirectory,
|
|
7479
8165
|
defaultDirectory,
|
|
7480
|
-
|
|
8166
|
+
defaultFileName
|
|
7481
8167
|
);
|
|
7482
8168
|
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
7483
8169
|
homeDirectory,
|
|
@@ -7537,7 +8223,7 @@ var EncryptedFileStore = class {
|
|
|
7537
8223
|
authTag: authTag.toString("base64"),
|
|
7538
8224
|
ciphertext: ciphertext.toString("base64")
|
|
7539
8225
|
};
|
|
7540
|
-
await this.fs.mkdir(
|
|
8226
|
+
await this.fs.mkdir(path11.dirname(this.filePath), { recursive: true });
|
|
7541
8227
|
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
7542
8228
|
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
7543
8229
|
let temporaryCreated = false;
|
|
@@ -7569,7 +8255,7 @@ var EncryptedFileStore = class {
|
|
|
7569
8255
|
}
|
|
7570
8256
|
}
|
|
7571
8257
|
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
7572
|
-
const resolvedPath =
|
|
8258
|
+
const resolvedPath = path11.resolve(targetPath);
|
|
7573
8259
|
const protectedPaths = getProtectedCredentialPaths(
|
|
7574
8260
|
resolvedPath,
|
|
7575
8261
|
this.symbolicLinkCheckStartPath
|
|
@@ -7603,27 +8289,62 @@ var EncryptedFileStore = class {
|
|
|
7603
8289
|
};
|
|
7604
8290
|
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
7605
8291
|
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
7606
|
-
return
|
|
8292
|
+
return path11.resolve(homeDirectory, firstSegment ?? ".");
|
|
7607
8293
|
}
|
|
7608
8294
|
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
7609
8295
|
if (symbolicLinkCheckStartPath === null) {
|
|
7610
|
-
return
|
|
8296
|
+
return getExplicitProtectedCredentialPaths(resolvedPath);
|
|
7611
8297
|
}
|
|
7612
|
-
const resolvedStartPath =
|
|
8298
|
+
const resolvedStartPath = path11.resolve(symbolicLinkCheckStartPath);
|
|
7613
8299
|
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
7614
|
-
return [
|
|
8300
|
+
return [path11.dirname(resolvedPath), resolvedPath];
|
|
7615
8301
|
}
|
|
7616
8302
|
const protectedPaths = [resolvedStartPath];
|
|
7617
8303
|
let currentPath = resolvedStartPath;
|
|
7618
|
-
for (const segment of
|
|
7619
|
-
currentPath =
|
|
8304
|
+
for (const segment of path11.relative(resolvedStartPath, resolvedPath).split(path11.sep).filter(Boolean)) {
|
|
8305
|
+
currentPath = path11.join(currentPath, segment);
|
|
8306
|
+
protectedPaths.push(currentPath);
|
|
8307
|
+
}
|
|
8308
|
+
return protectedPaths;
|
|
8309
|
+
}
|
|
8310
|
+
function assertSafeDefaultDirectory(defaultDirectory) {
|
|
8311
|
+
if (path11.isAbsolute(defaultDirectory) || path11.win32.isAbsolute(defaultDirectory)) {
|
|
8312
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8313
|
+
}
|
|
8314
|
+
for (const segment of splitPathSegments(defaultDirectory)) {
|
|
8315
|
+
if (segment === "..") {
|
|
8316
|
+
throw new Error("defaultDirectory must be a relative path inside the home directory");
|
|
8317
|
+
}
|
|
8318
|
+
}
|
|
8319
|
+
}
|
|
8320
|
+
function assertSafeDefaultFileName(defaultFileName) {
|
|
8321
|
+
if (defaultFileName.trim().length === 0 || defaultFileName === "." || defaultFileName === ".." || splitPathSegments(defaultFileName).length !== 1) {
|
|
8322
|
+
throw new Error("defaultFileName must be a file name without path separators");
|
|
8323
|
+
}
|
|
8324
|
+
}
|
|
8325
|
+
function splitPathSegments(value) {
|
|
8326
|
+
return value.split("/").flatMap((segment) => segment.split("\\")).filter((segment) => segment.length > 0);
|
|
8327
|
+
}
|
|
8328
|
+
function getExplicitProtectedCredentialPaths(resolvedPath) {
|
|
8329
|
+
const parsed = path11.parse(resolvedPath);
|
|
8330
|
+
const segments = resolvedPath.slice(parsed.root.length).split(path11.sep).filter((segment) => segment.length > 0);
|
|
8331
|
+
if (segments.length <= 1) {
|
|
8332
|
+
return [resolvedPath];
|
|
8333
|
+
}
|
|
8334
|
+
const protectedPaths = [];
|
|
8335
|
+
let currentPath = parsed.root;
|
|
8336
|
+
for (const [index, segment] of segments.entries()) {
|
|
8337
|
+
currentPath = path11.join(currentPath, segment);
|
|
8338
|
+
if (index === 0) {
|
|
8339
|
+
continue;
|
|
8340
|
+
}
|
|
7620
8341
|
protectedPaths.push(currentPath);
|
|
7621
8342
|
}
|
|
7622
8343
|
return protectedPaths;
|
|
7623
8344
|
}
|
|
7624
8345
|
function isPathInsideOrEqual(childPath, parentPath) {
|
|
7625
|
-
const relativePath =
|
|
7626
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
8346
|
+
const relativePath = path11.relative(parentPath, childPath);
|
|
8347
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
|
|
7627
8348
|
}
|
|
7628
8349
|
async function removeIfPresent(fileSystem, filePath) {
|
|
7629
8350
|
try {
|
|
@@ -7714,8 +8435,14 @@ var KeychainStore = class {
|
|
|
7714
8435
|
account;
|
|
7715
8436
|
constructor(input) {
|
|
7716
8437
|
this.runCommand = input.runCommand ?? runSecurityCommand;
|
|
7717
|
-
this.service = input.service;
|
|
7718
|
-
this.account = input.account;
|
|
8438
|
+
this.service = input.service.trim();
|
|
8439
|
+
this.account = input.account.trim();
|
|
8440
|
+
if (this.service.length === 0) {
|
|
8441
|
+
throw new Error("Keychain service must not be empty");
|
|
8442
|
+
}
|
|
8443
|
+
if (this.account.length === 0) {
|
|
8444
|
+
throw new Error("Keychain account must not be empty");
|
|
8445
|
+
}
|
|
7719
8446
|
}
|
|
7720
8447
|
async get() {
|
|
7721
8448
|
const result = await this.executeSecurityCommand(
|
|
@@ -7742,10 +8469,10 @@ var KeychainStore = class {
|
|
|
7742
8469
|
"-a",
|
|
7743
8470
|
this.account,
|
|
7744
8471
|
"-U",
|
|
7745
|
-
"-w"
|
|
8472
|
+
"-w",
|
|
8473
|
+
value
|
|
7746
8474
|
],
|
|
7747
|
-
"store secret in macOS Keychain"
|
|
7748
|
-
{ stdin: value }
|
|
8475
|
+
"store secret in macOS Keychain"
|
|
7749
8476
|
);
|
|
7750
8477
|
if (getCommandExitCode(result) !== 0) {
|
|
7751
8478
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
@@ -7890,13 +8617,14 @@ function createSecretStore(input) {
|
|
|
7890
8617
|
function resolveBackend(input) {
|
|
7891
8618
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7892
8619
|
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7893
|
-
|
|
8620
|
+
const backend = configuredBackend?.trim();
|
|
8621
|
+
if (backend === "keychain") {
|
|
7894
8622
|
return "keychain";
|
|
7895
8623
|
}
|
|
7896
|
-
if (
|
|
8624
|
+
if (backend === void 0 || backend === "file") {
|
|
7897
8625
|
return "file";
|
|
7898
8626
|
}
|
|
7899
|
-
throw new Error(`Unsupported auth store backend: ${
|
|
8627
|
+
throw new Error(`Unsupported auth store backend: ${backend}`);
|
|
7900
8628
|
}
|
|
7901
8629
|
function getOwnEnvValue(env, key2) {
|
|
7902
8630
|
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
@@ -7921,6 +8649,7 @@ var DEFAULT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth";
|
|
|
7921
8649
|
var DEFAULT_CLIENT_FILE_SALT = "poe-code:mcp-oauth:clients:v1";
|
|
7922
8650
|
var DEFAULT_CLIENT_FILE_DIRECTORY = ".poe-code/mcp-oauth/clients";
|
|
7923
8651
|
var DEFAULT_CLIENT_KEYCHAIN_SERVICE = "poe-code-mcp-oauth-clients";
|
|
8652
|
+
var MAX_JS_DATE_MS = 864e13;
|
|
7924
8653
|
function createAuthStoreSessionStore(options = {}) {
|
|
7925
8654
|
return {
|
|
7926
8655
|
async load(resource) {
|
|
@@ -7930,10 +8659,10 @@ function createAuthStoreSessionStore(options = {}) {
|
|
|
7930
8659
|
return null;
|
|
7931
8660
|
}
|
|
7932
8661
|
const parsed = JSON.parse(value);
|
|
7933
|
-
if (
|
|
8662
|
+
if (isStoredOAuthSession(parsed)) {
|
|
7934
8663
|
return parsed;
|
|
7935
8664
|
}
|
|
7936
|
-
throw new Error("Stored OAuth session must
|
|
8665
|
+
throw new Error("Stored OAuth session must match the expected shape");
|
|
7937
8666
|
},
|
|
7938
8667
|
async save(resource, session) {
|
|
7939
8668
|
const store = createResourceSecretStore(resource, options);
|
|
@@ -7977,10 +8706,10 @@ function createAuthStoreClientStore(options) {
|
|
|
7977
8706
|
function createNamedSecretStore(key2, options, defaults2) {
|
|
7978
8707
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
7979
8708
|
const configuredFilePath = options.fileStore?.filePath;
|
|
7980
|
-
const parsedFilePath = configuredFilePath === void 0 ? null :
|
|
8709
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path12.parse(configuredFilePath);
|
|
7981
8710
|
const fileStore = {
|
|
7982
8711
|
...options.fileStore,
|
|
7983
|
-
filePath: parsedFilePath === null ? void 0 :
|
|
8712
|
+
filePath: parsedFilePath === null ? void 0 : path12.join(
|
|
7984
8713
|
parsedFilePath.dir,
|
|
7985
8714
|
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7986
8715
|
),
|
|
@@ -7996,28 +8725,20 @@ function createNamedSecretStore(key2, options, defaults2) {
|
|
|
7996
8725
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
7997
8726
|
}
|
|
7998
8727
|
function createResourceSecretStore(resource, options) {
|
|
7999
|
-
return createNamedSecretStore(
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8006
|
-
accountPrefix: "provider"
|
|
8007
|
-
}
|
|
8008
|
-
);
|
|
8728
|
+
return createNamedSecretStore(canonicalizeResourceIndicator(resource), options, {
|
|
8729
|
+
salt: DEFAULT_FILE_SALT,
|
|
8730
|
+
directory: DEFAULT_FILE_DIRECTORY,
|
|
8731
|
+
service: DEFAULT_KEYCHAIN_SERVICE,
|
|
8732
|
+
accountPrefix: "provider"
|
|
8733
|
+
});
|
|
8009
8734
|
}
|
|
8010
8735
|
function createIssuerSecretStore(issuer, options) {
|
|
8011
|
-
return createNamedSecretStore(
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8018
|
-
accountPrefix: "issuer"
|
|
8019
|
-
}
|
|
8020
|
-
);
|
|
8736
|
+
return createNamedSecretStore(issuer, options, {
|
|
8737
|
+
salt: DEFAULT_CLIENT_FILE_SALT,
|
|
8738
|
+
directory: DEFAULT_CLIENT_FILE_DIRECTORY,
|
|
8739
|
+
service: DEFAULT_CLIENT_KEYCHAIN_SERVICE,
|
|
8740
|
+
accountPrefix: "issuer"
|
|
8741
|
+
});
|
|
8021
8742
|
}
|
|
8022
8743
|
function isObjectRecord(value) {
|
|
8023
8744
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8029,6 +8750,50 @@ function getOwnString(record, key2) {
|
|
|
8029
8750
|
const value = getOwnEntry4(record, key2);
|
|
8030
8751
|
return typeof value === "string" ? value : void 0;
|
|
8031
8752
|
}
|
|
8753
|
+
function isStoredOAuthSession(value) {
|
|
8754
|
+
if (!isObjectRecord(value)) {
|
|
8755
|
+
return false;
|
|
8756
|
+
}
|
|
8757
|
+
return isNonBlankOwnString(value, "resource") && isNonBlankOwnString(value, "authorizationServer") && isStoredOAuthClient(getOwnEntry4(value, "client")) && isStoredOAuthDiscovery(getOwnEntry4(value, "discovery")) && isStoredOAuthTokensOrMissing(getOwnEntry4(value, "tokens"));
|
|
8758
|
+
}
|
|
8759
|
+
function isStoredOAuthClient(value) {
|
|
8760
|
+
if (!isObjectRecord(value) || !isNonBlankOwnString(value, "clientId")) {
|
|
8761
|
+
return false;
|
|
8762
|
+
}
|
|
8763
|
+
const clientSecret = getOwnEntry4(value, "clientSecret");
|
|
8764
|
+
return clientSecret === void 0 || typeof clientSecret === "string" && clientSecret.trim().length > 0;
|
|
8765
|
+
}
|
|
8766
|
+
function isStoredOAuthDiscovery(value) {
|
|
8767
|
+
if (!isObjectRecord(value)) {
|
|
8768
|
+
return false;
|
|
8769
|
+
}
|
|
8770
|
+
return isNonBlankOwnString(value, "resourceMetadataUrl") && isObjectRecord(getOwnEntry4(value, "resourceMetadata")) && isObjectRecord(getOwnEntry4(value, "authorizationServerMetadata"));
|
|
8771
|
+
}
|
|
8772
|
+
function isStoredOAuthTokensOrMissing(value) {
|
|
8773
|
+
if (value === void 0) {
|
|
8774
|
+
return true;
|
|
8775
|
+
}
|
|
8776
|
+
if (!isObjectRecord(value)) {
|
|
8777
|
+
return false;
|
|
8778
|
+
}
|
|
8779
|
+
if (!isNonBlankOwnString(value, "accessToken") || getOwnString(value, "tokenType") !== "Bearer") {
|
|
8780
|
+
return false;
|
|
8781
|
+
}
|
|
8782
|
+
const expiresAt = getOwnEntry4(value, "expiresAt");
|
|
8783
|
+
if (expiresAt !== null && (typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS || !Number.isFinite(new Date(expiresAt).getTime()))) {
|
|
8784
|
+
return false;
|
|
8785
|
+
}
|
|
8786
|
+
const refreshToken = getOwnEntry4(value, "refreshToken");
|
|
8787
|
+
if (refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
|
|
8788
|
+
return false;
|
|
8789
|
+
}
|
|
8790
|
+
const scope = getOwnEntry4(value, "scope");
|
|
8791
|
+
return scope === void 0 || typeof scope === "string" && scope.trim().length > 0;
|
|
8792
|
+
}
|
|
8793
|
+
function isNonBlankOwnString(record, key2) {
|
|
8794
|
+
const value = getOwnString(record, key2);
|
|
8795
|
+
return value !== void 0 && value.trim().length > 0;
|
|
8796
|
+
}
|
|
8032
8797
|
|
|
8033
8798
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
8034
8799
|
import { URL as URL2 } from "node:url";
|
|
@@ -8139,9 +8904,7 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8139
8904
|
} catch (error3) {
|
|
8140
8905
|
res.writeHead(400);
|
|
8141
8906
|
res.end(error3 instanceof Error ? error3.message : "Invalid OAuth callback");
|
|
8142
|
-
|
|
8143
|
-
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8144
|
-
}
|
|
8907
|
+
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
8145
8908
|
return;
|
|
8146
8909
|
}
|
|
8147
8910
|
const authorizationError = callbackParameters.error;
|
|
@@ -8153,7 +8916,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8153
8916
|
return;
|
|
8154
8917
|
}
|
|
8155
8918
|
try {
|
|
8156
|
-
const code = validateAuthorizationCallbackParameters(
|
|
8919
|
+
const code = validateAuthorizationCallbackParameters(
|
|
8920
|
+
callbackParameters,
|
|
8921
|
+
expectedAuthorization
|
|
8922
|
+
);
|
|
8157
8923
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
8158
8924
|
res.end(buildSuccessPage(options.landingPage));
|
|
8159
8925
|
settle(() => resolve(code));
|
|
@@ -8176,7 +8942,10 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
8176
8942
|
const description = callbackParameters.errorDescription ?? callbackParameters.error;
|
|
8177
8943
|
throw createAuthorizationError(callbackParameters.error, description);
|
|
8178
8944
|
}
|
|
8179
|
-
const code = validateAuthorizationCallbackParameters(
|
|
8945
|
+
const code = validateAuthorizationCallbackParameters(
|
|
8946
|
+
callbackParameters,
|
|
8947
|
+
expectedAuthorization
|
|
8948
|
+
);
|
|
8180
8949
|
settle(() => resolve(code));
|
|
8181
8950
|
} catch (error3) {
|
|
8182
8951
|
settle(() => reject(error3 instanceof Error ? error3 : new Error(String(error3))));
|
|
@@ -8281,6 +9050,7 @@ function generateCodeChallenge(verifier) {
|
|
|
8281
9050
|
}
|
|
8282
9051
|
|
|
8283
9052
|
// ../mcp-oauth/src/client/token-endpoint.ts
|
|
9053
|
+
var MAX_JS_DATE_MS2 = 864e13;
|
|
8284
9054
|
var OAuthError = class extends Error {
|
|
8285
9055
|
error;
|
|
8286
9056
|
errorDescription;
|
|
@@ -8358,22 +9128,32 @@ async function requestTokens(input) {
|
|
|
8358
9128
|
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
8359
9129
|
throw new Error("OAuth token response missing access_token");
|
|
8360
9130
|
}
|
|
9131
|
+
const normalizedAccessToken = accessToken.trim();
|
|
8361
9132
|
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
8362
9133
|
if (tokenType === null) {
|
|
8363
9134
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
8364
9135
|
}
|
|
8365
9136
|
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
8366
|
-
|
|
8367
|
-
|
|
9137
|
+
let expiresAt = null;
|
|
9138
|
+
if (expiresIn !== void 0) {
|
|
9139
|
+
if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || !Number.isInteger(expiresIn) || expiresIn < 0) {
|
|
9140
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9141
|
+
}
|
|
9142
|
+
expiresAt = input.now() + expiresIn * 1e3;
|
|
9143
|
+
if (!Number.isSafeInteger(expiresAt) || expiresAt > MAX_JS_DATE_MS2 || !Number.isFinite(new Date(expiresAt).getTime())) {
|
|
9144
|
+
throw new Error("OAuth token response has invalid expires_in");
|
|
9145
|
+
}
|
|
8368
9146
|
}
|
|
8369
9147
|
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
8370
9148
|
const scope = getOwnEntry6(payload, "scope");
|
|
9149
|
+
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
9150
|
+
const normalizedScope = typeof scope === "string" && scope.trim().length > 0 ? scope.trim() : void 0;
|
|
8371
9151
|
return {
|
|
8372
|
-
accessToken,
|
|
8373
|
-
refreshToken:
|
|
9152
|
+
accessToken: normalizedAccessToken,
|
|
9153
|
+
refreshToken: normalizedRefreshToken === void 0 ? void 0 : normalizedRefreshToken,
|
|
8374
9154
|
tokenType,
|
|
8375
|
-
expiresAt
|
|
8376
|
-
scope:
|
|
9155
|
+
expiresAt,
|
|
9156
|
+
scope: normalizedScope === void 0 ? void 0 : normalizedScope
|
|
8377
9157
|
};
|
|
8378
9158
|
}
|
|
8379
9159
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -8424,6 +9204,7 @@ function normalizeBearerTokenType(value) {
|
|
|
8424
9204
|
}
|
|
8425
9205
|
|
|
8426
9206
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
9207
|
+
var MAX_JS_DATE_MS3 = 864e13;
|
|
8427
9208
|
function createOAuthClientProvider(options) {
|
|
8428
9209
|
if (isProviderOptions(options)) {
|
|
8429
9210
|
return options.provider;
|
|
@@ -8588,7 +9369,12 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8588
9369
|
});
|
|
8589
9370
|
let resolvedClient = null;
|
|
8590
9371
|
try {
|
|
8591
|
-
resolvedClient = await resolveClient(
|
|
9372
|
+
resolvedClient = await resolveClient(
|
|
9373
|
+
currentSession,
|
|
9374
|
+
discovery,
|
|
9375
|
+
loopback.redirectUri,
|
|
9376
|
+
fetch2
|
|
9377
|
+
);
|
|
8592
9378
|
const sessionWithoutTokens = {
|
|
8593
9379
|
resource,
|
|
8594
9380
|
authorizationServer: discovery.authorizationServer,
|
|
@@ -8655,28 +9441,26 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8655
9441
|
return finalPromise;
|
|
8656
9442
|
}
|
|
8657
9443
|
async function resolveClient(existingSession, discovery, redirectUri, fetch2) {
|
|
9444
|
+
const configuredClient = normalizeConfiguredClient(options.client);
|
|
8658
9445
|
if (options.client.mode === "static") {
|
|
9446
|
+
if (configuredClient === null) {
|
|
9447
|
+
throw new Error("OAuth client_id must not be blank");
|
|
9448
|
+
}
|
|
8659
9449
|
return {
|
|
8660
9450
|
kind: "static",
|
|
8661
9451
|
fromStoredRegistration: false,
|
|
8662
|
-
client:
|
|
8663
|
-
clientId: options.client.clientId,
|
|
8664
|
-
clientSecret: options.client.clientSecret
|
|
8665
|
-
}
|
|
9452
|
+
client: configuredClient
|
|
8666
9453
|
};
|
|
8667
9454
|
}
|
|
8668
9455
|
const registrationEndpoint = getOwnString2(
|
|
8669
9456
|
discovery.authorizationServerMetadata,
|
|
8670
9457
|
"registration_endpoint"
|
|
8671
9458
|
);
|
|
8672
|
-
if (registrationEndpoint === void 0 &&
|
|
9459
|
+
if (registrationEndpoint === void 0 && configuredClient !== null) {
|
|
8673
9460
|
return {
|
|
8674
9461
|
kind: "static",
|
|
8675
9462
|
fromStoredRegistration: false,
|
|
8676
|
-
client:
|
|
8677
|
-
clientId: options.client.clientId,
|
|
8678
|
-
clientSecret: options.client.clientSecret
|
|
8679
|
-
}
|
|
9463
|
+
client: configuredClient
|
|
8680
9464
|
};
|
|
8681
9465
|
}
|
|
8682
9466
|
const storedClient = await loadRegisteredClient(discovery.authorizationServer);
|
|
@@ -8698,7 +9482,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8698
9482
|
throw new Error("Authorization server metadata is missing registration_endpoint");
|
|
8699
9483
|
}
|
|
8700
9484
|
if (existingSession !== null && existingSession.client.clientId.length > 0) {
|
|
8701
|
-
const isConfiguredStaticFallback =
|
|
9485
|
+
const isConfiguredStaticFallback = configuredClient !== null && existingSession.client.clientId === configuredClient.clientId && existingSession.client.clientSecret === configuredClient.clientSecret;
|
|
8702
9486
|
if (!isConfiguredStaticFallback) {
|
|
8703
9487
|
await saveRegisteredClient(discovery.authorizationServer, existingSession.client);
|
|
8704
9488
|
return {
|
|
@@ -8726,8 +9510,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
8726
9510
|
}
|
|
8727
9511
|
const clientSecret = getOwnString2(payload, "client_secret");
|
|
8728
9512
|
const registeredClient = {
|
|
8729
|
-
clientId,
|
|
8730
|
-
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
9513
|
+
clientId: clientId.trim(),
|
|
9514
|
+
clientSecret: clientSecret !== void 0 && clientSecret.trim().length > 0 ? clientSecret.trim() : void 0
|
|
8731
9515
|
};
|
|
8732
9516
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
8733
9517
|
return {
|
|
@@ -8840,14 +9624,16 @@ function normalizeStoredClient(value) {
|
|
|
8840
9624
|
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8841
9625
|
return null;
|
|
8842
9626
|
}
|
|
9627
|
+
const normalizedClientId = clientId.trim();
|
|
8843
9628
|
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8844
9629
|
if (clientSecret === void 0) {
|
|
8845
|
-
return { clientId };
|
|
9630
|
+
return { clientId: normalizedClientId };
|
|
8846
9631
|
}
|
|
8847
9632
|
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8848
9633
|
return null;
|
|
8849
9634
|
}
|
|
8850
|
-
|
|
9635
|
+
const normalizedClientSecret = clientSecret.trim();
|
|
9636
|
+
return { clientId: normalizedClientId, clientSecret: normalizedClientSecret };
|
|
8851
9637
|
}
|
|
8852
9638
|
function normalizeStoredTokens(value) {
|
|
8853
9639
|
if (value === void 0 || !isObjectRecord3(value)) {
|
|
@@ -8858,20 +9644,45 @@ function normalizeStoredTokens(value) {
|
|
|
8858
9644
|
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8859
9645
|
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8860
9646
|
const scope = getOwnString2(value, "scope");
|
|
8861
|
-
const
|
|
8862
|
-
|
|
9647
|
+
const normalizedAccessToken = accessToken?.trim();
|
|
9648
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : void 0;
|
|
9649
|
+
const normalizedScope = scope?.trim();
|
|
9650
|
+
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)) {
|
|
8863
9651
|
return void 0;
|
|
8864
9652
|
}
|
|
8865
9653
|
return {
|
|
8866
|
-
accessToken,
|
|
9654
|
+
accessToken: normalizedAccessToken,
|
|
8867
9655
|
tokenType,
|
|
8868
9656
|
expiresAt,
|
|
8869
9657
|
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8870
|
-
...
|
|
9658
|
+
...normalizedScope === void 0 || normalizedScope.length === 0 ? {} : { scope: normalizedScope }
|
|
8871
9659
|
};
|
|
8872
9660
|
}
|
|
8873
9661
|
function getClientMetadata(client) {
|
|
8874
|
-
|
|
9662
|
+
if (client.metadata === void 0) {
|
|
9663
|
+
return void 0;
|
|
9664
|
+
}
|
|
9665
|
+
return {
|
|
9666
|
+
clientName: normalizeOptionalOAuthString(client.metadata.clientName),
|
|
9667
|
+
scope: normalizeOptionalOAuthString(client.metadata.scope),
|
|
9668
|
+
softwareId: normalizeOptionalOAuthString(client.metadata.softwareId),
|
|
9669
|
+
softwareVersion: normalizeOptionalOAuthString(client.metadata.softwareVersion)
|
|
9670
|
+
};
|
|
9671
|
+
}
|
|
9672
|
+
function normalizeConfiguredClient(client) {
|
|
9673
|
+
const clientId = normalizeOptionalOAuthString(client.clientId);
|
|
9674
|
+
if (clientId === void 0) {
|
|
9675
|
+
return null;
|
|
9676
|
+
}
|
|
9677
|
+
const clientSecret = normalizeOptionalOAuthString(client.clientSecret);
|
|
9678
|
+
return clientSecret === void 0 ? { clientId } : { clientId, clientSecret };
|
|
9679
|
+
}
|
|
9680
|
+
function normalizeOptionalOAuthString(value) {
|
|
9681
|
+
if (value === void 0) {
|
|
9682
|
+
return void 0;
|
|
9683
|
+
}
|
|
9684
|
+
const trimmed = value.trim();
|
|
9685
|
+
return trimmed.length === 0 ? void 0 : trimmed;
|
|
8875
9686
|
}
|
|
8876
9687
|
function getOwnEntry7(record, key2) {
|
|
8877
9688
|
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
@@ -8900,11 +9711,7 @@ function buildAuthorizationUrl(input) {
|
|
|
8900
9711
|
"authorization_endpoint",
|
|
8901
9712
|
"Authorization server metadata"
|
|
8902
9713
|
);
|
|
8903
|
-
const issuer = requireOwnString(
|
|
8904
|
-
input.metadata,
|
|
8905
|
-
"issuer",
|
|
8906
|
-
"Authorization server metadata"
|
|
8907
|
-
);
|
|
9714
|
+
const issuer = requireOwnString(input.metadata, "issuer", "Authorization server metadata");
|
|
8908
9715
|
const url = new URL2(authorizationEndpoint);
|
|
8909
9716
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
8910
9717
|
const state = createAuthorizationState({
|
|
@@ -9512,7 +10319,7 @@ var McpClient = class {
|
|
|
9512
10319
|
await onToolsChanged();
|
|
9513
10320
|
});
|
|
9514
10321
|
messageLayer.onNotification("notifications/resources/list_changed", async () => {
|
|
9515
|
-
if (onResourcesChanged === void 0) {
|
|
10322
|
+
if (onResourcesChanged === void 0 || this.currentServerCapabilities?.resources?.listChanged !== true) {
|
|
9516
10323
|
return;
|
|
9517
10324
|
}
|
|
9518
10325
|
await onResourcesChanged();
|
|
@@ -9531,7 +10338,7 @@ var McpClient = class {
|
|
|
9531
10338
|
await onResourceUpdated(uri);
|
|
9532
10339
|
});
|
|
9533
10340
|
messageLayer.onNotification("notifications/prompts/list_changed", async () => {
|
|
9534
|
-
if (onPromptsChanged === void 0) {
|
|
10341
|
+
if (onPromptsChanged === void 0 || this.currentServerCapabilities?.prompts?.listChanged !== true) {
|
|
9535
10342
|
return;
|
|
9536
10343
|
}
|
|
9537
10344
|
await onPromptsChanged();
|
|
@@ -9762,7 +10569,11 @@ var McpClient = class {
|
|
|
9762
10569
|
throw new Error("Server does not support resources");
|
|
9763
10570
|
}
|
|
9764
10571
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9765
|
-
|
|
10572
|
+
const result = await messageLayer.sendRequest("resources/list", requestParams);
|
|
10573
|
+
if (!isResourcesListResult(result)) {
|
|
10574
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/list result");
|
|
10575
|
+
}
|
|
10576
|
+
return result;
|
|
9766
10577
|
}
|
|
9767
10578
|
async listResourceTemplates(params17 = {}) {
|
|
9768
10579
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9771,7 +10582,11 @@ var McpClient = class {
|
|
|
9771
10582
|
throw new Error("Server does not support resources");
|
|
9772
10583
|
}
|
|
9773
10584
|
const requestParams = params17.cursor === void 0 ? void 0 : { cursor: params17.cursor };
|
|
9774
|
-
|
|
10585
|
+
const result = await messageLayer.sendRequest("resources/templates/list", requestParams);
|
|
10586
|
+
if (!isResourceTemplatesListResult(result)) {
|
|
10587
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/templates/list result");
|
|
10588
|
+
}
|
|
10589
|
+
return result;
|
|
9775
10590
|
}
|
|
9776
10591
|
async readResource(params17) {
|
|
9777
10592
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9779,7 +10594,11 @@ var McpClient = class {
|
|
|
9779
10594
|
if (serverCapabilities.resources === void 0) {
|
|
9780
10595
|
throw new Error("Server does not support resources");
|
|
9781
10596
|
}
|
|
9782
|
-
|
|
10597
|
+
const result = await messageLayer.sendRequest("resources/read", params17);
|
|
10598
|
+
if (!isReadResourceResult(result)) {
|
|
10599
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid resources/read result");
|
|
10600
|
+
}
|
|
10601
|
+
return result;
|
|
9783
10602
|
}
|
|
9784
10603
|
async subscribe(uri) {
|
|
9785
10604
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9814,7 +10633,11 @@ var McpClient = class {
|
|
|
9814
10633
|
if (serverCapabilities.prompts === void 0) {
|
|
9815
10634
|
throw new Error("Server does not support prompts");
|
|
9816
10635
|
}
|
|
9817
|
-
|
|
10636
|
+
const result = await messageLayer.sendRequest("prompts/get", params17);
|
|
10637
|
+
if (!isGetPromptResult(result)) {
|
|
10638
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid prompts/get result");
|
|
10639
|
+
}
|
|
10640
|
+
return result;
|
|
9818
10641
|
}
|
|
9819
10642
|
async complete(params17) {
|
|
9820
10643
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -9822,7 +10645,11 @@ var McpClient = class {
|
|
|
9822
10645
|
if (serverCapabilities.completions === void 0) {
|
|
9823
10646
|
throw new Error("Server does not support completions");
|
|
9824
10647
|
}
|
|
9825
|
-
|
|
10648
|
+
const result = await messageLayer.sendRequest("completion/complete", params17);
|
|
10649
|
+
if (!isCompleteResult(result)) {
|
|
10650
|
+
throw new McpError(ERROR_INVALID_REQUEST, "Invalid completion/complete result");
|
|
10651
|
+
}
|
|
10652
|
+
return result;
|
|
9826
10653
|
}
|
|
9827
10654
|
async setLogLevel(level) {
|
|
9828
10655
|
const messageLayer = this.getMessageLayerOrThrow();
|
|
@@ -10813,6 +11640,44 @@ function isCallToolResult(value) {
|
|
|
10813
11640
|
function isToolsListResult(value) {
|
|
10814
11641
|
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
10815
11642
|
}
|
|
11643
|
+
function isResourcesListResult(value) {
|
|
11644
|
+
return isObjectRecord5(value) && Array.isArray(value.resources) && value.resources.every(isResource) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11645
|
+
}
|
|
11646
|
+
function isResourceTemplatesListResult(value) {
|
|
11647
|
+
return isObjectRecord5(value) && Array.isArray(value.resourceTemplates) && value.resourceTemplates.every(isResourceTemplate) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
11648
|
+
}
|
|
11649
|
+
function isReadResourceResult(value) {
|
|
11650
|
+
return isObjectRecord5(value) && Array.isArray(value.contents) && value.contents.every(isResourceContents);
|
|
11651
|
+
}
|
|
11652
|
+
function isGetPromptResult(value) {
|
|
11653
|
+
return isObjectRecord5(value) && (value.description === void 0 || typeof value.description === "string") && Array.isArray(value.messages) && value.messages.every(isPromptMessage);
|
|
11654
|
+
}
|
|
11655
|
+
function isCompleteResult(value) {
|
|
11656
|
+
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");
|
|
11657
|
+
}
|
|
11658
|
+
function isResource(value) {
|
|
11659
|
+
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");
|
|
11660
|
+
}
|
|
11661
|
+
function isResourceTemplate(value) {
|
|
11662
|
+
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");
|
|
11663
|
+
}
|
|
11664
|
+
function isResourceContents(value) {
|
|
11665
|
+
if (!isObjectRecord5(value) || typeof value.uri !== "string") {
|
|
11666
|
+
return false;
|
|
11667
|
+
}
|
|
11668
|
+
if (value.mimeType !== void 0 && typeof value.mimeType !== "string") {
|
|
11669
|
+
return false;
|
|
11670
|
+
}
|
|
11671
|
+
const hasText = value.text !== void 0;
|
|
11672
|
+
const hasBlob = value.blob !== void 0;
|
|
11673
|
+
if (!hasText && !hasBlob) {
|
|
11674
|
+
return false;
|
|
11675
|
+
}
|
|
11676
|
+
return (!hasText || typeof value.text === "string") && (!hasBlob || typeof value.blob === "string");
|
|
11677
|
+
}
|
|
11678
|
+
function isPromptMessage(value) {
|
|
11679
|
+
return isObjectRecord5(value) && (value.role === "user" || value.role === "assistant") && isContentItem(value.content);
|
|
11680
|
+
}
|
|
10816
11681
|
function isContentItem(value) {
|
|
10817
11682
|
if (!isObjectRecord5(value)) {
|
|
10818
11683
|
return false;
|
|
@@ -10826,7 +11691,7 @@ function isContentItem(value) {
|
|
|
10826
11691
|
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
10827
11692
|
return false;
|
|
10828
11693
|
}
|
|
10829
|
-
return
|
|
11694
|
+
return isResourceContents(value.resource);
|
|
10830
11695
|
}
|
|
10831
11696
|
function hasOwn(value, property) {
|
|
10832
11697
|
return Object.prototype.hasOwnProperty.call(value, property);
|
|
@@ -10966,13 +11831,13 @@ function convertJsonSchema(schema) {
|
|
|
10966
11831
|
}
|
|
10967
11832
|
return convertSchema(schema, schema, []);
|
|
10968
11833
|
}
|
|
10969
|
-
function convertSchema(schema, root,
|
|
10970
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
11834
|
+
function convertSchema(schema, root, path25) {
|
|
11835
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path25);
|
|
10971
11836
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
10972
11837
|
const composition = getComposition(normalizedSchema.schema);
|
|
10973
11838
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
10974
11839
|
throw new Error(
|
|
10975
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
11840
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
10976
11841
|
normalizedSchema.schema.type
|
|
10977
11842
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
10978
11843
|
);
|
|
@@ -10984,13 +11849,13 @@ function convertSchema(schema, root, path24) {
|
|
|
10984
11849
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
10985
11850
|
}
|
|
10986
11851
|
if (composition !== void 0) {
|
|
10987
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
11852
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path25);
|
|
10988
11853
|
}
|
|
10989
11854
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
10990
11855
|
return applyMetadata(
|
|
10991
11856
|
S.Record(
|
|
10992
11857
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
10993
|
-
...
|
|
11858
|
+
...path25,
|
|
10994
11859
|
"additionalProperties"
|
|
10995
11860
|
])
|
|
10996
11861
|
),
|
|
@@ -11039,12 +11904,12 @@ function convertSchema(schema, root, path24) {
|
|
|
11039
11904
|
if (normalizedSchema.schema.items === void 0) {
|
|
11040
11905
|
throw new Error(
|
|
11041
11906
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11042
|
-
|
|
11907
|
+
path25
|
|
11043
11908
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
11044
11909
|
);
|
|
11045
11910
|
}
|
|
11046
11911
|
return S.Array(
|
|
11047
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
11912
|
+
convertSchema(normalizedSchema.schema.items, root, [...path25, "items"]),
|
|
11048
11913
|
createCommonOptions(
|
|
11049
11914
|
normalizedSchema.schema,
|
|
11050
11915
|
normalizedSchema.nullable,
|
|
@@ -11054,7 +11919,7 @@ function convertSchema(schema, root, path24) {
|
|
|
11054
11919
|
case "object":
|
|
11055
11920
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
11056
11921
|
nullable: normalizedSchema.nullable,
|
|
11057
|
-
path:
|
|
11922
|
+
path: path25
|
|
11058
11923
|
});
|
|
11059
11924
|
case "null":
|
|
11060
11925
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -11069,12 +11934,12 @@ function convertSchema(schema, root, path24) {
|
|
|
11069
11934
|
}
|
|
11070
11935
|
throw new Error(
|
|
11071
11936
|
`JSON Schema "${formatJsonSchemaPath(
|
|
11072
|
-
|
|
11937
|
+
path25
|
|
11073
11938
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
11074
11939
|
);
|
|
11075
11940
|
}
|
|
11076
11941
|
throw new Error(
|
|
11077
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
11942
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
11078
11943
|
normalizedSchema.schema.type
|
|
11079
11944
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
11080
11945
|
);
|
|
@@ -11118,21 +11983,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
11118
11983
|
)
|
|
11119
11984
|
});
|
|
11120
11985
|
}
|
|
11121
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
11986
|
+
function convertCompositionSchema(schema, root, nullable, path25) {
|
|
11122
11987
|
const composition = getComposition(schema);
|
|
11123
11988
|
const branchSchemas = composition?.branches ?? [];
|
|
11124
11989
|
const keyword = composition?.keyword ?? "oneOf";
|
|
11125
11990
|
const branches = branchSchemas.map(
|
|
11126
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
11991
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path25, keyword, String(index)])
|
|
11127
11992
|
);
|
|
11128
|
-
const discriminator = findDiscriminator(branches, root,
|
|
11993
|
+
const discriminator = findDiscriminator(branches, root, path25);
|
|
11129
11994
|
if (discriminator !== void 0) {
|
|
11130
11995
|
const convertedBranches = Object.fromEntries(
|
|
11131
11996
|
branches.map((branch, index) => [
|
|
11132
11997
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
11133
11998
|
convertObjectSchema(branch, root, {
|
|
11134
11999
|
omitProperty: discriminator,
|
|
11135
|
-
path: [...
|
|
12000
|
+
path: [...path25, keyword, String(index)]
|
|
11136
12001
|
})
|
|
11137
12002
|
])
|
|
11138
12003
|
);
|
|
@@ -11151,7 +12016,7 @@ function convertCompositionSchema(schema, root, nullable, path24) {
|
|
|
11151
12016
|
S.Union(
|
|
11152
12017
|
branches.map(
|
|
11153
12018
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
11154
|
-
path: [...
|
|
12019
|
+
path: [...path25, keyword, String(index)]
|
|
11155
12020
|
})
|
|
11156
12021
|
)
|
|
11157
12022
|
),
|
|
@@ -11265,11 +12130,11 @@ function getComposition(schema) {
|
|
|
11265
12130
|
}
|
|
11266
12131
|
return void 0;
|
|
11267
12132
|
}
|
|
11268
|
-
function formatJsonSchemaPath(
|
|
11269
|
-
if (
|
|
12133
|
+
function formatJsonSchemaPath(path25) {
|
|
12134
|
+
if (path25.length === 0) {
|
|
11270
12135
|
return "#";
|
|
11271
12136
|
}
|
|
11272
|
-
return `#/${
|
|
12137
|
+
return `#/${path25.map(escapeJsonPointerSegment).join("/")}`;
|
|
11273
12138
|
}
|
|
11274
12139
|
function formatJsonSchemaType(type2) {
|
|
11275
12140
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -11285,11 +12150,11 @@ function isRecordSchema(schema) {
|
|
|
11285
12150
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
11286
12151
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
11287
12152
|
}
|
|
11288
|
-
function findDiscriminator(branches, root,
|
|
12153
|
+
function findDiscriminator(branches, root, path25) {
|
|
11289
12154
|
const [firstBranch] = branches;
|
|
11290
12155
|
if (firstBranch === void 0) {
|
|
11291
12156
|
throw new Error(
|
|
11292
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12157
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
11293
12158
|
);
|
|
11294
12159
|
}
|
|
11295
12160
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -11329,19 +12194,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
11329
12194
|
}
|
|
11330
12195
|
return void 0;
|
|
11331
12196
|
}
|
|
11332
|
-
function resolveReferencedSchema(schema, root,
|
|
12197
|
+
function resolveReferencedSchema(schema, root, path25) {
|
|
11333
12198
|
if (schema.$ref === void 0) {
|
|
11334
12199
|
return schema;
|
|
11335
12200
|
}
|
|
11336
12201
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
11337
12202
|
if (resolvedTarget === void 0) {
|
|
11338
12203
|
throw new Error(
|
|
11339
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
12204
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
11340
12205
|
);
|
|
11341
12206
|
}
|
|
11342
12207
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
11343
12208
|
void ignoredRef;
|
|
11344
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
12209
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path25);
|
|
11345
12210
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
11346
12211
|
return resolvedSchema;
|
|
11347
12212
|
}
|
|
@@ -11365,9 +12230,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
11365
12230
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
11366
12231
|
};
|
|
11367
12232
|
}
|
|
11368
|
-
function hasSelfReferencingRef(schema, root,
|
|
12233
|
+
function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
11369
12234
|
const nextActivePaths = new Set(activePaths);
|
|
11370
|
-
nextActivePaths.add(
|
|
12235
|
+
nextActivePaths.add(path25);
|
|
11371
12236
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
11372
12237
|
if (localRefPath !== void 0) {
|
|
11373
12238
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -11378,13 +12243,13 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11378
12243
|
return true;
|
|
11379
12244
|
}
|
|
11380
12245
|
}
|
|
11381
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
12246
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path25}/items`, nextActivePaths)) {
|
|
11382
12247
|
return true;
|
|
11383
12248
|
}
|
|
11384
12249
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
11385
12250
|
schema.additionalProperties,
|
|
11386
12251
|
root,
|
|
11387
|
-
`${
|
|
12252
|
+
`${path25}/additionalProperties`,
|
|
11388
12253
|
nextActivePaths
|
|
11389
12254
|
)) {
|
|
11390
12255
|
return true;
|
|
@@ -11393,7 +12258,7 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11393
12258
|
if (hasSelfReferencingRef(
|
|
11394
12259
|
childSchema,
|
|
11395
12260
|
root,
|
|
11396
|
-
`${
|
|
12261
|
+
`${path25}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
11397
12262
|
nextActivePaths
|
|
11398
12263
|
)) {
|
|
11399
12264
|
return true;
|
|
@@ -11403,24 +12268,24 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
11403
12268
|
if (hasSelfReferencingRef(
|
|
11404
12269
|
childSchema,
|
|
11405
12270
|
root,
|
|
11406
|
-
`${
|
|
12271
|
+
`${path25}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
11407
12272
|
nextActivePaths
|
|
11408
12273
|
)) {
|
|
11409
12274
|
return true;
|
|
11410
12275
|
}
|
|
11411
12276
|
}
|
|
11412
12277
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
11413
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12278
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/oneOf/${index}`, nextActivePaths)) {
|
|
11414
12279
|
return true;
|
|
11415
12280
|
}
|
|
11416
12281
|
}
|
|
11417
12282
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
11418
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12283
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/anyOf/${index}`, nextActivePaths)) {
|
|
11419
12284
|
return true;
|
|
11420
12285
|
}
|
|
11421
12286
|
}
|
|
11422
12287
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
11423
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
12288
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/allOf/${index}`, nextActivePaths)) {
|
|
11424
12289
|
return true;
|
|
11425
12290
|
}
|
|
11426
12291
|
}
|
|
@@ -11436,14 +12301,14 @@ function getLocalRefPath(ref) {
|
|
|
11436
12301
|
return ref.startsWith("#/") ? ref : void 0;
|
|
11437
12302
|
}
|
|
11438
12303
|
function resolveLocalRef(root, ref) {
|
|
11439
|
-
const
|
|
11440
|
-
if (
|
|
12304
|
+
const path25 = getLocalRefPath(ref);
|
|
12305
|
+
if (path25 === void 0) {
|
|
11441
12306
|
return void 0;
|
|
11442
12307
|
}
|
|
11443
|
-
if (
|
|
12308
|
+
if (path25 === "#") {
|
|
11444
12309
|
return root;
|
|
11445
12310
|
}
|
|
11446
|
-
const segments =
|
|
12311
|
+
const segments = path25.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
11447
12312
|
let current = root;
|
|
11448
12313
|
for (const segment of segments) {
|
|
11449
12314
|
if (Array.isArray(current)) {
|
|
@@ -11489,15 +12354,15 @@ function getBooleanDefault(value) {
|
|
|
11489
12354
|
return typeof value === "boolean" ? value : void 0;
|
|
11490
12355
|
}
|
|
11491
12356
|
function getArrayDefault(value) {
|
|
11492
|
-
return Array.isArray(value) && value.every((item) =>
|
|
12357
|
+
return Array.isArray(value) && value.every((item) => isJsonValue2(item)) ? value : void 0;
|
|
11493
12358
|
}
|
|
11494
12359
|
function getPrimitiveEnumDefault(value, candidates) {
|
|
11495
12360
|
return isPrimitiveEnumValue(value) && candidates.includes(value) ? value : void 0;
|
|
11496
12361
|
}
|
|
11497
12362
|
function getJsonDefault(value) {
|
|
11498
|
-
return
|
|
12363
|
+
return isJsonValue2(value) ? value : void 0;
|
|
11499
12364
|
}
|
|
11500
|
-
function
|
|
12365
|
+
function isJsonValue2(value) {
|
|
11501
12366
|
if (value === null) {
|
|
11502
12367
|
return true;
|
|
11503
12368
|
}
|
|
@@ -11505,12 +12370,12 @@ function isJsonValue(value) {
|
|
|
11505
12370
|
return true;
|
|
11506
12371
|
}
|
|
11507
12372
|
if (Array.isArray(value)) {
|
|
11508
|
-
return value.every((item) =>
|
|
12373
|
+
return value.every((item) => isJsonValue2(item));
|
|
11509
12374
|
}
|
|
11510
12375
|
if (!isPlainObject(value)) {
|
|
11511
12376
|
return false;
|
|
11512
12377
|
}
|
|
11513
|
-
return Object.values(value).every((item) =>
|
|
12378
|
+
return Object.values(value).every((item) => isJsonValue2(item));
|
|
11514
12379
|
}
|
|
11515
12380
|
function isPlainObject(value) {
|
|
11516
12381
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -11700,7 +12565,7 @@ async function ensureConnected(connection) {
|
|
|
11700
12565
|
async function readCache(cachePath) {
|
|
11701
12566
|
try {
|
|
11702
12567
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
11703
|
-
const raw = await
|
|
12568
|
+
const raw = await readFile4(cachePath, "utf8");
|
|
11704
12569
|
const parsed = JSON.parse(raw);
|
|
11705
12570
|
if (parsed === null || typeof parsed !== "object" || !Array.isArray(parsed.tools) || parsed.upstream === void 0 || typeof parsed.upstream.name !== "string" || typeof parsed.upstream.version !== "string") {
|
|
11706
12571
|
return void 0;
|
|
@@ -11721,7 +12586,7 @@ async function readCache(cachePath) {
|
|
|
11721
12586
|
}
|
|
11722
12587
|
}
|
|
11723
12588
|
async function writeCache(cachePath, cache) {
|
|
11724
|
-
const directory =
|
|
12589
|
+
const directory = path13.dirname(cachePath);
|
|
11725
12590
|
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
11726
12591
|
let tempCreated = false;
|
|
11727
12592
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
@@ -11918,13 +12783,13 @@ function collectProxyGroups(root) {
|
|
|
11918
12783
|
function findProjectRoot(from = process.cwd()) {
|
|
11919
12784
|
let current = process.cwd();
|
|
11920
12785
|
if (from !== current) {
|
|
11921
|
-
current =
|
|
12786
|
+
current = path13.resolve(from);
|
|
11922
12787
|
}
|
|
11923
12788
|
while (true) {
|
|
11924
|
-
if (existsSync2(
|
|
12789
|
+
if (existsSync2(path13.join(current, "package.json"))) {
|
|
11925
12790
|
return current;
|
|
11926
12791
|
}
|
|
11927
|
-
const parent =
|
|
12792
|
+
const parent = path13.dirname(current);
|
|
11928
12793
|
if (parent === current) {
|
|
11929
12794
|
return void 0;
|
|
11930
12795
|
}
|
|
@@ -11941,7 +12806,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
11941
12806
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
11942
12807
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
11943
12808
|
}
|
|
11944
|
-
return
|
|
12809
|
+
return path13.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
11945
12810
|
}
|
|
11946
12811
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
11947
12812
|
let currentPath = filePath;
|
|
@@ -11955,10 +12820,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
11955
12820
|
throw error3;
|
|
11956
12821
|
}
|
|
11957
12822
|
}
|
|
11958
|
-
if (
|
|
12823
|
+
if (path13.basename(currentPath) === ".toolcraft") {
|
|
11959
12824
|
return;
|
|
11960
12825
|
}
|
|
11961
|
-
const parentPath =
|
|
12826
|
+
const parentPath = path13.dirname(currentPath);
|
|
11962
12827
|
if (parentPath === currentPath) {
|
|
11963
12828
|
return;
|
|
11964
12829
|
}
|
|
@@ -12104,20 +12969,20 @@ function reportsEnabled(option, env) {
|
|
|
12104
12969
|
function resolveReportDir(option, projectRoot) {
|
|
12105
12970
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12106
12971
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
12107
|
-
return
|
|
12972
|
+
return path14.join(projectRoot, ".toolcraft", "errors");
|
|
12108
12973
|
}
|
|
12109
|
-
return
|
|
12974
|
+
return path14.isAbsolute(configuredDir) ? configuredDir : path14.join(projectRoot, configuredDir);
|
|
12110
12975
|
}
|
|
12111
12976
|
function reportDirMustStayWithinProject(option) {
|
|
12112
12977
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
12113
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
12978
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path14.isAbsolute(configuredDir);
|
|
12114
12979
|
}
|
|
12115
12980
|
function isWithinDirectory(parent, child) {
|
|
12116
|
-
const relative =
|
|
12117
|
-
return relative === "" || !
|
|
12981
|
+
const relative = path14.relative(parent, child);
|
|
12982
|
+
return relative === "" || !path14.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path14.sep}`);
|
|
12118
12983
|
}
|
|
12119
12984
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
12120
|
-
if (!isWithinDirectory(
|
|
12985
|
+
if (!isWithinDirectory(path14.resolve(projectRoot), path14.resolve(reportDir))) {
|
|
12121
12986
|
throw new Error("Error report directory resolves outside project root.");
|
|
12122
12987
|
}
|
|
12123
12988
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
@@ -12168,7 +13033,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
12168
13033
|
return output.length === 0 ? "root" : output;
|
|
12169
13034
|
}
|
|
12170
13035
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
12171
|
-
const relative =
|
|
13036
|
+
const relative = path14.relative(projectRoot, absolutePath);
|
|
12172
13037
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
12173
13038
|
}
|
|
12174
13039
|
function redactValue(value) {
|
|
@@ -12488,7 +13353,7 @@ async function writeErrorReport(context) {
|
|
|
12488
13353
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
12489
13354
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
12490
13355
|
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
12491
|
-
const absolutePath =
|
|
13356
|
+
const absolutePath = path14.join(reportDir, fileName);
|
|
12492
13357
|
await mkdir2(reportDir, { recursive: true });
|
|
12493
13358
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
12494
13359
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -12958,7 +13823,7 @@ function inferProgramName(argv) {
|
|
|
12958
13823
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
12959
13824
|
return "toolcraft";
|
|
12960
13825
|
}
|
|
12961
|
-
const parsed =
|
|
13826
|
+
const parsed = path15.parse(entrypoint);
|
|
12962
13827
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
12963
13828
|
}
|
|
12964
13829
|
function normalizeRoots(roots, argv) {
|
|
@@ -13016,11 +13881,11 @@ function formatSegment(segment, casing) {
|
|
|
13016
13881
|
const separator = casing === "snake" ? "_" : "-";
|
|
13017
13882
|
return splitWords3(segment).join(separator);
|
|
13018
13883
|
}
|
|
13019
|
-
function toOptionFlag(
|
|
13020
|
-
return `--${
|
|
13884
|
+
function toOptionFlag(path25, casing) {
|
|
13885
|
+
return `--${path25.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
13021
13886
|
}
|
|
13022
|
-
function toOptionAttribute(
|
|
13023
|
-
return
|
|
13887
|
+
function toOptionAttribute(path25, casing) {
|
|
13888
|
+
return path25.map((segment) => {
|
|
13024
13889
|
const formatted = formatSegment(segment, casing);
|
|
13025
13890
|
if (casing === "snake") {
|
|
13026
13891
|
return formatted;
|
|
@@ -13031,23 +13896,23 @@ function toOptionAttribute(path24, casing) {
|
|
|
13031
13896
|
).join("");
|
|
13032
13897
|
}).join(".");
|
|
13033
13898
|
}
|
|
13034
|
-
function toDisplayPath(
|
|
13035
|
-
return
|
|
13899
|
+
function toDisplayPath(path25) {
|
|
13900
|
+
return path25.join(".");
|
|
13036
13901
|
}
|
|
13037
|
-
function toUnionKindControlPath(
|
|
13038
|
-
if (
|
|
13902
|
+
function toUnionKindControlPath(path25) {
|
|
13903
|
+
if (path25.length === 0) {
|
|
13039
13904
|
return ["kind"];
|
|
13040
13905
|
}
|
|
13041
|
-
const head =
|
|
13042
|
-
const tail =
|
|
13906
|
+
const head = path25.slice(0, -1);
|
|
13907
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
13043
13908
|
return [...head, `${tail}Kind`];
|
|
13044
13909
|
}
|
|
13045
|
-
function toUnionKindDisplayPath(
|
|
13046
|
-
if (
|
|
13910
|
+
function toUnionKindDisplayPath(path25) {
|
|
13911
|
+
if (path25.length === 0) {
|
|
13047
13912
|
return "kind";
|
|
13048
13913
|
}
|
|
13049
|
-
const head =
|
|
13050
|
-
const tail =
|
|
13914
|
+
const head = path25.slice(0, -1);
|
|
13915
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
13051
13916
|
return [...head, `${tail}-kind`].join(".");
|
|
13052
13917
|
}
|
|
13053
13918
|
function createSyntheticEnumSchema(values) {
|
|
@@ -13063,14 +13928,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
13063
13928
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
13064
13929
|
return requiredKeys.join("+");
|
|
13065
13930
|
}
|
|
13066
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
13931
|
+
function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inheritedOptional = false, variantContext) {
|
|
13067
13932
|
const collected = {
|
|
13068
13933
|
dynamicFields: [],
|
|
13069
13934
|
fields: [],
|
|
13070
13935
|
variants: []
|
|
13071
13936
|
};
|
|
13072
13937
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
13073
|
-
const nextPath = [...
|
|
13938
|
+
const nextPath = [...path25, key2];
|
|
13074
13939
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
13075
13940
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
13076
13941
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -13256,9 +14121,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inher
|
|
|
13256
14121
|
}
|
|
13257
14122
|
return collected;
|
|
13258
14123
|
}
|
|
13259
|
-
function toCommanderOptionAttribute(
|
|
13260
|
-
const optionAttribute = toOptionAttribute(
|
|
13261
|
-
const optionFlag = toOptionFlag(
|
|
14124
|
+
function toCommanderOptionAttribute(path25, casing, globalLongOptionFlags) {
|
|
14125
|
+
const optionAttribute = toOptionAttribute(path25, casing);
|
|
14126
|
+
const optionFlag = toOptionFlag(path25, casing);
|
|
13262
14127
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
13263
14128
|
return optionAttribute;
|
|
13264
14129
|
}
|
|
@@ -13531,6 +14396,20 @@ function parseArrayValue(value, schema, label) {
|
|
|
13531
14396
|
(item) => parseScalarValue(item, itemSchema, label)
|
|
13532
14397
|
);
|
|
13533
14398
|
}
|
|
14399
|
+
function isNegativeNumericArrayToken(token, schema) {
|
|
14400
|
+
if (!token.startsWith("-") || token.startsWith("--")) {
|
|
14401
|
+
return false;
|
|
14402
|
+
}
|
|
14403
|
+
const itemSchema = unwrapOptional2(schema.item);
|
|
14404
|
+
if (itemSchema.kind !== "number") {
|
|
14405
|
+
return false;
|
|
14406
|
+
}
|
|
14407
|
+
const items = splitArrayInput(token);
|
|
14408
|
+
return items.length > 0 && items.every((item) => isValidNumberSchemaValue(Number(item), itemSchema));
|
|
14409
|
+
}
|
|
14410
|
+
function isNextArrayOptionToken(token, schema) {
|
|
14411
|
+
return token.startsWith("-") && !isNegativeNumericArrayToken(token, schema);
|
|
14412
|
+
}
|
|
13534
14413
|
function validateArrayBounds(value, schema, label) {
|
|
13535
14414
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
13536
14415
|
throw new UserError(
|
|
@@ -14338,10 +15217,10 @@ function parseDebugStackMode(value) {
|
|
|
14338
15217
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
14339
15218
|
);
|
|
14340
15219
|
}
|
|
14341
|
-
function setNestedValue(target,
|
|
15220
|
+
function setNestedValue(target, path25, value) {
|
|
14342
15221
|
let cursor2 = target;
|
|
14343
|
-
for (let index = 0; index <
|
|
14344
|
-
const segment =
|
|
15222
|
+
for (let index = 0; index < path25.length - 1; index += 1) {
|
|
15223
|
+
const segment = path25[index] ?? "";
|
|
14345
15224
|
const existing = Object.prototype.hasOwnProperty.call(cursor2, segment) ? cursor2[segment] : void 0;
|
|
14346
15225
|
if (typeof existing === "object" && existing !== null) {
|
|
14347
15226
|
cursor2 = existing;
|
|
@@ -14356,7 +15235,7 @@ function setNestedValue(target, path24, value) {
|
|
|
14356
15235
|
});
|
|
14357
15236
|
cursor2 = next;
|
|
14358
15237
|
}
|
|
14359
|
-
const leaf =
|
|
15238
|
+
const leaf = path25[path25.length - 1];
|
|
14360
15239
|
if (leaf !== void 0) {
|
|
14361
15240
|
Object.defineProperty(cursor2, leaf, {
|
|
14362
15241
|
value,
|
|
@@ -14473,21 +15352,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
14473
15352
|
}
|
|
14474
15353
|
function createFs2() {
|
|
14475
15354
|
return {
|
|
14476
|
-
readFile: async (
|
|
14477
|
-
writeFile: async (
|
|
14478
|
-
await writeFile5(
|
|
15355
|
+
readFile: async (path25, encoding = "utf8") => readFile5(path25, { encoding }),
|
|
15356
|
+
writeFile: async (path25, contents, options) => {
|
|
15357
|
+
await writeFile5(path25, contents, options);
|
|
14479
15358
|
},
|
|
14480
|
-
exists: async (
|
|
15359
|
+
exists: async (path25) => {
|
|
14481
15360
|
try {
|
|
14482
|
-
await access2(
|
|
15361
|
+
await access2(path25);
|
|
14483
15362
|
return true;
|
|
14484
15363
|
} catch {
|
|
14485
15364
|
return false;
|
|
14486
15365
|
}
|
|
14487
15366
|
},
|
|
14488
|
-
lstat: async (
|
|
15367
|
+
lstat: async (path25) => lstat3(path25),
|
|
14489
15368
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
14490
|
-
unlink: async (
|
|
15369
|
+
unlink: async (path25) => unlink3(path25)
|
|
14491
15370
|
};
|
|
14492
15371
|
}
|
|
14493
15372
|
function createEnv2(values = process.env) {
|
|
@@ -14503,9 +15382,9 @@ function isPlainObject4(value) {
|
|
|
14503
15382
|
function hasFieldValue(value) {
|
|
14504
15383
|
return value !== void 0;
|
|
14505
15384
|
}
|
|
14506
|
-
function hasNestedField(fields,
|
|
15385
|
+
function hasNestedField(fields, path25) {
|
|
14507
15386
|
return fields.some(
|
|
14508
|
-
(field) =>
|
|
15387
|
+
(field) => path25.length < field.path.length && path25.every((segment, index) => field.path[index] === segment)
|
|
14509
15388
|
);
|
|
14510
15389
|
}
|
|
14511
15390
|
function describeExpectedPresetValue(schema) {
|
|
@@ -14608,7 +15487,7 @@ function validatePresetFieldValue(value, field, presetPath) {
|
|
|
14608
15487
|
async function loadPresetValues(fields, presetPath) {
|
|
14609
15488
|
let rawPreset;
|
|
14610
15489
|
try {
|
|
14611
|
-
rawPreset = await
|
|
15490
|
+
rawPreset = await readFile5(presetPath, {
|
|
14612
15491
|
encoding: "utf8"
|
|
14613
15492
|
});
|
|
14614
15493
|
} catch (error3) {
|
|
@@ -14634,9 +15513,9 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
14634
15513
|
}
|
|
14635
15514
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
14636
15515
|
const presetValues = {};
|
|
14637
|
-
function visitObject(current,
|
|
15516
|
+
function visitObject(current, path25) {
|
|
14638
15517
|
for (const [key2, value] of Object.entries(current)) {
|
|
14639
|
-
const nextPath = [...
|
|
15518
|
+
const nextPath = [...path25, key2];
|
|
14640
15519
|
const displayPath = toDisplayPath(nextPath);
|
|
14641
15520
|
const field = fieldByPath.get(displayPath);
|
|
14642
15521
|
if (field !== void 0) {
|
|
@@ -14843,8 +15722,8 @@ function createFixtureService(definition) {
|
|
|
14843
15722
|
);
|
|
14844
15723
|
}
|
|
14845
15724
|
function resolveFixturePath(commandPath) {
|
|
14846
|
-
const parsed =
|
|
14847
|
-
return
|
|
15725
|
+
const parsed = path15.parse(commandPath);
|
|
15726
|
+
return path15.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
14848
15727
|
}
|
|
14849
15728
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
14850
15729
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -14875,7 +15754,7 @@ async function loadFixtureScenario(command, selector) {
|
|
|
14875
15754
|
const fixturePath = resolveFixturePath(commandPath);
|
|
14876
15755
|
let rawFixture;
|
|
14877
15756
|
try {
|
|
14878
|
-
rawFixture = await
|
|
15757
|
+
rawFixture = await readFile5(fixturePath, {
|
|
14879
15758
|
encoding: "utf8"
|
|
14880
15759
|
});
|
|
14881
15760
|
} catch {
|
|
@@ -14978,8 +15857,8 @@ function validateServices(services) {
|
|
|
14978
15857
|
}
|
|
14979
15858
|
}
|
|
14980
15859
|
}
|
|
14981
|
-
function getNestedValue(target,
|
|
14982
|
-
return
|
|
15860
|
+
function getNestedValue(target, path25) {
|
|
15861
|
+
return path25.reduce(
|
|
14983
15862
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
14984
15863
|
target
|
|
14985
15864
|
);
|
|
@@ -15064,7 +15943,7 @@ function consumeFieldValue(args, index, schema, label, inlineValue) {
|
|
|
15064
15943
|
let cursor2 = index + 1;
|
|
15065
15944
|
while (cursor2 < args.length) {
|
|
15066
15945
|
const token = args[cursor2] ?? "";
|
|
15067
|
-
if (token
|
|
15946
|
+
if (isNextArrayOptionToken(token, schema)) {
|
|
15068
15947
|
break;
|
|
15069
15948
|
}
|
|
15070
15949
|
const parsed = parseArrayValue(token, schema, label);
|
|
@@ -15940,6 +16819,12 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
15940
16819
|
);
|
|
15941
16820
|
return;
|
|
15942
16821
|
}
|
|
16822
|
+
logger2.error(
|
|
16823
|
+
appendUsagePointer(formatCommanderErrorMessage(error3), {
|
|
16824
|
+
rootUsageName: options.rootUsageName,
|
|
16825
|
+
commandPath: options.commandPath.length > 0 ? options.commandPath : findCurrentCommanderCommandPath(options.program, options.argv ?? process.argv)
|
|
16826
|
+
})
|
|
16827
|
+
);
|
|
15943
16828
|
return;
|
|
15944
16829
|
}
|
|
15945
16830
|
if (isHttpErrorLike(error3)) {
|
|
@@ -15957,6 +16842,9 @@ This is a bug in toolcraft or in the command definition; it cannot be worked aro
|
|
|
15957
16842
|
}
|
|
15958
16843
|
process.exitCode = 1;
|
|
15959
16844
|
}
|
|
16845
|
+
function formatCommanderErrorMessage(error3) {
|
|
16846
|
+
return error3.message.startsWith("error:") ? error3.message : `error: ${error3.message}`;
|
|
16847
|
+
}
|
|
15960
16848
|
function formatInvalidEnumMessage(label, value, values, opts = {}) {
|
|
15961
16849
|
const suggestions = suggest(
|
|
15962
16850
|
value,
|
|
@@ -16281,7 +17169,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
|
|
|
16281
17169
|
// src/terminal-session.ts
|
|
16282
17170
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
16283
17171
|
import { accessSync, chmodSync, constants } from "node:fs";
|
|
16284
|
-
import { createRequire } from "node:module";
|
|
17172
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
16285
17173
|
import { dirname, join } from "node:path";
|
|
16286
17174
|
import * as nodePty from "node-pty";
|
|
16287
17175
|
|
|
@@ -17493,8 +18381,8 @@ var spawnHelperChecked = false;
|
|
|
17493
18381
|
function ensureSpawnHelperExecutable() {
|
|
17494
18382
|
if (spawnHelperChecked) return;
|
|
17495
18383
|
spawnHelperChecked = true;
|
|
17496
|
-
const
|
|
17497
|
-
const nodePtyDir = dirname(
|
|
18384
|
+
const require4 = createRequire2(import.meta.url);
|
|
18385
|
+
const nodePtyDir = dirname(require4.resolve("node-pty"));
|
|
17498
18386
|
const helper = join(nodePtyDir, "..", "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper");
|
|
17499
18387
|
try {
|
|
17500
18388
|
accessSync(helper, constants.X_OK);
|
|
@@ -17907,7 +18795,7 @@ var getSession = defineCommand({
|
|
|
17907
18795
|
|
|
17908
18796
|
// ../agent-skill-config/src/configs.ts
|
|
17909
18797
|
import os2 from "node:os";
|
|
17910
|
-
import
|
|
18798
|
+
import path16 from "node:path";
|
|
17911
18799
|
|
|
17912
18800
|
// ../agent-defs/src/agents/claude-code.ts
|
|
17913
18801
|
var claudeCodeAgent = {
|
|
@@ -18271,7 +19159,7 @@ var templateMutation = {
|
|
|
18271
19159
|
|
|
18272
19160
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
18273
19161
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18274
|
-
import
|
|
19162
|
+
import path18 from "node:path";
|
|
18275
19163
|
|
|
18276
19164
|
// ../config-mutations/src/formats/json.ts
|
|
18277
19165
|
import * as jsonc from "jsonc-parser";
|
|
@@ -18394,22 +19282,22 @@ function prune(obj, shape) {
|
|
|
18394
19282
|
}
|
|
18395
19283
|
return { changed, result };
|
|
18396
19284
|
}
|
|
18397
|
-
function modifyAtPath(content,
|
|
19285
|
+
function modifyAtPath(content, path25, value) {
|
|
18398
19286
|
const indent = detectIndent(content);
|
|
18399
19287
|
const formattingOptions = {
|
|
18400
19288
|
tabSize: indent === " " ? 1 : indent.length,
|
|
18401
19289
|
insertSpaces: indent !== " ",
|
|
18402
19290
|
eol: "\n"
|
|
18403
19291
|
};
|
|
18404
|
-
const edits = jsonc.modify(content,
|
|
19292
|
+
const edits = jsonc.modify(content, path25, value, { formattingOptions });
|
|
18405
19293
|
let result = jsonc.applyEdits(content, edits);
|
|
18406
19294
|
if (!result.endsWith("\n")) {
|
|
18407
19295
|
result += "\n";
|
|
18408
19296
|
}
|
|
18409
19297
|
return result;
|
|
18410
19298
|
}
|
|
18411
|
-
function removeAtPath(content,
|
|
18412
|
-
return modifyAtPath(content,
|
|
19299
|
+
function removeAtPath(content, path25) {
|
|
19300
|
+
return modifyAtPath(content, path25, void 0);
|
|
18413
19301
|
}
|
|
18414
19302
|
function serializeUpdate(content, current, next) {
|
|
18415
19303
|
let result = content || "{}";
|
|
@@ -18419,15 +19307,15 @@ function serializeUpdate(content, current, next) {
|
|
|
18419
19307
|
}
|
|
18420
19308
|
return result;
|
|
18421
19309
|
}
|
|
18422
|
-
function applyObjectUpdate(content,
|
|
19310
|
+
function applyObjectUpdate(content, path25, current, next) {
|
|
18423
19311
|
let result = content;
|
|
18424
19312
|
for (const key2 of Object.keys(current)) {
|
|
18425
19313
|
if (!hasConfigEntry(next, key2)) {
|
|
18426
|
-
result = removeAtPath(result, [...
|
|
19314
|
+
result = removeAtPath(result, [...path25, key2]);
|
|
18427
19315
|
}
|
|
18428
19316
|
}
|
|
18429
19317
|
for (const [key2, nextValue] of Object.entries(next)) {
|
|
18430
|
-
const nextPath = [...
|
|
19318
|
+
const nextPath = [...path25, key2];
|
|
18431
19319
|
const hasCurrent = hasConfigEntry(current, key2);
|
|
18432
19320
|
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
18433
19321
|
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
@@ -18627,20 +19515,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
18627
19515
|
}
|
|
18628
19516
|
return formatRegistry[formatName];
|
|
18629
19517
|
}
|
|
18630
|
-
function detectFormat(
|
|
18631
|
-
const ext = getExtension(
|
|
19518
|
+
function detectFormat(path25) {
|
|
19519
|
+
const ext = getExtension(path25);
|
|
18632
19520
|
return extensionMap[ext];
|
|
18633
19521
|
}
|
|
18634
|
-
function getExtension(
|
|
18635
|
-
const lastDot =
|
|
19522
|
+
function getExtension(path25) {
|
|
19523
|
+
const lastDot = path25.lastIndexOf(".");
|
|
18636
19524
|
if (lastDot === -1) {
|
|
18637
19525
|
return "";
|
|
18638
19526
|
}
|
|
18639
|
-
return
|
|
19527
|
+
return path25.slice(lastDot).toLowerCase();
|
|
18640
19528
|
}
|
|
18641
19529
|
|
|
18642
19530
|
// ../config-mutations/src/execution/path-utils.ts
|
|
18643
|
-
import
|
|
19531
|
+
import path17 from "node:path";
|
|
18644
19532
|
function expandHome(targetPath, homeDir) {
|
|
18645
19533
|
if (!targetPath?.startsWith("~")) {
|
|
18646
19534
|
return targetPath;
|
|
@@ -18657,7 +19545,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
18657
19545
|
remainder = remainder.slice(1);
|
|
18658
19546
|
}
|
|
18659
19547
|
}
|
|
18660
|
-
return remainder.length === 0 ? homeDir :
|
|
19548
|
+
return remainder.length === 0 ? homeDir : path17.join(homeDir, remainder);
|
|
18661
19549
|
}
|
|
18662
19550
|
function validateHomePath(targetPath) {
|
|
18663
19551
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -18672,21 +19560,21 @@ function validateHomePath(targetPath) {
|
|
|
18672
19560
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
18673
19561
|
validateHomePath(rawPath);
|
|
18674
19562
|
const expanded = expandHome(rawPath, homeDir);
|
|
18675
|
-
const canonicalHome =
|
|
18676
|
-
const canonicalExpanded =
|
|
18677
|
-
const relative =
|
|
18678
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
19563
|
+
const canonicalHome = path17.resolve(homeDir);
|
|
19564
|
+
const canonicalExpanded = path17.resolve(expanded);
|
|
19565
|
+
const relative = path17.relative(canonicalHome, canonicalExpanded);
|
|
19566
|
+
if (relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
|
|
18679
19567
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
18680
19568
|
}
|
|
18681
19569
|
if (!pathMapper) {
|
|
18682
19570
|
return canonicalExpanded;
|
|
18683
19571
|
}
|
|
18684
|
-
const rawDirectory =
|
|
19572
|
+
const rawDirectory = path17.dirname(expanded);
|
|
18685
19573
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
18686
19574
|
targetDirectory: rawDirectory
|
|
18687
19575
|
});
|
|
18688
|
-
const filename =
|
|
18689
|
-
return filename.length === 0 ? mappedDirectory :
|
|
19576
|
+
const filename = path17.basename(expanded);
|
|
19577
|
+
return filename.length === 0 ? mappedDirectory : path17.join(mappedDirectory, filename);
|
|
18690
19578
|
}
|
|
18691
19579
|
|
|
18692
19580
|
// ../config-mutations/src/error-codes.ts
|
|
@@ -18698,9 +19586,9 @@ function hasOwnErrorCode5(error3, code) {
|
|
|
18698
19586
|
function isNotFound(error3) {
|
|
18699
19587
|
return hasOwnErrorCode5(error3, "ENOENT");
|
|
18700
19588
|
}
|
|
18701
|
-
async function readFileIfExists(
|
|
19589
|
+
async function readFileIfExists(fs5, target) {
|
|
18702
19590
|
try {
|
|
18703
|
-
return await
|
|
19591
|
+
return await fs5.readFile(target, "utf8");
|
|
18704
19592
|
} catch (error3) {
|
|
18705
19593
|
if (isNotFound(error3)) {
|
|
18706
19594
|
return null;
|
|
@@ -18708,9 +19596,9 @@ async function readFileIfExists(fs4, target) {
|
|
|
18708
19596
|
throw error3;
|
|
18709
19597
|
}
|
|
18710
19598
|
}
|
|
18711
|
-
async function pathExists(
|
|
19599
|
+
async function pathExists(fs5, target) {
|
|
18712
19600
|
try {
|
|
18713
|
-
await
|
|
19601
|
+
await fs5.stat(target);
|
|
18714
19602
|
return true;
|
|
18715
19603
|
} catch (error3) {
|
|
18716
19604
|
if (isNotFound(error3)) {
|
|
@@ -18756,8 +19644,8 @@ function isAlreadyExists(error3) {
|
|
|
18756
19644
|
return hasOwnErrorCode5(error3, "EEXIST");
|
|
18757
19645
|
}
|
|
18758
19646
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
18759
|
-
const boundary =
|
|
18760
|
-
let currentPath =
|
|
19647
|
+
const boundary = path18.dirname(path18.resolve(context.homeDir));
|
|
19648
|
+
let currentPath = path18.resolve(targetPath);
|
|
18761
19649
|
while (currentPath !== boundary) {
|
|
18762
19650
|
try {
|
|
18763
19651
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -18768,7 +19656,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
18768
19656
|
throw error3;
|
|
18769
19657
|
}
|
|
18770
19658
|
}
|
|
18771
|
-
const parentPath =
|
|
19659
|
+
const parentPath = path18.dirname(currentPath);
|
|
18772
19660
|
if (parentPath === currentPath) {
|
|
18773
19661
|
return;
|
|
18774
19662
|
}
|
|
@@ -18833,6 +19721,56 @@ function describeMutation(kind, targetPath) {
|
|
|
18833
19721
|
return "Operation";
|
|
18834
19722
|
}
|
|
18835
19723
|
}
|
|
19724
|
+
function mutationTargetPath(mutation, options) {
|
|
19725
|
+
switch (mutation.kind) {
|
|
19726
|
+
case "ensureDirectory":
|
|
19727
|
+
case "removeDirectory":
|
|
19728
|
+
return resolveValue(mutation.path, options);
|
|
19729
|
+
case "removeFile":
|
|
19730
|
+
case "chmod":
|
|
19731
|
+
case "backup":
|
|
19732
|
+
case "restoreBackup":
|
|
19733
|
+
case "configMerge":
|
|
19734
|
+
case "configPrune":
|
|
19735
|
+
case "configTransform":
|
|
19736
|
+
case "templateWrite":
|
|
19737
|
+
case "templateMergeToml":
|
|
19738
|
+
case "templateMergeJson":
|
|
19739
|
+
return resolveValue(mutation.target, options);
|
|
19740
|
+
default:
|
|
19741
|
+
return void 0;
|
|
19742
|
+
}
|
|
19743
|
+
}
|
|
19744
|
+
function resolveMutationDetails(mutation, context, options) {
|
|
19745
|
+
try {
|
|
19746
|
+
const rawTarget = mutationTargetPath(mutation, options);
|
|
19747
|
+
if (rawTarget === void 0) {
|
|
19748
|
+
return {
|
|
19749
|
+
kind: mutation.kind,
|
|
19750
|
+
label: mutation.label ?? mutation.kind
|
|
19751
|
+
};
|
|
19752
|
+
}
|
|
19753
|
+
try {
|
|
19754
|
+
const targetPath = resolvePath(rawTarget, context.homeDir, context.pathMapper);
|
|
19755
|
+
return {
|
|
19756
|
+
kind: mutation.kind,
|
|
19757
|
+
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19758
|
+
targetPath
|
|
19759
|
+
};
|
|
19760
|
+
} catch {
|
|
19761
|
+
return {
|
|
19762
|
+
kind: mutation.kind,
|
|
19763
|
+
label: mutation.label ?? describeMutation(mutation.kind, rawTarget),
|
|
19764
|
+
targetPath: void 0
|
|
19765
|
+
};
|
|
19766
|
+
}
|
|
19767
|
+
} catch {
|
|
19768
|
+
return {
|
|
19769
|
+
kind: mutation.kind,
|
|
19770
|
+
label: mutation.label ?? mutation.kind
|
|
19771
|
+
};
|
|
19772
|
+
}
|
|
19773
|
+
}
|
|
18836
19774
|
function pruneKeysByPrefix(table, prefix) {
|
|
18837
19775
|
const result = {};
|
|
18838
19776
|
for (const [key2, value] of Object.entries(table)) {
|
|
@@ -18923,6 +19861,7 @@ async function applyEnsureDirectory(mutation, context, options) {
|
|
|
18923
19861
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
18924
19862
|
targetPath
|
|
18925
19863
|
};
|
|
19864
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
18926
19865
|
const existed = await pathExists(context.fs, targetPath);
|
|
18927
19866
|
if (!context.dryRun) {
|
|
18928
19867
|
await context.fs.mkdir(targetPath, { recursive: true });
|
|
@@ -19039,6 +19978,7 @@ async function applyChmod(mutation, context, options) {
|
|
|
19039
19978
|
};
|
|
19040
19979
|
}
|
|
19041
19980
|
try {
|
|
19981
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19042
19982
|
const stat2 = await context.fs.stat(targetPath);
|
|
19043
19983
|
const currentMode = typeof stat2.mode === "number" ? stat2.mode & 511 : null;
|
|
19044
19984
|
if (currentMode === mutation.mode) {
|
|
@@ -19072,6 +20012,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
19072
20012
|
label: mutation.label ?? describeMutation(mutation.kind, targetPath),
|
|
19073
20013
|
targetPath
|
|
19074
20014
|
};
|
|
20015
|
+
await assertRegularWriteTarget(context, targetPath);
|
|
19075
20016
|
if (mutation.once && await findLatestGeneratedBackup(context.fs, targetPath) !== null) {
|
|
19076
20017
|
return {
|
|
19077
20018
|
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
@@ -19138,13 +20079,13 @@ async function applyRestoreBackup(mutation, context, options) {
|
|
|
19138
20079
|
}
|
|
19139
20080
|
return { outcome: { changed: true, effect: "copy", detail: "restore" }, details };
|
|
19140
20081
|
}
|
|
19141
|
-
async function findLatestGeneratedBackup(
|
|
20082
|
+
async function findLatestGeneratedBackup(fs5, targetPath) {
|
|
19142
20083
|
const separatorIndex = targetPath.lastIndexOf("/");
|
|
19143
20084
|
const directoryPath = separatorIndex <= 0 ? "/" : targetPath.slice(0, separatorIndex);
|
|
19144
20085
|
const targetName = targetPath.slice(separatorIndex + 1);
|
|
19145
20086
|
let entries;
|
|
19146
20087
|
try {
|
|
19147
|
-
entries = await
|
|
20088
|
+
entries = await fs5.readdir(directoryPath);
|
|
19148
20089
|
} catch (error3) {
|
|
19149
20090
|
if (isNotFound(error3)) {
|
|
19150
20091
|
return null;
|
|
@@ -19208,6 +20149,9 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
19208
20149
|
preserveContent = null;
|
|
19209
20150
|
}
|
|
19210
20151
|
const value = resolveValue(mutation.value, options);
|
|
20152
|
+
if (!isConfigObject4(value)) {
|
|
20153
|
+
throw new Error(`configMerge value must be an object for "${rawPath}".`);
|
|
20154
|
+
}
|
|
19211
20155
|
let merged;
|
|
19212
20156
|
if (mutation.pruneByPrefix) {
|
|
19213
20157
|
merged = mergeWithPruneByPrefix(current, value, mutation.pruneByPrefix);
|
|
@@ -19341,6 +20285,13 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
19341
20285
|
};
|
|
19342
20286
|
}
|
|
19343
20287
|
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
20288
|
+
const serializedChanged = serialized !== rawContent;
|
|
20289
|
+
if (!serializedChanged) {
|
|
20290
|
+
return {
|
|
20291
|
+
outcome: { changed: false, effect: "none", detail: "noop" },
|
|
20292
|
+
details
|
|
20293
|
+
};
|
|
20294
|
+
}
|
|
19344
20295
|
if (!context.dryRun) {
|
|
19345
20296
|
await writeAtomically2(context, targetPath, serialized);
|
|
19346
20297
|
}
|
|
@@ -19457,25 +20408,14 @@ async function runMutations(mutations, context, options) {
|
|
|
19457
20408
|
};
|
|
19458
20409
|
}
|
|
19459
20410
|
async function executeMutation(mutation, context, options) {
|
|
19460
|
-
context
|
|
19461
|
-
|
|
19462
|
-
label: mutation.label ?? mutation.kind,
|
|
19463
|
-
targetPath: void 0
|
|
19464
|
-
// Will be resolved during apply
|
|
19465
|
-
});
|
|
20411
|
+
const pendingDetails = resolveMutationDetails(mutation, context, options);
|
|
20412
|
+
context.observers?.onStart?.(pendingDetails);
|
|
19466
20413
|
try {
|
|
19467
20414
|
const { outcome, details } = await applyMutation(mutation, context, options);
|
|
19468
20415
|
context.observers?.onComplete?.(details, outcome);
|
|
19469
20416
|
return { outcome, details };
|
|
19470
20417
|
} catch (error3) {
|
|
19471
|
-
context.observers?.onError?.(
|
|
19472
|
-
{
|
|
19473
|
-
kind: mutation.kind,
|
|
19474
|
-
label: mutation.label ?? mutation.kind,
|
|
19475
|
-
targetPath: void 0
|
|
19476
|
-
},
|
|
19477
|
-
error3
|
|
19478
|
-
);
|
|
20418
|
+
context.observers?.onError?.(pendingDetails, error3);
|
|
19479
20419
|
throw error3;
|
|
19480
20420
|
}
|
|
19481
20421
|
}
|
|
@@ -19486,8 +20426,8 @@ function hasOwnErrorCode6(error3, code) {
|
|
|
19486
20426
|
}
|
|
19487
20427
|
|
|
19488
20428
|
// ../agent-skill-config/src/templates.ts
|
|
19489
|
-
import { readFile as
|
|
19490
|
-
import
|
|
20429
|
+
import { readFile as readFile6, stat } from "node:fs/promises";
|
|
20430
|
+
import path19 from "node:path";
|
|
19491
20431
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19492
20432
|
|
|
19493
20433
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -19504,9 +20444,9 @@ function toHomeRelative(localSkillDir) {
|
|
|
19504
20444
|
const normalized = localSkillDir.startsWith("./") ? localSkillDir.slice(2) : localSkillDir;
|
|
19505
20445
|
return `~/${normalized}`;
|
|
19506
20446
|
}
|
|
19507
|
-
async function pathExists2(
|
|
20447
|
+
async function pathExists2(fs5, targetPath) {
|
|
19508
20448
|
try {
|
|
19509
|
-
await
|
|
20449
|
+
await fs5.stat(targetPath);
|
|
19510
20450
|
return true;
|
|
19511
20451
|
} catch (error3) {
|
|
19512
20452
|
if (hasOwnErrorCode6(error3, "ENOENT")) {
|
|
@@ -19523,7 +20463,7 @@ async function installSkill(agentId, skill, options) {
|
|
|
19523
20463
|
}
|
|
19524
20464
|
const scope = options.scope ?? "local";
|
|
19525
20465
|
const config2 = support.config;
|
|
19526
|
-
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
20466
|
+
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")) {
|
|
19527
20467
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
19528
20468
|
}
|
|
19529
20469
|
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
@@ -19559,29 +20499,29 @@ async function installSkill(agentId, skill, options) {
|
|
|
19559
20499
|
}
|
|
19560
20500
|
}
|
|
19561
20501
|
);
|
|
19562
|
-
return { skillPath:
|
|
20502
|
+
return { skillPath: absoluteSkillPath, displayPath };
|
|
19563
20503
|
}
|
|
19564
20504
|
|
|
19565
20505
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
19566
|
-
import
|
|
19567
|
-
import
|
|
20506
|
+
import * as fs2 from "node:fs";
|
|
20507
|
+
import path20 from "node:path";
|
|
19568
20508
|
|
|
19569
20509
|
// ../agent-skill-config/src/git-exclude.ts
|
|
19570
20510
|
import { execFileSync } from "node:child_process";
|
|
19571
20511
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
19572
|
-
import * as
|
|
19573
|
-
import
|
|
20512
|
+
import * as fs3 from "node:fs";
|
|
20513
|
+
import path21 from "node:path";
|
|
19574
20514
|
|
|
19575
20515
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
19576
|
-
import * as
|
|
20516
|
+
import * as fs4 from "node:fs";
|
|
19577
20517
|
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
19578
|
-
import
|
|
20518
|
+
import path22 from "node:path";
|
|
19579
20519
|
|
|
19580
20520
|
// src/commands/installer.ts
|
|
19581
20521
|
import os3 from "node:os";
|
|
19582
|
-
import
|
|
20522
|
+
import path23 from "node:path";
|
|
19583
20523
|
import * as nodeFs2 from "node:fs/promises";
|
|
19584
|
-
import { readFile as
|
|
20524
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
19585
20525
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
19586
20526
|
var DEFAULT_INSTALL_SCOPE = "local";
|
|
19587
20527
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
@@ -19631,7 +20571,7 @@ async function loadTerminalPilotTemplate() {
|
|
|
19631
20571
|
];
|
|
19632
20572
|
for (const candidate of candidates) {
|
|
19633
20573
|
try {
|
|
19634
|
-
terminalPilotTemplateCache = await
|
|
20574
|
+
terminalPilotTemplateCache = await readFile7(candidate, "utf8");
|
|
19635
20575
|
return terminalPilotTemplateCache;
|
|
19636
20576
|
} catch (error3) {
|
|
19637
20577
|
if (!isNotFoundError2(error3)) {
|
|
@@ -19646,7 +20586,7 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
19646
20586
|
return homeDir;
|
|
19647
20587
|
}
|
|
19648
20588
|
if (targetPath.startsWith("~/")) {
|
|
19649
|
-
return
|
|
20589
|
+
return path23.join(homeDir, targetPath.slice(2));
|
|
19650
20590
|
}
|
|
19651
20591
|
return targetPath;
|
|
19652
20592
|
}
|
|
@@ -19656,22 +20596,22 @@ function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
|
19656
20596
|
throwUnsupportedAgent(agent);
|
|
19657
20597
|
}
|
|
19658
20598
|
return {
|
|
19659
|
-
displayPath:
|
|
20599
|
+
displayPath: path23.join(
|
|
19660
20600
|
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
19661
20601
|
TERMINAL_PILOT_SKILL_NAME
|
|
19662
20602
|
),
|
|
19663
|
-
fullPath:
|
|
19664
|
-
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) :
|
|
20603
|
+
fullPath: path23.join(
|
|
20604
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path23.resolve(cwd, config2.localSkillDir),
|
|
19665
20605
|
TERMINAL_PILOT_SKILL_NAME
|
|
19666
20606
|
)
|
|
19667
20607
|
};
|
|
19668
20608
|
}
|
|
19669
|
-
async function assertNoSymbolicLinkPath(
|
|
19670
|
-
const rootPath =
|
|
20609
|
+
async function assertNoSymbolicLinkPath(fs5, targetPath) {
|
|
20610
|
+
const rootPath = path23.parse(targetPath).root;
|
|
19671
20611
|
let currentPath = targetPath;
|
|
19672
20612
|
while (currentPath !== rootPath) {
|
|
19673
20613
|
try {
|
|
19674
|
-
if ((await
|
|
20614
|
+
if ((await fs5.lstat(currentPath)).isSymbolicLink()) {
|
|
19675
20615
|
throw new UserError(`Refusing terminal-pilot skill operation through symbolic link: ${currentPath}`);
|
|
19676
20616
|
}
|
|
19677
20617
|
} catch (error3) {
|
|
@@ -19679,7 +20619,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
19679
20619
|
throw error3;
|
|
19680
20620
|
}
|
|
19681
20621
|
}
|
|
19682
|
-
currentPath =
|
|
20622
|
+
currentPath = path23.dirname(currentPath);
|
|
19683
20623
|
}
|
|
19684
20624
|
}
|
|
19685
20625
|
|
|
@@ -20378,11 +21318,11 @@ import { Resvg } from "@resvg/resvg-js";
|
|
|
20378
21318
|
|
|
20379
21319
|
// ../terminal-png/src/font.ts
|
|
20380
21320
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
20381
|
-
import { createRequire as
|
|
21321
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
20382
21322
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
20383
21323
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
20384
|
-
var
|
|
20385
|
-
var fontPackageRoot = dirname2(
|
|
21324
|
+
var require3 = createRequire3(import.meta.url);
|
|
21325
|
+
var fontPackageRoot = dirname2(require3.resolve("jetbrains-mono/package.json"));
|
|
20386
21326
|
var webfontRoot = join2(fontPackageRoot, "fonts/webfonts");
|
|
20387
21327
|
function readWebfontBase64(filename) {
|
|
20388
21328
|
return readFileSync4(join2(webfontRoot, filename)).toString("base64");
|
|
@@ -21092,9 +22032,9 @@ var uninstall = defineCommand({
|
|
|
21092
22032
|
};
|
|
21093
22033
|
}
|
|
21094
22034
|
});
|
|
21095
|
-
async function folderExists(
|
|
22035
|
+
async function folderExists(fs5, folderPath) {
|
|
21096
22036
|
try {
|
|
21097
|
-
await
|
|
22037
|
+
await fs5.stat(folderPath);
|
|
21098
22038
|
return true;
|
|
21099
22039
|
} catch (error3) {
|
|
21100
22040
|
if (hasOwnErrorCode4(error3, "ENOENT")) {
|
|
@@ -21239,7 +22179,7 @@ async function isDirectExecution(argv) {
|
|
|
21239
22179
|
try {
|
|
21240
22180
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
21241
22181
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
21242
|
-
realpath3(
|
|
22182
|
+
realpath3(path24.resolve(entryPoint)),
|
|
21243
22183
|
realpath3(modulePath)
|
|
21244
22184
|
]);
|
|
21245
22185
|
return resolvedEntryPoint === resolvedModulePath;
|