aicodeman 1.34.0 → 1.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/README.zh-CN.md +8 -0
- package/dist/attachment-registry.d.ts +6 -0
- package/dist/attachment-registry.d.ts.map +1 -1
- package/dist/attachment-registry.js +9 -3
- package/dist/attachment-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/config/cli-registry/patterns.d.ts +6 -0
- package/dist/config/cli-registry/patterns.d.ts.map +1 -1
- package/dist/config/cli-registry/patterns.js +13 -0
- package/dist/config/cli-registry/patterns.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +13 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +60 -2
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +175 -7
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +93 -6
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/config/dependency-registry.d.ts +7 -0
- package/dist/config/dependency-registry.d.ts.map +1 -1
- package/dist/config/dependency-registry.js +15 -0
- package/dist/config/dependency-registry.js.map +1 -1
- package/dist/config/path-probe.d.ts +37 -0
- package/dist/config/path-probe.d.ts.map +1 -0
- package/dist/config/path-probe.js +43 -0
- package/dist/config/path-probe.js.map +1 -0
- package/dist/deepseek-route-config.d.ts +110 -0
- package/dist/deepseek-route-config.d.ts.map +1 -0
- package/dist/deepseek-route-config.js +477 -0
- package/dist/deepseek-route-config.js.map +1 -0
- package/dist/git-workspace-status.d.ts +246 -0
- package/dist/git-workspace-status.d.ts.map +1 -0
- package/dist/git-workspace-status.js +626 -0
- package/dist/git-workspace-status.js.map +1 -0
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +83 -13
- package/dist/hooks-config.js.map +1 -1
- package/dist/model-config-resolvers.d.ts +29 -0
- package/dist/model-config-resolvers.d.ts.map +1 -0
- package/dist/model-config-resolvers.js +34 -0
- package/dist/model-config-resolvers.js.map +1 -0
- package/dist/session-display-model.d.ts +110 -0
- package/dist/session-display-model.d.ts.map +1 -0
- package/dist/session-display-model.js +154 -0
- package/dist/session-display-model.js.map +1 -0
- package/dist/session.d.ts +145 -8
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +280 -35
- package/dist/session.js.map +1 -1
- package/dist/types/api.d.ts +7 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/api.js.map +1 -1
- package/dist/types/session.d.ts +28 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/types/tools.d.ts +1 -1
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/bounded-path-probe.d.ts +99 -0
- package/dist/utils/bounded-path-probe.d.ts.map +1 -0
- package/dist/utils/bounded-path-probe.js +228 -0
- package/dist/utils/bounded-path-probe.js.map +1 -0
- package/dist/utils/cli-executable-resolver.d.ts +2 -0
- package/dist/utils/cli-executable-resolver.d.ts.map +1 -1
- package/dist/utils/cli-executable-resolver.js +2 -1
- package/dist/utils/cli-executable-resolver.js.map +1 -1
- package/dist/utils/deepseek-cli-resolver.d.ts +8 -0
- package/dist/utils/deepseek-cli-resolver.d.ts.map +1 -1
- package/dist/utils/deepseek-cli-resolver.js +18 -2
- package/dist/utils/deepseek-cli-resolver.js.map +1 -1
- package/dist/utils/dependency-checker.d.ts +2 -0
- package/dist/utils/dependency-checker.d.ts.map +1 -1
- package/dist/utils/dependency-checker.js +37 -9
- package/dist/utils/dependency-checker.js.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/web/case-path.d.ts +58 -0
- package/dist/web/case-path.d.ts.map +1 -0
- package/dist/web/case-path.js +182 -0
- package/dist/web/case-path.js.map +1 -0
- package/dist/web/launch-defaults.d.ts +22 -0
- package/dist/web/launch-defaults.d.ts.map +1 -0
- package/dist/web/launch-defaults.js +46 -0
- package/dist/web/launch-defaults.js.map +1 -0
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/app.abadc970.js +43 -0
- package/dist/web/public/app.abadc970.js.br +0 -0
- package/dist/web/public/app.abadc970.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.d95fade9.js → constants.c0f8f9de.js} +1009 -127
- package/dist/web/public/constants.c0f8f9de.js.br +0 -0
- package/dist/web/public/constants.c0f8f9de.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js +1 -0
- package/dist/web/public/entrance-animations.js.br +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/git-status-ui.js +719 -0
- package/dist/web/public/git-status-ui.js.br +0 -0
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/home-sessions.js +12 -9
- package/dist/web/public/home-sessions.js.br +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/host-wake-ui.js.gz +0 -0
- package/dist/web/public/i18n.a31747a9.js +2 -0
- package/dist/web/public/i18n.a31747a9.js.br +0 -0
- package/dist/web/public/i18n.a31747a9.js.gz +0 -0
- package/dist/web/public/{image-input.a216cf9e.js → image-input.898a538b.js} +18 -8
- package/dist/web/public/image-input.898a538b.js.br +0 -0
- package/dist/web/public/image-input.898a538b.js.gz +0 -0
- package/dist/web/public/index.html +205 -42
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.c1e7c7b7.js.gz +0 -0
- package/dist/web/public/{mobile-handlers.23a85db1.js → mobile-handlers.0ef9c311.js} +20 -0
- package/dist/web/public/mobile-handlers.0ef9c311.js.br +0 -0
- package/dist/web/public/mobile-handlers.0ef9c311.js.gz +0 -0
- package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.111b187d.css +1 -0
- package/dist/web/public/mobile.111b187d.css.br +0 -0
- package/dist/web/public/mobile.111b187d.css.gz +0 -0
- package/dist/web/public/notification-manager.50bb87d8.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.6a5898d9.js → panels-ui.4735dfc2.js} +4 -4
- package/dist/web/public/panels-ui.4735dfc2.js.br +0 -0
- package/dist/web/public/{panels-ui.6a5898d9.js.gz → panels-ui.4735dfc2.js.gz} +0 -0
- package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
- package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/reboot-restore-ui.js.gz +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/session-lineage.js +229 -86
- package/dist/web/public/session-lineage.js.br +0 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/session-ui.f731602c.js +100 -0
- package/dist/web/public/session-ui.f731602c.js.br +0 -0
- package/dist/web/public/session-ui.f731602c.js.gz +0 -0
- package/dist/web/public/settings-ui.a97ab16f.js +97 -0
- package/dist/web/public/settings-ui.a97ab16f.js.br +0 -0
- package/dist/web/public/settings-ui.a97ab16f.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js +290 -0
- package/dist/web/public/spreadsheet-preview-worker.js.br +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js +555 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js.br +0 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js +1006 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.br +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.8ee12666.css +1 -0
- package/dist/web/public/styles.8ee12666.css.br +0 -0
- package/dist/web/public/styles.8ee12666.css.gz +0 -0
- package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
- package/dist/web/public/sw.js +2 -2
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-layout-browser.065fcba4.js +1 -0
- package/dist/web/public/tab-layout-browser.065fcba4.js.br +0 -0
- package/dist/web/public/tab-layout-browser.065fcba4.js.gz +0 -0
- package/dist/web/public/{tab-rail-resize.dcdc5772.js → tab-rail-resize.a5867793.js} +1 -1
- package/dist/web/public/tab-rail-resize.a5867793.js.br +0 -0
- package/dist/web/public/tab-rail-resize.a5867793.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js +1 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.br +0 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.gz +0 -0
- package/dist/web/public/terminal-split.js +146 -649
- package/dist/web/public/terminal-split.js.br +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js +1611 -0
- package/dist/web/public/terminal-tile.js.br +0 -0
- package/dist/web/public/terminal-tile.js.gz +0 -0
- package/dist/web/public/terminal-ui.5059b30e.js +2 -0
- package/dist/web/public/terminal-ui.5059b30e.js.br +0 -0
- package/dist/web/public/terminal-ui.5059b30e.js.gz +0 -0
- package/dist/web/public/tile-grid.js +2684 -0
- package/dist/web/public/tile-grid.js.br +0 -0
- package/dist/web/public/tile-grid.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/exceljs.min.js +44 -0
- package/dist/web/public/vendor/exceljs.min.js.br +0 -0
- package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
- package/dist/web/public/vendor/fflate.min.js +1 -0
- package/dist/web/public/vendor/fflate.min.js.br +0 -0
- package/dist/web/public/vendor/fflate.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.bbb5f84c.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/{voice-input.c4b51eb6.js → voice-input.2342c37b.js} +64 -10
- package/dist/web/public/voice-input.2342c37b.js.br +0 -0
- package/dist/web/public/voice-input.2342c37b.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js +9 -1
- package/dist/web/public/webview-tabs.js.br +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +136 -18
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/cli-registry-routes.d.ts.map +1 -1
- package/dist/web/routes/cli-registry-routes.js +3 -1
- package/dist/web/routes/cli-registry-routes.js.map +1 -1
- package/dist/web/routes/doctor-routes.d.ts +23 -0
- package/dist/web/routes/doctor-routes.d.ts.map +1 -0
- package/dist/web/routes/doctor-routes.js +83 -0
- package/dist/web/routes/doctor-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts +7 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +34 -4
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/git-status-routes.d.ts +16 -0
- package/dist/web/routes/git-status-routes.d.ts.map +1 -0
- package/dist/web/routes/git-status-routes.js +98 -0
- package/dist/web/routes/git-status-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +2 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts +18 -0
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +106 -42
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/status-telemetry-routes.d.ts +3 -0
- package/dist/web/routes/status-telemetry-routes.d.ts.map +1 -1
- package/dist/web/routes/status-telemetry-routes.js +12 -0
- package/dist/web/routes/status-telemetry-routes.js.map +1 -1
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +13 -0
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +28 -0
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +41 -0
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +5 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +35 -12
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-listener-wiring.d.ts +1 -0
- package/dist/web/session-listener-wiring.d.ts.map +1 -1
- package/dist/web/session-listener-wiring.js +11 -0
- package/dist/web/session-listener-wiring.js.map +1 -1
- package/package.json +3 -1
- package/scripts/postinstall.js +16 -0
- package/skills/codeman/reference/verbs.md +3 -0
- package/dist/web/public/app.cf0db8ce.js +0 -43
- package/dist/web/public/app.cf0db8ce.js.br +0 -0
- package/dist/web/public/app.cf0db8ce.js.gz +0 -0
- package/dist/web/public/constants.d95fade9.js.br +0 -0
- package/dist/web/public/constants.d95fade9.js.gz +0 -0
- package/dist/web/public/i18n.398b8331.js +0 -1
- package/dist/web/public/i18n.398b8331.js.br +0 -0
- package/dist/web/public/i18n.398b8331.js.gz +0 -0
- package/dist/web/public/image-input.a216cf9e.js.br +0 -0
- package/dist/web/public/image-input.a216cf9e.js.gz +0 -0
- package/dist/web/public/mobile-handlers.23a85db1.js.br +0 -0
- package/dist/web/public/mobile-handlers.23a85db1.js.gz +0 -0
- package/dist/web/public/mobile.1aa4952d.css +0 -1
- package/dist/web/public/mobile.1aa4952d.css.br +0 -0
- package/dist/web/public/mobile.1aa4952d.css.gz +0 -0
- package/dist/web/public/panels-ui.6a5898d9.js.br +0 -0
- package/dist/web/public/session-ui.bf66c13b.js +0 -89
- package/dist/web/public/session-ui.bf66c13b.js.br +0 -0
- package/dist/web/public/session-ui.bf66c13b.js.gz +0 -0
- package/dist/web/public/settings-ui.331d3b1d.js +0 -97
- package/dist/web/public/settings-ui.331d3b1d.js.br +0 -0
- package/dist/web/public/settings-ui.331d3b1d.js.gz +0 -0
- package/dist/web/public/styles.8c485d26.css +0 -1
- package/dist/web/public/styles.8c485d26.css.br +0 -0
- package/dist/web/public/styles.8c485d26.css.gz +0 -0
- package/dist/web/public/tab-layout-browser.4e0ed50c.js +0 -1
- package/dist/web/public/tab-layout-browser.4e0ed50c.js.br +0 -0
- package/dist/web/public/tab-layout-browser.4e0ed50c.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.dcdc5772.js.br +0 -0
- package/dist/web/public/tab-rail-resize.dcdc5772.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js +0 -1
- package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js.br +0 -0
- package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js.gz +0 -0
- package/dist/web/public/terminal-ui.a4535311.js +0 -2
- package/dist/web/public/terminal-ui.a4535311.js.br +0 -0
- package/dist/web/public/terminal-ui.a4535311.js.gz +0 -0
- package/dist/web/public/upload.html +0 -155
- package/dist/web/public/upload.html.br +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/voice-input.c4b51eb6.js.br +0 -0
- package/dist/web/public/voice-input.c4b51eb6.js.gz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-checker.d.ts","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"dependency-checker.d.ts","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEvG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,gBAAgB,CAK9E;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,wFAAwF;IACxF,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,mBAAmB,IAAI,MAAM,EAAE,CAAC;IAChC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACpD;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,CA6D3E;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,EAAE,CAElF;AA4ED,wBAAgB,cAAc,IAAI,SAAS,CAe1C"}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { execFileSync } from 'node:child_process';
|
|
9
9
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { isAbsolute, join } from 'node:path';
|
|
10
11
|
import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
|
|
12
|
+
import { isExecutableRegularFile } from './cli-executable-resolver.js';
|
|
11
13
|
export function detectEnvironment(inputs) {
|
|
12
14
|
if (inputs.platform === 'win32')
|
|
13
15
|
return 'win32';
|
|
@@ -55,19 +57,37 @@ export function checkTool(tool, host) {
|
|
|
55
57
|
if (!spec)
|
|
56
58
|
return { ...base, status: 'skipped', reason: `not applicable on ${host.environment}` };
|
|
57
59
|
if (spec.resolver.kind === 'path') {
|
|
58
|
-
const { bins, versionArg, versionRegex, requireVersionMatch } = spec.resolver;
|
|
60
|
+
const { bins, versionArg, versionRegex, requireVersionMatch, searchDirs } = spec.resolver;
|
|
59
61
|
for (const bin of bins) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
// The same candidate order and the same per-candidate test as the run mode's resolver
|
|
63
|
+
// (createCliExecutableResolver): the `which` hit (the PATH), then each search dir. Under
|
|
64
|
+
// a service the PATH is minimal and the run mode finds the CLI through those dirs, so
|
|
65
|
+
// the doctor must too. A search-dir candidate counts only as an absolute path to an
|
|
66
|
+
// executable regular file, so a relative dir from a custom clis.json or a file without
|
|
67
|
+
// the x bit reads as missing here exactly as it does in the Run menu.
|
|
68
|
+
const candidates = [];
|
|
69
|
+
const onPath = host.which(bin);
|
|
70
|
+
if (onPath && isAbsolute(onPath))
|
|
71
|
+
candidates.push(onPath);
|
|
72
|
+
for (const dir of searchDirs ?? []) {
|
|
73
|
+
const candidate = join(dir, bin);
|
|
74
|
+
if (candidates.includes(candidate))
|
|
75
|
+
continue; // a search dir that is also on the PATH
|
|
76
|
+
if (isAbsolute(candidate) && host.isExecutableFile(candidate))
|
|
77
|
+
candidates.push(candidate);
|
|
78
|
+
}
|
|
79
|
+
for (const candidate of candidates) {
|
|
80
|
+
// Run the RESOLVED path: a bare name would miss the same binary `which` just missed.
|
|
81
|
+
const out = host.runVersion(candidate, [versionArg ?? '--version']);
|
|
63
82
|
const version = out ? extractVersion(out, versionRegex) : undefined;
|
|
64
83
|
// A generic binary name that prints the wrong thing is some OTHER program (see
|
|
65
|
-
// PathResolver.requireVersionMatch).
|
|
66
|
-
// alternative is claiming a tool is installed that the feature's own resolver
|
|
67
|
-
// rejects,
|
|
84
|
+
// PathResolver.requireVersionMatch). Try the next candidate, then report MISSING;
|
|
85
|
+
// the alternative is claiming a tool is installed that the feature's own resolver
|
|
86
|
+
// rejects, or missing one it accepts (an npm squatter on the PATH in front of the
|
|
87
|
+
// real grok in ~/.grok/bin), which reads as "the mode is broken".
|
|
68
88
|
if (requireVersionMatch && !version)
|
|
69
89
|
continue;
|
|
70
|
-
return finalize(base, tool,
|
|
90
|
+
return finalize(base, tool, candidate, version);
|
|
71
91
|
}
|
|
72
92
|
}
|
|
73
93
|
return { ...base, status: 'missing', installHint };
|
|
@@ -91,11 +111,16 @@ export function checkTool(tool, host) {
|
|
|
91
111
|
export function checkAll(registry, host) {
|
|
92
112
|
return registry.map((tool) => checkTool(tool, host));
|
|
93
113
|
}
|
|
114
|
+
// SIGKILL on every probe below: execFileSync's `timeout` only SENDS the kill signal and then
|
|
115
|
+
// keeps waiting for the child, so a `--version` that ignores the default SIGTERM would hold
|
|
116
|
+
// the doctor (now a Settings button) until GET /api/doctor's own timeout, then be orphaned.
|
|
117
|
+
// Same reasoning as the resolver host in cli-executable-resolver.ts.
|
|
94
118
|
function safeWhich(bin) {
|
|
95
119
|
try {
|
|
96
120
|
const out = execFileSync(process.platform === 'win32' ? 'where' : 'which', [bin], {
|
|
97
121
|
encoding: 'utf-8',
|
|
98
122
|
timeout: EXEC_TIMEOUT_MS,
|
|
123
|
+
killSignal: 'SIGKILL',
|
|
99
124
|
}).trim();
|
|
100
125
|
const first = out.split(/\r?\n/)[0]?.trim();
|
|
101
126
|
return first && existsSync(first) ? first : null;
|
|
@@ -110,6 +135,7 @@ function safeRunVersion(bin, args) {
|
|
|
110
135
|
encoding: 'utf-8',
|
|
111
136
|
timeout: EXEC_TIMEOUT_MS,
|
|
112
137
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
138
|
+
killSignal: 'SIGKILL',
|
|
113
139
|
});
|
|
114
140
|
}
|
|
115
141
|
catch (err) {
|
|
@@ -147,8 +173,9 @@ function readWindowsFileVersion(winPath) {
|
|
|
147
173
|
const windowsPath = execFileSync('wslpath', ['-w', winPath], {
|
|
148
174
|
encoding: 'utf-8',
|
|
149
175
|
timeout: EXEC_TIMEOUT_MS,
|
|
176
|
+
killSignal: 'SIGKILL',
|
|
150
177
|
}).trim();
|
|
151
|
-
const out = execFileSync('powershell.exe', ['-NoProfile', '-Command', `(Get-Item '${windowsPath.replace(/'/g, "''")}').VersionInfo.ProductVersion`], { encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }).trim();
|
|
178
|
+
const out = execFileSync('powershell.exe', ['-NoProfile', '-Command', `(Get-Item '${windowsPath.replace(/'/g, "''")}').VersionInfo.ProductVersion`], { encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS, killSignal: 'SIGKILL' }).trim();
|
|
152
179
|
return out || null;
|
|
153
180
|
}
|
|
154
181
|
catch {
|
|
@@ -165,6 +192,7 @@ export function createRealHost() {
|
|
|
165
192
|
environment,
|
|
166
193
|
which: safeWhich,
|
|
167
194
|
fileExists: existsSync,
|
|
195
|
+
isExecutableFile: isExecutableRegularFile,
|
|
168
196
|
runVersion: safeRunVersion,
|
|
169
197
|
windowsProgramRoots: listWindowsProgramRoots,
|
|
170
198
|
windowsFileVersion: readWindowsFileVersion,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-checker.js","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency-checker.js","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -31,4 +31,6 @@ export type { DeepSeekProfile, DeepSeekProfileKind } from './deepseek-cli-resolv
|
|
|
31
31
|
export { compileFileQuery, matchFileQuery } from './file-query.js';
|
|
32
32
|
export type { FileQueryMatcher } from './file-query.js';
|
|
33
33
|
export { resolveOmpDir, isOmpAvailable, getOmpNotFoundMessage, getOmpCliVersion } from './omp-cli-resolver.js';
|
|
34
|
+
export { boundedPathExists, describeUnknownPath, probePath, probePathKind, isNearStalledPath, unknownPathReason, } from './bounded-path-probe.js';
|
|
35
|
+
export type { PathProbeState, PathProbeKind, PathProbeOptions } from './bounded-path-probe.js';
|
|
34
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -28,4 +28,5 @@ export { resolveGrokDir, isGrokAvailable, getGrokCliVersion, getGrokNotFoundMess
|
|
|
28
28
|
export { resolveDeepSeekDir, isDeepSeekAvailable, isDeepSeekRunnable, getDeepSeekCliVersion, getDeepSeekNotFoundMessage, listDeepSeekProfiles, resolveDefaultDeepSeekProfile, isLaunchableProfile, resolveDshHome, profileExists, } from './deepseek-cli-resolver.js';
|
|
29
29
|
export { compileFileQuery, matchFileQuery } from './file-query.js';
|
|
30
30
|
export { resolveOmpDir, isOmpAvailable, getOmpNotFoundMessage, getOmpCliVersion } from './omp-cli-resolver.js';
|
|
31
|
+
export { boundedPathExists, describeUnknownPath, probePath, probePathKind, isNearStalledPath, unknownPathReason, } from './bounded-path-probe.js';
|
|
31
32
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,2BAA2B,EAC3B,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Validation for "create a new case in a custom folder" (`POST /api/cases` with a
|
|
3
|
+
* `path`). Creating a case writes a scaffold (`CLAUDE.md`, `src/`, `.claude/settings.local.json`)
|
|
4
|
+
* and registers the folder in the shared, ownerless linked-cases registry, so the target has to be
|
|
5
|
+
* judged before anything is created:
|
|
6
|
+
*
|
|
7
|
+
* - it must be an absolute path (a leading `~` is expanded) with no traversal and none of the shell
|
|
8
|
+
* metacharacters a session's working directory is later rejected for (`isValidWorkingDir`), so
|
|
9
|
+
* a case this accepts is one a session can actually start in;
|
|
10
|
+
* - it must not be a system directory, the home directory itself, Codeman's own data directory, or
|
|
11
|
+
* a credential/config tree (`~/.ssh`, `~/.aws`, `~/.claude`, ...). Judged on the path as typed AND on
|
|
12
|
+
* its symlink-resolved form, against both the given and the symlink-resolved roots (a home reached
|
|
13
|
+
* through a link, macOS's `/etc` -> `/private/etc`), so a link into a blocked tree is not a way
|
|
14
|
+
* around it;
|
|
15
|
+
* - it must not be, or be inside, a cases directory: a case there is a plain Create New, and the same
|
|
16
|
+
* folder listed both as a local case and as a linked one would make deleting it remove files;
|
|
17
|
+
* - its parent must already exist (one folder is created, never a whole chain), and the folder
|
|
18
|
+
* itself must not exist or must be an EMPTY directory (a folder with contents is Link Existing's
|
|
19
|
+
* job, and silently scaffolding into someone's project is the one thing this must never do);
|
|
20
|
+
* - it must not be a symlink.
|
|
21
|
+
*
|
|
22
|
+
* Pure except for the filesystem reads in `prepareNewCasePath`; the policy lives in `blockedReason`
|
|
23
|
+
* so it can be tested without a disk.
|
|
24
|
+
*
|
|
25
|
+
* @module web/case-path
|
|
26
|
+
*/
|
|
27
|
+
export interface NewCasePathContext {
|
|
28
|
+
home: string;
|
|
29
|
+
/** Codeman's own state directory (`getDataDir()`), which must never become a case. */
|
|
30
|
+
dataDir: string;
|
|
31
|
+
/**
|
|
32
|
+
* The cases directories (the caller's own and the shared one). A folder in one of them is already
|
|
33
|
+
* listed as a local case, so it must not be registered as a linked one too.
|
|
34
|
+
*/
|
|
35
|
+
casesDirs?: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
export type NewCasePathResult = {
|
|
38
|
+
ok: true;
|
|
39
|
+
path: string;
|
|
40
|
+
existedEmpty: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
ok: false;
|
|
43
|
+
code: 'INVALID' | 'BLOCKED' | 'NOT_FOUND' | 'EXISTS' | 'UNREACHABLE';
|
|
44
|
+
reason: string;
|
|
45
|
+
};
|
|
46
|
+
/** `~` and `~/x` to the home directory; anything else is returned unchanged. */
|
|
47
|
+
export declare function expandHome(raw: string, home: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Why a case may not live at this (already absolute and normalised) path, or null. `systemRoots`
|
|
50
|
+
* defaults to the system trees as spelled; pass their symlink-resolved forms to judge a resolved path.
|
|
51
|
+
*/
|
|
52
|
+
export declare function blockedReason(absPath: string, ctx: NewCasePathContext, systemRoots?: readonly string[]): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Judge `raw` as the folder for a new case and, if it is acceptable, say what to create.
|
|
55
|
+
* Never creates anything.
|
|
56
|
+
*/
|
|
57
|
+
export declare function prepareNewCasePath(raw: string, ctx: NewCasePathContext): Promise<NewCasePathResult>;
|
|
58
|
+
//# sourceMappingURL=case-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-path.d.ts","sourceRoot":"","sources":["../../src/web/case-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AA0BH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GACjD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAKxG,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,kBAAkB,EACvB,WAAW,GAAE,SAAS,MAAM,EAAyB,GACpD,MAAM,GAAG,IAAI,CAsBf;AAsBD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgEzG"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Validation for "create a new case in a custom folder" (`POST /api/cases` with a
|
|
3
|
+
* `path`). Creating a case writes a scaffold (`CLAUDE.md`, `src/`, `.claude/settings.local.json`)
|
|
4
|
+
* and registers the folder in the shared, ownerless linked-cases registry, so the target has to be
|
|
5
|
+
* judged before anything is created:
|
|
6
|
+
*
|
|
7
|
+
* - it must be an absolute path (a leading `~` is expanded) with no traversal and none of the shell
|
|
8
|
+
* metacharacters a session's working directory is later rejected for (`isValidWorkingDir`), so
|
|
9
|
+
* a case this accepts is one a session can actually start in;
|
|
10
|
+
* - it must not be a system directory, the home directory itself, Codeman's own data directory, or
|
|
11
|
+
* a credential/config tree (`~/.ssh`, `~/.aws`, `~/.claude`, ...). Judged on the path as typed AND on
|
|
12
|
+
* its symlink-resolved form, against both the given and the symlink-resolved roots (a home reached
|
|
13
|
+
* through a link, macOS's `/etc` -> `/private/etc`), so a link into a blocked tree is not a way
|
|
14
|
+
* around it;
|
|
15
|
+
* - it must not be, or be inside, a cases directory: a case there is a plain Create New, and the same
|
|
16
|
+
* folder listed both as a local case and as a linked one would make deleting it remove files;
|
|
17
|
+
* - its parent must already exist (one folder is created, never a whole chain), and the folder
|
|
18
|
+
* itself must not exist or must be an EMPTY directory (a folder with contents is Link Existing's
|
|
19
|
+
* job, and silently scaffolding into someone's project is the one thing this must never do);
|
|
20
|
+
* - it must not be a symlink.
|
|
21
|
+
*
|
|
22
|
+
* Pure except for the filesystem reads in `prepareNewCasePath`; the policy lives in `blockedReason`
|
|
23
|
+
* so it can be tested without a disk.
|
|
24
|
+
*
|
|
25
|
+
* @module web/case-path
|
|
26
|
+
*/
|
|
27
|
+
import { promises as fs } from 'node:fs';
|
|
28
|
+
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
29
|
+
import { isValidWorkingDir } from './schemas.js';
|
|
30
|
+
import { describeUnknownPath, probePath } from '../utils/index.js';
|
|
31
|
+
/** System trees nobody creates a project in; creating one here is a mistake or an attack. */
|
|
32
|
+
const BLOCKED_SYSTEM_ROOTS = [
|
|
33
|
+
'/bin',
|
|
34
|
+
'/boot',
|
|
35
|
+
'/dev',
|
|
36
|
+
'/etc',
|
|
37
|
+
'/lib',
|
|
38
|
+
'/lib32',
|
|
39
|
+
'/lib64',
|
|
40
|
+
'/proc',
|
|
41
|
+
'/run',
|
|
42
|
+
'/sbin',
|
|
43
|
+
'/sys',
|
|
44
|
+
'/usr',
|
|
45
|
+
];
|
|
46
|
+
/** Home-relative trees that hold credentials or other tools' own configuration. */
|
|
47
|
+
const BLOCKED_HOME_DIRS = ['.ssh', '.gnupg', '.aws', '.kube', '.docker', '.claude', '.codex', '.gemini'];
|
|
48
|
+
const isWithin = (child, root) => child === root || child.startsWith(root.endsWith(sep) ? root : root + sep);
|
|
49
|
+
/** `~` and `~/x` to the home directory; anything else is returned unchanged. */
|
|
50
|
+
export function expandHome(raw, home) {
|
|
51
|
+
if (raw === '~')
|
|
52
|
+
return home;
|
|
53
|
+
if (raw.startsWith('~/'))
|
|
54
|
+
return join(home, raw.slice(2));
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Why a case may not live at this (already absolute and normalised) path, or null. `systemRoots`
|
|
59
|
+
* defaults to the system trees as spelled; pass their symlink-resolved forms to judge a resolved path.
|
|
60
|
+
*/
|
|
61
|
+
export function blockedReason(absPath, ctx, systemRoots = BLOCKED_SYSTEM_ROOTS) {
|
|
62
|
+
if (absPath === sep)
|
|
63
|
+
return 'The filesystem root cannot be a case';
|
|
64
|
+
for (const root of systemRoots) {
|
|
65
|
+
if (isWithin(absPath, root))
|
|
66
|
+
return `${root} is a system directory`;
|
|
67
|
+
}
|
|
68
|
+
if (absPath === ctx.home)
|
|
69
|
+
return 'The home folder itself cannot be a case; pick a folder inside it';
|
|
70
|
+
for (const dir of BLOCKED_HOME_DIRS) {
|
|
71
|
+
if (isWithin(absPath, join(ctx.home, dir)))
|
|
72
|
+
return `~/${dir} holds credentials or another tool's configuration`;
|
|
73
|
+
}
|
|
74
|
+
if (isWithin(absPath, ctx.dataDir))
|
|
75
|
+
return "Codeman's own data folder cannot be a case";
|
|
76
|
+
// Any Codeman instance's data dir under the home folder (~/.codeman, ~/.codeman-beta, ...), not only
|
|
77
|
+
// the one this process uses.
|
|
78
|
+
if (absPath.startsWith(ctx.home + sep)) {
|
|
79
|
+
const firstSegment = absPath.slice(ctx.home.length + 1).split(sep)[0];
|
|
80
|
+
if (/^\.codeman/.test(firstSegment))
|
|
81
|
+
return "Codeman's own data folder cannot be a case";
|
|
82
|
+
}
|
|
83
|
+
for (const dir of ctx.casesDirs ?? []) {
|
|
84
|
+
if (isWithin(absPath, dir)) {
|
|
85
|
+
return 'That folder is inside the cases folder; create a case there with plain Create New (no custom folder)';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** `p` with its symlinks resolved, or `p` itself when it does not exist (or cannot be read). */
|
|
91
|
+
async function realpathOr(p) {
|
|
92
|
+
try {
|
|
93
|
+
return await fs.realpath(p);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return p;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** The context and system roots with their symlinks resolved, for judging a resolved path. */
|
|
100
|
+
async function resolvedPolicy(ctx) {
|
|
101
|
+
const [home, dataDir, casesDirs, systemRoots] = await Promise.all([
|
|
102
|
+
realpathOr(ctx.home),
|
|
103
|
+
realpathOr(ctx.dataDir),
|
|
104
|
+
Promise.all((ctx.casesDirs ?? []).map(realpathOr)),
|
|
105
|
+
Promise.all(BLOCKED_SYSTEM_ROOTS.map(realpathOr)),
|
|
106
|
+
]);
|
|
107
|
+
return [{ home, dataDir, casesDirs }, systemRoots];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Judge `raw` as the folder for a new case and, if it is acceptable, say what to create.
|
|
111
|
+
* Never creates anything.
|
|
112
|
+
*/
|
|
113
|
+
export async function prepareNewCasePath(raw, ctx) {
|
|
114
|
+
const typed = raw.trim();
|
|
115
|
+
if (!typed)
|
|
116
|
+
return { ok: false, code: 'INVALID', reason: 'Enter a folder path' };
|
|
117
|
+
const expanded = expandHome(typed, ctx.home);
|
|
118
|
+
if (!isValidWorkingDir(expanded)) {
|
|
119
|
+
return {
|
|
120
|
+
ok: false,
|
|
121
|
+
code: 'INVALID',
|
|
122
|
+
reason: 'Use an absolute path with letters, numbers, spaces, - _ . only (no .., no shell characters)',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const target = resolve(expanded);
|
|
126
|
+
const typedBlock = blockedReason(target, ctx);
|
|
127
|
+
if (typedBlock)
|
|
128
|
+
return { ok: false, code: 'BLOCKED', reason: typedBlock };
|
|
129
|
+
// Bounded first: the parent can sit on a network mount that stopped answering, where the
|
|
130
|
+
// realpath/stat/lstat/readdir below would each hold a threadpool worker until it returns.
|
|
131
|
+
// It is one folder the user named, so the probe may pass the bulk cap (never the ceiling).
|
|
132
|
+
const parentState = await probePath(dirname(target), { pastCap: true });
|
|
133
|
+
if (parentState === 'absent') {
|
|
134
|
+
return { ok: false, code: 'NOT_FOUND', reason: `The parent folder ${dirname(target)} does not exist` };
|
|
135
|
+
}
|
|
136
|
+
if (parentState === 'unknown') {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
code: 'UNREACHABLE',
|
|
140
|
+
reason: describeUnknownPath('The parent folder', dirname(target), { pastCap: true }),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Resolve the parent's symlinks, then judge again: a link into a blocked tree must not pass.
|
|
144
|
+
let realParent;
|
|
145
|
+
try {
|
|
146
|
+
realParent = await fs.realpath(dirname(target));
|
|
147
|
+
if (!(await fs.stat(realParent)).isDirectory()) {
|
|
148
|
+
return { ok: false, code: 'INVALID', reason: `${dirname(target)} is not a folder` };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return { ok: false, code: 'NOT_FOUND', reason: `The parent folder ${dirname(target)} does not exist` };
|
|
153
|
+
}
|
|
154
|
+
const real = join(realParent, basename(target));
|
|
155
|
+
// The resolved path against the roots as given AND as resolved: with home reached through a link, a
|
|
156
|
+
// link to <real home>/.ssh is only caught by the resolved home; on macOS /etc is /private/etc.
|
|
157
|
+
const [resolvedCtx, resolvedSystemRoots] = await resolvedPolicy(ctx);
|
|
158
|
+
const realBlock = blockedReason(real, ctx) ?? blockedReason(real, resolvedCtx, resolvedSystemRoots);
|
|
159
|
+
if (realBlock)
|
|
160
|
+
return { ok: false, code: 'BLOCKED', reason: realBlock };
|
|
161
|
+
try {
|
|
162
|
+
const st = await fs.lstat(real);
|
|
163
|
+
if (st.isSymbolicLink())
|
|
164
|
+
return { ok: false, code: 'INVALID', reason: `${target} is a symbolic link` };
|
|
165
|
+
if (!st.isDirectory())
|
|
166
|
+
return { ok: false, code: 'INVALID', reason: `${target} exists and is not a folder` };
|
|
167
|
+
if ((await fs.readdir(real)).length > 0) {
|
|
168
|
+
return {
|
|
169
|
+
ok: false,
|
|
170
|
+
code: 'EXISTS',
|
|
171
|
+
reason: `${target} already has files in it. Use "Link Existing" for a project that already exists`,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { ok: true, path: real, existedEmpty: true };
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
if (err.code === 'ENOENT')
|
|
178
|
+
return { ok: true, path: real, existedEmpty: false };
|
|
179
|
+
return { ok: false, code: 'INVALID', reason: `Cannot read ${target}: ${err.message}` };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=case-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case-path.js","sourceRoot":"","sources":["../../src/web/case-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Launch-time defaults from synced App Settings, driven by registry data.
|
|
3
|
+
*
|
|
4
|
+
* A CLI entry declares `capabilities.launchDefaults` (launch param -> settings key; today
|
|
5
|
+
* only codex, `{ model: 'codexModel', reasoningEffort: 'codexReasoningEffort' }`), and
|
|
6
|
+
* `applyLaunchDefaults()` fills those settings into the entry's `launch.legacyConfigField`
|
|
7
|
+
* object, setting ONLY the fields the caller left unset. Persisted values are re-validated
|
|
8
|
+
* with `SettingsUpdateSchema`, so a hand-edited settings.json can never smuggle an
|
|
9
|
+
* unchecked value onto the command line.
|
|
10
|
+
*
|
|
11
|
+
* Scope is the caller's decision: the create and quick-start routes apply it to local
|
|
12
|
+
* launches only, never to remote, Docker or custom-endpoint launches. Nothing here writes
|
|
13
|
+
* a CLI's own config files.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Return `configs` with the launch defaults of `mode`'s registry entry filled into its
|
|
17
|
+
* legacy config object (e.g. `codexConfig`). Every other field of `configs` is passed
|
|
18
|
+
* through untouched, and `configs` itself comes back unchanged (same object) when the entry
|
|
19
|
+
* declares no defaults, `customEndpoint` is set, or no setting names a value.
|
|
20
|
+
*/
|
|
21
|
+
export declare function applyLaunchDefaults<T extends object>(mode: string, configs: T, customEndpoint?: boolean): Promise<T>;
|
|
22
|
+
//# sourceMappingURL=launch-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-defaults.d.ts","sourceRoot":"","sources":["../../src/web/launch-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EACxD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,EACV,cAAc,UAAQ,GACrB,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Launch-time defaults from synced App Settings, driven by registry data.
|
|
3
|
+
*
|
|
4
|
+
* A CLI entry declares `capabilities.launchDefaults` (launch param -> settings key; today
|
|
5
|
+
* only codex, `{ model: 'codexModel', reasoningEffort: 'codexReasoningEffort' }`), and
|
|
6
|
+
* `applyLaunchDefaults()` fills those settings into the entry's `launch.legacyConfigField`
|
|
7
|
+
* object, setting ONLY the fields the caller left unset. Persisted values are re-validated
|
|
8
|
+
* with `SettingsUpdateSchema`, so a hand-edited settings.json can never smuggle an
|
|
9
|
+
* unchecked value onto the command line.
|
|
10
|
+
*
|
|
11
|
+
* Scope is the caller's decision: the create and quick-start routes apply it to local
|
|
12
|
+
* launches only, never to remote, Docker or custom-endpoint launches. Nothing here writes
|
|
13
|
+
* a CLI's own config files.
|
|
14
|
+
*/
|
|
15
|
+
import { getCli } from '../config/cli-registry/registry.js';
|
|
16
|
+
import { SettingsUpdateSchema } from './schemas.js';
|
|
17
|
+
import { readJsonConfig, SETTINGS_PATH } from './route-helpers.js';
|
|
18
|
+
/**
|
|
19
|
+
* Return `configs` with the launch defaults of `mode`'s registry entry filled into its
|
|
20
|
+
* legacy config object (e.g. `codexConfig`). Every other field of `configs` is passed
|
|
21
|
+
* through untouched, and `configs` itself comes back unchanged (same object) when the entry
|
|
22
|
+
* declares no defaults, `customEndpoint` is set, or no setting names a value.
|
|
23
|
+
*/
|
|
24
|
+
export async function applyLaunchDefaults(mode, configs, customEndpoint = false) {
|
|
25
|
+
const entry = getCli(mode);
|
|
26
|
+
const declared = entry?.capabilities.launchDefaults;
|
|
27
|
+
const field = entry?.launch.legacyConfigField;
|
|
28
|
+
if (customEndpoint || !declared || field === undefined)
|
|
29
|
+
return configs;
|
|
30
|
+
const settings = await readJsonConfig(SETTINGS_PATH, 'CLI launch defaults', {});
|
|
31
|
+
const aliases = entry.launch.legacyConfigAliases ?? {};
|
|
32
|
+
const current = configs[field];
|
|
33
|
+
const defaults = {};
|
|
34
|
+
for (const [param, settingKey] of Object.entries(declared)) {
|
|
35
|
+
const parsed = SettingsUpdateSchema.shape[settingKey].safeParse(settings[settingKey]);
|
|
36
|
+
// '' is the settings' "leave it to the CLI" value, the same as unset.
|
|
37
|
+
const value = parsed.success ? parsed.data || undefined : undefined;
|
|
38
|
+
const wireKey = aliases[param] ?? param;
|
|
39
|
+
if (value !== undefined && (current?.[wireKey] ?? undefined) === undefined)
|
|
40
|
+
defaults[wireKey] = value;
|
|
41
|
+
}
|
|
42
|
+
if (Object.keys(defaults).length === 0)
|
|
43
|
+
return configs;
|
|
44
|
+
return { ...configs, [field]: { ...current, ...defaults } };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=launch-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-defaults.js","sourceRoot":"","sources":["../../src/web/launch-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,OAAU,EACV,cAAc,GAAG,KAAK;IAEtB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,EAAE,YAAY,CAAC,cAAc,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,EAAE,MAAM,CAAC,iBAAiB,CAAC;IAC9C,IAAI,cAAc,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IAEvE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAA0B,aAAa,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACzG,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;IACvD,MAAM,OAAO,GAAI,OAAmC,CAAC,KAAK,CAAwC,CAAC;IACnG,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QACtF,sEAAsE;QACtE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;QACxC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,KAAK,SAAS;YAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IACxG,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACvD,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,EAAE,EAAE,CAAC;AAC9D,CAAC"}
|
|
Binary file
|
|
Binary file
|