@aliou/pi-processes 0.9.5 → 0.10.1
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/CONTRIBUTING.md +40 -42
- package/README.md +54 -84
- package/extensions/process-tabs.ts +26 -0
- package/extensions/processes/client.ts +194 -0
- package/extensions/processes/commands/clear.ts +29 -0
- package/extensions/processes/commands/kill.ts +152 -0
- package/extensions/processes/commands/overview.ts +102 -0
- package/extensions/processes/components/overview-component.ts +729 -0
- package/extensions/processes/components/overview-panel.ts +177 -0
- package/extensions/processes/config/defaults.ts +28 -0
- package/extensions/processes/config/index.ts +13 -0
- package/extensions/processes/config/loader.ts +62 -0
- package/extensions/processes/config/migrations/000-import-legacy-process-config.ts +113 -0
- package/extensions/processes/config/migrations/001-v0-9-4-to-v0-10-0-config.ts +184 -0
- package/extensions/processes/config/migrations/002-stamp-v0-10-0-config-version.ts +21 -0
- package/extensions/processes/config/migrations/index.ts +25 -0
- package/extensions/processes/config/schema.ts +9 -0
- package/extensions/processes/config/types.ts +72 -0
- package/extensions/processes/constants.ts +1 -0
- package/extensions/processes/handlers/commands.ts +113 -0
- package/extensions/processes/handlers/kill-process.ts +31 -0
- package/extensions/processes/handlers/notifications.ts +147 -0
- package/extensions/processes/handlers/requests.ts +114 -0
- package/extensions/processes/handlers/subscriptions.ts +144 -0
- package/extensions/processes/hooks/background-blocker.ts +201 -0
- package/extensions/processes/hooks/cleanup.ts +43 -0
- package/extensions/processes/hooks/event-bridge.ts +32 -0
- package/extensions/processes/i18n/index.ts +3 -0
- package/extensions/processes/i18n/messages.ts +27 -0
- package/extensions/processes/i18n/translator.ts +49 -0
- package/extensions/processes/index.ts +109 -0
- package/extensions/processes/message-renderer.ts +117 -0
- package/extensions/processes/notification-sender.ts +43 -0
- package/extensions/processes/notifications/classify.ts +27 -0
- package/extensions/processes/notifications/log-matchers.ts +146 -0
- package/extensions/processes/notifications/registry.ts +225 -0
- package/extensions/processes/notifications/render-content.ts +122 -0
- package/extensions/processes/notifications/service.ts +336 -0
- package/extensions/processes/notifications/types.ts +11 -0
- package/extensions/processes/settings/apply-setting-change.ts +30 -0
- package/extensions/processes/settings/build-sections.ts +420 -0
- package/extensions/processes/settings/index.ts +42 -0
- package/extensions/processes/tools/clear/index.ts +21 -0
- package/extensions/processes/tools/clear/render.ts +40 -0
- package/extensions/processes/tools/components/index.ts +4 -0
- package/extensions/processes/tools/components/process-action-header.ts +31 -0
- package/extensions/processes/tools/components/process-action-title.ts +17 -0
- package/extensions/processes/tools/components/tool-layout.ts +70 -0
- package/extensions/processes/tools/components/watch.ts +53 -0
- package/extensions/processes/tools/index.ts +265 -0
- package/extensions/processes/tools/list/index.ts +157 -0
- package/extensions/processes/tools/list/render.ts +211 -0
- package/extensions/processes/tools/notify.ts +191 -0
- package/extensions/processes/tools/output/index.ts +307 -0
- package/extensions/processes/tools/output/render.ts +229 -0
- package/extensions/processes/tools/schema.ts +263 -0
- package/extensions/processes/tools/start/index.ts +64 -0
- package/extensions/processes/tools/start/render.ts +67 -0
- package/extensions/processes/tools/stop/index.ts +35 -0
- package/extensions/processes/tools/stop/render.ts +43 -0
- package/extensions/processes/tools/update/index.ts +320 -0
- package/extensions/processes/tools/update/render.ts +251 -0
- package/extensions/processes/tools/utils.ts +112 -0
- package/extensions/processes/tools/watch-format.ts +14 -0
- package/extensions/processes/tools/write/index.ts +75 -0
- package/extensions/processes/tools/write/render.ts +68 -0
- package/extensions/processes/utils/truncate.ts +285 -0
- package/extensions/processes-dock/client.ts +60 -0
- package/extensions/processes-dock/commands/dock.ts +70 -0
- package/extensions/processes-dock/commands/pin.ts +166 -0
- package/extensions/processes-dock/components/log-dock-component.ts +375 -0
- package/extensions/processes-dock/dock-state.ts +33 -0
- package/extensions/processes-dock/index.ts +28 -0
- package/extensions/processes-dock/logs-client.ts +5 -0
- package/extensions/processes-dock/widget/setup.ts +520 -0
- package/extensions/processes-dock/widget/status.ts +149 -0
- package/extensions/processes-dock/widget/types.ts +16 -0
- package/extensions/processes-logs/client.ts +51 -0
- package/extensions/processes-logs/commands/logs.ts +108 -0
- package/extensions/processes-logs/completions.ts +31 -0
- package/extensions/processes-logs/components/log-file-viewer.ts +274 -0
- package/extensions/processes-logs/components/log-overlay-component.ts +685 -0
- package/extensions/processes-logs/index.ts +27 -0
- package/extensions/processes-logs/logs-client.ts +101 -0
- package/extensions/shared/line-buffer.ts +35 -0
- package/extensions/shared/output-payload.ts +28 -0
- package/extensions/shared/ui.ts +146 -0
- package/package.json +29 -10
- package/schema.json +134 -0
- package/skills/pi-processes/SKILL.md +496 -25
- package/src/get-manager.ts +15 -0
- package/src/manager/index.ts +182 -0
- package/src/manager/internal-types.ts +130 -0
- package/src/manager/limits.ts +15 -0
- package/src/manager/process-log-store.ts +422 -0
- package/src/manager/process-output.ts +345 -0
- package/src/manager/process-registry.ts +78 -0
- package/src/manager/process-runtime-controller.ts +519 -0
- package/src/protocol/broadcasts.ts +14 -0
- package/src/protocol/channels.ts +30 -0
- package/src/protocol/commands.ts +24 -0
- package/src/protocol/index.ts +34 -0
- package/src/protocol/logs.ts +23 -0
- package/src/protocol/notifications.ts +48 -0
- package/src/protocol/requests.ts +76 -0
- package/src/types.ts +66 -0
- package/src/utils/ansi.ts +2 -4
- package/src/utils/format.ts +24 -32
- package/src/utils/index.ts +5 -1
- package/src/utils/is-record.ts +3 -0
- package/src/utils/match-line.ts +32 -0
- package/src/utils/platform.ts +13 -0
- package/src/utils/process-group.ts +4 -0
- package/src/utils/shorten-path.ts +11 -0
- package/src/utils/signals.ts +22 -0
- package/src/commands/clear/command.ts +0 -14
- package/src/commands/clear/index.ts +0 -1
- package/src/commands/completions.ts +0 -38
- package/src/commands/dock/command.ts +0 -29
- package/src/commands/dock/index.ts +0 -1
- package/src/commands/index.ts +0 -33
- package/src/commands/kill/command.ts +0 -69
- package/src/commands/kill/index.ts +0 -1
- package/src/commands/logs/command.ts +0 -47
- package/src/commands/logs/index.ts +0 -1
- package/src/commands/pick-process.ts +0 -34
- package/src/commands/pin/command.ts +0 -34
- package/src/commands/pin/index.ts +0 -1
- package/src/commands/processes/command.ts +0 -39
- package/src/commands/processes/index.ts +0 -1
- package/src/commands/settings/apply-setting-change.ts +0 -72
- package/src/commands/settings/build-sections.ts +0 -160
- package/src/commands/settings/command.ts +0 -20
- package/src/commands/settings/index.ts +0 -1
- package/src/components/log-dock-component.test.ts +0 -29
- package/src/components/log-dock-component.ts +0 -236
- package/src/components/log-file-viewer.ts +0 -317
- package/src/components/log-overlay-component.ts +0 -546
- package/src/components/panel-helpers.ts +0 -37
- package/src/components/process-picker-component.ts +0 -166
- package/src/components/processes-component.ts +0 -485
- package/src/components/status-format.ts +0 -38
- package/src/config.ts +0 -107
- package/src/constants/index.ts +0 -16
- package/src/constants/types.ts +0 -119
- package/src/hooks/background-blocker.ts +0 -66
- package/src/hooks/cleanup.ts +0 -10
- package/src/hooks/index.ts +0 -32
- package/src/hooks/message-renderer.ts +0 -115
- package/src/hooks/process-end.ts +0 -69
- package/src/hooks/process-watch.ts +0 -85
- package/src/hooks/utils.ts +0 -23
- package/src/hooks/widget/index.ts +0 -2
- package/src/hooks/widget/setup.ts +0 -167
- package/src/hooks/widget/status-widget.ts +0 -105
- package/src/hooks/widget/types.ts +0 -20
- package/src/index.ts +0 -35
- package/src/manager.test.ts +0 -331
- package/src/manager.ts +0 -758
- package/src/tools/actions/clear.ts +0 -20
- package/src/tools/actions/debug.ts +0 -155
- package/src/tools/actions/index.ts +0 -171
- package/src/tools/actions/kill.ts +0 -89
- package/src/tools/actions/list.ts +0 -188
- package/src/tools/actions/logs.ts +0 -117
- package/src/tools/actions/output-truncate.ts +0 -187
- package/src/tools/actions/output.test.ts +0 -392
- package/src/tools/actions/output.ts +0 -447
- package/src/tools/actions/start.ts +0 -245
- package/src/tools/actions/write.ts +0 -113
- package/src/tools/index.ts +0 -207
- package/src/utils/ansi.test.ts +0 -22
- package/src/utils/command-executor.test.ts +0 -48
- package/src/utils/keybindings.ts +0 -71
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ExecuteResult } from "../../constants";
|
|
2
|
-
import type { ProcessManager } from "../../manager";
|
|
3
|
-
|
|
4
|
-
export function executeClear(manager: ProcessManager): ExecuteResult {
|
|
5
|
-
const cleared = manager.clearFinished();
|
|
6
|
-
const message =
|
|
7
|
-
cleared > 0
|
|
8
|
-
? `Cleared ${cleared} finished process(es)`
|
|
9
|
-
: "No finished processes to clear";
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
content: [{ type: "text", text: message }],
|
|
13
|
-
details: {
|
|
14
|
-
action: "clear",
|
|
15
|
-
success: true,
|
|
16
|
-
message,
|
|
17
|
-
cleared,
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { ToolCallHeader } from "@aliou/pi-utils-ui";
|
|
2
|
-
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import type { ExecuteResult, ProcessInfo } from "../../constants";
|
|
4
|
-
|
|
5
|
-
interface DebugParams {
|
|
6
|
-
preview?: "start" | "list" | "output" | "logs" | "error";
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function renderDebugCall(
|
|
10
|
-
args: DebugParams,
|
|
11
|
-
theme: Theme,
|
|
12
|
-
): ToolCallHeader {
|
|
13
|
-
return new ToolCallHeader(
|
|
14
|
-
{
|
|
15
|
-
toolName: "Process",
|
|
16
|
-
action: "debug_preview",
|
|
17
|
-
mainArg: args.preview,
|
|
18
|
-
},
|
|
19
|
-
theme,
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function mockProcess(overrides?: Partial<ProcessInfo>): ProcessInfo {
|
|
24
|
-
const now = Date.now();
|
|
25
|
-
return {
|
|
26
|
-
id: "proc_42",
|
|
27
|
-
name: "demo-server",
|
|
28
|
-
pid: 4242,
|
|
29
|
-
command: "pnpm dev --port 3000",
|
|
30
|
-
cwd: "/tmp/demo",
|
|
31
|
-
startTime: now - 12_000,
|
|
32
|
-
endTime: null,
|
|
33
|
-
status: "running",
|
|
34
|
-
exitCode: null,
|
|
35
|
-
success: null,
|
|
36
|
-
stdoutFile: "/tmp/pi-processes-demo/proc_42-stdout.log",
|
|
37
|
-
stderrFile: "/tmp/pi-processes-demo/proc_42-stderr.log",
|
|
38
|
-
alertOnSuccess: false,
|
|
39
|
-
alertOnFailure: true,
|
|
40
|
-
alertOnKill: false,
|
|
41
|
-
...overrides,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Temporary no-side-effect previews for process tool renderers.
|
|
47
|
-
* Remove before release.
|
|
48
|
-
*/
|
|
49
|
-
export function executeDebugPreview(params: DebugParams): ExecuteResult {
|
|
50
|
-
const preview = params.preview ?? "start";
|
|
51
|
-
|
|
52
|
-
if (preview === "start") {
|
|
53
|
-
const process = mockProcess();
|
|
54
|
-
const message = [
|
|
55
|
-
`Started "${process.name}" (${process.id}, PID: ${process.pid})`,
|
|
56
|
-
"Log files:",
|
|
57
|
-
` stdout: ${process.stdoutFile}`,
|
|
58
|
-
` stderr: ${process.stderrFile}`,
|
|
59
|
-
].join("\n");
|
|
60
|
-
return {
|
|
61
|
-
content: [{ type: "text", text: message }],
|
|
62
|
-
details: {
|
|
63
|
-
action: "start",
|
|
64
|
-
success: true,
|
|
65
|
-
message,
|
|
66
|
-
process,
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (preview === "list") {
|
|
72
|
-
const processes = [
|
|
73
|
-
mockProcess(),
|
|
74
|
-
mockProcess({
|
|
75
|
-
id: "proc_11",
|
|
76
|
-
name: "builder",
|
|
77
|
-
pid: 1011,
|
|
78
|
-
command: "pnpm build --watch",
|
|
79
|
-
}),
|
|
80
|
-
mockProcess({
|
|
81
|
-
id: "proc_10",
|
|
82
|
-
name: "tests",
|
|
83
|
-
pid: 1010,
|
|
84
|
-
command: "pnpm test",
|
|
85
|
-
status: "exited",
|
|
86
|
-
success: false,
|
|
87
|
-
endTime: Date.now() - 3_000,
|
|
88
|
-
exitCode: 1,
|
|
89
|
-
}),
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
content: [{ type: "text", text: "Debug preview: list" }],
|
|
94
|
-
details: {
|
|
95
|
-
action: "list",
|
|
96
|
-
success: true,
|
|
97
|
-
message: "Debug preview: list",
|
|
98
|
-
processes,
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (preview === "output") {
|
|
104
|
-
const message =
|
|
105
|
-
'"demo-server" (proc_42) [running]: 4 stdout lines, 2 stderr lines';
|
|
106
|
-
const content = [
|
|
107
|
-
message,
|
|
108
|
-
"stdout:",
|
|
109
|
-
"starting...",
|
|
110
|
-
"loading config",
|
|
111
|
-
"ready on http://localhost:3000",
|
|
112
|
-
"watching for changes",
|
|
113
|
-
"",
|
|
114
|
-
"stderr:",
|
|
115
|
-
"warn: deprecated option in config",
|
|
116
|
-
"error: simulated stack trace line",
|
|
117
|
-
"",
|
|
118
|
-
"Process is still running. Use watches instead of polling.",
|
|
119
|
-
"",
|
|
120
|
-
"[Complete currently-retained logs:",
|
|
121
|
-
"stdout=/tmp/pi-processes-demo/proc_42-stdout.log",
|
|
122
|
-
"stderr=/tmp/pi-processes-demo/proc_42-stderr.log]",
|
|
123
|
-
].join("\n");
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
content: [{ type: "text", text: content }],
|
|
127
|
-
details: {
|
|
128
|
-
action: "output",
|
|
129
|
-
success: true,
|
|
130
|
-
message,
|
|
131
|
-
logFiles: {
|
|
132
|
-
stdoutFile: "/tmp/pi-processes-demo/proc_42-stdout.log",
|
|
133
|
-
stderrFile: "/tmp/pi-processes-demo/proc_42-stderr.log",
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (preview === "logs") {
|
|
140
|
-
return {
|
|
141
|
-
content: [{ type: "text", text: "Debug preview: logs" }],
|
|
142
|
-
details: {
|
|
143
|
-
action: "logs",
|
|
144
|
-
success: true,
|
|
145
|
-
message: "Debug preview: logs",
|
|
146
|
-
logFiles: {
|
|
147
|
-
stdoutFile: "/tmp/pi-processes-demo/proc_42-stdout.log",
|
|
148
|
-
stderrFile: "/tmp/pi-processes-demo/proc_42-stderr.log",
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
throw new Error("Invalid logWatches[0].pattern: Unterminated group");
|
|
155
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { ToolBody, ToolCallHeader } from "@aliou/pi-utils-ui";
|
|
2
|
-
import type {
|
|
3
|
-
AgentToolResult,
|
|
4
|
-
ExtensionContext,
|
|
5
|
-
Theme,
|
|
6
|
-
ToolRenderResultOptions,
|
|
7
|
-
} from "@earendil-works/pi-coding-agent";
|
|
8
|
-
import type { Component } from "@earendil-works/pi-tui";
|
|
9
|
-
import type {
|
|
10
|
-
ExecuteResult,
|
|
11
|
-
ProcessAction,
|
|
12
|
-
ProcessesDetails,
|
|
13
|
-
} from "../../constants";
|
|
14
|
-
import type { ProcessManager } from "../../manager";
|
|
15
|
-
import { executeClear } from "./clear";
|
|
16
|
-
import { executeDebugPreview, renderDebugCall } from "./debug";
|
|
17
|
-
import { executeKill, renderKillCall } from "./kill";
|
|
18
|
-
import { executeList, renderListResult } from "./list";
|
|
19
|
-
import { executeLogs, renderLogsCall, renderLogsResult } from "./logs";
|
|
20
|
-
import { executeOutput, renderOutputCall, renderOutputResult } from "./output";
|
|
21
|
-
import { executeStart, renderStartCall, renderStartResult } from "./start";
|
|
22
|
-
import { executeWrite, renderWriteCall } from "./write";
|
|
23
|
-
|
|
24
|
-
const DEBUG_PREVIEW_ENABLED = process.env.PI_PROCESSES_DEBUG_PREVIEW === "1";
|
|
25
|
-
|
|
26
|
-
interface ActionParams {
|
|
27
|
-
action: ProcessAction | string;
|
|
28
|
-
command?: string;
|
|
29
|
-
name?: string;
|
|
30
|
-
id?: string;
|
|
31
|
-
input?: string;
|
|
32
|
-
end?: boolean;
|
|
33
|
-
cwd?: string;
|
|
34
|
-
alertOnSuccess?: boolean;
|
|
35
|
-
alertOnFailure?: boolean;
|
|
36
|
-
alertOnKill?: boolean;
|
|
37
|
-
logWatches?: Array<{
|
|
38
|
-
pattern: string;
|
|
39
|
-
stream?: "stdout" | "stderr" | "both";
|
|
40
|
-
repeat?: boolean;
|
|
41
|
-
}>;
|
|
42
|
-
preview?: "start" | "list" | "output" | "logs" | "error";
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function executeAction(
|
|
46
|
-
params: ActionParams,
|
|
47
|
-
manager: ProcessManager,
|
|
48
|
-
ctx: ExtensionContext,
|
|
49
|
-
): Promise<ExecuteResult> {
|
|
50
|
-
switch (params.action) {
|
|
51
|
-
case "start":
|
|
52
|
-
return executeStart(params, manager, ctx);
|
|
53
|
-
case "list":
|
|
54
|
-
return executeList(manager);
|
|
55
|
-
case "output":
|
|
56
|
-
return executeOutput(params, manager);
|
|
57
|
-
case "logs":
|
|
58
|
-
return executeLogs(params, manager);
|
|
59
|
-
case "kill":
|
|
60
|
-
return executeKill(params, manager);
|
|
61
|
-
case "clear":
|
|
62
|
-
return executeClear(manager);
|
|
63
|
-
case "write":
|
|
64
|
-
return executeWrite(params, manager);
|
|
65
|
-
case "debug_preview":
|
|
66
|
-
if (!DEBUG_PREVIEW_ENABLED) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
"Action 'debug_preview' is disabled. Set PI_PROCESSES_DEBUG_PREVIEW=1 to enable.",
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
return executeDebugPreview(params);
|
|
72
|
-
default:
|
|
73
|
-
return {
|
|
74
|
-
content: [{ type: "text", text: `Unknown action: ${params.action}` }],
|
|
75
|
-
details: {
|
|
76
|
-
action: params.action as ProcessAction,
|
|
77
|
-
success: false,
|
|
78
|
-
message: `Unknown action: ${params.action}`,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function renderActionCall(args: ActionParams, theme: Theme): Component {
|
|
85
|
-
switch (args.action) {
|
|
86
|
-
case "start":
|
|
87
|
-
return renderStartCall(args, theme);
|
|
88
|
-
case "output":
|
|
89
|
-
return renderOutputCall(args, theme);
|
|
90
|
-
case "logs":
|
|
91
|
-
return renderLogsCall(args, theme);
|
|
92
|
-
case "kill":
|
|
93
|
-
return renderKillCall(args, theme);
|
|
94
|
-
case "write":
|
|
95
|
-
return renderWriteCall(args, theme);
|
|
96
|
-
case "debug_preview":
|
|
97
|
-
return renderDebugCall(args, theme);
|
|
98
|
-
default:
|
|
99
|
-
return new ToolCallHeader(
|
|
100
|
-
{ toolName: "Process", action: args.action },
|
|
101
|
-
theme,
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function renderActionResult(
|
|
107
|
-
result: AgentToolResult<ProcessesDetails>,
|
|
108
|
-
options: ToolRenderResultOptions,
|
|
109
|
-
theme: Theme,
|
|
110
|
-
): Component {
|
|
111
|
-
const { details } = result;
|
|
112
|
-
|
|
113
|
-
if (!details) {
|
|
114
|
-
return new ToolBody(
|
|
115
|
-
{
|
|
116
|
-
fields: [
|
|
117
|
-
{
|
|
118
|
-
label: "Result",
|
|
119
|
-
value: "No result details available.",
|
|
120
|
-
showCollapsed: true,
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
},
|
|
124
|
-
options,
|
|
125
|
-
theme,
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
switch (details.action) {
|
|
130
|
-
case "start":
|
|
131
|
-
return renderStartResult(result, options, theme);
|
|
132
|
-
case "list":
|
|
133
|
-
return renderListResult(result, options, theme);
|
|
134
|
-
case "output":
|
|
135
|
-
return renderOutputResult(result, options, theme);
|
|
136
|
-
case "logs":
|
|
137
|
-
return renderLogsResult(result, options, theme);
|
|
138
|
-
case "kill":
|
|
139
|
-
case "write":
|
|
140
|
-
case "clear":
|
|
141
|
-
case "debug_preview":
|
|
142
|
-
// Default rendering for these actions
|
|
143
|
-
return new ToolBody(
|
|
144
|
-
{
|
|
145
|
-
fields: [
|
|
146
|
-
{
|
|
147
|
-
label: "Result",
|
|
148
|
-
value: details.message,
|
|
149
|
-
showCollapsed: true,
|
|
150
|
-
},
|
|
151
|
-
],
|
|
152
|
-
},
|
|
153
|
-
options,
|
|
154
|
-
theme,
|
|
155
|
-
);
|
|
156
|
-
default:
|
|
157
|
-
return new ToolBody(
|
|
158
|
-
{
|
|
159
|
-
fields: [
|
|
160
|
-
{
|
|
161
|
-
label: "Result",
|
|
162
|
-
value: details.message,
|
|
163
|
-
showCollapsed: true,
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
options,
|
|
168
|
-
theme,
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { ToolCallHeader } from "@aliou/pi-utils-ui";
|
|
2
|
-
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import type { ExecuteResult } from "../../constants";
|
|
4
|
-
import type { ProcessManager } from "../../manager";
|
|
5
|
-
|
|
6
|
-
interface KillParams {
|
|
7
|
-
id?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function renderKillCall(args: KillParams, theme: Theme): ToolCallHeader {
|
|
11
|
-
return new ToolCallHeader(
|
|
12
|
-
{
|
|
13
|
-
toolName: "Process",
|
|
14
|
-
action: "kill",
|
|
15
|
-
mainArg: args.id,
|
|
16
|
-
},
|
|
17
|
-
theme,
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function executeKill(
|
|
22
|
-
params: KillParams,
|
|
23
|
-
manager: ProcessManager,
|
|
24
|
-
): Promise<ExecuteResult> {
|
|
25
|
-
if (!params.id) {
|
|
26
|
-
return {
|
|
27
|
-
content: [{ type: "text", text: "Missing required parameter: id" }],
|
|
28
|
-
details: {
|
|
29
|
-
action: "kill",
|
|
30
|
-
success: false,
|
|
31
|
-
message: "Missing required parameter: id",
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const proc = manager.get(params.id);
|
|
37
|
-
if (!proc) {
|
|
38
|
-
const message = `Process not found: ${params.id}`;
|
|
39
|
-
return {
|
|
40
|
-
content: [{ type: "text", text: message }],
|
|
41
|
-
details: {
|
|
42
|
-
action: "kill",
|
|
43
|
-
success: false,
|
|
44
|
-
message,
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const result = await manager.kill(proc.id, {
|
|
50
|
-
signal: "SIGTERM",
|
|
51
|
-
timeoutMs: 3000,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
if (result.ok) {
|
|
55
|
-
const message = `Terminated "${proc.name}" (${proc.id})`;
|
|
56
|
-
return {
|
|
57
|
-
content: [{ type: "text", text: message }],
|
|
58
|
-
details: {
|
|
59
|
-
action: "kill",
|
|
60
|
-
success: true,
|
|
61
|
-
message,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (result.reason === "timeout") {
|
|
67
|
-
const message =
|
|
68
|
-
`SIGTERM timed out for "${proc.name}" (${proc.id}). ` +
|
|
69
|
-
"Run /ps and press x on terminate_timeout to force kill (SIGKILL).";
|
|
70
|
-
return {
|
|
71
|
-
content: [{ type: "text", text: message }],
|
|
72
|
-
details: {
|
|
73
|
-
action: "kill",
|
|
74
|
-
success: false,
|
|
75
|
-
message,
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const message = `Failed to terminate "${proc.name}" (${proc.id})`;
|
|
81
|
-
return {
|
|
82
|
-
content: [{ type: "text", text: message }],
|
|
83
|
-
details: {
|
|
84
|
-
action: "kill",
|
|
85
|
-
success: false,
|
|
86
|
-
message,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { ToolBody, ToolFooter } from "@aliou/pi-utils-ui";
|
|
2
|
-
import type {
|
|
3
|
-
AgentToolResult,
|
|
4
|
-
Theme,
|
|
5
|
-
ToolRenderResultOptions,
|
|
6
|
-
} from "@earendil-works/pi-coding-agent";
|
|
7
|
-
import { Text } from "@earendil-works/pi-tui";
|
|
8
|
-
import type { ExecuteResult, ProcessesDetails } from "../../constants";
|
|
9
|
-
import type { ProcessManager } from "../../manager";
|
|
10
|
-
import {
|
|
11
|
-
formatRuntime,
|
|
12
|
-
formatStatus,
|
|
13
|
-
formatStatusTag,
|
|
14
|
-
formatTimestamp,
|
|
15
|
-
truncateCmd,
|
|
16
|
-
} from "../../utils";
|
|
17
|
-
|
|
18
|
-
export function executeList(manager: ProcessManager): ExecuteResult {
|
|
19
|
-
const processes = manager.list();
|
|
20
|
-
|
|
21
|
-
if (processes.length === 0) {
|
|
22
|
-
return {
|
|
23
|
-
content: [{ type: "text", text: "No background processes running" }],
|
|
24
|
-
details: {
|
|
25
|
-
action: "list",
|
|
26
|
-
success: true,
|
|
27
|
-
message: "No background processes running",
|
|
28
|
-
processes: [],
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const summary = processes
|
|
34
|
-
.map(
|
|
35
|
-
(p) =>
|
|
36
|
-
`${p.id} "${p.name}": ${truncateCmd(p.command)} [${formatStatus(p)}] ${formatRuntime(p.startTime, p.endTime)}`,
|
|
37
|
-
)
|
|
38
|
-
.join("\n");
|
|
39
|
-
|
|
40
|
-
const message = `${processes.length} process(es):\n${summary}`;
|
|
41
|
-
return {
|
|
42
|
-
content: [{ type: "text", text: message }],
|
|
43
|
-
details: {
|
|
44
|
-
action: "list",
|
|
45
|
-
success: true,
|
|
46
|
-
message,
|
|
47
|
-
processes,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function renderListResult(
|
|
53
|
-
result: AgentToolResult<ProcessesDetails>,
|
|
54
|
-
options: ToolRenderResultOptions,
|
|
55
|
-
theme: Theme,
|
|
56
|
-
): ToolBody {
|
|
57
|
-
const { details } = result;
|
|
58
|
-
|
|
59
|
-
if (!details.processes || details.processes.length === 0) {
|
|
60
|
-
return new ToolBody(
|
|
61
|
-
{
|
|
62
|
-
fields: [
|
|
63
|
-
{
|
|
64
|
-
label: "Processes",
|
|
65
|
-
value: "No background processes running",
|
|
66
|
-
showCollapsed: true,
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
options,
|
|
71
|
-
theme,
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const processes = [...details.processes];
|
|
76
|
-
|
|
77
|
-
const statusRank = (status: string): number => {
|
|
78
|
-
switch (status) {
|
|
79
|
-
case "running":
|
|
80
|
-
return 0;
|
|
81
|
-
case "terminating":
|
|
82
|
-
return 1;
|
|
83
|
-
case "terminate_timeout":
|
|
84
|
-
return 2;
|
|
85
|
-
case "killed":
|
|
86
|
-
return 3;
|
|
87
|
-
case "exited":
|
|
88
|
-
return 4;
|
|
89
|
-
default:
|
|
90
|
-
return 5;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
processes.sort((a, b) => {
|
|
95
|
-
const rankDiff = statusRank(a.status) - statusRank(b.status);
|
|
96
|
-
if (rankDiff !== 0) return rankDiff;
|
|
97
|
-
return b.startTime - a.startTime;
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const runningCount = processes.filter(
|
|
101
|
-
(p) => p.status === "running" || p.status === "terminating",
|
|
102
|
-
).length;
|
|
103
|
-
|
|
104
|
-
const lines: string[] = [
|
|
105
|
-
theme.fg(
|
|
106
|
-
"success",
|
|
107
|
-
`${processes.length} process(es), ${runningCount} running/terminating`,
|
|
108
|
-
),
|
|
109
|
-
];
|
|
110
|
-
|
|
111
|
-
for (const process of processes) {
|
|
112
|
-
const status = formatStatusTag(process, theme);
|
|
113
|
-
lines.push(
|
|
114
|
-
[
|
|
115
|
-
`- ${theme.fg("accent", process.name)} ${theme.fg("muted", `(${process.id})`)}`,
|
|
116
|
-
` pid: ${process.pid} status: ${status}`,
|
|
117
|
-
` started: ${theme.fg("muted", formatTimestamp(process.startTime))}`,
|
|
118
|
-
` ended: ${theme.fg("muted", formatTimestamp(process.endTime))}`,
|
|
119
|
-
` runtime: ${theme.fg("muted", formatRuntime(process.startTime, process.endTime))}`,
|
|
120
|
-
].join("\n"),
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const fields: Array<
|
|
125
|
-
{ label: string; value: string; showCollapsed?: boolean } | Text
|
|
126
|
-
> = [new Text(lines.join("\n"), 0, 0)];
|
|
127
|
-
|
|
128
|
-
const running = details.processes.filter(
|
|
129
|
-
(p) => p.status === "running" || p.status === "terminating",
|
|
130
|
-
);
|
|
131
|
-
const finishedOk = details.processes.filter(
|
|
132
|
-
(p) => p.status === "exited" && p.success,
|
|
133
|
-
).length;
|
|
134
|
-
const failed = details.processes.filter(
|
|
135
|
-
(p) => p.status === "exited" && !p.success,
|
|
136
|
-
).length;
|
|
137
|
-
const killed = details.processes.filter((p) => p.status === "killed").length;
|
|
138
|
-
|
|
139
|
-
const runningSummary =
|
|
140
|
-
running.length > 0
|
|
141
|
-
? running
|
|
142
|
-
.slice(0, 3)
|
|
143
|
-
.map(
|
|
144
|
-
(p) =>
|
|
145
|
-
`${theme.fg("accent", `"${p.name}"`)} [${formatStatusTag(p, theme)}]`,
|
|
146
|
-
)
|
|
147
|
-
.join(", ")
|
|
148
|
-
: theme.fg("muted", "no running process");
|
|
149
|
-
|
|
150
|
-
const restParts: string[] = [];
|
|
151
|
-
if (finishedOk > 0) restParts.push(`${finishedOk} finished`);
|
|
152
|
-
if (failed > 0) restParts.push(`${failed} failed`);
|
|
153
|
-
if (killed > 0) restParts.push(`${killed} killed`);
|
|
154
|
-
const restSummary =
|
|
155
|
-
restParts.length > 0 ? theme.fg("muted", ` + ${restParts.join(", ")}`) : "";
|
|
156
|
-
|
|
157
|
-
fields.push({
|
|
158
|
-
label: "Processes",
|
|
159
|
-
value: runningSummary + restSummary,
|
|
160
|
-
showCollapsed: true,
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const footerItems: Array<{
|
|
164
|
-
label: string;
|
|
165
|
-
value: string;
|
|
166
|
-
}> = [];
|
|
167
|
-
if (runningCount > 0) {
|
|
168
|
-
footerItems.push({ label: "running", value: String(runningCount) });
|
|
169
|
-
}
|
|
170
|
-
if (failed > 0) {
|
|
171
|
-
footerItems.push({ label: "failed", value: String(failed) });
|
|
172
|
-
}
|
|
173
|
-
if (killed > 0) {
|
|
174
|
-
footerItems.push({ label: "killed", value: String(killed) });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return new ToolBody(
|
|
178
|
-
{
|
|
179
|
-
fields,
|
|
180
|
-
footer:
|
|
181
|
-
footerItems.length > 0
|
|
182
|
-
? new ToolFooter(theme, { items: footerItems, separator: " | " })
|
|
183
|
-
: undefined,
|
|
184
|
-
},
|
|
185
|
-
options,
|
|
186
|
-
theme,
|
|
187
|
-
);
|
|
188
|
-
}
|