@adhdev/daemon-core 0.8.13 → 0.8.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +66 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -37
- package/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +3 -3
- package/src/cli-adapters/provider-cli-adapter.ts +10 -10
- package/src/cli-adapters/pty-transport.ts +17 -6
- package/src/commands/workspace-commands.ts +37 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.15",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"author": "vilmire",
|
|
39
39
|
"license": "AGPL-3.0-or-later",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@agentclientprotocol/sdk": "^0.16.1",
|
|
42
41
|
"@adhdev/session-host-core": "*",
|
|
42
|
+
"@agentclientprotocol/sdk": "^0.16.1",
|
|
43
43
|
"@xterm/xterm": "^6.0.0",
|
|
44
44
|
"chalk": "^5.3.0",
|
|
45
45
|
"chokidar": "^5.0.0",
|
|
46
46
|
"conf": "^13.0.0",
|
|
47
|
-
"node-pty": "^1.
|
|
47
|
+
"node-pty": "^1.2.0-beta.12",
|
|
48
48
|
"ws": "^8.19.0"
|
|
49
49
|
},
|
|
50
50
|
"bundleDependencies": [
|
|
@@ -27,15 +27,7 @@ import {
|
|
|
27
27
|
type PtyRuntimeTransport,
|
|
28
28
|
type PtyTransportFactory,
|
|
29
29
|
} from './pty-transport.js';
|
|
30
|
-
import { sanitizeSpawnEnv
|
|
31
|
-
|
|
32
|
-
let pty: any;
|
|
33
|
-
try {
|
|
34
|
-
pty = require('node-pty');
|
|
35
|
-
ensureNodePtySpawnHelperPermissions((msg: string) => LOG.info('CLI', msg));
|
|
36
|
-
} catch {
|
|
37
|
-
LOG.error('CLI', '[ProviderCliAdapter] node-pty not found. Terminal features disabled.');
|
|
38
|
-
}
|
|
30
|
+
import { sanitizeSpawnEnv } from './spawn-env.js';
|
|
39
31
|
|
|
40
32
|
// ─── Types ──────────────────────────────────────────
|
|
41
33
|
|
|
@@ -759,7 +751,10 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
759
751
|
);
|
|
760
752
|
// On Windows, .cmd/.bat shims cannot be spawned directly — must go through cmd.exe
|
|
761
753
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
762
|
-
const
|
|
754
|
+
const useShellWin = isCmdShim
|
|
755
|
+
|| !path.isAbsolute(binaryPath)
|
|
756
|
+
|| isScriptBinary(binaryPath);
|
|
757
|
+
const useShell = isWin ? useShellWin : useShellUnix;
|
|
763
758
|
|
|
764
759
|
if (useShell) {
|
|
765
760
|
if (!spawnConfig.shell && !isWin) {
|
|
@@ -767,6 +762,8 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
767
762
|
}
|
|
768
763
|
if (isCmdShim) {
|
|
769
764
|
LOG.info('CLI', `[${this.cliType}] Using cmd.exe shell for .cmd/.bat shim: ${binaryPath}`);
|
|
765
|
+
} else if (isWin) {
|
|
766
|
+
LOG.info('CLI', `[${this.cliType}] Using cmd.exe shell on Windows: ${binaryPath}`);
|
|
770
767
|
}
|
|
771
768
|
shellCmd = isWin ? 'cmd.exe' : (process.env.SHELL || '/bin/zsh');
|
|
772
769
|
if (isWin) {
|
|
@@ -780,6 +777,9 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
780
777
|
shellArgs = ['-l', '-c', fullCmd];
|
|
781
778
|
}
|
|
782
779
|
} else {
|
|
780
|
+
if (isWin && spawnConfig.shell) {
|
|
781
|
+
LOG.info('CLI', `[${this.cliType}] Spawning Windows binary directly without cmd.exe: ${binaryPath}`);
|
|
782
|
+
}
|
|
783
783
|
shellCmd = binaryPath;
|
|
784
784
|
shellArgs = allArgs;
|
|
785
785
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import * as os from 'os';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { ensureNodePtySpawnHelperPermissions } from './spawn-env.js';
|
|
3
|
+
|
|
4
|
+
let cachedPty: any | null | undefined;
|
|
5
|
+
|
|
6
|
+
function loadNodePty(): any {
|
|
7
|
+
if (cachedPty !== undefined) return cachedPty;
|
|
8
|
+
try {
|
|
9
|
+
// Keep node-pty out of processes that delegate PTY ownership elsewhere
|
|
10
|
+
// (for example via session-host on Windows), so native PTY crashes do not
|
|
11
|
+
// take down the daemon just by importing this module.
|
|
12
|
+
cachedPty = require('node-pty');
|
|
13
|
+
ensureNodePtySpawnHelperPermissions();
|
|
14
|
+
} catch {
|
|
15
|
+
cachedPty = null;
|
|
16
|
+
}
|
|
17
|
+
return cachedPty;
|
|
8
18
|
}
|
|
9
19
|
|
|
10
20
|
export interface PtySpawnOptions {
|
|
@@ -90,6 +100,7 @@ class NodePtyRuntimeTransport implements PtyRuntimeTransport {
|
|
|
90
100
|
|
|
91
101
|
export class NodePtyTransportFactory implements PtyTransportFactory {
|
|
92
102
|
spawn(command: string, args: string[], options: PtySpawnOptions): PtyRuntimeTransport {
|
|
103
|
+
const pty = loadNodePty();
|
|
93
104
|
if (!pty) throw new Error('node-pty is not installed');
|
|
94
105
|
// Validate cwd — an invalid directory causes a native crash on Windows
|
|
95
106
|
// (node-pty error code 267: ERROR_DIRECTORY) that bypasses JS try/catch
|
|
@@ -3,12 +3,31 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { loadConfig, saveConfig } from '../config/config.js';
|
|
6
|
+
import type { ADHDevConfig } from '../config/config.js';
|
|
6
7
|
import * as W from '../config/workspaces.js';
|
|
7
8
|
|
|
8
9
|
export type WorkspaceCommandResult = { success: boolean;[key: string]: unknown };
|
|
9
10
|
|
|
11
|
+
function loadWorkspaceConfig(): ADHDevConfig | { error: string } {
|
|
12
|
+
try {
|
|
13
|
+
return loadConfig();
|
|
14
|
+
} catch (e: any) {
|
|
15
|
+
return { error: `Could not load config: ${e?.message || 'unknown error'}` };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function persistWorkspaceConfig(config: ADHDevConfig): { ok: true } | { error: string } {
|
|
20
|
+
try {
|
|
21
|
+
saveConfig(config);
|
|
22
|
+
return { ok: true };
|
|
23
|
+
} catch (e: any) {
|
|
24
|
+
return { error: `Could not save config: ${e?.message || 'unknown error'}` };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
10
28
|
export function handleWorkspaceList(): WorkspaceCommandResult {
|
|
11
|
-
const config =
|
|
29
|
+
const config = loadWorkspaceConfig();
|
|
30
|
+
if ('error' in config) return { success: false, error: config.error };
|
|
12
31
|
const state = W.getWorkspaceState(config);
|
|
13
32
|
return {
|
|
14
33
|
success: true,
|
|
@@ -24,11 +43,13 @@ export function handleWorkspaceAdd(args: any): WorkspaceCommandResult {
|
|
|
24
43
|
const createIfMissing = args?.createIfMissing === true;
|
|
25
44
|
if (!rawPath) return { success: false, error: 'path required' };
|
|
26
45
|
|
|
27
|
-
const config =
|
|
46
|
+
const config = loadWorkspaceConfig();
|
|
47
|
+
if ('error' in config) return { success: false, error: config.error };
|
|
28
48
|
const result = W.addWorkspaceEntry(config, rawPath, label, { createIfMissing });
|
|
29
49
|
if ('error' in result) return { success: false, error: result.error };
|
|
30
50
|
|
|
31
|
-
|
|
51
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
52
|
+
if ('error' in saveResult) return { success: false, error: saveResult.error };
|
|
32
53
|
const state = W.getWorkspaceState(result.config);
|
|
33
54
|
return { success: true, entry: result.entry, ...state };
|
|
34
55
|
}
|
|
@@ -37,12 +58,14 @@ export function handleWorkspaceRemove(args: any): WorkspaceCommandResult {
|
|
|
37
58
|
const id = (args?.id || '').trim();
|
|
38
59
|
if (!id) return { success: false, error: 'id required' };
|
|
39
60
|
|
|
40
|
-
const config =
|
|
61
|
+
const config = loadWorkspaceConfig();
|
|
62
|
+
if ('error' in config) return { success: false, error: config.error };
|
|
41
63
|
const removed = (config.workspaces || []).find(w => w.id === id);
|
|
42
64
|
const result = W.removeWorkspaceEntry(config, id);
|
|
43
65
|
if ('error' in result) return { success: false, error: result.error };
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
68
|
+
if ('error' in saveResult) return { success: false, error: saveResult.error };
|
|
46
69
|
const state = W.getWorkspaceState(result.config);
|
|
47
70
|
return { success: true, removedId: id, ...state };
|
|
48
71
|
}
|
|
@@ -50,10 +73,12 @@ export function handleWorkspaceRemove(args: any): WorkspaceCommandResult {
|
|
|
50
73
|
export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
51
74
|
const clear = args?.clear === true || args?.id === null || args?.id === '';
|
|
52
75
|
if (clear) {
|
|
53
|
-
const config =
|
|
76
|
+
const config = loadWorkspaceConfig();
|
|
77
|
+
if ('error' in config) return { success: false, error: config.error };
|
|
54
78
|
const result = W.setDefaultWorkspaceId(config, null);
|
|
55
79
|
if ('error' in result) return { success: false, error: result.error };
|
|
56
|
-
|
|
80
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
81
|
+
if ('error' in saveResult) return { success: false, error: saveResult.error };
|
|
57
82
|
const state = W.getWorkspaceState(result.config);
|
|
58
83
|
return {
|
|
59
84
|
success: true,
|
|
@@ -70,7 +95,9 @@ export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
|
70
95
|
return { success: false, error: 'id or path required (or clear: true)' };
|
|
71
96
|
}
|
|
72
97
|
|
|
73
|
-
|
|
98
|
+
const configResult = loadWorkspaceConfig();
|
|
99
|
+
if ('error' in configResult) return { success: false, error: configResult.error };
|
|
100
|
+
let config = configResult;
|
|
74
101
|
let nextId: string;
|
|
75
102
|
|
|
76
103
|
if (pathArg) {
|
|
@@ -89,7 +116,8 @@ export function handleWorkspaceSetDefault(args: any): WorkspaceCommandResult {
|
|
|
89
116
|
const result = W.setDefaultWorkspaceId(config, nextId);
|
|
90
117
|
if ('error' in result) return { success: false, error: result.error };
|
|
91
118
|
|
|
92
|
-
|
|
119
|
+
const saveResult = persistWorkspaceConfig(result.config);
|
|
120
|
+
if ('error' in saveResult) return { success: false, error: saveResult.error };
|
|
93
121
|
const state = W.getWorkspaceState(result.config);
|
|
94
122
|
return { success: true, ...state };
|
|
95
123
|
}
|