nomoreide 0.1.31 → 0.1.33
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/core/agent-runtime.d.ts +37 -4
- package/dist/core/agent-runtime.js +146 -44
- package/dist/core/agent-runtime.js.map +1 -1
- package/dist/core/process-manager.d.ts +15 -0
- package/dist/core/process-manager.js +105 -6
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/service-registry.d.ts +50 -0
- package/dist/core/service-registry.js +98 -0
- package/dist/core/service-registry.js.map +1 -0
- package/dist/mcp/server.js +8 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/web/agent-info.d.ts +1 -0
- package/dist/web/agent-info.js +1 -1
- package/dist/web/agent-info.js.map +1 -1
- package/dist/web/client/assets/{index-9WxIP_RA.js → index-DHmbWLCJ.js} +31 -31
- package/dist/web/client/index.html +1 -1
- package/dist/web/routes/agent-chat-routes.d.ts +1 -1
- package/dist/web/routes/agent-chat-routes.js +16 -7
- package/dist/web/routes/agent-chat-routes.js.map +1 -1
- package/dist/web/server.js +10 -2
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import type { ApprovalBroker } from "./approval-broker.js";
|
|
2
|
+
export type AgentChatProviderId = "claude" | "codex";
|
|
3
|
+
export type DetectedAgentName = "claude-code" | "codex" | "gemini" | "unknown";
|
|
4
|
+
export interface AgentChatProvider {
|
|
5
|
+
id: AgentChatProviderId;
|
|
6
|
+
label: string;
|
|
7
|
+
commandName: string;
|
|
8
|
+
bin: string;
|
|
9
|
+
installHint: string;
|
|
10
|
+
intro: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AgentInvocation {
|
|
13
|
+
bin: string;
|
|
14
|
+
args: string[];
|
|
15
|
+
}
|
|
2
16
|
/** Streamed back to the route, which forwards each as an SSE event. */
|
|
3
17
|
export type AgentStreamEvent = {
|
|
4
18
|
type: "session";
|
|
@@ -30,8 +44,10 @@ export type AgentStreamEvent = {
|
|
|
30
44
|
message: string;
|
|
31
45
|
};
|
|
32
46
|
export interface AgentRuntimeDeps {
|
|
33
|
-
/** Working directory the
|
|
47
|
+
/** Working directory the agent session runs in (the workspace root). */
|
|
34
48
|
cwd: string;
|
|
49
|
+
/** CLI provider selected from the agent that started NoMoreIDE. */
|
|
50
|
+
provider?: AgentChatProvider;
|
|
35
51
|
}
|
|
36
52
|
export interface AgentRunOptions {
|
|
37
53
|
signal?: AbortSignal;
|
|
@@ -41,10 +57,20 @@ export interface AgentRunOptions {
|
|
|
41
57
|
url: string;
|
|
42
58
|
};
|
|
43
59
|
}
|
|
44
|
-
/**
|
|
45
|
-
export declare function
|
|
60
|
+
/** Pick the in-dock chat provider from the same detected-agent signal as /agent. */
|
|
61
|
+
export declare function resolveChatProvider(detectedName: DetectedAgentName): AgentChatProvider;
|
|
62
|
+
export declare function publicProviderInfo(provider: AgentChatProvider): {
|
|
63
|
+
id: AgentChatProviderId;
|
|
64
|
+
label: string;
|
|
65
|
+
commandName: string;
|
|
66
|
+
installHint: string;
|
|
67
|
+
intro: string;
|
|
68
|
+
};
|
|
69
|
+
/** True when the selected agent CLI is installed and runnable. Memoized. */
|
|
70
|
+
export declare function isAgentAvailable(provider?: AgentChatProvider): Promise<boolean>;
|
|
46
71
|
/** Whether tool calls are gated behind dock approval (vs. fully autonomous). */
|
|
47
|
-
export declare function approvalsEnabled(): boolean;
|
|
72
|
+
export declare function approvalsEnabled(provider?: AgentChatProvider): boolean;
|
|
73
|
+
export declare function buildAgentInvocation(provider: AgentChatProvider, message: string, resumeSessionId: string | undefined, gating: boolean): AgentInvocation;
|
|
48
74
|
export declare class AgentRuntime {
|
|
49
75
|
private readonly deps;
|
|
50
76
|
constructor(deps: AgentRuntimeDeps);
|
|
@@ -54,3 +80,10 @@ export declare class AgentRuntime {
|
|
|
54
80
|
*/
|
|
55
81
|
run(message: string, resumeSessionId: string | undefined, onEvent: (event: AgentStreamEvent) => void, options?: AgentRunOptions): Promise<void>;
|
|
56
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse one NDJSON line from Claude Code's stream-json output, emitting the
|
|
85
|
+
* relevant dock events. Returns the session id when this line is the init event.
|
|
86
|
+
*/
|
|
87
|
+
export declare function handleClaudeLine(line: string, toolNames: Map<string, string>, onEvent: (event: AgentStreamEvent) => void): string | undefined;
|
|
88
|
+
/** Parse one JSONL event from `codex exec --json`. */
|
|
89
|
+
export declare function handleCodexLine(line: string, toolNames: Map<string, string>, onEvent: (event: AgentStreamEvent) => void): string | undefined;
|
|
@@ -3,42 +3,102 @@ import { mkdtempSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
/**
|
|
6
|
-
* In-dashboard AI agent backed by the real
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the user's existing Claude Code login (no separate API key).
|
|
6
|
+
* In-dashboard AI agent backed by the real local agent CLI. NoMoreIDE selects
|
|
7
|
+
* Claude Code or Codex from the same startup-agent detection used by /agent,
|
|
8
|
+
* then drives that CLI in a machine-readable headless mode rather than calling
|
|
9
|
+
* a vendor API directly.
|
|
11
10
|
*
|
|
12
|
-
* Conversation continuity uses
|
|
13
|
-
* returns a
|
|
14
|
-
* the next turn
|
|
11
|
+
* Conversation continuity uses the selected CLI's own session store: the first
|
|
12
|
+
* turn returns a session id, which the client sends back as `resumeSessionId` on
|
|
13
|
+
* the next turn. The server holds no transcript state.
|
|
15
14
|
*
|
|
16
15
|
* Tool permissions: unless NOMOREIDE_AGENT_PERMISSION_MODE=bypassPermissions,
|
|
17
16
|
* the agent runs in `default` mode with a PreToolUse hook on mutating tools.
|
|
18
17
|
* The hook blocks and asks the dock (via ApprovalBroker) for an Allow/Deny.
|
|
19
18
|
*/
|
|
20
19
|
const CLAUDE_BIN = process.env.NOMOREIDE_CLAUDE_BIN || "claude";
|
|
20
|
+
const CODEX_BIN = process.env.NOMOREIDE_CODEX_BIN || "codex";
|
|
21
21
|
/** "bypassPermissions" runs fully autonomous (no approval prompts). */
|
|
22
22
|
const PERMISSION_MODE = process.env.NOMOREIDE_AGENT_PERMISSION_MODE || "default";
|
|
23
|
+
const CODEX_APPROVAL_POLICY = process.env.NOMOREIDE_CODEX_APPROVAL_POLICY || "never";
|
|
23
24
|
/** Tools that trigger an approval prompt (mutating / side-effecting ones). */
|
|
24
25
|
const GATED_TOOLS = "Bash|Edit|Write|MultiEdit|NotebookEdit";
|
|
25
26
|
/** Truncate tool-result previews shown in the dock. */
|
|
26
27
|
const PREVIEW_LIMIT = 400;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
const CLAUDE_PROVIDER = {
|
|
29
|
+
id: "claude",
|
|
30
|
+
label: "Claude Code",
|
|
31
|
+
commandName: "claude",
|
|
32
|
+
bin: CLAUDE_BIN,
|
|
33
|
+
installHint: "Install Claude Code (and run `claude login`) so it is on NoMoreIDE's PATH, then reload.",
|
|
34
|
+
intro: "This is real Claude Code, running in your workspace with full tools - e.g. \"restart the api and tail its logs\", \"what changed in git and why?\", \"fix the failing test\".",
|
|
35
|
+
};
|
|
36
|
+
const CODEX_PROVIDER = {
|
|
37
|
+
id: "codex",
|
|
38
|
+
label: "Codex",
|
|
39
|
+
commandName: "codex",
|
|
40
|
+
bin: CODEX_BIN,
|
|
41
|
+
installHint: "Install Codex CLI (and run `codex login`) so it is on NoMoreIDE's PATH, then reload.",
|
|
42
|
+
intro: "This is real Codex CLI, running in your workspace with full tools - e.g. \"restart the api and tail its logs\", \"what changed in git and why?\", \"fix the failing test\".",
|
|
43
|
+
};
|
|
44
|
+
const availabilityProbes = new Map();
|
|
45
|
+
/** Pick the in-dock chat provider from the same detected-agent signal as /agent. */
|
|
46
|
+
export function resolveChatProvider(detectedName) {
|
|
47
|
+
return detectedName === "codex" ? CODEX_PROVIDER : CLAUDE_PROVIDER;
|
|
48
|
+
}
|
|
49
|
+
export function publicProviderInfo(provider) {
|
|
50
|
+
return {
|
|
51
|
+
id: provider.id,
|
|
52
|
+
label: provider.label,
|
|
53
|
+
commandName: provider.commandName,
|
|
54
|
+
installHint: provider.installHint,
|
|
55
|
+
intro: provider.intro,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** True when the selected agent CLI is installed and runnable. Memoized. */
|
|
59
|
+
export function isAgentAvailable(provider = CLAUDE_PROVIDER) {
|
|
60
|
+
const existing = availabilityProbes.get(provider.id);
|
|
61
|
+
if (existing)
|
|
62
|
+
return existing;
|
|
63
|
+
const probe = new Promise((resolve) => {
|
|
64
|
+
const child = spawn(provider.bin, ["--version"], { stdio: "ignore" });
|
|
65
|
+
child.on("error", () => resolve(false));
|
|
66
|
+
child.on("close", (code) => resolve(code === 0));
|
|
67
|
+
}).catch(() => false);
|
|
68
|
+
availabilityProbes.set(provider.id, probe);
|
|
69
|
+
return probe;
|
|
38
70
|
}
|
|
39
71
|
/** Whether tool calls are gated behind dock approval (vs. fully autonomous). */
|
|
40
|
-
export function approvalsEnabled() {
|
|
41
|
-
return PERMISSION_MODE !== "bypassPermissions";
|
|
72
|
+
export function approvalsEnabled(provider = CLAUDE_PROVIDER) {
|
|
73
|
+
return provider.id === "claude" && PERMISSION_MODE !== "bypassPermissions";
|
|
74
|
+
}
|
|
75
|
+
export function buildAgentInvocation(provider, message, resumeSessionId, gating) {
|
|
76
|
+
if (provider.id === "codex") {
|
|
77
|
+
const args = ["-a", CODEX_APPROVAL_POLICY, "exec"];
|
|
78
|
+
if (resumeSessionId) {
|
|
79
|
+
args.push("resume", "--json", "--skip-git-repo-check", resumeSessionId, message);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
args.push("--json", "--skip-git-repo-check", message);
|
|
83
|
+
}
|
|
84
|
+
return { bin: provider.bin, args };
|
|
85
|
+
}
|
|
86
|
+
const args = [
|
|
87
|
+
"--print",
|
|
88
|
+
"--output-format",
|
|
89
|
+
"stream-json",
|
|
90
|
+
"--verbose",
|
|
91
|
+
"--include-partial-messages",
|
|
92
|
+
"--permission-mode",
|
|
93
|
+
gating ? "default" : PERMISSION_MODE,
|
|
94
|
+
];
|
|
95
|
+
if (gating) {
|
|
96
|
+
args.push("--settings", approvalSettings());
|
|
97
|
+
}
|
|
98
|
+
if (resumeSessionId)
|
|
99
|
+
args.push("--resume", resumeSessionId);
|
|
100
|
+
args.push(message);
|
|
101
|
+
return { bin: provider.bin, args };
|
|
42
102
|
}
|
|
43
103
|
export class AgentRuntime {
|
|
44
104
|
deps;
|
|
@@ -51,27 +111,18 @@ export class AgentRuntime {
|
|
|
51
111
|
*/
|
|
52
112
|
async run(message, resumeSessionId, onEvent, options = {}) {
|
|
53
113
|
const { signal, approval } = options;
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"stream-json",
|
|
59
|
-
"--verbose",
|
|
60
|
-
"--include-partial-messages",
|
|
61
|
-
"--permission-mode",
|
|
62
|
-
gating ? "default" : PERMISSION_MODE,
|
|
63
|
-
];
|
|
64
|
-
if (gating) {
|
|
65
|
-
args.push("--settings", approvalSettings());
|
|
66
|
-
}
|
|
67
|
-
if (resumeSessionId)
|
|
68
|
-
args.push("--resume", resumeSessionId);
|
|
69
|
-
args.push(message);
|
|
70
|
-
const env = gating
|
|
114
|
+
const provider = this.deps.provider ?? CLAUDE_PROVIDER;
|
|
115
|
+
const gating = Boolean(approval) && approvalsEnabled(provider);
|
|
116
|
+
const invocation = buildAgentInvocation(provider, message, resumeSessionId, gating);
|
|
117
|
+
const env = gating && approval
|
|
71
118
|
? { ...process.env, NOMOREIDE_APPROVAL_URL: approval.url }
|
|
72
119
|
: process.env;
|
|
73
120
|
await new Promise((resolve) => {
|
|
74
|
-
const child = spawn(
|
|
121
|
+
const child = spawn(invocation.bin, invocation.args, {
|
|
122
|
+
cwd: this.deps.cwd,
|
|
123
|
+
env,
|
|
124
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
125
|
+
});
|
|
75
126
|
const toolNames = new Map();
|
|
76
127
|
let stdout = "";
|
|
77
128
|
let stderr = "";
|
|
@@ -88,8 +139,10 @@ export class AgentRuntime {
|
|
|
88
139
|
// Bridge the broker's approval requests onto the SSE stream the moment
|
|
89
140
|
// we learn this run's session id.
|
|
90
141
|
const onLine = (line) => {
|
|
91
|
-
const sessionId =
|
|
92
|
-
|
|
142
|
+
const sessionId = provider.id === "codex"
|
|
143
|
+
? handleCodexLine(line, toolNames, onEvent)
|
|
144
|
+
: handleClaudeLine(line, toolNames, onEvent);
|
|
145
|
+
if (sessionId && gating && approval && !openedSession) {
|
|
93
146
|
openedSession = sessionId;
|
|
94
147
|
approval.broker.openRun(sessionId, (request) => onEvent({
|
|
95
148
|
type: "approval_request",
|
|
@@ -109,7 +162,7 @@ export class AgentRuntime {
|
|
|
109
162
|
onEvent({
|
|
110
163
|
type: "error",
|
|
111
164
|
message: error.code === "ENOENT"
|
|
112
|
-
? `Could not run "${
|
|
165
|
+
? `Could not run "${provider.bin}". ${provider.installHint}`
|
|
113
166
|
: error.message,
|
|
114
167
|
});
|
|
115
168
|
finish();
|
|
@@ -139,7 +192,7 @@ export class AgentRuntime {
|
|
|
139
192
|
if (code !== 0) {
|
|
140
193
|
onEvent({
|
|
141
194
|
type: "error",
|
|
142
|
-
message: stderr.trim() ||
|
|
195
|
+
message: stderr.trim() || `${provider.label} exited with code ${code}.`,
|
|
143
196
|
});
|
|
144
197
|
}
|
|
145
198
|
finish();
|
|
@@ -151,7 +204,7 @@ export class AgentRuntime {
|
|
|
151
204
|
* Parse one NDJSON line from Claude Code's stream-json output, emitting the
|
|
152
205
|
* relevant dock events. Returns the session id when this line is the init event.
|
|
153
206
|
*/
|
|
154
|
-
function
|
|
207
|
+
export function handleClaudeLine(line, toolNames, onEvent) {
|
|
155
208
|
let obj;
|
|
156
209
|
try {
|
|
157
210
|
obj = JSON.parse(line);
|
|
@@ -206,6 +259,55 @@ function handleLine(line, toolNames, onEvent) {
|
|
|
206
259
|
return undefined;
|
|
207
260
|
}
|
|
208
261
|
}
|
|
262
|
+
/** Parse one JSONL event from `codex exec --json`. */
|
|
263
|
+
export function handleCodexLine(line, toolNames, onEvent) {
|
|
264
|
+
let obj;
|
|
265
|
+
try {
|
|
266
|
+
obj = JSON.parse(line);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
if (obj.type === "thread.started" && typeof obj.thread_id === "string") {
|
|
272
|
+
onEvent({ type: "session", sessionId: obj.thread_id });
|
|
273
|
+
return obj.thread_id;
|
|
274
|
+
}
|
|
275
|
+
if (obj.type === "item.started" || obj.type === "item.completed") {
|
|
276
|
+
const item = obj.item;
|
|
277
|
+
if (!item || typeof item.id !== "string" || typeof item.type !== "string") {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
if (item.type === "command_execution") {
|
|
281
|
+
const name = "command";
|
|
282
|
+
toolNames.set(item.id, name);
|
|
283
|
+
const command = typeof item.command === "string" ? item.command : "";
|
|
284
|
+
if (obj.type === "item.started") {
|
|
285
|
+
onEvent({ type: "tool_use", id: item.id, name, input: { command } });
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
onEvent({
|
|
289
|
+
type: "tool_result",
|
|
290
|
+
id: item.id,
|
|
291
|
+
name,
|
|
292
|
+
preview: previewOf(item.aggregated_output),
|
|
293
|
+
isError: typeof item.exit_code === "number"
|
|
294
|
+
? item.exit_code !== 0
|
|
295
|
+
: item.status === "failed",
|
|
296
|
+
});
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
if (item.type === "agent_message" && obj.type === "item.completed") {
|
|
300
|
+
const text = typeof item.text === "string" ? item.text : "";
|
|
301
|
+
if (text)
|
|
302
|
+
onEvent({ type: "text", text });
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (obj.type === "turn.completed") {
|
|
307
|
+
onEvent({ type: "done", stopReason: null });
|
|
308
|
+
}
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
209
311
|
function messageContent(message) {
|
|
210
312
|
const content = message?.content;
|
|
211
313
|
return Array.isArray(content) ? content : [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../src/core/agent-runtime.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../src/core/agent-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConfigStore } from "./config-store.js";
|
|
2
2
|
import type { LogStore } from "./log-store.js";
|
|
3
3
|
import { type PortHolder } from "./port-utils.js";
|
|
4
|
+
import { type ServiceRegistry } from "./service-registry.js";
|
|
4
5
|
import type { TimelineStore } from "./timeline-store.js";
|
|
5
6
|
import type { ServiceStatus } from "./types.js";
|
|
6
7
|
interface ProcessManagerOptions {
|
|
@@ -8,6 +9,13 @@ interface ProcessManagerOptions {
|
|
|
8
9
|
logStore: LogStore;
|
|
9
10
|
stopTimeoutMs?: number;
|
|
10
11
|
timelineStore?: TimelineStore;
|
|
12
|
+
/**
|
|
13
|
+
* Shared cross-session view of running services. When provided, the manager
|
|
14
|
+
* adopts services started by other sessions instead of spawning duplicates,
|
|
15
|
+
* and can stop services it did not spawn itself. Omit for an isolated manager
|
|
16
|
+
* (e.g. in tests) — behavior is then identical to a single-session manager.
|
|
17
|
+
*/
|
|
18
|
+
registry?: ServiceRegistry;
|
|
11
19
|
}
|
|
12
20
|
export interface NoMoreIdeStatus {
|
|
13
21
|
services: Record<string, ServiceStatus>;
|
|
@@ -28,6 +36,7 @@ export declare class ProcessManager {
|
|
|
28
36
|
private readonly logStore;
|
|
29
37
|
private readonly stopTimeoutMs;
|
|
30
38
|
private readonly timelineStore?;
|
|
39
|
+
private readonly registry?;
|
|
31
40
|
constructor(options: ProcessManagerOptions);
|
|
32
41
|
startService(name: string, options?: StartServiceOptions): Promise<ServiceStatus>;
|
|
33
42
|
stopService(name: string): Promise<ServiceStatus>;
|
|
@@ -45,6 +54,12 @@ export declare class ProcessManager {
|
|
|
45
54
|
installShutdownHandlers(): () => void;
|
|
46
55
|
status(): NoMoreIdeStatus;
|
|
47
56
|
statusWithResources(): Promise<NoMoreIdeStatus>;
|
|
57
|
+
/**
|
|
58
|
+
* Fold in services started by sibling sessions. A registry entry wins only
|
|
59
|
+
* when this session has no running view of that service, so a locally-owned
|
|
60
|
+
* "running" status is never overwritten by the shared snapshot.
|
|
61
|
+
*/
|
|
62
|
+
private mergeRegistry;
|
|
48
63
|
private startDockerComposeService;
|
|
49
64
|
private stopDockerComposeService;
|
|
50
65
|
readDockerServiceLogs(name: string, tail?: number): Promise<string>;
|
|
@@ -3,6 +3,7 @@ import { readDockerServiceLogs, readDockerServiceStatus, startDockerService, sto
|
|
|
3
3
|
import { startHttpInspector, } from "./http-inspector.js";
|
|
4
4
|
import { getPortHolder, isPortAvailable } from "./port-utils.js";
|
|
5
5
|
import { readProcessTree } from "./process-tree.js";
|
|
6
|
+
import { isPidAlive, } from "./service-registry.js";
|
|
6
7
|
import { createSshCommand } from "./ssh-service-runner.js";
|
|
7
8
|
export class PortConflictError extends Error {
|
|
8
9
|
code = "PORT_IN_USE";
|
|
@@ -24,11 +25,13 @@ export class ProcessManager {
|
|
|
24
25
|
logStore;
|
|
25
26
|
stopTimeoutMs;
|
|
26
27
|
timelineStore;
|
|
28
|
+
registry;
|
|
27
29
|
constructor(options) {
|
|
28
30
|
this.configStore = options.configStore;
|
|
29
31
|
this.logStore = options.logStore;
|
|
30
32
|
this.stopTimeoutMs = options.stopTimeoutMs ?? 3000;
|
|
31
33
|
this.timelineStore = options.timelineStore;
|
|
34
|
+
this.registry = options.registry;
|
|
32
35
|
}
|
|
33
36
|
async startService(name, options = {}) {
|
|
34
37
|
const service = await this.getService(name);
|
|
@@ -40,6 +43,13 @@ export class ProcessManager {
|
|
|
40
43
|
if (kind === "docker-compose") {
|
|
41
44
|
return this.startDockerComposeService(name, service);
|
|
42
45
|
}
|
|
46
|
+
// Another session may already be running this exact service. Adopt its
|
|
47
|
+
// status instead of spawning a duplicate — this also covers portless
|
|
48
|
+
// services, where the port check below cannot detect the conflict.
|
|
49
|
+
const tracked = this.registry?.get(name);
|
|
50
|
+
if (tracked) {
|
|
51
|
+
return registryEntryToStatus(tracked);
|
|
52
|
+
}
|
|
43
53
|
if (service.port && !(await isPortAvailable(service.port))) {
|
|
44
54
|
const holder = await getPortHolder(service.port);
|
|
45
55
|
if (options.killHolder && holder) {
|
|
@@ -66,6 +76,18 @@ export class ProcessManager {
|
|
|
66
76
|
},
|
|
67
77
|
};
|
|
68
78
|
this.runtimes.set(name, runtime);
|
|
79
|
+
if (child.pid) {
|
|
80
|
+
this.registry?.record({
|
|
81
|
+
name,
|
|
82
|
+
pid: child.pid,
|
|
83
|
+
pgid: child.pid, // detached spawn → child.pid is the process-group leader
|
|
84
|
+
port: service.port,
|
|
85
|
+
kind,
|
|
86
|
+
host: kind === "ssh" ? service.host : undefined,
|
|
87
|
+
startedAt: runtime.status.startedAt ?? new Date().toISOString(),
|
|
88
|
+
ownerPid: process.pid,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
69
91
|
void this.appendTimeline({
|
|
70
92
|
kind: "service.lifecycle",
|
|
71
93
|
service: name,
|
|
@@ -87,6 +109,7 @@ export class ProcessManager {
|
|
|
87
109
|
signal,
|
|
88
110
|
};
|
|
89
111
|
runtime.child = undefined;
|
|
112
|
+
this.registry?.remove(name);
|
|
90
113
|
void this.stopInspector(runtime);
|
|
91
114
|
void this.appendTimeline({
|
|
92
115
|
kind: "service.lifecycle",
|
|
@@ -107,6 +130,7 @@ export class ProcessManager {
|
|
|
107
130
|
exitCode: 1,
|
|
108
131
|
signal: null,
|
|
109
132
|
};
|
|
133
|
+
this.registry?.remove(name);
|
|
110
134
|
void this.logStore.append(name, "stderr", error.message);
|
|
111
135
|
void this.appendTimeline({
|
|
112
136
|
kind: "service.lifecycle",
|
|
@@ -124,6 +148,13 @@ export class ProcessManager {
|
|
|
124
148
|
return this.stopDockerComposeService(name, runtime);
|
|
125
149
|
}
|
|
126
150
|
if (!runtime?.child || runtime.status.state !== "running") {
|
|
151
|
+
// No live child in this session — a sibling session may own it. If the
|
|
152
|
+
// registry has a live entry, signal its process group to stop it.
|
|
153
|
+
const tracked = this.registry?.get(name);
|
|
154
|
+
if (tracked) {
|
|
155
|
+
await stopByPid(tracked.pid, tracked.pgid, this.stopTimeoutMs);
|
|
156
|
+
this.registry?.remove(name);
|
|
157
|
+
}
|
|
127
158
|
const stopped = { name, state: "stopped" };
|
|
128
159
|
this.runtimes.set(name, { status: stopped, stopping: false });
|
|
129
160
|
void this.appendTimeline({
|
|
@@ -262,6 +293,9 @@ export class ProcessManager {
|
|
|
262
293
|
continue;
|
|
263
294
|
signalProcessTree(runtime.child, signal);
|
|
264
295
|
}
|
|
296
|
+
// Drop this session's entries synchronously; the async exit handlers above
|
|
297
|
+
// may not run before the host process exits.
|
|
298
|
+
this.registry?.removeOwnedBy(process.pid);
|
|
265
299
|
}
|
|
266
300
|
installShutdownHandlers() {
|
|
267
301
|
let firing = false;
|
|
@@ -289,12 +323,12 @@ export class ProcessManager {
|
|
|
289
323
|
};
|
|
290
324
|
}
|
|
291
325
|
status() {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
};
|
|
326
|
+
const services = {};
|
|
327
|
+
for (const [name, runtime] of this.runtimes.entries()) {
|
|
328
|
+
services[name] = { ...runtime.status };
|
|
329
|
+
}
|
|
330
|
+
this.mergeRegistry(services);
|
|
331
|
+
return { services };
|
|
298
332
|
}
|
|
299
333
|
async statusWithResources() {
|
|
300
334
|
const services = {};
|
|
@@ -306,8 +340,29 @@ export class ProcessManager {
|
|
|
306
340
|
status.inspector = this.inspectorStatus(runtime);
|
|
307
341
|
services[name] = status;
|
|
308
342
|
}
|
|
343
|
+
this.mergeRegistry(services);
|
|
344
|
+
for (const status of Object.values(services)) {
|
|
345
|
+
if (status.pid && status.state === "running" && !status.processTree) {
|
|
346
|
+
status.processTree = await readProcessTree(status.pid);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
309
349
|
return { services };
|
|
310
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Fold in services started by sibling sessions. A registry entry wins only
|
|
353
|
+
* when this session has no running view of that service, so a locally-owned
|
|
354
|
+
* "running" status is never overwritten by the shared snapshot.
|
|
355
|
+
*/
|
|
356
|
+
mergeRegistry(services) {
|
|
357
|
+
if (!this.registry)
|
|
358
|
+
return;
|
|
359
|
+
for (const entry of this.registry.list()) {
|
|
360
|
+
const local = services[entry.name];
|
|
361
|
+
if (!local || local.state !== "running") {
|
|
362
|
+
services[entry.name] = registryEntryToStatus(entry);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
311
366
|
async startDockerComposeService(name, service) {
|
|
312
367
|
const target = toDockerTarget(name, service);
|
|
313
368
|
const info = await startDockerService(target);
|
|
@@ -392,6 +447,7 @@ export class ProcessManager {
|
|
|
392
447
|
const runtime = this.runtimes.get(service);
|
|
393
448
|
if (runtime) {
|
|
394
449
|
runtime.status = { ...runtime.status, url };
|
|
450
|
+
this.registry?.update(service, { url });
|
|
395
451
|
void this.maybeStartInspector(service);
|
|
396
452
|
}
|
|
397
453
|
void this.appendTimeline({
|
|
@@ -422,6 +478,49 @@ export class ProcessManager {
|
|
|
422
478
|
function resolveKind(service) {
|
|
423
479
|
return service.kind ?? "local";
|
|
424
480
|
}
|
|
481
|
+
function registryEntryToStatus(entry) {
|
|
482
|
+
return {
|
|
483
|
+
name: entry.name,
|
|
484
|
+
state: "running",
|
|
485
|
+
kind: entry.kind,
|
|
486
|
+
pid: entry.pid,
|
|
487
|
+
url: entry.url,
|
|
488
|
+
host: entry.host,
|
|
489
|
+
startedAt: entry.startedAt,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Stop a process by pid when we hold no ChildProcess handle for it (it was
|
|
494
|
+
* spawned by another session). Signals the whole process group, then escalates
|
|
495
|
+
* to SIGKILL if it has not exited within the timeout.
|
|
496
|
+
*/
|
|
497
|
+
async function stopByPid(pid, pgid, timeoutMs) {
|
|
498
|
+
signalPid(pid, pgid, "SIGTERM");
|
|
499
|
+
const deadline = Date.now() + timeoutMs;
|
|
500
|
+
while (Date.now() < deadline) {
|
|
501
|
+
if (!isPidAlive(pid))
|
|
502
|
+
return;
|
|
503
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
504
|
+
}
|
|
505
|
+
signalPid(pid, pgid, "SIGKILL");
|
|
506
|
+
}
|
|
507
|
+
function signalPid(pid, pgid, signal) {
|
|
508
|
+
const group = pgid ?? pid;
|
|
509
|
+
try {
|
|
510
|
+
// Negative pid signals the whole process group (detached spawn → pgid===pid).
|
|
511
|
+
process.kill(-group, signal);
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
if (error.code === "ESRCH")
|
|
515
|
+
return;
|
|
516
|
+
try {
|
|
517
|
+
process.kill(pid, signal);
|
|
518
|
+
}
|
|
519
|
+
catch {
|
|
520
|
+
// ignore
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
425
524
|
function toDockerTarget(name, service) {
|
|
426
525
|
if (!service.cwd || !service.composeService) {
|
|
427
526
|
throw new Error(`Service "${name}" is missing docker-compose cwd or composeService.`);
|