@grackle-ai/powerline 0.170.0 → 0.171.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/ahp-handlers.d.ts +7 -44
  2. package/dist/ahp-handlers.d.ts.map +1 -1
  3. package/dist/ahp-handlers.js +21 -1024
  4. package/dist/ahp-handlers.js.map +1 -1
  5. package/dist/ahp-types.d.ts +92 -0
  6. package/dist/ahp-types.d.ts.map +1 -0
  7. package/dist/ahp-types.js +19 -0
  8. package/dist/ahp-types.js.map +1 -0
  9. package/dist/channel-codec.d.ts +31 -0
  10. package/dist/channel-codec.d.ts.map +1 -0
  11. package/dist/channel-codec.js +38 -0
  12. package/dist/channel-codec.js.map +1 -0
  13. package/dist/forwarder.d.ts +26 -0
  14. package/dist/forwarder.d.ts.map +1 -0
  15. package/dist/forwarder.js +223 -0
  16. package/dist/forwarder.js.map +1 -0
  17. package/dist/handlers/action-handlers.d.ts +12 -0
  18. package/dist/handlers/action-handlers.d.ts.map +1 -0
  19. package/dist/handlers/action-handlers.js +49 -0
  20. package/dist/handlers/action-handlers.js.map +1 -0
  21. package/dist/handlers/session-handlers.d.ts +16 -0
  22. package/dist/handlers/session-handlers.d.ts.map +1 -0
  23. package/dist/handlers/session-handlers.js +262 -0
  24. package/dist/handlers/session-handlers.js.map +1 -0
  25. package/dist/handlers/subscribe-handlers.d.ts +10 -0
  26. package/dist/handlers/subscribe-handlers.d.ts.map +1 -0
  27. package/dist/handlers/subscribe-handlers.js +82 -0
  28. package/dist/handlers/subscribe-handlers.js.map +1 -0
  29. package/dist/index.js +11 -25
  30. package/dist/index.js.map +1 -1
  31. package/dist/resource-watch.d.ts +30 -0
  32. package/dist/resource-watch.d.ts.map +1 -0
  33. package/dist/resource-watch.js +169 -0
  34. package/dist/resource-watch.js.map +1 -0
  35. package/dist/runtime-loader.d.ts +9 -0
  36. package/dist/runtime-loader.d.ts.map +1 -0
  37. package/dist/runtime-loader.js +69 -0
  38. package/dist/runtime-loader.js.map +1 -0
  39. package/package.json +10 -10
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AHP session lifecycle handlers: create, dispose, list, initialize.
3
+ * @module handlers/session-handlers
4
+ */
5
+ import type { AhpResponse, CreateSessionParams, DisposeSessionParams, InitializeParams, InitializeResult, ListSessionsParams, ListSessionsResult } from "@grackle-ai/ahp";
6
+ import type { AhpServerConnection } from "@grackle-ai/ahp-transport";
7
+ import type { ClientState } from "../ahp-types.js";
8
+ /** Return the canned AHP initialize handshake result. */
9
+ export declare function handleInitialize(_params: InitializeParams): InitializeResult;
10
+ /** Parse `createSession` params and spawn or resume the runtime session. */
11
+ export declare function handleCreateSession(params: CreateSessionParams, conn: AhpServerConnection, cState: ClientState, clients: Map<string, ClientState>): AhpResponse | undefined;
12
+ /** Kill a session and remove it from the registry. */
13
+ export declare function handleDisposeSession(params: DisposeSessionParams, conn: AhpServerConnection, clients: Map<string, ClientState>): AhpResponse;
14
+ /** Map the in-memory session registry to an AHP session list. */
15
+ export declare function handleListSessions(_params: ListSessionsParams): ListSessionsResult;
16
+ //# sourceMappingURL=session-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/session-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAInB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAKrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAqCnD,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAM5E;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAChC,WAAW,GAAG,SAAS,CAkJzB;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAChC,WAAW,CA4Cb;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAalF"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * AHP session lifecycle handlers: create, dispose, list, initialize.
3
+ * @module handlers/session-handlers
4
+ */
5
+ import { ActionType, JsonRpcErrorCodes, SessionStatus } from "@grackle-ai/ahp";
6
+ import { validateGitBranchName, worktreeDir } from "@grackle-ai/runtime-sdk";
7
+ import { resolve as resolvePath } from "node:path";
8
+ import { PROTOCOL_VERSION, SESSION_CHANNEL_PREFIX, sessionChannel, sessionIdFromChannel, } from "../channel-codec.js";
9
+ import { getRuntime } from "../runtime-registry.js";
10
+ import { deleteSessionPump, getSession, listAllSessions, removeSession, startSessionPump, } from "../session-mgr.js";
11
+ /**
12
+ * Record the filesystem roots a newly-created session exposes for resource
13
+ * read/list/watch.
14
+ */
15
+ function addSessionRoots(cState, cfg) {
16
+ const wd = typeof cfg.workingDirectory === "string" && cfg.workingDirectory !== ""
17
+ ? cfg.workingDirectory
18
+ : undefined;
19
+ if (wd === undefined) {
20
+ return;
21
+ }
22
+ const root = resolvePath(wd);
23
+ cState.allowedRoots.add(root);
24
+ const branch = typeof cfg.branch === "string" && cfg.branch !== "" ? cfg.branch : undefined;
25
+ const useWorktrees = cfg.useWorktrees !== false;
26
+ if (useWorktrees && branch !== undefined) {
27
+ cState.allowedRoots.add(worktreeDir(root, branch));
28
+ }
29
+ }
30
+ /** Return the canned AHP initialize handshake result. */
31
+ export function handleInitialize(_params) {
32
+ return {
33
+ protocolVersion: PROTOCOL_VERSION,
34
+ serverSeq: 0,
35
+ snapshots: [],
36
+ };
37
+ }
38
+ /** Parse `createSession` params and spawn or resume the runtime session. */
39
+ export function handleCreateSession(params, conn, cState, clients) {
40
+ const sessionId = sessionIdFromChannel(params.channel);
41
+ if (sessionId === undefined) {
42
+ return {
43
+ jsonrpc: "2.0",
44
+ id: 0,
45
+ error: {
46
+ code: JsonRpcErrorCodes.InvalidParams,
47
+ message: `createSession: channel must be ${SESSION_CHANNEL_PREFIX}<sessionId>`,
48
+ },
49
+ };
50
+ }
51
+ const runtimeName = params.provider;
52
+ if (runtimeName === undefined) {
53
+ return {
54
+ jsonrpc: "2.0",
55
+ id: 0,
56
+ error: {
57
+ code: JsonRpcErrorCodes.InvalidParams,
58
+ message: "createSession: `provider` is required",
59
+ },
60
+ };
61
+ }
62
+ const runtime = getRuntime(runtimeName);
63
+ if (runtime === undefined) {
64
+ return {
65
+ jsonrpc: "2.0",
66
+ id: 0,
67
+ error: {
68
+ code: JsonRpcErrorCodes.InvalidParams,
69
+ message: `Unknown runtime: ${runtimeName}`,
70
+ },
71
+ };
72
+ }
73
+ const existing = getSession(sessionId);
74
+ if (existing !== undefined) {
75
+ return {
76
+ jsonrpc: "2.0",
77
+ id: 0,
78
+ error: {
79
+ code: JsonRpcErrorCodes.InvalidRequest,
80
+ message: `Session already active: ${sessionId}`,
81
+ },
82
+ };
83
+ }
84
+ const config = params.config ?? {};
85
+ const cfg = config;
86
+ const resumeId = typeof cfg.resumeFromRuntimeSessionId === "string" ? cfg.resumeFromRuntimeSessionId : undefined;
87
+ let session;
88
+ try {
89
+ if (resumeId !== undefined) {
90
+ session = runtime.resume({
91
+ sessionId,
92
+ runtimeSessionId: resumeId,
93
+ });
94
+ }
95
+ else {
96
+ const prompt = typeof cfg.prompt === "string" ? cfg.prompt : "";
97
+ const model = typeof cfg.model === "string" ? cfg.model : "";
98
+ const maxTurns = typeof cfg.maxTurns === "number" ? cfg.maxTurns : 0;
99
+ const branchVal = typeof cfg.branch === "string" && cfg.branch !== "" ? cfg.branch : undefined;
100
+ if (branchVal !== undefined) {
101
+ try {
102
+ validateGitBranchName(branchVal);
103
+ }
104
+ catch (err) {
105
+ return {
106
+ jsonrpc: "2.0",
107
+ id: 0,
108
+ error: {
109
+ code: JsonRpcErrorCodes.InvalidParams,
110
+ message: err instanceof Error ? err.message : "Invalid branch name",
111
+ },
112
+ };
113
+ }
114
+ }
115
+ const wdVal = typeof cfg.workingDirectory === "string" && cfg.workingDirectory !== ""
116
+ ? cfg.workingDirectory
117
+ : undefined;
118
+ const useWorktrees = typeof cfg.useWorktrees === "boolean" ? cfg.useWorktrees : undefined;
119
+ const systemContext = typeof cfg.systemContext === "string" && cfg.systemContext !== ""
120
+ ? cfg.systemContext
121
+ : undefined;
122
+ const workspaceId = typeof cfg.workspaceId === "string" && cfg.workspaceId !== "" ? cfg.workspaceId : undefined;
123
+ const taskId = typeof cfg.taskId === "string" ? cfg.taskId : undefined;
124
+ const mcpServersJson = typeof cfg.mcpServersJson === "string" ? cfg.mcpServersJson : "";
125
+ const mcpUrl = typeof cfg.mcpUrl === "string" ? cfg.mcpUrl : "";
126
+ const mcpToken = typeof cfg.mcpToken === "string" ? cfg.mcpToken : "";
127
+ const scriptContent = typeof cfg.scriptContent === "string" && cfg.scriptContent !== ""
128
+ ? cfg.scriptContent
129
+ : undefined;
130
+ const pipe = typeof cfg.pipe === "string" && cfg.pipe !== ""
131
+ ? cfg.pipe
132
+ : undefined;
133
+ session = runtime.spawn({
134
+ sessionId,
135
+ prompt,
136
+ model,
137
+ maxTurns,
138
+ ...(branchVal !== undefined ? { branch: branchVal } : {}),
139
+ ...(wdVal !== undefined ? { workingDirectory: wdVal } : {}),
140
+ ...(useWorktrees !== undefined ? { useWorktrees } : {}),
141
+ ...(systemContext !== undefined ? { systemContext } : {}),
142
+ ...(workspaceId !== undefined ? { workspaceId } : {}),
143
+ ...(taskId !== undefined ? { taskId } : {}),
144
+ mcpServers: mcpServersJson
145
+ ? JSON.parse(mcpServersJson)
146
+ : undefined,
147
+ ...(mcpUrl && mcpToken ? { mcpBroker: { url: mcpUrl, token: mcpToken } } : {}),
148
+ ...(scriptContent !== undefined ? { scriptContent } : {}),
149
+ ...(pipe !== undefined ? { pipe } : {}),
150
+ });
151
+ }
152
+ }
153
+ catch (err) {
154
+ return {
155
+ jsonrpc: "2.0",
156
+ id: 0,
157
+ error: {
158
+ code: JsonRpcErrorCodes.InternalError,
159
+ message: err instanceof Error ? err.message : String(err),
160
+ },
161
+ };
162
+ }
163
+ const ownerClientId = conn.clientId;
164
+ startSessionPump(session, (deadSessionId) => {
165
+ const owner = clients.get(ownerClientId);
166
+ owner?.sessionIds.delete(deadSessionId);
167
+ });
168
+ cState.sessionIds.add(sessionId);
169
+ addSessionRoots(cState, cfg);
170
+ return {
171
+ jsonrpc: "2.0",
172
+ id: 0,
173
+ result: null,
174
+ };
175
+ }
176
+ /** Kill a session and remove it from the registry. */
177
+ export function handleDisposeSession(params, conn, clients) {
178
+ const sessionId = sessionIdFromChannel(params.channel);
179
+ if (sessionId === undefined) {
180
+ return {
181
+ jsonrpc: "2.0",
182
+ id: 0,
183
+ error: {
184
+ code: JsonRpcErrorCodes.InvalidParams,
185
+ message: "disposeSession: channel must be ahp-session:/<id>",
186
+ },
187
+ };
188
+ }
189
+ const session = getSession(sessionId);
190
+ if (session !== undefined) {
191
+ session.kill("killed");
192
+ removeSession(sessionId);
193
+ deleteSessionPump(sessionId);
194
+ }
195
+ const cState = clients.get(conn.clientId);
196
+ if (cState !== undefined) {
197
+ cState.sessionIds.delete(sessionId);
198
+ const fwd = cState.forwarders.get(sessionId);
199
+ if (fwd !== undefined) {
200
+ fwd.serverSeq += 1;
201
+ const killedAction = {
202
+ type: ActionType.SessionMetaChanged,
203
+ _meta: { status: "killed" },
204
+ };
205
+ conn.session.notify("action", {
206
+ channel: sessionChannel(sessionId),
207
+ serverSeq: fwd.serverSeq,
208
+ action: killedAction,
209
+ origin: undefined,
210
+ });
211
+ fwd.cancelled = true;
212
+ fwd.wake?.();
213
+ cState.forwarders.delete(sessionId);
214
+ }
215
+ }
216
+ return {
217
+ jsonrpc: "2.0",
218
+ id: 0,
219
+ result: null,
220
+ };
221
+ }
222
+ /** Map the in-memory session registry to an AHP session list. */
223
+ export function handleListSessions(_params) {
224
+ const items = listAllSessions().map((s) => {
225
+ const now = Date.now();
226
+ return {
227
+ resource: sessionChannel(s.id),
228
+ provider: s.runtimeName,
229
+ title: s.id,
230
+ status: mapAgentStatusToAhp(s.status),
231
+ createdAt: now,
232
+ modifiedAt: now,
233
+ };
234
+ });
235
+ return { items };
236
+ }
237
+ /** Map PowerLine's loose status string to AHP's bitset enum. */
238
+ function mapAgentStatusToAhp(status) {
239
+ switch (status) {
240
+ case "pending":
241
+ return SessionStatus.InProgress;
242
+ case "running":
243
+ return SessionStatus.InProgress;
244
+ case "idle":
245
+ return SessionStatus.InputNeeded;
246
+ case "stopped":
247
+ return SessionStatus.Idle;
248
+ case "suspended":
249
+ return SessionStatus.Idle;
250
+ case "waiting_input":
251
+ return SessionStatus.InputNeeded;
252
+ case "completed":
253
+ return SessionStatus.Idle;
254
+ case "failed":
255
+ case "killed":
256
+ case "terminated":
257
+ return SessionStatus.Error;
258
+ default:
259
+ return SessionStatus.Idle;
260
+ }
261
+ }
262
+ //# sourceMappingURL=session-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-handlers.js","sourceRoot":"","sources":["../../src/handlers/session-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * AHP subscribe/unsubscribe handlers: session and resource-watch subscriptions.
3
+ * @module handlers/subscribe-handlers
4
+ */
5
+ import type { AhpResponse, SubscribeParams } from "@grackle-ai/ahp";
6
+ import type { AhpServerConnection } from "@grackle-ai/ahp-transport";
7
+ import type { ClientState } from "../ahp-types.js";
8
+ /** Route a subscribe request to either resource-watch or session forwarding. */
9
+ export declare function handleSubscribe(params: SubscribeParams, conn: AhpServerConnection, cState: ClientState, clients: Map<string, ClientState>): AhpResponse;
10
+ //# sourceMappingURL=subscribe-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/subscribe-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AAErF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,iBAAiB,CAAC;AAMnE,gFAAgF;AAChF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAChC,WAAW,CAqBb"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * AHP subscribe/unsubscribe handlers: session and resource-watch subscriptions.
3
+ * @module handlers/subscribe-handlers
4
+ */
5
+ import { JsonRpcErrorCodes } from "@grackle-ai/ahp";
6
+ import { RESOURCE_WATCH_CHANNEL_PREFIX, sessionIdFromChannel } from "../channel-codec.js";
7
+ import { runForwarder } from "../forwarder.js";
8
+ import { startResourceWatch } from "../resource-watch.js";
9
+ import { getSession, isParked } from "../session-mgr.js";
10
+ /** Route a subscribe request to either resource-watch or session forwarding. */
11
+ export function handleSubscribe(params, conn, cState, clients) {
12
+ if (params.channel.startsWith(RESOURCE_WATCH_CHANNEL_PREFIX)) {
13
+ const entry = cState.watches.get(params.channel);
14
+ if (entry === undefined) {
15
+ return {
16
+ jsonrpc: "2.0",
17
+ id: 0,
18
+ error: {
19
+ code: JsonRpcErrorCodes.InvalidParams,
20
+ message: `Unknown resource-watch channel: ${params.channel}`,
21
+ },
22
+ };
23
+ }
24
+ startResourceWatch(conn, params.channel, entry);
25
+ return {
26
+ jsonrpc: "2.0",
27
+ id: 0,
28
+ result: { snapshot: undefined },
29
+ };
30
+ }
31
+ return handleSessionSubscribe(params, conn, cState, clients);
32
+ }
33
+ /** Set up the per-(session, client) forwarder for a session-channel subscribe. */
34
+ function handleSessionSubscribe(params, conn, cState, clients) {
35
+ const sessionId = sessionIdFromChannel(params.channel);
36
+ if (sessionId === undefined) {
37
+ return {
38
+ jsonrpc: "2.0",
39
+ id: 0,
40
+ result: { snapshot: undefined },
41
+ };
42
+ }
43
+ const session = getSession(sessionId);
44
+ if (session === undefined && !isParked(sessionId)) {
45
+ return {
46
+ jsonrpc: "2.0",
47
+ id: 0,
48
+ error: {
49
+ code: JsonRpcErrorCodes.InvalidParams,
50
+ message: `Unknown session channel: ${params.channel}`,
51
+ },
52
+ };
53
+ }
54
+ const prior = cState.forwarders.get(sessionId);
55
+ if (prior !== undefined) {
56
+ prior.cancelled = true;
57
+ prior.wake?.();
58
+ }
59
+ const forwarder = {
60
+ mapperContext: {
61
+ turnId: undefined,
62
+ openToolCalls: [],
63
+ partCounter: 0,
64
+ eventIndex: 0,
65
+ metaAccumulator: {},
66
+ },
67
+ serverSeq: 0,
68
+ cancelled: false,
69
+ lastMetaSnapshot: undefined,
70
+ pos: 0,
71
+ };
72
+ cState.forwarders.set(sessionId, forwarder);
73
+ queueMicrotask(() => {
74
+ runForwarder(conn, sessionId, forwarder, clients).catch(() => { });
75
+ });
76
+ return {
77
+ jsonrpc: "2.0",
78
+ id: 0,
79
+ result: { snapshot: undefined },
80
+ };
81
+ }
82
+ //# sourceMappingURL=subscribe-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-handlers.js","sourceRoot":"","sources":["../../src/handlers/subscribe-handlers.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,14 +4,10 @@ import { mountAhpServer } from "./ahp-handlers.js";
4
4
  import { registerRuntime } from "./runtime-registry.js";
5
5
  import { StubRuntime } from "./runtimes/stub.js";
6
6
  import { StubMcpRuntime } from "./runtimes/stub-mcp.js";
7
- import { GenAIScriptRuntime } from "@grackle-ai/runtime-genaiscript";
8
- import { ClaudeCodeRuntime } from "@grackle-ai/runtime-claude-code";
9
- import { CopilotRuntime } from "@grackle-ai/runtime-copilot";
10
- import { CodexRuntime } from "@grackle-ai/runtime-codex";
11
- import { AcpRuntime } from "@grackle-ai/runtime-acp";
12
7
  import { DEFAULT_POWERLINE_PORT } from "@grackle-ai/common";
13
8
  import { createRequire } from "node:module";
14
9
  import { logger } from "./logger.js";
10
+ import { loadRuntimesFromCatalog } from "./runtime-loader.js";
15
11
  const esmRequire = createRequire(import.meta.url);
16
12
  const { version } = esmRequire("../package.json");
17
13
  // The PowerLine is an independent service, not a nested Claude Code session.
@@ -19,7 +15,7 @@ const { version } = esmRequire("../package.json");
19
15
  // refuse to start when the PowerLine happens to be launched from within
20
16
  // a Claude Code session (e.g. during development or local testing).
21
17
  delete process.env.CLAUDECODE;
22
- function main() {
18
+ async function main() {
23
19
  const program = new Command();
24
20
  program
25
21
  .name("grackle-powerline")
@@ -29,7 +25,7 @@ function main() {
29
25
  .option("--token <token>", "Authentication token")
30
26
  .option("--no-auth", "Run without authentication (development only)")
31
27
  .option("--host <host>", "Host to bind to", "127.0.0.1")
32
- .action((opts) => {
28
+ .action(async (opts) => {
33
29
  const port = parseInt(opts.port, 10);
34
30
  const host = opts.host;
35
31
  const powerlineToken = opts.auth
@@ -40,24 +36,11 @@ function main() {
40
36
  process.exitCode = 1;
41
37
  return;
42
38
  }
43
- // Register runtimes
39
+ // Register stubs (PowerLine-internal test runtimes, no catalog factory).
44
40
  registerRuntime(new StubRuntime());
45
41
  registerRuntime(new StubMcpRuntime());
46
- registerRuntime(new GenAIScriptRuntime());
47
- registerRuntime(new ClaudeCodeRuntime());
48
- registerRuntime(new CopilotRuntime());
49
- registerRuntime(new CodexRuntime());
50
- registerRuntime(new AcpRuntime({ name: "goose", command: "goose", args: ["acp"] }));
51
- registerRuntime(new AcpRuntime({ name: "codex-acp", command: "codex-acp", args: [] }));
52
- registerRuntime(new AcpRuntime({ name: "copilot-acp", command: "copilot", args: ["--acp", "--stdio"] }));
53
- registerRuntime(new AcpRuntime({
54
- name: "claude-code-acp",
55
- command: "claude-agent-acp",
56
- args: [],
57
- // Isolate from ~/.claude so interactive-only settings (e.g.
58
- // permissions.defaultMode "auto") don't crash session/new (#1366).
59
- isolateClaudeConfig: true,
60
- }));
42
+ // Register production runtimes from the catalog.
43
+ await loadRuntimesFromCatalog();
61
44
  // HR8d: PowerLine speaks AHP JSON-RPC over WebSocket (not gRPC).
62
45
  // AhpServerSocket handles the HTTP upgrade and Bearer-token auth.
63
46
  const server = http.createServer((req, res) => {
@@ -108,7 +91,10 @@ function main() {
108
91
  process.on("SIGINT", shutdown);
109
92
  process.on("SIGTERM", shutdown);
110
93
  });
111
- program.parse();
94
+ await program.parseAsync();
112
95
  }
113
- main();
96
+ main().catch((err) => {
97
+ logger.fatal({ err }, "PowerLine failed to start");
98
+ process.exitCode = 1;
99
+ });
114
100
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Filesystem resource watch lifecycle: create, start, stop, flush.
3
+ * @module resource-watch
4
+ */
5
+ import type { CreateResourceWatchParams, CreateResourceWatchResult } from "@grackle-ai/ahp";
6
+ import type { AhpServerConnection } from "@grackle-ai/ahp-transport";
7
+ import type { ClientState, ResourceWatchEntry } from "./ahp-types.js";
8
+ /**
9
+ * Allocate a resource-watch channel for a sandbox-validated URI. The watcher
10
+ * itself is started lazily when the client subscribes to the returned channel
11
+ * ({@link startResourceWatch}).
12
+ *
13
+ * @throws ResourceError — `InvalidParams`/`PermissionDenied` (sandbox) or
14
+ * `NotFound` if the watch target does not exist.
15
+ */
16
+ export declare function createResourceWatchEntry(params: CreateResourceWatchParams, cState: ClientState): Promise<CreateResourceWatchResult>;
17
+ /**
18
+ * Flush the coalesced change batch for a watch as a single
19
+ * `resourceWatch/changed` action. Never dispatches an empty batch (per spec).
20
+ */
21
+ export declare function flushResourceWatch(conn: AhpServerConnection, channel: string, entry: ResourceWatchEntry): void;
22
+ /**
23
+ * Start the chokidar watcher for a previously-created watch entry and wire its
24
+ * events into coalesced `resourceWatch/changed` notifications. Idempotent: a
25
+ * second subscribe to the same channel is a no-op.
26
+ */
27
+ export declare function startResourceWatch(conn: AhpServerConnection, channel: string, entry: ResourceWatchEntry): void;
28
+ /** Release a watch's filesystem resources (watcher + pending flush timer). */
29
+ export declare function stopResourceWatch(entry: ResourceWatchEntry): void;
30
+ //# sourceMappingURL=resource-watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-watch.d.ts","sourceRoot":"","sources":["../src/resource-watch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EAG1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAQrE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AA8BtE;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,yBAAyB,CAAC,CAsBpC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,GACxB,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,GACxB,IAAI,CAsEN;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAejE"}