@caoruhua/open-claude-remote 0.1.0 → 0.1.3
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 +285 -295
- package/dist/backend/src/api/auth-routes.d.ts.map +1 -0
- package/dist/backend/src/api/auth-routes.js.map +1 -0
- package/dist/backend/src/api/config-routes.d.ts +7 -0
- package/dist/backend/src/api/config-routes.d.ts.map +1 -0
- package/dist/{api → backend/src/api}/config-routes.js +125 -13
- package/dist/backend/src/api/config-routes.js.map +1 -0
- package/dist/backend/src/api/health-routes.d.ts.map +1 -0
- package/dist/backend/src/api/health-routes.js.map +1 -0
- package/dist/backend/src/api/hook-routes.d.ts.map +1 -0
- package/dist/backend/src/api/hook-routes.js.map +1 -0
- package/dist/{api → backend/src/api}/instance-routes.d.ts +5 -1
- package/dist/backend/src/api/instance-routes.d.ts.map +1 -0
- package/dist/{api → backend/src/api}/instance-routes.js +5 -1
- package/dist/backend/src/api/instance-routes.js.map +1 -0
- package/dist/backend/src/api/push-routes.d.ts.map +1 -0
- package/dist/backend/src/api/push-routes.js.map +1 -0
- package/dist/{api → backend/src/api}/router.d.ts +7 -1
- package/dist/backend/src/api/router.d.ts.map +1 -0
- package/dist/{api → backend/src/api}/router.js +1 -1
- package/dist/backend/src/api/router.js.map +1 -0
- package/dist/backend/src/api/status-routes.d.ts.map +1 -0
- package/dist/backend/src/api/status-routes.js.map +1 -0
- package/dist/backend/src/attach.d.ts.map +1 -0
- package/dist/{attach.js → backend/src/attach.js} +11 -11
- package/dist/backend/src/attach.js.map +1 -0
- package/dist/backend/src/auth/auth-middleware.d.ts.map +1 -0
- package/dist/backend/src/auth/auth-middleware.js.map +1 -0
- package/dist/backend/src/auth/rate-limiter.d.ts.map +1 -0
- package/dist/backend/src/auth/rate-limiter.js.map +1 -0
- package/dist/backend/src/auth/token-generator.d.ts.map +1 -0
- package/dist/{auth → backend/src/auth}/token-generator.js +1 -1
- package/dist/backend/src/auth/token-generator.js.map +1 -0
- package/dist/{cli-utils.d.ts → backend/src/cli-utils.d.ts} +3 -3
- package/dist/backend/src/cli-utils.d.ts.map +1 -0
- package/dist/{cli-utils.js → backend/src/cli-utils.js} +49 -36
- package/dist/backend/src/cli-utils.js.map +1 -0
- package/dist/backend/src/cli.d.ts +22 -0
- package/dist/backend/src/cli.d.ts.map +1 -0
- package/dist/{cli.js → backend/src/cli.js} +21 -16
- package/dist/backend/src/cli.js.map +1 -0
- package/dist/{config.d.ts → backend/src/config.d.ts} +29 -5
- package/dist/backend/src/config.d.ts.map +1 -0
- package/dist/{config.js → backend/src/config.js} +198 -12
- package/dist/backend/src/config.js.map +1 -0
- package/dist/backend/src/deps/detector.d.ts +18 -0
- package/dist/backend/src/deps/detector.d.ts.map +1 -0
- package/dist/backend/src/deps/detector.js +49 -0
- package/dist/backend/src/deps/detector.js.map +1 -0
- package/dist/backend/src/deps/index.d.ts +14 -0
- package/dist/backend/src/deps/index.d.ts.map +1 -0
- package/dist/backend/src/deps/index.js +219 -0
- package/dist/backend/src/deps/index.js.map +1 -0
- package/dist/backend/src/deps/installer.d.ts +13 -0
- package/dist/backend/src/deps/installer.d.ts.map +1 -0
- package/dist/backend/src/deps/installer.js +113 -0
- package/dist/backend/src/deps/installer.js.map +1 -0
- package/dist/backend/src/deps/platform.d.ts +27 -0
- package/dist/backend/src/deps/platform.d.ts.map +1 -0
- package/dist/backend/src/deps/platform.js +154 -0
- package/dist/backend/src/deps/platform.js.map +1 -0
- package/dist/backend/src/deps/prompt.d.ts +51 -0
- package/dist/backend/src/deps/prompt.d.ts.map +1 -0
- package/dist/backend/src/deps/prompt.js +128 -0
- package/dist/backend/src/deps/prompt.js.map +1 -0
- package/dist/backend/src/deps/types.d.ts +40 -0
- package/dist/backend/src/deps/types.d.ts.map +1 -0
- package/dist/backend/src/deps/types.js +54 -0
- package/dist/backend/src/deps/types.js.map +1 -0
- package/dist/backend/src/hooks/hook-receiver.d.ts +39 -0
- package/dist/backend/src/hooks/hook-receiver.d.ts.map +1 -0
- package/dist/backend/src/hooks/hook-receiver.js +96 -0
- package/dist/backend/src/hooks/hook-receiver.js.map +1 -0
- package/dist/backend/src/hooks/hook-types.d.ts +165 -0
- package/dist/backend/src/hooks/hook-types.d.ts.map +1 -0
- package/dist/backend/src/hooks/hook-types.js +16 -0
- package/dist/backend/src/hooks/hook-types.js.map +1 -0
- package/dist/backend/src/index.d.ts.map +1 -0
- package/dist/{index.js → backend/src/index.js} +27 -32
- package/dist/backend/src/index.js.map +1 -0
- package/dist/backend/src/logger/logger.d.ts.map +1 -0
- package/dist/{logger → backend/src/logger}/logger.js +3 -5
- package/dist/{logger → backend/src/logger}/logger.js.map +1 -1
- package/dist/backend/src/notification/dingtalk-service.d.ts.map +1 -0
- package/dist/{notification → backend/src/notification}/dingtalk-service.js +1 -1
- package/dist/backend/src/notification/dingtalk-service.js.map +1 -0
- package/dist/backend/src/notification/notification-manager.d.ts +44 -0
- package/dist/backend/src/notification/notification-manager.d.ts.map +1 -0
- package/dist/backend/src/notification/notification-manager.js +94 -0
- package/dist/backend/src/notification/notification-manager.js.map +1 -0
- package/dist/backend/src/notification/notification-service-factory.d.ts +67 -0
- package/dist/backend/src/notification/notification-service-factory.d.ts.map +1 -0
- package/dist/backend/src/notification/notification-service-factory.js +146 -0
- package/dist/backend/src/notification/notification-service-factory.js.map +1 -0
- package/dist/backend/src/notification/wechat-work-service.d.ts +24 -0
- package/dist/backend/src/notification/wechat-work-service.d.ts.map +1 -0
- package/dist/backend/src/notification/wechat-work-service.js +88 -0
- package/dist/backend/src/notification/wechat-work-service.js.map +1 -0
- package/dist/backend/src/pty/output-buffer.d.ts.map +1 -0
- package/dist/backend/src/pty/output-buffer.js.map +1 -0
- package/dist/backend/src/pty/pty-manager.d.ts.map +1 -0
- package/dist/backend/src/pty/pty-manager.js.map +1 -0
- package/dist/backend/src/pty/types.d.ts.map +1 -0
- package/dist/{pty → backend/src/pty}/types.js.map +1 -1
- package/dist/backend/src/pty/virtual-pty.d.ts.map +1 -0
- package/dist/backend/src/pty/virtual-pty.js.map +1 -0
- package/dist/backend/src/push/push-service.d.ts.map +1 -0
- package/dist/backend/src/push/push-service.js.map +1 -0
- package/dist/{registry → backend/src/registry}/instance-registry.d.ts +1 -1
- package/dist/backend/src/registry/instance-registry.d.ts.map +1 -0
- package/dist/{registry → backend/src/registry}/instance-registry.js +1 -1
- package/dist/backend/src/registry/instance-registry.js.map +1 -0
- package/dist/backend/src/registry/instance-spawner.d.ts.map +1 -0
- package/dist/{registry → backend/src/registry}/instance-spawner.js +17 -5
- package/dist/backend/src/registry/instance-spawner.js.map +1 -0
- package/dist/backend/src/registry/port-finder.d.ts.map +1 -0
- package/dist/backend/src/registry/port-finder.js.map +1 -0
- package/dist/backend/src/registry/shared-token.d.ts.map +1 -0
- package/dist/backend/src/registry/shared-token.js.map +1 -0
- package/dist/{registry → backend/src/registry}/stop-instances.d.ts +1 -1
- package/dist/backend/src/registry/stop-instances.d.ts.map +1 -0
- package/dist/{registry → backend/src/registry}/stop-instances.js +1 -1
- package/dist/backend/src/registry/stop-instances.js.map +1 -0
- package/dist/{session → backend/src/session}/session-controller.d.ts +21 -6
- package/dist/backend/src/session/session-controller.d.ts.map +1 -0
- package/dist/{session → backend/src/session}/session-controller.js +108 -25
- package/dist/backend/src/session/session-controller.js.map +1 -0
- package/dist/backend/src/terminal/terminal-relay.d.ts.map +1 -0
- package/dist/backend/src/terminal/terminal-relay.js.map +1 -0
- package/dist/backend/src/utils/ansi-filter.d.ts.map +1 -0
- package/dist/backend/src/utils/ansi-filter.js.map +1 -0
- package/dist/backend/src/utils/file-lock.d.ts.map +1 -0
- package/dist/backend/src/utils/file-lock.js.map +1 -0
- package/dist/backend/src/utils/ip-monitor.d.ts.map +1 -0
- package/dist/backend/src/utils/ip-monitor.js.map +1 -0
- package/dist/backend/src/utils/network.d.ts.map +1 -0
- package/dist/backend/src/utils/network.js.map +1 -0
- package/dist/backend/src/utils/qrcode-banner.d.ts.map +1 -0
- package/dist/backend/src/utils/qrcode-banner.js.map +1 -0
- package/dist/backend/src/ws/ws-handler.d.ts.map +1 -0
- package/dist/backend/src/ws/ws-handler.js.map +1 -0
- package/dist/{ws → backend/src/ws}/ws-server.d.ts +1 -1
- package/dist/backend/src/ws/ws-server.d.ts.map +1 -0
- package/dist/{ws → backend/src/ws}/ws-server.js +2 -2
- package/dist/backend/src/ws/ws-server.js.map +1 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/defaults.d.ts.map +1 -0
- package/dist/shared/defaults.js.map +1 -0
- package/{shared-dist → dist/shared}/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/{shared-dist → dist/shared}/index.js +1 -0
- package/dist/shared/index.js.map +1 -0
- package/{shared-dist → dist/shared}/instance.d.ts +13 -0
- package/dist/shared/instance.d.ts.map +1 -0
- package/dist/shared/instance.js.map +1 -0
- package/dist/shared/notification-types.d.ts +85 -0
- package/dist/shared/notification-types.d.ts.map +1 -0
- package/dist/shared/notification-types.js +92 -0
- package/dist/shared/notification-types.js.map +1 -0
- package/{shared-dist → dist/shared}/ws-protocol.d.ts +6 -1
- package/dist/shared/ws-protocol.d.ts.map +1 -0
- package/dist/shared/ws-protocol.js.map +1 -0
- package/frontend-dist/assets/index-DOeBWumG.js +152 -0
- package/frontend-dist/index.html +2 -2
- package/package.json +62 -27
- package/scripts/build.sh +21 -0
- package/scripts/dev.sh +11 -0
- package/scripts/fix-node-pty-permissions.js +47 -0
- package/scripts/git-hooks/pre-commit +258 -0
- package/scripts/stop.sh +5 -0
- package/dist/api/auth-routes.d.ts.map +0 -1
- package/dist/api/auth-routes.js.map +0 -1
- package/dist/api/config-routes.d.ts +0 -4
- package/dist/api/config-routes.d.ts.map +0 -1
- package/dist/api/config-routes.js.map +0 -1
- package/dist/api/health-routes.d.ts.map +0 -1
- package/dist/api/health-routes.js.map +0 -1
- package/dist/api/hook-routes.d.ts.map +0 -1
- package/dist/api/hook-routes.js.map +0 -1
- package/dist/api/instance-routes.d.ts.map +0 -1
- package/dist/api/instance-routes.js.map +0 -1
- package/dist/api/push-routes.d.ts.map +0 -1
- package/dist/api/push-routes.js.map +0 -1
- package/dist/api/router.d.ts.map +0 -1
- package/dist/api/router.js.map +0 -1
- package/dist/api/status-routes.d.ts.map +0 -1
- package/dist/api/status-routes.js.map +0 -1
- package/dist/attach.d.ts.map +0 -1
- package/dist/attach.js.map +0 -1
- package/dist/auth/auth-middleware.d.ts.map +0 -1
- package/dist/auth/auth-middleware.js.map +0 -1
- package/dist/auth/rate-limiter.d.ts.map +0 -1
- package/dist/auth/rate-limiter.js.map +0 -1
- package/dist/auth/token-generator.d.ts.map +0 -1
- package/dist/auth/token-generator.js.map +0 -1
- package/dist/cli-utils.d.ts.map +0 -1
- package/dist/cli-utils.js.map +0 -1
- package/dist/cli.d.ts +0 -21
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/hooks/hook-receiver.d.ts +0 -39
- package/dist/hooks/hook-receiver.d.ts.map +0 -1
- package/dist/hooks/hook-receiver.js +0 -46
- package/dist/hooks/hook-receiver.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger/logger.d.ts.map +0 -1
- package/dist/notification/dingtalk-service.d.ts.map +0 -1
- package/dist/notification/dingtalk-service.js.map +0 -1
- package/dist/pty/output-buffer.d.ts.map +0 -1
- package/dist/pty/output-buffer.js.map +0 -1
- package/dist/pty/pty-manager.d.ts.map +0 -1
- package/dist/pty/pty-manager.js.map +0 -1
- package/dist/pty/types.d.ts.map +0 -1
- package/dist/pty/virtual-pty.d.ts.map +0 -1
- package/dist/pty/virtual-pty.js.map +0 -1
- package/dist/push/push-service.d.ts.map +0 -1
- package/dist/push/push-service.js.map +0 -1
- package/dist/registry/instance-registry.d.ts.map +0 -1
- package/dist/registry/instance-registry.js.map +0 -1
- package/dist/registry/instance-spawner.d.ts.map +0 -1
- package/dist/registry/instance-spawner.js.map +0 -1
- package/dist/registry/port-finder.d.ts.map +0 -1
- package/dist/registry/port-finder.js.map +0 -1
- package/dist/registry/shared-token.d.ts.map +0 -1
- package/dist/registry/shared-token.js.map +0 -1
- package/dist/registry/stop-instances.d.ts.map +0 -1
- package/dist/registry/stop-instances.js.map +0 -1
- package/dist/session/session-controller.d.ts.map +0 -1
- package/dist/session/session-controller.js.map +0 -1
- package/dist/terminal/terminal-relay.d.ts.map +0 -1
- package/dist/terminal/terminal-relay.js.map +0 -1
- package/dist/utils/ansi-filter.d.ts.map +0 -1
- package/dist/utils/ansi-filter.js.map +0 -1
- package/dist/utils/file-lock.d.ts.map +0 -1
- package/dist/utils/file-lock.js.map +0 -1
- package/dist/utils/ip-monitor.d.ts.map +0 -1
- package/dist/utils/ip-monitor.js.map +0 -1
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/network.js.map +0 -1
- package/dist/utils/pid-file.d.ts +0 -10
- package/dist/utils/pid-file.d.ts.map +0 -1
- package/dist/utils/pid-file.js +0 -30
- package/dist/utils/pid-file.js.map +0 -1
- package/dist/utils/qrcode-banner.d.ts.map +0 -1
- package/dist/utils/qrcode-banner.js.map +0 -1
- package/dist/ws/ws-handler.d.ts.map +0 -1
- package/dist/ws/ws-handler.js.map +0 -1
- package/dist/ws/ws-server.d.ts.map +0 -1
- package/dist/ws/ws-server.js.map +0 -1
- package/frontend-dist/assets/index-BqqB1hYe.js +0 -141
- package/shared-dist/constants.d.ts.map +0 -1
- package/shared-dist/constants.js.map +0 -1
- package/shared-dist/defaults.d.ts.map +0 -1
- package/shared-dist/defaults.js.map +0 -1
- package/shared-dist/index.d.ts.map +0 -1
- package/shared-dist/index.js.map +0 -1
- package/shared-dist/instance.d.ts.map +0 -1
- package/shared-dist/instance.js.map +0 -1
- package/shared-dist/question-utils.d.ts +0 -15
- package/shared-dist/question-utils.d.ts.map +0 -1
- package/shared-dist/question-utils.js +0 -24
- package/shared-dist/question-utils.js.map +0 -1
- package/shared-dist/ws-protocol.d.ts.map +0 -1
- package/shared-dist/ws-protocol.js.map +0 -1
- /package/dist/{api → backend/src/api}/auth-routes.d.ts +0 -0
- /package/dist/{api → backend/src/api}/auth-routes.js +0 -0
- /package/dist/{api → backend/src/api}/health-routes.d.ts +0 -0
- /package/dist/{api → backend/src/api}/health-routes.js +0 -0
- /package/dist/{api → backend/src/api}/hook-routes.d.ts +0 -0
- /package/dist/{api → backend/src/api}/hook-routes.js +0 -0
- /package/dist/{api → backend/src/api}/push-routes.d.ts +0 -0
- /package/dist/{api → backend/src/api}/push-routes.js +0 -0
- /package/dist/{api → backend/src/api}/status-routes.d.ts +0 -0
- /package/dist/{api → backend/src/api}/status-routes.js +0 -0
- /package/dist/{attach.d.ts → backend/src/attach.d.ts} +0 -0
- /package/dist/{auth → backend/src/auth}/auth-middleware.d.ts +0 -0
- /package/dist/{auth → backend/src/auth}/auth-middleware.js +0 -0
- /package/dist/{auth → backend/src/auth}/rate-limiter.d.ts +0 -0
- /package/dist/{auth → backend/src/auth}/rate-limiter.js +0 -0
- /package/dist/{auth → backend/src/auth}/token-generator.d.ts +0 -0
- /package/dist/{index.d.ts → backend/src/index.d.ts} +0 -0
- /package/dist/{logger → backend/src/logger}/logger.d.ts +0 -0
- /package/dist/{notification → backend/src/notification}/dingtalk-service.d.ts +0 -0
- /package/dist/{pty → backend/src/pty}/output-buffer.d.ts +0 -0
- /package/dist/{pty → backend/src/pty}/output-buffer.js +0 -0
- /package/dist/{pty → backend/src/pty}/pty-manager.d.ts +0 -0
- /package/dist/{pty → backend/src/pty}/pty-manager.js +0 -0
- /package/dist/{pty → backend/src/pty}/types.d.ts +0 -0
- /package/dist/{pty → backend/src/pty}/types.js +0 -0
- /package/dist/{pty → backend/src/pty}/virtual-pty.d.ts +0 -0
- /package/dist/{pty → backend/src/pty}/virtual-pty.js +0 -0
- /package/dist/{push → backend/src/push}/push-service.d.ts +0 -0
- /package/dist/{push → backend/src/push}/push-service.js +0 -0
- /package/dist/{registry → backend/src/registry}/instance-spawner.d.ts +0 -0
- /package/dist/{registry → backend/src/registry}/port-finder.d.ts +0 -0
- /package/dist/{registry → backend/src/registry}/port-finder.js +0 -0
- /package/dist/{registry → backend/src/registry}/shared-token.d.ts +0 -0
- /package/dist/{registry → backend/src/registry}/shared-token.js +0 -0
- /package/dist/{terminal → backend/src/terminal}/terminal-relay.d.ts +0 -0
- /package/dist/{terminal → backend/src/terminal}/terminal-relay.js +0 -0
- /package/dist/{utils → backend/src/utils}/ansi-filter.d.ts +0 -0
- /package/dist/{utils → backend/src/utils}/ansi-filter.js +0 -0
- /package/dist/{utils → backend/src/utils}/file-lock.d.ts +0 -0
- /package/dist/{utils → backend/src/utils}/file-lock.js +0 -0
- /package/dist/{utils → backend/src/utils}/ip-monitor.d.ts +0 -0
- /package/dist/{utils → backend/src/utils}/ip-monitor.js +0 -0
- /package/dist/{utils → backend/src/utils}/network.d.ts +0 -0
- /package/dist/{utils → backend/src/utils}/network.js +0 -0
- /package/dist/{utils → backend/src/utils}/qrcode-banner.d.ts +0 -0
- /package/dist/{utils → backend/src/utils}/qrcode-banner.js +0 -0
- /package/dist/{ws → backend/src/ws}/ws-handler.d.ts +0 -0
- /package/dist/{ws → backend/src/ws}/ws-handler.js +0 -0
- /package/{shared-dist → dist/shared}/constants.d.ts +0 -0
- /package/{shared-dist → dist/shared}/constants.js +0 -0
- /package/{shared-dist → dist/shared}/defaults.d.ts +0 -0
- /package/{shared-dist → dist/shared}/defaults.js +0 -0
- /package/{shared-dist → dist/shared}/instance.js +0 -0
- /package/{shared-dist → dist/shared}/ws-protocol.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI
|
|
2
|
+
* CLI argument parsing utilities.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Extracted from cli.ts to avoid static imports in the entry point.
|
|
5
5
|
*/
|
|
6
6
|
function parsePort(raw) {
|
|
7
7
|
if (!raw || !/^\d+$/.test(raw)) {
|
|
@@ -20,12 +20,12 @@ export function parseCliArgs(argv) {
|
|
|
20
20
|
claudeArgs: [],
|
|
21
21
|
};
|
|
22
22
|
let i = 2; // Skip 'node' and script path
|
|
23
|
-
//
|
|
23
|
+
// Check subcommands
|
|
24
24
|
if (argv.length > 2) {
|
|
25
25
|
const firstArg = argv[2];
|
|
26
26
|
if (firstArg === 'attach') {
|
|
27
27
|
if (argv.length <= 3) {
|
|
28
|
-
throw new Error('attach
|
|
28
|
+
throw new Error('attach requires a target instance (port or name)');
|
|
29
29
|
}
|
|
30
30
|
options.attach = argv[3];
|
|
31
31
|
return options;
|
|
@@ -88,45 +88,58 @@ export function parseCliArgs(argv) {
|
|
|
88
88
|
}
|
|
89
89
|
export function showHelp() {
|
|
90
90
|
console.log(`
|
|
91
|
-
Claude Code Remote -
|
|
91
|
+
Claude Code Remote - Control Claude Code from your mobile browser over LAN
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
Usage:
|
|
94
94
|
claude-remote [options] [--] [claude args...]
|
|
95
|
-
claude-remote attach <port|name>
|
|
95
|
+
claude-remote attach <port|name>
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
--port <number>
|
|
99
|
-
--host <ip>
|
|
100
|
-
--token <string>
|
|
101
|
-
--name <string>
|
|
102
|
-
--no-terminal
|
|
103
|
-
--help, -h
|
|
97
|
+
Options:
|
|
98
|
+
--port <number> Server port (default: 3000, auto-increments if busy)
|
|
99
|
+
--host <ip> Bind address (default: auto-detect LAN IP)
|
|
100
|
+
--token <string> Auth token (default: shared token)
|
|
101
|
+
--name <string> Instance name (default: working directory name)
|
|
102
|
+
--no-terminal Headless mode (internal: for web-spawned instances)
|
|
103
|
+
--help, -h Show this help message
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
~/.claude-remote/config.json
|
|
105
|
+
Config file:
|
|
106
|
+
~/.claude-remote/config.json
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
port
|
|
110
|
-
host
|
|
111
|
-
token
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
claudeCwd Claude 工作目录 (默认: 当前目录)
|
|
115
|
-
claudeArgs Claude CLI 额外参数 (数组)
|
|
116
|
-
maxBufferLines 输出缓冲区行数 (默认: 10000)
|
|
117
|
-
workspaces 预设工作目录列表 (数组)
|
|
118
|
-
defaultClaudeArgs 默认 Claude 参数 (数组)
|
|
108
|
+
Server options:
|
|
109
|
+
port Server port (default: 3000)
|
|
110
|
+
host Bind address (default: "0.0.0.0")
|
|
111
|
+
token Auth token (default: auto-generated shared token)
|
|
112
|
+
sessionTtlMs Session TTL in ms (default: 86400000 = 24h)
|
|
113
|
+
authRateLimit Auth rate limit per min per IP (default: 20)
|
|
119
114
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
claude-remote --name api # 自定义实例名称
|
|
125
|
-
claude-remote -- --dangerously-skip-permissions # 透传参数给 claude
|
|
126
|
-
claude-remote attach 3001 # 接管端口 3001 的实例
|
|
127
|
-
claude-remote attach myproject # 接管名为 myproject 的实例
|
|
115
|
+
Claude CLI options:
|
|
116
|
+
claudeCommand Claude CLI path (default: "claude")
|
|
117
|
+
claudeArgs Extra Claude CLI arguments (array)
|
|
118
|
+
claudeCwd Claude working directory (default: current dir)
|
|
128
119
|
|
|
129
|
-
|
|
120
|
+
Instance options:
|
|
121
|
+
instanceName Instance name (default: working dir name)
|
|
122
|
+
maxBufferLines Output buffer max lines (default: 10000)
|
|
123
|
+
workspaces Allowed working directories for web-spawned instances (array)
|
|
124
|
+
|
|
125
|
+
UI options:
|
|
126
|
+
shortcuts Quick-input buttons (array, see README for format)
|
|
127
|
+
commands Custom command buttons (array, see README for format)
|
|
128
|
+
|
|
129
|
+
Notification options:
|
|
130
|
+
dingtalk DingTalk notification config (object)
|
|
131
|
+
Example: { "webhookUrl": "https://oapi.dingtalk.com/..." }
|
|
132
|
+
|
|
133
|
+
Examples:
|
|
134
|
+
claude-remote # Start Claude Code
|
|
135
|
+
claude-remote chat # Start in chat mode
|
|
136
|
+
claude-remote --port 8080 # Use port 8080
|
|
137
|
+
claude-remote --name api # Custom instance name
|
|
138
|
+
claude-remote -- --dangerously-skip-permissions # Pass args to claude
|
|
139
|
+
claude-remote attach 3001 # Attach to instance on port 3001
|
|
140
|
+
claude-remote attach myproject # Attach to instance named myproject
|
|
141
|
+
|
|
142
|
+
For more Claude Code options, run: claude --help
|
|
130
143
|
`);
|
|
131
144
|
}
|
|
132
145
|
//# sourceMappingURL=cli-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-utils.js","sourceRoot":"","sources":["../../../backend/src/cli-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* claude-remote CLI entry point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* claude-remote [options] [--] [claude args...]
|
|
7
|
+
* claude-remote attach <port|name>
|
|
8
|
+
*
|
|
9
|
+
* Options:
|
|
10
|
+
* --port <number> Server port (default: 3000, auto-increments if busy)
|
|
11
|
+
* --host <ip> Bind address (default: auto-detect LAN IP)
|
|
12
|
+
* --token <string> Auth token (default: shared token)
|
|
13
|
+
* --name <string> Instance name (default: working directory name)
|
|
14
|
+
* --help, -h Show help
|
|
15
|
+
*
|
|
16
|
+
* All other arguments are passed through to the claude command.
|
|
17
|
+
*
|
|
18
|
+
* Note: This file must not have any static imports because ESM hoists them
|
|
19
|
+
* to execute at module top-level, which would cause CLI_MODE to be set
|
|
20
|
+
* after the logger module has already loaded.
|
|
21
|
+
*/
|
|
22
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../backend/src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
|
@@ -3,34 +3,34 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* claude-remote CLI entry point
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Usage:
|
|
7
7
|
* claude-remote [options] [--] [claude args...]
|
|
8
8
|
* claude-remote attach <port|name>
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* --port <number>
|
|
12
|
-
* --host <ip>
|
|
13
|
-
* --token <string>
|
|
14
|
-
* --name <string>
|
|
15
|
-
* --help, -h
|
|
10
|
+
* Options:
|
|
11
|
+
* --port <number> Server port (default: 3000, auto-increments if busy)
|
|
12
|
+
* --host <ip> Bind address (default: auto-detect LAN IP)
|
|
13
|
+
* --token <string> Auth token (default: shared token)
|
|
14
|
+
* --name <string> Instance name (default: working directory name)
|
|
15
|
+
* --help, -h Show help
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* All other arguments are passed through to the claude command.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Note: This file must not have any static imports because ESM hoists them
|
|
20
|
+
* to execute at module top-level, which would cause CLI_MODE to be set
|
|
21
|
+
* after the logger module has already loaded.
|
|
21
22
|
*/
|
|
22
|
-
//
|
|
23
|
+
// Must set CLI_MODE before any module loads, as logger.ts reads it at module top-level
|
|
23
24
|
process.env.CLI_MODE = 'true';
|
|
24
|
-
//
|
|
25
|
+
// All modules must use dynamic import
|
|
25
26
|
void (async () => {
|
|
26
|
-
const { fileURLToPath } = await import('node:url');
|
|
27
27
|
const { parseCliArgs, showHelp } = await import('./cli-utils.js');
|
|
28
28
|
const options = parseCliArgs(process.argv);
|
|
29
29
|
if (options.help) {
|
|
30
30
|
showHelp();
|
|
31
31
|
process.exit(0);
|
|
32
32
|
}
|
|
33
|
-
//
|
|
33
|
+
// Handle attach subcommand
|
|
34
34
|
if (options.attach) {
|
|
35
35
|
const { attachInstance } = await import('./attach.js');
|
|
36
36
|
await attachInstance({ target: options.attach });
|
|
@@ -40,7 +40,12 @@ void (async () => {
|
|
|
40
40
|
if (options.noTerminal) {
|
|
41
41
|
process.env.NO_TERMINAL = 'true';
|
|
42
42
|
}
|
|
43
|
-
//
|
|
43
|
+
// Detect and install missing dependencies (pnpm, claude CLI, etc.)
|
|
44
|
+
const { ensureDependencies } = await import('./deps/index.js');
|
|
45
|
+
const depsResult = await ensureDependencies();
|
|
46
|
+
if (!depsResult.allInstalled) {
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
44
49
|
const { loadConfig, createSessionCookieName } = await import('./config.js');
|
|
45
50
|
// Build CLI overrides for config
|
|
46
51
|
const cliOverrides = {
|
|
@@ -51,7 +56,7 @@ void (async () => {
|
|
|
51
56
|
claudeArgs: options.claudeArgs.length > 0 ? options.claudeArgs : undefined,
|
|
52
57
|
noTerminal: options.noTerminal,
|
|
53
58
|
};
|
|
54
|
-
//
|
|
59
|
+
// Dynamically load startServer
|
|
55
60
|
const { startServer } = await import('./index.js');
|
|
56
61
|
await startServer(cliOverrides);
|
|
57
62
|
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../backend/src/cli.ts"],"names":[],"mappings":";;AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,uFAAuF;AACvF,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC;AAE9B,sCAAsC;AACtC,KAAK,CAAC,KAAK,IAAI,EAAE;IACf,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,QAAQ,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACvD,MAAM,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,yCAAyC;IACzC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC;IACnC,CAAC;IAED,mEAAmE;IACnE,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAE5E,iCAAiC;IACjC,MAAM,YAAY,GAAG;QACnB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,YAAY,EAAE,OAAO,CAAC,IAAI;QAC1B,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAC1E,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC;IAEF,+BAA+B;IAC/B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,WAAW,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC,CAAC,EAAE,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type NotificationConfigs, type SettingsFile } from '../../shared/index.js';
|
|
1
2
|
/**
|
|
2
3
|
* 用户配置文件结构 (~/.claude-remote/config.json)
|
|
3
4
|
* 这些是用户可以持久化的配置项
|
|
@@ -39,11 +40,10 @@ export interface UserConfig {
|
|
|
39
40
|
}>;
|
|
40
41
|
/** 预设工作目录列表 */
|
|
41
42
|
workspaces?: string[];
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
};
|
|
43
|
+
/** 多渠道通知配置 */
|
|
44
|
+
notifications?: NotificationConfigs;
|
|
45
|
+
/** Settings 文件扫描目录列表(默认: ["~/.claude/", "~/.claude-remote/settings/"]) */
|
|
46
|
+
settingsDirs?: string[];
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* 运行时配置结构 (融合用户配置 + CLI 参数 + 默认值)
|
|
@@ -143,4 +143,28 @@ export declare function extractSettingsFromArgs(args: string[]): {
|
|
|
143
143
|
settingsValue: Record<string, unknown>;
|
|
144
144
|
otherArgs: string[];
|
|
145
145
|
} | null;
|
|
146
|
+
/**
|
|
147
|
+
* 获取默认 Settings 扫描目录列表
|
|
148
|
+
* @returns 默认目录路径数组(已展开 ~ 为实际路径)
|
|
149
|
+
*/
|
|
150
|
+
export declare function getDefaultSettingsDirs(): string[];
|
|
151
|
+
/**
|
|
152
|
+
* 获取配置的 Settings 目录列表
|
|
153
|
+
* @param userConfig 用户配置(可选)
|
|
154
|
+
* @returns 目录路径数组(已展开 ~ 为实际路径)
|
|
155
|
+
*/
|
|
156
|
+
export declare function getSettingsDirs(userConfig?: UserConfig): string[];
|
|
157
|
+
/**
|
|
158
|
+
* 扫描多个目录中的 settings 文件
|
|
159
|
+
* @param settingsDirs 要扫描的目录列表
|
|
160
|
+
* @returns Settings 文件列表(已去重)
|
|
161
|
+
*/
|
|
162
|
+
export declare function scanSettingsFiles(settingsDirs: string[]): SettingsFile[];
|
|
163
|
+
/**
|
|
164
|
+
* 从多个目录中查找 settings 文件的完整路径
|
|
165
|
+
* @param settingsDirs 要搜索的目录列表
|
|
166
|
+
* @param filename 文件名
|
|
167
|
+
* @returns 完整文件路径,未找到返回 null
|
|
168
|
+
*/
|
|
169
|
+
export declare function getSettingsFilePath(settingsDirs: string[], filename: string): string | null;
|
|
146
170
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../backend/src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DEFAULT_PORT, DEFAULT_SESSION_TTL_MS, DEFAULT_AUTH_RATE_LIMIT, DEFAULT_MAX_BUFFER_LINES, SETTINGS_DIR, CLAUDE_REMOTE_DIR, DEFAULT_SHORTCUTS as SHARED_DEFAULT_SHORTCUTS, DEFAULT_COMMANDS as SHARED_DEFAULT_COMMANDS, } from '
|
|
2
|
-
import { basename, dirname, resolve } from 'node:path';
|
|
1
|
+
import { DEFAULT_PORT, DEFAULT_SESSION_TTL_MS, DEFAULT_AUTH_RATE_LIMIT, DEFAULT_MAX_BUFFER_LINES, SETTINGS_DIR, CLAUDE_REMOTE_DIR, DEFAULT_SHORTCUTS as SHARED_DEFAULT_SHORTCUTS, DEFAULT_COMMANDS as SHARED_DEFAULT_COMMANDS, } from '../../shared/index.js';
|
|
2
|
+
import { basename, dirname, resolve, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';
|
|
5
5
|
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
7
|
import { detectLanIp, detectNonLoopbackIp } from './utils/network.js';
|
|
@@ -36,12 +36,36 @@ export function loadUserConfig(configDir) {
|
|
|
36
36
|
try {
|
|
37
37
|
const content = readFileSync(configPath, 'utf-8');
|
|
38
38
|
const config = JSON.parse(content);
|
|
39
|
-
// 向后兼容:迁移旧的 defaultClaudeArgs 到 claudeArgs
|
|
40
39
|
const rawConfig = config;
|
|
40
|
+
let needsSave = false;
|
|
41
|
+
// 向后兼容:迁移旧的 defaultClaudeArgs 到 claudeArgs
|
|
41
42
|
if (!config.claudeArgs && rawConfig.defaultClaudeArgs) {
|
|
42
43
|
config.claudeArgs = rawConfig.defaultClaudeArgs;
|
|
44
|
+
delete rawConfig.defaultClaudeArgs;
|
|
45
|
+
needsSave = true;
|
|
43
46
|
logger.info('Migrated defaultClaudeArgs to claudeArgs');
|
|
44
47
|
}
|
|
48
|
+
// 迁移旧版 dingtalk 配置到 notifications.dingtalk(仅在新版未配置时)
|
|
49
|
+
if (rawConfig.dingtalk) {
|
|
50
|
+
if (!config.notifications) {
|
|
51
|
+
config.notifications = {};
|
|
52
|
+
}
|
|
53
|
+
// 仅在 notifications.dingtalk 不存在时迁移,避免覆盖已有新版配置
|
|
54
|
+
if (!config.notifications.dingtalk) {
|
|
55
|
+
config.notifications.dingtalk = rawConfig.dingtalk;
|
|
56
|
+
logger.info('Migrated legacy dingtalk config to notifications.dingtalk');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
logger.info('Skipped dingtalk migration: notifications.dingtalk already exists');
|
|
60
|
+
}
|
|
61
|
+
delete rawConfig.dingtalk;
|
|
62
|
+
needsSave = true;
|
|
63
|
+
}
|
|
64
|
+
// 如果有迁移发生,保存更新后的配置
|
|
65
|
+
if (needsSave) {
|
|
66
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
67
|
+
logger.info({ configPath }, 'User config migrated and saved');
|
|
68
|
+
}
|
|
45
69
|
logger.info({ configPath, keys: Object.keys(config) }, 'User config loaded');
|
|
46
70
|
return config;
|
|
47
71
|
}
|
|
@@ -64,12 +88,19 @@ export function loadConfig(cliOverrides = {}, configDir) {
|
|
|
64
88
|
// 优先级: CLI > 用户配置 > 默认值
|
|
65
89
|
const port = cliOverrides.port ?? userConfig.port ?? DEFAULT_PORT;
|
|
66
90
|
const claudeCwd = userConfig.claudeCwd ?? process.cwd();
|
|
67
|
-
//
|
|
91
|
+
// claudeArgs 优先级: CLI > 用户配置 > 默认值
|
|
92
|
+
// 当 CLI 显式传参时,完全使用 CLI 参数(不合并配置文件参数)
|
|
93
|
+
// 这样可以避免 web-spawned 实例的参数重复累积问题
|
|
68
94
|
const userArgs = userConfig.claudeArgs ?? [];
|
|
69
95
|
const cliArgs = cliOverrides.claudeArgs ?? [];
|
|
70
|
-
|
|
96
|
+
// 如果 CLI 传了参数(非 undefined),完全使用 CLI 参数
|
|
97
|
+
// 否则使用配置文件参数
|
|
98
|
+
const mergedArgs = cliOverrides.claudeArgs !== undefined ? cliArgs : userArgs;
|
|
71
99
|
if (userArgs.length > 0 && cliArgs.length > 0) {
|
|
72
|
-
logger.info({ userArgs, cliArgs, mergedArgs }, '
|
|
100
|
+
logger.info({ userArgs, cliArgs, mergedArgs }, 'Using CLI claudeArgs (ignoring config file args to avoid duplication)');
|
|
101
|
+
}
|
|
102
|
+
else if (mergedArgs.length > 0) {
|
|
103
|
+
logger.debug({ mergedArgs }, 'Using claudeArgs');
|
|
73
104
|
}
|
|
74
105
|
const config = {
|
|
75
106
|
port,
|
|
@@ -133,22 +164,32 @@ export function createClaudeSettings(port, existingSettings) {
|
|
|
133
164
|
const hookCommand = `curl -s -X POST ${hookUrl} -H 'Content-Type: application/json' -d @-`;
|
|
134
165
|
const hooksConfig = {
|
|
135
166
|
hooks: {
|
|
167
|
+
// 通知事件(permission_prompt, idle_prompt, elicitation_dialog)
|
|
136
168
|
Notification: [
|
|
137
169
|
{
|
|
138
170
|
matcher: "permission_prompt",
|
|
139
171
|
hooks: [{ type: "command", command: hookCommand }]
|
|
140
|
-
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
matcher: "idle_prompt",
|
|
175
|
+
hooks: [{ type: "command", command: hookCommand }]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
matcher: "elicitation_dialog",
|
|
179
|
+
hooks: [{ type: "command", command: hookCommand }]
|
|
180
|
+
},
|
|
141
181
|
],
|
|
142
|
-
|
|
182
|
+
// 任务完成(用于检测用户响应后任务继续执行)
|
|
183
|
+
Stop: [
|
|
143
184
|
{
|
|
144
|
-
matcher: "
|
|
185
|
+
matcher: "",
|
|
145
186
|
hooks: [{ type: "command", command: hookCommand }]
|
|
146
187
|
}
|
|
147
|
-
]
|
|
188
|
+
],
|
|
148
189
|
}
|
|
149
190
|
};
|
|
150
191
|
// 如果有现有 settings,合并 hooks 配置(保留用户自定义的其他 hook 事件)
|
|
151
|
-
// 注意:同名 hook
|
|
192
|
+
// 注意:同名 hook 事件会被我们的配置覆盖,
|
|
152
193
|
// 因为这些事件是 claude-remote 正常工作的必要条件
|
|
153
194
|
if (existingSettings) {
|
|
154
195
|
const existingHooks = (existingSettings.hooks ?? {});
|
|
@@ -326,4 +367,149 @@ export function extractSettingsFromArgs(args) {
|
|
|
326
367
|
}
|
|
327
368
|
return null;
|
|
328
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* 获取默认 Settings 扫描目录列表
|
|
372
|
+
* @returns 默认目录路径数组(已展开 ~ 为实际路径)
|
|
373
|
+
*/
|
|
374
|
+
export function getDefaultSettingsDirs() {
|
|
375
|
+
const home = homedir();
|
|
376
|
+
return [
|
|
377
|
+
resolve(home, '.claude'),
|
|
378
|
+
resolve(home, CLAUDE_REMOTE_DIR, SETTINGS_DIR),
|
|
379
|
+
];
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* 获取配置的 Settings 目录列表
|
|
383
|
+
* @param userConfig 用户配置(可选)
|
|
384
|
+
* @returns 目录路径数组(已展开 ~ 为实际路径)
|
|
385
|
+
*/
|
|
386
|
+
export function getSettingsDirs(userConfig) {
|
|
387
|
+
if (!userConfig?.settingsDirs || userConfig.settingsDirs.length === 0) {
|
|
388
|
+
return getDefaultSettingsDirs();
|
|
389
|
+
}
|
|
390
|
+
// 展开 ~ 为 home 目录
|
|
391
|
+
const home = homedir();
|
|
392
|
+
return userConfig.settingsDirs.map(dir => {
|
|
393
|
+
if (dir.startsWith('~/')) {
|
|
394
|
+
return resolve(home, dir.slice(2));
|
|
395
|
+
}
|
|
396
|
+
return resolve(dir);
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* 安全检查:文件名是否合法
|
|
401
|
+
* - 不能包含路径分隔符
|
|
402
|
+
* - 不能包含路径遍历字符
|
|
403
|
+
* - 必须以 .json 结尾
|
|
404
|
+
*/
|
|
405
|
+
function isSafeSettingsFilename(filename) {
|
|
406
|
+
// 禁止路径分隔符和遍历
|
|
407
|
+
if (filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
// 必须以 .json 结尾
|
|
411
|
+
if (!filename.endsWith('.json')) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* 检查文件名是否为有效的 settings 文件
|
|
418
|
+
* - 以 "settings" 开头(不区分大小写)
|
|
419
|
+
* - 或者为有效的自定义配置文件名(非纯数字)
|
|
420
|
+
*/
|
|
421
|
+
function isValidSettingsFilename(filename) {
|
|
422
|
+
const baseName = filename.slice(0, -5); // 去掉 .json 后缀
|
|
423
|
+
// 排除纯数字文件名(如 3000.json,这些是端口配置)
|
|
424
|
+
if (/^\d+$/.test(baseName)) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
// 以 settings 开头的文件
|
|
428
|
+
if (baseName.toLowerCase().startsWith('settings')) {
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
// 可选:未来可扩展支持其他命名规则
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* 生成显示名称
|
|
436
|
+
* - 去掉 settings 前缀和 .json 后缀
|
|
437
|
+
* - 如果结果为空,使用原文件名
|
|
438
|
+
*/
|
|
439
|
+
function makeDisplayName(filename) {
|
|
440
|
+
const baseName = filename.slice(0, -5); // 去掉 .json 后缀
|
|
441
|
+
// 去掉 settings 前缀(不区分大小写)
|
|
442
|
+
const withoutPrefix = baseName.replace(/^settings[-._]?/i, '');
|
|
443
|
+
// 如果结果为空或只有分隔符,使用原 baseName
|
|
444
|
+
return withoutPrefix.trim() || baseName;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* 扫描多个目录中的 settings 文件
|
|
448
|
+
* @param settingsDirs 要扫描的目录列表
|
|
449
|
+
* @returns Settings 文件列表(已去重)
|
|
450
|
+
*/
|
|
451
|
+
export function scanSettingsFiles(settingsDirs) {
|
|
452
|
+
const seen = new Set();
|
|
453
|
+
const results = [];
|
|
454
|
+
for (const dir of settingsDirs) {
|
|
455
|
+
// 目录不存在则跳过
|
|
456
|
+
if (!existsSync(dir)) {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
461
|
+
for (const entry of entries) {
|
|
462
|
+
// 只处理文件
|
|
463
|
+
if (!entry.isFile())
|
|
464
|
+
continue;
|
|
465
|
+
const filename = entry.name;
|
|
466
|
+
// 安全检查
|
|
467
|
+
if (!isSafeSettingsFilename(filename))
|
|
468
|
+
continue;
|
|
469
|
+
// 有效性检查
|
|
470
|
+
if (!isValidSettingsFilename(filename))
|
|
471
|
+
continue;
|
|
472
|
+
// 去重(基于 filename)
|
|
473
|
+
if (seen.has(filename))
|
|
474
|
+
continue;
|
|
475
|
+
seen.add(filename);
|
|
476
|
+
// 取目录的 basename 用于显示(如 .claude 或 settings)
|
|
477
|
+
const dirDisplay = basename(dir);
|
|
478
|
+
results.push({
|
|
479
|
+
filename,
|
|
480
|
+
displayName: makeDisplayName(filename),
|
|
481
|
+
directory: dirDisplay,
|
|
482
|
+
directoryPath: dir,
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
catch (err) {
|
|
487
|
+
// 目录读取失败,记录日志并跳过
|
|
488
|
+
logger.warn({ dir, err }, 'Failed to scan settings directory');
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// 按显示名称排序
|
|
492
|
+
results.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
493
|
+
return results;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* 从多个目录中查找 settings 文件的完整路径
|
|
497
|
+
* @param settingsDirs 要搜索的目录列表
|
|
498
|
+
* @param filename 文件名
|
|
499
|
+
* @returns 完整文件路径,未找到返回 null
|
|
500
|
+
*/
|
|
501
|
+
export function getSettingsFilePath(settingsDirs, filename) {
|
|
502
|
+
// 安全检查
|
|
503
|
+
if (!isSafeSettingsFilename(filename)) {
|
|
504
|
+
logger.warn({ filename }, 'Invalid settings filename rejected');
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
for (const dir of settingsDirs) {
|
|
508
|
+
const fullPath = join(dir, filename);
|
|
509
|
+
if (existsSync(fullPath)) {
|
|
510
|
+
return fullPath;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
329
515
|
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../backend/src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 依赖检测模块
|
|
3
|
+
*/
|
|
4
|
+
import { type CheckResult, type DependencyName } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* 检测单个依赖是否已安装
|
|
7
|
+
* 使用 execFile 避免命令拼接的安全风险
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkDependency(name: DependencyName): Promise<CheckResult>;
|
|
10
|
+
/**
|
|
11
|
+
* 检测 Node.js 版本是否满足最低要求
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkNodeVersion(version: string, minVersion: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* 检测所有依赖的状态
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkAllDependencies(): Promise<Record<DependencyName, CheckResult>>;
|
|
18
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../../backend/src/deps/detector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAoBhF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAI7E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CACnD,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CACpC,CAQA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 依赖检测模块
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import { DEPENDENCIES, parseMajorVersion, } from './types.js';
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
/**
|
|
9
|
+
* 检测单个依赖是否已安装
|
|
10
|
+
* 使用 execFile 避免命令拼接的安全风险
|
|
11
|
+
*/
|
|
12
|
+
export async function checkDependency(name) {
|
|
13
|
+
const dep = DEPENDENCIES[name];
|
|
14
|
+
try {
|
|
15
|
+
const { stdout } = await execFileAsync(dep.checkCommand, dep.checkArgs, {
|
|
16
|
+
timeout: 5000,
|
|
17
|
+
});
|
|
18
|
+
const output = stdout.trim();
|
|
19
|
+
const match = output.match(dep.versionRegex);
|
|
20
|
+
if (match) {
|
|
21
|
+
return { installed: true, version: match[1] };
|
|
22
|
+
}
|
|
23
|
+
// 版本格式不匹配,但命令执行成功,认为已安装
|
|
24
|
+
return { installed: true, version: output.split('\n')[0] };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { installed: false };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 检测 Node.js 版本是否满足最低要求
|
|
32
|
+
*/
|
|
33
|
+
export function checkNodeVersion(version, minVersion) {
|
|
34
|
+
const major = parseMajorVersion(version);
|
|
35
|
+
const minMajor = parseMajorVersion(minVersion);
|
|
36
|
+
return major >= minMajor;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 检测所有依赖的状态
|
|
40
|
+
*/
|
|
41
|
+
export async function checkAllDependencies() {
|
|
42
|
+
const results = {
|
|
43
|
+
node: await checkDependency('node'),
|
|
44
|
+
pnpm: await checkDependency('pnpm'),
|
|
45
|
+
claude: await checkDependency('claude'),
|
|
46
|
+
};
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=detector.js.map
|