@agimon-ai/po-runner 0.0.0-alpha.31 → 0.0.0-alpha.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/README.md +10 -8
- package/dist/apiContracts.cjs +36 -0
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/apiContracts.mjs +36 -0
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/{bashRunService-DQeetQzV.mjs → bashRunService-CmjnipLE.mjs} +2 -2
- package/dist/bashRunService-CmjnipLE.mjs.map +1 -0
- package/dist/{bashRunService-DGZZGWLL.cjs → bashRunService-DLpFoP81.cjs} +2 -2
- package/dist/bashRunService-DLpFoP81.cjs.map +1 -0
- package/dist/bashRunService.cjs +1 -1
- package/dist/bashRunService.d.mts.map +1 -1
- package/dist/bashRunService.mjs +1 -1
- package/dist/bashSchema.cjs +1 -1
- package/dist/bashSchema.d.mts +1 -1
- package/dist/bashSchema.mjs +1 -1
- package/dist/{bashTool-Bahf40vt.cjs → bashTool-CfNNdq62.cjs} +7 -13
- package/dist/bashTool-CfNNdq62.cjs.map +1 -0
- package/dist/bashTool-DRW3lseL.mjs +26 -0
- package/dist/bashTool-DRW3lseL.mjs.map +1 -0
- package/dist/bashTool-Dc1ld2E3.d.mts +14 -0
- package/dist/bashTool-Dc1ld2E3.d.mts.map +1 -0
- package/dist/bashTool.cjs +2 -2
- package/dist/bashTool.d.mts +1 -1
- package/dist/bashTool.mjs +2 -2
- package/dist/bin/cli.cjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/cliApp.d.mts +1 -1
- package/dist/extensions/mcp.cjs +6 -6
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.mjs +6 -6
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/server.cjs +27 -32
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +27 -32
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/{headless-as3Q6ucs.cjs → headless-BlgjJiv0.cjs} +10 -27
- package/dist/headless-BlgjJiv0.cjs.map +1 -0
- package/dist/{headless-VzfNzuEv.mjs → headless-kp9-KBp3.mjs} +11 -28
- package/dist/headless-kp9-KBp3.mjs.map +1 -0
- package/dist/{index-Df58fJ3b.d.mts → index-BhS6r6Eq.d.mts} +4 -6
- package/dist/index-BhS6r6Eq.d.mts.map +1 -0
- package/dist/{index-DM7yJpMs.d.mts → index-DBQPUAC3.d.mts} +2 -2
- package/dist/index-DBQPUAC3.d.mts.map +1 -0
- package/dist/{index-COFsd7Mb.d.mts → index-W2PLbgCR.d.mts} +2 -2
- package/dist/{index-COFsd7Mb.d.mts.map → index-W2PLbgCR.d.mts.map} +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{logReader-BEneVvSC.cjs → logReader-3RzQjCs4.cjs} +76 -29
- package/dist/logReader-3RzQjCs4.cjs.map +1 -0
- package/dist/{logReader-D1xSM6uE.mjs → logReader-DpO_fcDj.mjs} +76 -29
- package/dist/logReader-DpO_fcDj.mjs.map +1 -0
- package/dist/{logReader-MdW9ffvV.d.mts → logReader-wZC8OH3h.d.mts} +3 -1
- package/dist/{logReader-MdW9ffvV.d.mts.map → logReader-wZC8OH3h.d.mts.map} +1 -1
- package/dist/logReader.cjs +1 -1
- package/dist/logReader.d.mts +2 -2
- package/dist/logReader.mjs +1 -1
- package/dist/responseEnvelope.cjs +1 -1
- package/dist/responseEnvelope.d.mts +1 -1
- package/dist/responseEnvelope.mjs +1 -1
- package/dist/{runnerDependencies-DRtNq2hj.mjs → runnerDependencies-C6K2P-ID.mjs} +3 -3
- package/dist/{runnerDependencies-DRtNq2hj.mjs.map → runnerDependencies-C6K2P-ID.mjs.map} +1 -1
- package/dist/{runnerDependencies-D7v_k-sz.cjs → runnerDependencies-DOY30X-w.cjs} +3 -3
- package/dist/{runnerDependencies-D7v_k-sz.cjs.map → runnerDependencies-DOY30X-w.cjs.map} +1 -1
- package/dist/runnerDependencies.cjs +1 -1
- package/dist/runnerDependencies.d.mts +1 -1
- package/dist/runnerDependencies.mjs +1 -1
- package/dist/{type-BrjS0_wq.d.mts → type-DmfWxPZQ.d.mts} +2 -2
- package/dist/{type-BrjS0_wq.d.mts.map → type-DmfWxPZQ.d.mts.map} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +16 -16
- package/src/prompts/codemode-how-to-runner/SKILL.md +6 -4
- package/src/prompts/help-how-to-runner/SKILL.md +5 -4
- package/dist/bashRunService-DGZZGWLL.cjs.map +0 -1
- package/dist/bashRunService-DQeetQzV.mjs.map +0 -1
- package/dist/bashTool-Bahf40vt.cjs.map +0 -1
- package/dist/bashTool-DAhPY4ID.d.mts +0 -20
- package/dist/bashTool-DAhPY4ID.d.mts.map +0 -1
- package/dist/bashTool-gjIKvJQ-.mjs +0 -32
- package/dist/bashTool-gjIKvJQ-.mjs.map +0 -1
- package/dist/headless-VzfNzuEv.mjs.map +0 -1
- package/dist/headless-as3Q6ucs.cjs.map +0 -1
- package/dist/index-DM7yJpMs.d.mts.map +0 -1
- package/dist/index-Df58fJ3b.d.mts.map +0 -1
- package/dist/logReader-BEneVvSC.cjs.map +0 -1
- package/dist/logReader-D1xSM6uE.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ it to a named layer to enable it only in selected major modes.
|
|
|
40
40
|
|
|
41
41
|
```json
|
|
42
42
|
{
|
|
43
|
-
"command": "pnpm test",
|
|
43
|
+
"command": ["pnpm test"],
|
|
44
44
|
"timeout": 60
|
|
45
45
|
}
|
|
46
46
|
```
|
|
@@ -49,7 +49,7 @@ Commands crossing the promotion threshold move to a supervised runner. The defau
|
|
|
49
49
|
seconds. Set `background: true` to detach immediately, or `interactive: true` only when a command
|
|
50
50
|
needs terminal input.
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Always pass `command` as an array, including for one command. Dependent commands run in separate fresh shells, sequentially and fail-fast:
|
|
53
53
|
|
|
54
54
|
```json
|
|
55
55
|
{
|
|
@@ -59,9 +59,11 @@ Pass an array to run dependent commands in separate fresh shells, sequentially a
|
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
With `interactive: true`, only the last command gets a pseudo terminal. Runner returns control when
|
|
63
|
+
that stage starts; inspect its stage runner ID and logs, then use that ID for input, not the sequence ID.
|
|
64
|
+
Each command gets its own timeout and complete log. The result lists all attempted log paths and only
|
|
65
|
+
the last executed command's trimmed output. Shell state such as `cd` and `export` does not carry
|
|
66
|
+
between entries. Keep repository mutations separate from verification.
|
|
65
67
|
A promoted array remains one supervised sequence, and its next command waits for the current process
|
|
66
68
|
to actually exit. Native sessions receive one aggregate completion; remote MCP callers poll.
|
|
67
69
|
|
|
@@ -119,9 +121,9 @@ Session removal, restart, or termination stops its runner processes and removes
|
|
|
119
121
|
and registry entries. An external observer handles owner hard-kill cleanup. Compaction and ordinary
|
|
120
122
|
activity changes do not remove evidence. Save important deliverables to the session artifact folder.
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
Inspect saved logs when an excerpt is truncated instead of rerunning
|
|
124
|
-
the promotion threshold remain environment-configurable.
|
|
124
|
+
Do not pipe or redirect command output to a file, `head`, or `tail`. Runner automatically saves full
|
|
125
|
+
logs and bounds returned output. Inspect saved logs when an excerpt is truncated instead of rerunning
|
|
126
|
+
the command. Result limits and the promotion threshold remain environment-configurable.
|
|
125
127
|
|
|
126
128
|
### Result excerpts
|
|
127
129
|
|
package/dist/apiContracts.cjs
CHANGED
|
@@ -80,6 +80,18 @@ const RunnerScreenSchema = typebox.Type.Object({
|
|
|
80
80
|
offset: O(N),
|
|
81
81
|
ended: O(B)
|
|
82
82
|
});
|
|
83
|
+
const RunnerOutputSchema = typebox.Type.Object({
|
|
84
|
+
chunk: typebox.Type.String({ contentEncoding: "base64" }),
|
|
85
|
+
offset: typebox.Type.Integer({
|
|
86
|
+
minimum: 0,
|
|
87
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
88
|
+
}),
|
|
89
|
+
reset: B,
|
|
90
|
+
generation: O(S),
|
|
91
|
+
exists: B,
|
|
92
|
+
hasMore: B,
|
|
93
|
+
ended: B
|
|
94
|
+
});
|
|
83
95
|
const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
|
|
84
96
|
version: 1,
|
|
85
97
|
dynamic: [],
|
|
@@ -105,6 +117,30 @@ const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
|
|
|
105
117
|
})),
|
|
106
118
|
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(RunnerLogSchema)
|
|
107
119
|
},
|
|
120
|
+
...["log", "screen"].map((kind) => ({
|
|
121
|
+
id: `runner.${kind}.read`,
|
|
122
|
+
scope: "session",
|
|
123
|
+
basePath: "runner",
|
|
124
|
+
path: `/runners/{runId}/${kind}/read`,
|
|
125
|
+
method: "GET",
|
|
126
|
+
authentication: "owner",
|
|
127
|
+
description: `Read at most 64 KiB of session-owned runner ${kind} bytes as base64. A completed runner remains readable; screen reads require an owned interactive multiplexer pane.`,
|
|
128
|
+
parameters: [{
|
|
129
|
+
name: "from",
|
|
130
|
+
in: "query",
|
|
131
|
+
required: false,
|
|
132
|
+
schema: typebox.Type.Integer({
|
|
133
|
+
minimum: 0,
|
|
134
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
135
|
+
})
|
|
136
|
+
}, ...kind === "screen" ? [{
|
|
137
|
+
name: "generation",
|
|
138
|
+
in: "query",
|
|
139
|
+
required: false,
|
|
140
|
+
schema: S
|
|
141
|
+
}] : []],
|
|
142
|
+
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(RunnerOutputSchema)
|
|
143
|
+
})),
|
|
108
144
|
...["log", "screen"].map((kind) => ({
|
|
109
145
|
id: `runner.${kind}.stream`,
|
|
110
146
|
scope: "session",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Run = Type.Object({\n id: S,\n name: S,\n pid: N,\n command: S,\n cwd: S,\n interactive: B,\n backend: literals(['rmux', 'tmux', 'native']),\n state: literals(['running', 'completed']),\n promoted: B,\n startedAt: S,\n logPath: S,\n exit: O(\n Type.Object({\n reason: literals(['completed', 'failed', 'signaled', 'stopped', 'timed_out', 'launcher_error', 'backend_lost']),\n code: Type.Union([N, Type.Null()]),\n signal: Type.Union([S, Type.Null()]),\n terminationReason: O(\n literals([\n 'timeout',\n 'user_stop',\n 'request_cancelled',\n 'parent_session_cleanup',\n 'owner_lost',\n 'external_signal',\n ]),\n ),\n stopReason: O(S),\n finishedAt: S,\n }),\n ),\n});\nexport const RunnerPayloadSchema = Type.Object({\n runs: Type.Array(Run),\n sessionDirectory: O(S),\n startFailure: O(Type.Object({ id: S, message: S })),\n});\nexport const RunnerLogSchema = Type.Object({\n runId: S,\n running: B,\n text: S,\n lineCount: N,\n totalLines: N,\n fileSize: N,\n completeBytes: N,\n path: S,\n exists: B,\n lineNumbers: O(Type.Array(N)),\n});\nexport const RunnerAppendSchema = Type.Object({ lines: Type.Array(S), offset: O(N), ended: O(B) });\nexport const RunnerScreenSchema = Type.Object({ chunk: S, offset: O(N), ended: O(B) });\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'runner.log',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/log',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a runner log tail or literal substring search.',\n parameters: ['lines', 'grep', 'ignoreCase', 'contextLines'].map((name) => ({\n name,\n in: 'query',\n required: false,\n schema: S,\n })),\n responses: jsonApiResponses(RunnerLogSchema),\n },\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.stream`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/stream`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Follow runner ${kind}. SSE data is JSON; ping events carry empty data.`,\n parameters: [{ name: 'from', in: 'query' as const, required: false, schema: N }],\n responses: {\n '200': {\n description: 'Event stream.',\n contentType: 'text/event-stream',\n schema: S,\n events: {\n [kind === 'log' ? 'append' : 'screen']: kind === 'log' ? RunnerAppendSchema : RunnerScreenSchema,\n ping: Type.Literal(''),\n },\n },\n '404': { description: 'Runner unavailable.', schema: Type.Object({ error: S }) },\n },\n })),\n {\n id: 'runner.input',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/screen/input',\n method: 'POST',\n authentication: 'owner',\n description: 'Send text to an interactive runner.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: jsonApiResponses(Type.Object({ delivered: Type.Literal(true) })),\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'runner.channel',\n scope,\n service: 'po.hub',\n member: 'runner_runs',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Runner channel payload in the hub frame payload property.',\n input: RunnerPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Run = Type.Object({\n id: S,\n name: S,\n pid: N,\n command: S,\n cwd: S,\n interactive: B,\n backend: literals(['rmux', 'tmux', 'native']),\n state: literals(['running', 'completed']),\n promoted: B,\n startedAt: S,\n logPath: S,\n exit: O(\n Type.Object({\n reason: literals(['completed', 'failed', 'signaled', 'stopped', 'timed_out', 'launcher_error', 'backend_lost']),\n code: Type.Union([N, Type.Null()]),\n signal: Type.Union([S, Type.Null()]),\n terminationReason: O(\n literals([\n 'timeout',\n 'user_stop',\n 'request_cancelled',\n 'parent_session_cleanup',\n 'owner_lost',\n 'external_signal',\n ]),\n ),\n stopReason: O(S),\n finishedAt: S,\n }),\n ),\n});\nexport const RunnerPayloadSchema = Type.Object({\n runs: Type.Array(Run),\n sessionDirectory: O(S),\n startFailure: O(Type.Object({ id: S, message: S })),\n});\nexport const RunnerLogSchema = Type.Object({\n runId: S,\n running: B,\n text: S,\n lineCount: N,\n totalLines: N,\n fileSize: N,\n completeBytes: N,\n path: S,\n exists: B,\n lineNumbers: O(Type.Array(N)),\n});\nexport const RunnerAppendSchema = Type.Object({ lines: Type.Array(S), offset: O(N), ended: O(B) });\nexport const RunnerScreenSchema = Type.Object({ chunk: S, offset: O(N), ended: O(B) });\nexport const RunnerOutputSchema = Type.Object({\n chunk: Type.String({ contentEncoding: 'base64' }),\n offset: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),\n reset: B,\n generation: O(S),\n exists: B,\n hasMore: B,\n ended: B,\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'runner.log',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/log',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a runner log tail or literal substring search.',\n parameters: ['lines', 'grep', 'ignoreCase', 'contextLines'].map((name) => ({\n name,\n in: 'query',\n required: false,\n schema: S,\n })),\n responses: jsonApiResponses(RunnerLogSchema),\n },\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.read`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/read`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Read at most 64 KiB of session-owned runner ${kind} bytes as base64. A completed runner remains readable; screen reads require an owned interactive multiplexer pane.`,\n parameters: [\n {\n name: 'from',\n in: 'query' as const,\n required: false,\n schema: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),\n },\n ...(kind === 'screen' ? [{ name: 'generation', in: 'query' as const, required: false, schema: S }] : []),\n ],\n responses: jsonApiResponses(RunnerOutputSchema),\n })),\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.stream`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/stream`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Follow runner ${kind}. SSE data is JSON; ping events carry empty data.`,\n parameters: [{ name: 'from', in: 'query' as const, required: false, schema: N }],\n responses: {\n '200': {\n description: 'Event stream.',\n contentType: 'text/event-stream',\n schema: S,\n events: {\n [kind === 'log' ? 'append' : 'screen']: kind === 'log' ? RunnerAppendSchema : RunnerScreenSchema,\n ping: Type.Literal(''),\n },\n },\n '404': { description: 'Runner unavailable.', schema: Type.Object({ error: S }) },\n },\n })),\n {\n id: 'runner.input',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/screen/input',\n method: 'POST',\n authentication: 'owner',\n description: 'Send text to an interactive runner.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: jsonApiResponses(Type.Object({ delivered: Type.Literal(true) })),\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'runner.channel',\n scope,\n service: 'po.hub',\n member: 'runner_runs',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Runner channel payload in the hub frame payload property.',\n input: RunnerPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAoEa"}
|
package/dist/apiContracts.mjs
CHANGED
|
@@ -76,6 +76,18 @@ const RunnerScreenSchema = Type.Object({
|
|
|
76
76
|
offset: O(N),
|
|
77
77
|
ended: O(B)
|
|
78
78
|
});
|
|
79
|
+
const RunnerOutputSchema = Type.Object({
|
|
80
|
+
chunk: Type.String({ contentEncoding: "base64" }),
|
|
81
|
+
offset: Type.Integer({
|
|
82
|
+
minimum: 0,
|
|
83
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
84
|
+
}),
|
|
85
|
+
reset: B,
|
|
86
|
+
generation: O(S),
|
|
87
|
+
exists: B,
|
|
88
|
+
hasMore: B,
|
|
89
|
+
ended: B
|
|
90
|
+
});
|
|
79
91
|
const apiContracts = defineApiContract({
|
|
80
92
|
version: 1,
|
|
81
93
|
dynamic: [],
|
|
@@ -101,6 +113,30 @@ const apiContracts = defineApiContract({
|
|
|
101
113
|
})),
|
|
102
114
|
responses: jsonApiResponses(RunnerLogSchema)
|
|
103
115
|
},
|
|
116
|
+
...["log", "screen"].map((kind) => ({
|
|
117
|
+
id: `runner.${kind}.read`,
|
|
118
|
+
scope: "session",
|
|
119
|
+
basePath: "runner",
|
|
120
|
+
path: `/runners/{runId}/${kind}/read`,
|
|
121
|
+
method: "GET",
|
|
122
|
+
authentication: "owner",
|
|
123
|
+
description: `Read at most 64 KiB of session-owned runner ${kind} bytes as base64. A completed runner remains readable; screen reads require an owned interactive multiplexer pane.`,
|
|
124
|
+
parameters: [{
|
|
125
|
+
name: "from",
|
|
126
|
+
in: "query",
|
|
127
|
+
required: false,
|
|
128
|
+
schema: Type.Integer({
|
|
129
|
+
minimum: 0,
|
|
130
|
+
maximum: Number.MAX_SAFE_INTEGER
|
|
131
|
+
})
|
|
132
|
+
}, ...kind === "screen" ? [{
|
|
133
|
+
name: "generation",
|
|
134
|
+
in: "query",
|
|
135
|
+
required: false,
|
|
136
|
+
schema: S
|
|
137
|
+
}] : []],
|
|
138
|
+
responses: jsonApiResponses(RunnerOutputSchema)
|
|
139
|
+
})),
|
|
104
140
|
...["log", "screen"].map((kind) => ({
|
|
105
141
|
id: `runner.${kind}.stream`,
|
|
106
142
|
scope: "session",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Run = Type.Object({\n id: S,\n name: S,\n pid: N,\n command: S,\n cwd: S,\n interactive: B,\n backend: literals(['rmux', 'tmux', 'native']),\n state: literals(['running', 'completed']),\n promoted: B,\n startedAt: S,\n logPath: S,\n exit: O(\n Type.Object({\n reason: literals(['completed', 'failed', 'signaled', 'stopped', 'timed_out', 'launcher_error', 'backend_lost']),\n code: Type.Union([N, Type.Null()]),\n signal: Type.Union([S, Type.Null()]),\n terminationReason: O(\n literals([\n 'timeout',\n 'user_stop',\n 'request_cancelled',\n 'parent_session_cleanup',\n 'owner_lost',\n 'external_signal',\n ]),\n ),\n stopReason: O(S),\n finishedAt: S,\n }),\n ),\n});\nexport const RunnerPayloadSchema = Type.Object({\n runs: Type.Array(Run),\n sessionDirectory: O(S),\n startFailure: O(Type.Object({ id: S, message: S })),\n});\nexport const RunnerLogSchema = Type.Object({\n runId: S,\n running: B,\n text: S,\n lineCount: N,\n totalLines: N,\n fileSize: N,\n completeBytes: N,\n path: S,\n exists: B,\n lineNumbers: O(Type.Array(N)),\n});\nexport const RunnerAppendSchema = Type.Object({ lines: Type.Array(S), offset: O(N), ended: O(B) });\nexport const RunnerScreenSchema = Type.Object({ chunk: S, offset: O(N), ended: O(B) });\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'runner.log',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/log',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a runner log tail or literal substring search.',\n parameters: ['lines', 'grep', 'ignoreCase', 'contextLines'].map((name) => ({\n name,\n in: 'query',\n required: false,\n schema: S,\n })),\n responses: jsonApiResponses(RunnerLogSchema),\n },\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.stream`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/stream`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Follow runner ${kind}. SSE data is JSON; ping events carry empty data.`,\n parameters: [{ name: 'from', in: 'query' as const, required: false, schema: N }],\n responses: {\n '200': {\n description: 'Event stream.',\n contentType: 'text/event-stream',\n schema: S,\n events: {\n [kind === 'log' ? 'append' : 'screen']: kind === 'log' ? RunnerAppendSchema : RunnerScreenSchema,\n ping: Type.Literal(''),\n },\n },\n '404': { description: 'Runner unavailable.', schema: Type.Object({ error: S }) },\n },\n })),\n {\n id: 'runner.input',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/screen/input',\n method: 'POST',\n authentication: 'owner',\n description: 'Send text to an interactive runner.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: jsonApiResponses(Type.Object({ delivered: Type.Literal(true) })),\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'runner.channel',\n scope,\n service: 'po.hub',\n member: 'runner_runs',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Runner channel payload in the hub frame payload property.',\n input: RunnerPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst literals = <T extends string>(values: T[]) => Type.Union(values.map((value) => Type.Literal(value)));\nconst Run = Type.Object({\n id: S,\n name: S,\n pid: N,\n command: S,\n cwd: S,\n interactive: B,\n backend: literals(['rmux', 'tmux', 'native']),\n state: literals(['running', 'completed']),\n promoted: B,\n startedAt: S,\n logPath: S,\n exit: O(\n Type.Object({\n reason: literals(['completed', 'failed', 'signaled', 'stopped', 'timed_out', 'launcher_error', 'backend_lost']),\n code: Type.Union([N, Type.Null()]),\n signal: Type.Union([S, Type.Null()]),\n terminationReason: O(\n literals([\n 'timeout',\n 'user_stop',\n 'request_cancelled',\n 'parent_session_cleanup',\n 'owner_lost',\n 'external_signal',\n ]),\n ),\n stopReason: O(S),\n finishedAt: S,\n }),\n ),\n});\nexport const RunnerPayloadSchema = Type.Object({\n runs: Type.Array(Run),\n sessionDirectory: O(S),\n startFailure: O(Type.Object({ id: S, message: S })),\n});\nexport const RunnerLogSchema = Type.Object({\n runId: S,\n running: B,\n text: S,\n lineCount: N,\n totalLines: N,\n fileSize: N,\n completeBytes: N,\n path: S,\n exists: B,\n lineNumbers: O(Type.Array(N)),\n});\nexport const RunnerAppendSchema = Type.Object({ lines: Type.Array(S), offset: O(N), ended: O(B) });\nexport const RunnerScreenSchema = Type.Object({ chunk: S, offset: O(N), ended: O(B) });\nexport const RunnerOutputSchema = Type.Object({\n chunk: Type.String({ contentEncoding: 'base64' }),\n offset: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),\n reset: B,\n generation: O(S),\n exists: B,\n hasMore: B,\n ended: B,\n});\nexport const apiContracts = defineApiContract({\n version: 1,\n dynamic: [],\n http: [\n {\n id: 'runner.log',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/log',\n method: 'GET',\n authentication: 'owner',\n description: 'Read a runner log tail or literal substring search.',\n parameters: ['lines', 'grep', 'ignoreCase', 'contextLines'].map((name) => ({\n name,\n in: 'query',\n required: false,\n schema: S,\n })),\n responses: jsonApiResponses(RunnerLogSchema),\n },\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.read`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/read`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Read at most 64 KiB of session-owned runner ${kind} bytes as base64. A completed runner remains readable; screen reads require an owned interactive multiplexer pane.`,\n parameters: [\n {\n name: 'from',\n in: 'query' as const,\n required: false,\n schema: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),\n },\n ...(kind === 'screen' ? [{ name: 'generation', in: 'query' as const, required: false, schema: S }] : []),\n ],\n responses: jsonApiResponses(RunnerOutputSchema),\n })),\n ...(['log', 'screen'] as const).map((kind) => ({\n id: `runner.${kind}.stream`,\n scope: 'session' as const,\n basePath: 'runner',\n path: `/runners/{runId}/${kind}/stream`,\n method: 'GET' as const,\n authentication: 'owner' as const,\n description: `Follow runner ${kind}. SSE data is JSON; ping events carry empty data.`,\n parameters: [{ name: 'from', in: 'query' as const, required: false, schema: N }],\n responses: {\n '200': {\n description: 'Event stream.',\n contentType: 'text/event-stream',\n schema: S,\n events: {\n [kind === 'log' ? 'append' : 'screen']: kind === 'log' ? RunnerAppendSchema : RunnerScreenSchema,\n ping: Type.Literal(''),\n },\n },\n '404': { description: 'Runner unavailable.', schema: Type.Object({ error: S }) },\n },\n })),\n {\n id: 'runner.input',\n scope: 'session',\n basePath: 'runner',\n path: '/runners/{runId}/screen/input',\n method: 'POST',\n authentication: 'owner',\n description: 'Send text to an interactive runner.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: jsonApiResponses(Type.Object({ delivered: Type.Literal(true) })),\n },\n ],\n sockets: (['global', 'workspace'] as const).map((scope) => ({\n id: 'runner.channel',\n scope,\n service: 'po.hub',\n member: 'runner_runs',\n kind: 'channel',\n direction: 'server-to-client',\n description: 'Runner channel payload in the hub frame payload property.',\n input: RunnerPayloadSchema,\n })),\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
@@ -225,7 +225,7 @@ var BashRunService = class {
|
|
|
225
225
|
error: "Operation aborted"
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
|
-
if (request.background === true || interactive) return this.promote(handle, request.background === true ? "requested" : "interactive", request.signal);
|
|
228
|
+
if (request.waitForExit !== true && (request.background === true || interactive)) return this.promote(handle, request.background === true ? "requested" : "interactive", request.signal);
|
|
229
229
|
const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : void 0;
|
|
230
230
|
try {
|
|
231
231
|
const outcome = await this.race(handle, request.timeoutMs, request.signal, request.waitForExit !== true);
|
|
@@ -446,4 +446,4 @@ var BashRunService = class {
|
|
|
446
446
|
//#endregion
|
|
447
447
|
export { BashRunService as t };
|
|
448
448
|
|
|
449
|
-
//# sourceMappingURL=bashRunService-
|
|
449
|
+
//# sourceMappingURL=bashRunService-CmjnipLE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashRunService-CmjnipLE.mjs","names":[],"sources":["../src/constants/bashRunService.ts","../src/services/bashRunService/resources.ts","../src/services/bashRunService/index.ts"],"sourcesContent":["export const RUNNER_ID_RANDOM_BYTES = 3;\nexport const OUTPUT_UPDATE_POLL_MS = 100;\nexport const COMPLETED = 'completed';\nexport const FAILED = 'failed';\nexport const LAUNCHER_ERROR = 'launcher_error';\nexport const SIGNALED = 'signaled';\n/** An interactive launch found neither multiplexer. */\nexport const TERMINAL_UNAVAILABLE = 'A terminal needs rmux or tmux, and neither is available on this machine.';\n","/** Split shell words without mistaking quoted examples for executed commands. */\nfunction commandInvocations(command: string): string[][] {\n const invocations: string[][] = [];\n let words: string[] = [];\n let word = '';\n let quote = '';\n let escaped = false;\n const flushWord = (): void => {\n if (word) words.push(word);\n word = '';\n };\n for (const character of command) {\n if (escaped) {\n word += character;\n escaped = false;\n } else if (character === '\\\\' && quote !== \"'\") {\n escaped = true;\n } else if (quote) {\n if (character === quote) quote = '';\n else word += character;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (';&|\\n'.includes(character)) {\n flushWord();\n if (words.length) invocations.push(words);\n words = [];\n } else if (/\\s/.test(character)) {\n flushWord();\n } else {\n word += character;\n }\n }\n flushWord();\n if (words.length) invocations.push(words);\n return invocations;\n}\n\nfunction executableName(word: string): string {\n return word.replace(/\\\\/g, '/').split('/').pop() ?? word;\n}\n\n/** Admission policy, not a shell security boundary. Opaque scripts still need explicit ownership. */\nexport function isHeavyCommand(command: string): boolean {\n const heavyTarget =\n /(?:^|[\\s:,=])(?:build(?:-[\\w-]+)?|test(?:-[\\w-]+)?|lint|fixcode|typecheck|check|bundle)(?:[\\s:,=]|$)/;\n const expensiveBinary =\n /^(?:vitest|jest|tsc|tsgo|tsdown|webpack|rollup|esbuild|oxlint|oxfmt|pytest|maestro|xcodebuild|gradle|gradlew)$/;\n return commandInvocations(command).some((words) => {\n while (words.length) {\n const first = words[0]!;\n if (/^[A-Za-z_][A-Za-z_0-9]*=/.test(first) || /^(?:env|command|exec|time)$/.test(executableName(first))) {\n words.shift();\n } else break;\n }\n let executable = executableName(words.shift() ?? '');\n if (words.includes('--help') || words.includes('--version')) return false;\n if (/^(?:pnpm|npm|npx|yarn|bun)$/.test(executable)) {\n while (words[0]?.startsWith('-')) {\n const option = words.shift()!;\n if (/^(?:--filter|--dir|-C|--cwd|--prefix)$/.test(option)) words.shift();\n }\n if (words[0] === 'exec' || words[0] === 'run') words.shift();\n const invocation = words.shift() ?? '';\n if (/^(?:build|test|lint|fixcode|typecheck|check)(?::[\\w-]+)?$/.test(invocation)) return true;\n executable = executableName(invocation);\n }\n if (expensiveBinary.test(executable)) return true;\n if (executable === 'nx') {\n if (/^(?:show|graph|daemon|reset|report|list)$/.test(words[0] ?? '')) return false;\n return heavyTarget.test(words.join(' '));\n }\n if (/^(?:playwright|vite|cargo|go)$/.test(executable)) return heavyTarget.test(words.join(' '));\n if (/^(?:python|python3)$/.test(executable)) return words[0] === '-m' && words[1] === 'pytest';\n if (/^(?:node|bun|tsx)$/.test(executable)) {\n executable = executableName(words.find((word) => !word.startsWith('-')) ?? '');\n }\n const script = executable.replace(/\\.(?:[cm]?[jt]s)$/, '');\n return (\n script !== executable &&\n (expensiveBinary.test(script) || /^(?:build|test|lint|fixcode|typecheck|dev)(?:[-:]|$)/.test(script))\n );\n });\n}\n","import { randomBytes } from 'node:crypto';\n\nimport type { PoHostExecutionBudget, PoHostExecutionPermit } from '@agimon-ai/po-core/packageApi';\n\nimport {\n COMPLETED,\n FAILED,\n LAUNCHER_ERROR,\n OUTPUT_UPDATE_POLL_MS,\n RUNNER_ID_RANDOM_BYTES,\n SIGNALED,\n TERMINAL_UNAVAILABLE,\n} from '../../constants/bashRunService';\nimport type {\n BashRunRequest,\n BashRunResult,\n CompletedRun,\n IBashRunService,\n PromotedRun,\n} from '../../types/bashRunService';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, RunHandle } from '../../types/launcher';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport { type IRtkProcessor, RTK_FAILED_WARNING } from '../../types/rtkProcessor';\nimport type { IRunnerRegistry } from '../../types/runnerRegistry';\nimport { getBackgroundThresholdMs } from '../runnerConfig';\nimport type { IRunnerNamer } from '../runnerNamer/type';\nimport { isHeavyCommand } from './resources';\n\n/** The command outlived the background threshold and should be promoted. */\nconst TIMED_OUT = Symbol('threshold-reached');\n/** The command outlived the caller's explicit timeout and should be stopped. */\nconst DEADLINE = Symbol('deadline-reached');\n/** The caller cancelled the command and its owned runner should be stopped. */\nconst ABORTED = Symbol('aborted');\n\nfunction runnerId(): string {\n const timestamp = Date.now().toString(36);\n const random = randomBytes(RUNNER_ID_RANDOM_BYTES).toString('base64url');\n return `${timestamp}-${random}`;\n}\n\nexport class BashRunService implements IBashRunService {\n constructor(\n private readonly launcher: ILauncher,\n private readonly rmuxBackend: IRmuxBackend,\n private readonly namer: IRunnerNamer,\n private readonly registry: IRunnerRegistry,\n private readonly clock: IClock,\n private readonly rtkProcessor: IRtkProcessor,\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly executionBudget?: PoHostExecutionBudget,\n ) {}\n\n async run(request: BashRunRequest): Promise<BashRunResult> {\n const id = runnerId();\n const name = await this.namer.allocate(request.command, request.sessionId, request.name);\n const cwd = request.cwd ?? this.cwd;\n // Reassigned once the launch shows whether a pane was actually available.\n let interactive = request.interactive === true;\n const wantsPane = interactive || request.preferInteractive === true;\n if (request.signal?.aborted) return { kind: FAILED, id, name, error: 'Operation aborted' };\n\n let handle: RunHandle;\n let releaseSlot: PoHostExecutionPermit | undefined;\n try {\n if (this.executionBudget && isHeavyCommand(request.command)) {\n releaseSlot = await this.executionBudget.acquire(request.signal);\n }\n request.signal?.throwIfAborted();\n const rmuxHandle = await this.rmuxBackend.launch({\n id,\n name,\n command: request.command,\n cwd,\n sessionId: request.sessionId,\n interactive: wantsPane,\n });\n if (interactive && !rmuxHandle) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: TERMINAL_UNAVAILABLE };\n }\n interactive = wantsPane && rmuxHandle !== undefined;\n handle =\n rmuxHandle ?? this.launcher.launch({ id, name, command: request.command, cwd, sessionId: request.sessionId });\n } catch (error) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (handle.pid === undefined) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: 'The command did not start, so it cannot be supervised' };\n }\n // A background promotion is not process completion. Keep the slot until actual exit.\n if (releaseSlot) void handle.completion().then(releaseSlot, releaseSlot);\n // Register first so a process that survives PID attachment failure remains discoverable.\n try {\n await this.registry.register({\n id,\n name,\n pid: handle.pid,\n command: request.command,\n cwd,\n logPath: handle.logPath,\n interactive,\n sessionId: request.sessionId,\n backend: handle.backend,\n ...(handle.backendTarget ? { backendTarget: handle.backendTarget } : {}),\n });\n await request.onStarted?.({ id, name, logPath: handle.logPath });\n } catch (error) {\n await handle.stop();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (releaseSlot) {\n try {\n await releaseSlot.attachProcess?.(handle.pid);\n } catch (error) {\n if (!(await handle.stop())) {\n return this.promote(handle, 'requested', undefined);\n }\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n }\n if (request.signal?.aborted) {\n if (!(await handle.stop())) return this.promote(handle, 'requested', undefined);\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: 'Operation aborted' };\n }\n\n // A sequence owns the wait and hands control back as soon as its interactive stage starts.\n if (request.waitForExit !== true && (request.background === true || interactive))\n return this.promote(handle, request.background === true ? 'requested' : 'interactive', request.signal);\n\n const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : undefined;\n try {\n const outcome = await this.race(handle, request.timeoutMs, request.signal, request.waitForExit !== true);\n outputUpdates?.flush();\n if (outcome === TIMED_OUT) {\n return this.promote(handle, 'threshold', request.signal);\n }\n if (outcome === ABORTED) {\n await this.registry.requestTermination(id, { reason: 'stopped', terminationReason: 'request_cancelled' });\n const stopped = await handle.stop();\n if (!stopped && request.waitForExit) return this.promote(handle, 'requested', undefined);\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n aborted: true,\n };\n }\n if (outcome === DEADLINE) {\n // An explicit timeout means the caller wants the command dead, not\n // supervised, so it is stopped rather than promoted.\n await this.registry.requestTermination(id, { reason: 'timed_out', terminationReason: 'timeout' });\n const stopped = await handle.stop();\n if (!stopped && request.waitForExit) return this.promote(handle, 'requested', undefined);\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'timed_out', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n timedOut: true,\n };\n }\n if (outcome instanceof Error) {\n await this.registry.complete(id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n return { kind: FAILED, id, name, error: outcome.message };\n }\n\n await this.registry.complete(id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: outcome.code,\n signal: outcome.signal,\n logPath: handle.logPath,\n backend: handle.backend,\n ...(await this.processLog(request.command, handle.logPath)),\n };\n } finally {\n outputUpdates?.dispose();\n }\n }\n\n private async processLog(command: string, logPath: string): Promise<Pick<CompletedRun, 'rtkOutput' | 'rtkWarning'>> {\n try {\n const result = await this.rtkProcessor.process({ command, logPath });\n if (result.kind === 'processed') return { rtkOutput: result.result };\n if (result.kind === 'fallback') return { rtkWarning: result.warning };\n return {};\n } catch {\n return { rtkWarning: RTK_FAILED_WARNING };\n }\n }\n\n private followOutput(\n handle: RunHandle,\n onOutput: NonNullable<BashRunRequest['onOutput']>,\n ): { flush(): void; dispose(): void } {\n let active = true;\n let previous = '';\n let cancelPoll: (() => void) | undefined;\n const flush = (): void => {\n if (!active) return;\n const output = handle.output();\n if (output === previous) return;\n previous = output;\n onOutput(output);\n };\n const poll = (): void => {\n if (!active) return;\n flush();\n if (active) cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n };\n cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n return {\n flush,\n dispose: () => {\n active = false;\n cancelPoll?.();\n cancelPoll = undefined;\n },\n };\n }\n\n /**\n * Waits for the command, giving up at the background threshold or at the\n * caller's timeout, whichever comes first.\n *\n * A rejected completion is returned rather than thrown so the caller can\n * report a start failure as a tool result instead of an exception.\n */\n private async race(\n handle: RunHandle,\n timeoutMs: number | undefined,\n signal: AbortSignal | undefined,\n promoteAtThreshold = true,\n ): Promise<\n Awaited<ReturnType<RunHandle['completion']>> | Error | typeof TIMED_OUT | typeof DEADLINE | typeof ABORTED\n > {\n const cancels: Array<() => void> = [];\n const racers: Array<Promise<unknown>> = [handle.completion().catch((error: Error) => error)];\n\n if (promoteAtThreshold)\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(getBackgroundThresholdMs(this.env), () => resolve(TIMED_OUT)));\n }),\n );\n if (timeoutMs !== undefined && timeoutMs > 0) {\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(timeoutMs, () => resolve(DEADLINE)));\n }),\n );\n }\n if (signal) {\n racers.push(\n new Promise((resolve) => {\n if (signal.aborted) {\n resolve(ABORTED);\n return;\n }\n const abort = (): void => resolve(ABORTED);\n signal.addEventListener('abort', abort, { once: true });\n cancels.push(() => signal.removeEventListener('abort', abort));\n }),\n );\n }\n\n try {\n return (await Promise.race(racers)) as\n | Awaited<ReturnType<RunHandle['completion']>>\n | Error\n | typeof TIMED_OUT\n | typeof DEADLINE\n | typeof ABORTED;\n } finally {\n for (const cancel of cancels) cancel();\n }\n }\n\n private async promote(\n handle: RunHandle,\n reason: PromotedRun['reason'],\n signal: AbortSignal | undefined,\n ): Promise<BashRunResult> {\n if (handle.pid === undefined)\n return { kind: FAILED, id: handle.id, name: handle.name, error: 'The command did not start' };\n await this.registry.markPromoted(handle.id);\n // Registration first: an unregistered runner is invisible, and the handle\n // stops buffering the moment it is detached.\n handle.detach();\n let abortStop: Promise<boolean> | undefined;\n const abort = (): void => {\n abortStop = this.registry\n .requestTermination(handle.id, { reason: 'stopped', terminationReason: 'request_cancelled' })\n .then(() => handle.stop())\n .then(async () => {\n await this.registry.complete(handle.id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return true;\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to stop aborted runner ${handle.id}: ${message}`);\n return false;\n });\n };\n // The signal belongs to the tool call, which ends when this returns, and\n // Pi aborts it at that point. A promoted runner outlives the call, so only\n // an abort that landed before the handoff stops it.\n if (signal?.aborted) abort();\n void handle\n .completion()\n .then(\n async (outcome) => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n },\n async () => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n },\n )\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to complete runner ${handle.id}: ${message}`);\n });\n\n return {\n kind: 'promoted',\n id: handle.id,\n name: handle.name,\n pid: handle.pid,\n logPath: handle.logPath,\n backend: handle.backend,\n reason,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -225,7 +225,7 @@ var BashRunService = class {
|
|
|
225
225
|
error: "Operation aborted"
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
|
-
if (request.background === true || interactive) return this.promote(handle, request.background === true ? "requested" : "interactive", request.signal);
|
|
228
|
+
if (request.waitForExit !== true && (request.background === true || interactive)) return this.promote(handle, request.background === true ? "requested" : "interactive", request.signal);
|
|
229
229
|
const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : void 0;
|
|
230
230
|
try {
|
|
231
231
|
const outcome = await this.race(handle, request.timeoutMs, request.signal, request.waitForExit !== true);
|
|
@@ -451,4 +451,4 @@ Object.defineProperty(exports, "BashRunService", {
|
|
|
451
451
|
}
|
|
452
452
|
});
|
|
453
453
|
|
|
454
|
-
//# sourceMappingURL=bashRunService-
|
|
454
|
+
//# sourceMappingURL=bashRunService-DLpFoP81.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashRunService-DLpFoP81.cjs","names":["randomBytes","RTK_FAILED_WARNING","getBackgroundThresholdMs"],"sources":["../src/constants/bashRunService.ts","../src/services/bashRunService/resources.ts","../src/services/bashRunService/index.ts"],"sourcesContent":["export const RUNNER_ID_RANDOM_BYTES = 3;\nexport const OUTPUT_UPDATE_POLL_MS = 100;\nexport const COMPLETED = 'completed';\nexport const FAILED = 'failed';\nexport const LAUNCHER_ERROR = 'launcher_error';\nexport const SIGNALED = 'signaled';\n/** An interactive launch found neither multiplexer. */\nexport const TERMINAL_UNAVAILABLE = 'A terminal needs rmux or tmux, and neither is available on this machine.';\n","/** Split shell words without mistaking quoted examples for executed commands. */\nfunction commandInvocations(command: string): string[][] {\n const invocations: string[][] = [];\n let words: string[] = [];\n let word = '';\n let quote = '';\n let escaped = false;\n const flushWord = (): void => {\n if (word) words.push(word);\n word = '';\n };\n for (const character of command) {\n if (escaped) {\n word += character;\n escaped = false;\n } else if (character === '\\\\' && quote !== \"'\") {\n escaped = true;\n } else if (quote) {\n if (character === quote) quote = '';\n else word += character;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (';&|\\n'.includes(character)) {\n flushWord();\n if (words.length) invocations.push(words);\n words = [];\n } else if (/\\s/.test(character)) {\n flushWord();\n } else {\n word += character;\n }\n }\n flushWord();\n if (words.length) invocations.push(words);\n return invocations;\n}\n\nfunction executableName(word: string): string {\n return word.replace(/\\\\/g, '/').split('/').pop() ?? word;\n}\n\n/** Admission policy, not a shell security boundary. Opaque scripts still need explicit ownership. */\nexport function isHeavyCommand(command: string): boolean {\n const heavyTarget =\n /(?:^|[\\s:,=])(?:build(?:-[\\w-]+)?|test(?:-[\\w-]+)?|lint|fixcode|typecheck|check|bundle)(?:[\\s:,=]|$)/;\n const expensiveBinary =\n /^(?:vitest|jest|tsc|tsgo|tsdown|webpack|rollup|esbuild|oxlint|oxfmt|pytest|maestro|xcodebuild|gradle|gradlew)$/;\n return commandInvocations(command).some((words) => {\n while (words.length) {\n const first = words[0]!;\n if (/^[A-Za-z_][A-Za-z_0-9]*=/.test(first) || /^(?:env|command|exec|time)$/.test(executableName(first))) {\n words.shift();\n } else break;\n }\n let executable = executableName(words.shift() ?? '');\n if (words.includes('--help') || words.includes('--version')) return false;\n if (/^(?:pnpm|npm|npx|yarn|bun)$/.test(executable)) {\n while (words[0]?.startsWith('-')) {\n const option = words.shift()!;\n if (/^(?:--filter|--dir|-C|--cwd|--prefix)$/.test(option)) words.shift();\n }\n if (words[0] === 'exec' || words[0] === 'run') words.shift();\n const invocation = words.shift() ?? '';\n if (/^(?:build|test|lint|fixcode|typecheck|check)(?::[\\w-]+)?$/.test(invocation)) return true;\n executable = executableName(invocation);\n }\n if (expensiveBinary.test(executable)) return true;\n if (executable === 'nx') {\n if (/^(?:show|graph|daemon|reset|report|list)$/.test(words[0] ?? '')) return false;\n return heavyTarget.test(words.join(' '));\n }\n if (/^(?:playwright|vite|cargo|go)$/.test(executable)) return heavyTarget.test(words.join(' '));\n if (/^(?:python|python3)$/.test(executable)) return words[0] === '-m' && words[1] === 'pytest';\n if (/^(?:node|bun|tsx)$/.test(executable)) {\n executable = executableName(words.find((word) => !word.startsWith('-')) ?? '');\n }\n const script = executable.replace(/\\.(?:[cm]?[jt]s)$/, '');\n return (\n script !== executable &&\n (expensiveBinary.test(script) || /^(?:build|test|lint|fixcode|typecheck|dev)(?:[-:]|$)/.test(script))\n );\n });\n}\n","import { randomBytes } from 'node:crypto';\n\nimport type { PoHostExecutionBudget, PoHostExecutionPermit } from '@agimon-ai/po-core/packageApi';\n\nimport {\n COMPLETED,\n FAILED,\n LAUNCHER_ERROR,\n OUTPUT_UPDATE_POLL_MS,\n RUNNER_ID_RANDOM_BYTES,\n SIGNALED,\n TERMINAL_UNAVAILABLE,\n} from '../../constants/bashRunService';\nimport type {\n BashRunRequest,\n BashRunResult,\n CompletedRun,\n IBashRunService,\n PromotedRun,\n} from '../../types/bashRunService';\nimport type { IClock } from '../../types/clock';\nimport type { ILauncher, RunHandle } from '../../types/launcher';\nimport type { IRmuxBackend } from '../../types/rmuxBackend';\nimport { type IRtkProcessor, RTK_FAILED_WARNING } from '../../types/rtkProcessor';\nimport type { IRunnerRegistry } from '../../types/runnerRegistry';\nimport { getBackgroundThresholdMs } from '../runnerConfig';\nimport type { IRunnerNamer } from '../runnerNamer/type';\nimport { isHeavyCommand } from './resources';\n\n/** The command outlived the background threshold and should be promoted. */\nconst TIMED_OUT = Symbol('threshold-reached');\n/** The command outlived the caller's explicit timeout and should be stopped. */\nconst DEADLINE = Symbol('deadline-reached');\n/** The caller cancelled the command and its owned runner should be stopped. */\nconst ABORTED = Symbol('aborted');\n\nfunction runnerId(): string {\n const timestamp = Date.now().toString(36);\n const random = randomBytes(RUNNER_ID_RANDOM_BYTES).toString('base64url');\n return `${timestamp}-${random}`;\n}\n\nexport class BashRunService implements IBashRunService {\n constructor(\n private readonly launcher: ILauncher,\n private readonly rmuxBackend: IRmuxBackend,\n private readonly namer: IRunnerNamer,\n private readonly registry: IRunnerRegistry,\n private readonly clock: IClock,\n private readonly rtkProcessor: IRtkProcessor,\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = process.env,\n private readonly executionBudget?: PoHostExecutionBudget,\n ) {}\n\n async run(request: BashRunRequest): Promise<BashRunResult> {\n const id = runnerId();\n const name = await this.namer.allocate(request.command, request.sessionId, request.name);\n const cwd = request.cwd ?? this.cwd;\n // Reassigned once the launch shows whether a pane was actually available.\n let interactive = request.interactive === true;\n const wantsPane = interactive || request.preferInteractive === true;\n if (request.signal?.aborted) return { kind: FAILED, id, name, error: 'Operation aborted' };\n\n let handle: RunHandle;\n let releaseSlot: PoHostExecutionPermit | undefined;\n try {\n if (this.executionBudget && isHeavyCommand(request.command)) {\n releaseSlot = await this.executionBudget.acquire(request.signal);\n }\n request.signal?.throwIfAborted();\n const rmuxHandle = await this.rmuxBackend.launch({\n id,\n name,\n command: request.command,\n cwd,\n sessionId: request.sessionId,\n interactive: wantsPane,\n });\n if (interactive && !rmuxHandle) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: TERMINAL_UNAVAILABLE };\n }\n interactive = wantsPane && rmuxHandle !== undefined;\n handle =\n rmuxHandle ?? this.launcher.launch({ id, name, command: request.command, cwd, sessionId: request.sessionId });\n } catch (error) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (handle.pid === undefined) {\n releaseSlot?.();\n return { kind: FAILED, id, name, error: 'The command did not start, so it cannot be supervised' };\n }\n // A background promotion is not process completion. Keep the slot until actual exit.\n if (releaseSlot) void handle.completion().then(releaseSlot, releaseSlot);\n // Register first so a process that survives PID attachment failure remains discoverable.\n try {\n await this.registry.register({\n id,\n name,\n pid: handle.pid,\n command: request.command,\n cwd,\n logPath: handle.logPath,\n interactive,\n sessionId: request.sessionId,\n backend: handle.backend,\n ...(handle.backendTarget ? { backendTarget: handle.backendTarget } : {}),\n });\n await request.onStarted?.({ id, name, logPath: handle.logPath });\n } catch (error) {\n await handle.stop();\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n\n if (releaseSlot) {\n try {\n await releaseSlot.attachProcess?.(handle.pid);\n } catch (error) {\n if (!(await handle.stop())) {\n return this.promote(handle, 'requested', undefined);\n }\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: error instanceof Error ? error.message : String(error) };\n }\n }\n if (request.signal?.aborted) {\n if (!(await handle.stop())) return this.promote(handle, 'requested', undefined);\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return { kind: FAILED, id, name, error: 'Operation aborted' };\n }\n\n // A sequence owns the wait and hands control back as soon as its interactive stage starts.\n if (request.waitForExit !== true && (request.background === true || interactive))\n return this.promote(handle, request.background === true ? 'requested' : 'interactive', request.signal);\n\n const outputUpdates = request.onOutput ? this.followOutput(handle, request.onOutput) : undefined;\n try {\n const outcome = await this.race(handle, request.timeoutMs, request.signal, request.waitForExit !== true);\n outputUpdates?.flush();\n if (outcome === TIMED_OUT) {\n return this.promote(handle, 'threshold', request.signal);\n }\n if (outcome === ABORTED) {\n await this.registry.requestTermination(id, { reason: 'stopped', terminationReason: 'request_cancelled' });\n const stopped = await handle.stop();\n if (!stopped && request.waitForExit) return this.promote(handle, 'requested', undefined);\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n aborted: true,\n };\n }\n if (outcome === DEADLINE) {\n // An explicit timeout means the caller wants the command dead, not\n // supervised, so it is stopped rather than promoted.\n await this.registry.requestTermination(id, { reason: 'timed_out', terminationReason: 'timeout' });\n const stopped = await handle.stop();\n if (!stopped && request.waitForExit) return this.promote(handle, 'requested', undefined);\n outputUpdates?.flush();\n await this.registry.complete(id, { reason: 'timed_out', code: null, signal: 'SIGTERM' });\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: null,\n signal: 'SIGTERM',\n logPath: handle.logPath,\n backend: handle.backend,\n timedOut: true,\n };\n }\n if (outcome instanceof Error) {\n await this.registry.complete(id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n return { kind: FAILED, id, name, error: outcome.message };\n }\n\n await this.registry.complete(id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n\n return {\n kind: COMPLETED,\n id,\n name,\n output: handle.output(),\n exitCode: outcome.code,\n signal: outcome.signal,\n logPath: handle.logPath,\n backend: handle.backend,\n ...(await this.processLog(request.command, handle.logPath)),\n };\n } finally {\n outputUpdates?.dispose();\n }\n }\n\n private async processLog(command: string, logPath: string): Promise<Pick<CompletedRun, 'rtkOutput' | 'rtkWarning'>> {\n try {\n const result = await this.rtkProcessor.process({ command, logPath });\n if (result.kind === 'processed') return { rtkOutput: result.result };\n if (result.kind === 'fallback') return { rtkWarning: result.warning };\n return {};\n } catch {\n return { rtkWarning: RTK_FAILED_WARNING };\n }\n }\n\n private followOutput(\n handle: RunHandle,\n onOutput: NonNullable<BashRunRequest['onOutput']>,\n ): { flush(): void; dispose(): void } {\n let active = true;\n let previous = '';\n let cancelPoll: (() => void) | undefined;\n const flush = (): void => {\n if (!active) return;\n const output = handle.output();\n if (output === previous) return;\n previous = output;\n onOutput(output);\n };\n const poll = (): void => {\n if (!active) return;\n flush();\n if (active) cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n };\n cancelPoll = this.clock.after(OUTPUT_UPDATE_POLL_MS, poll);\n return {\n flush,\n dispose: () => {\n active = false;\n cancelPoll?.();\n cancelPoll = undefined;\n },\n };\n }\n\n /**\n * Waits for the command, giving up at the background threshold or at the\n * caller's timeout, whichever comes first.\n *\n * A rejected completion is returned rather than thrown so the caller can\n * report a start failure as a tool result instead of an exception.\n */\n private async race(\n handle: RunHandle,\n timeoutMs: number | undefined,\n signal: AbortSignal | undefined,\n promoteAtThreshold = true,\n ): Promise<\n Awaited<ReturnType<RunHandle['completion']>> | Error | typeof TIMED_OUT | typeof DEADLINE | typeof ABORTED\n > {\n const cancels: Array<() => void> = [];\n const racers: Array<Promise<unknown>> = [handle.completion().catch((error: Error) => error)];\n\n if (promoteAtThreshold)\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(getBackgroundThresholdMs(this.env), () => resolve(TIMED_OUT)));\n }),\n );\n if (timeoutMs !== undefined && timeoutMs > 0) {\n racers.push(\n new Promise((resolve) => {\n cancels.push(this.clock.after(timeoutMs, () => resolve(DEADLINE)));\n }),\n );\n }\n if (signal) {\n racers.push(\n new Promise((resolve) => {\n if (signal.aborted) {\n resolve(ABORTED);\n return;\n }\n const abort = (): void => resolve(ABORTED);\n signal.addEventListener('abort', abort, { once: true });\n cancels.push(() => signal.removeEventListener('abort', abort));\n }),\n );\n }\n\n try {\n return (await Promise.race(racers)) as\n | Awaited<ReturnType<RunHandle['completion']>>\n | Error\n | typeof TIMED_OUT\n | typeof DEADLINE\n | typeof ABORTED;\n } finally {\n for (const cancel of cancels) cancel();\n }\n }\n\n private async promote(\n handle: RunHandle,\n reason: PromotedRun['reason'],\n signal: AbortSignal | undefined,\n ): Promise<BashRunResult> {\n if (handle.pid === undefined)\n return { kind: FAILED, id: handle.id, name: handle.name, error: 'The command did not start' };\n await this.registry.markPromoted(handle.id);\n // Registration first: an unregistered runner is invisible, and the handle\n // stops buffering the moment it is detached.\n handle.detach();\n let abortStop: Promise<boolean> | undefined;\n const abort = (): void => {\n abortStop = this.registry\n .requestTermination(handle.id, { reason: 'stopped', terminationReason: 'request_cancelled' })\n .then(() => handle.stop())\n .then(async () => {\n await this.registry.complete(handle.id, { reason: 'stopped', code: null, signal: 'SIGTERM' });\n return true;\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to stop aborted runner ${handle.id}: ${message}`);\n return false;\n });\n };\n // The signal belongs to the tool call, which ends when this returns, and\n // Pi aborts it at that point. A promoted runner outlives the call, so only\n // an abort that landed before the handoff stops it.\n if (signal?.aborted) abort();\n void handle\n .completion()\n .then(\n async (outcome) => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, {\n reason: outcome.reason ?? (outcome.signal ? SIGNALED : outcome.code === 0 ? COMPLETED : FAILED),\n code: outcome.code,\n signal: outcome.signal,\n ...(outcome.terminationReason ? { terminationReason: outcome.terminationReason } : {}),\n ...(outcome.stopReason ? { stopReason: outcome.stopReason } : {}),\n });\n },\n async () => {\n if (await abortStop) return;\n await this.registry.complete(handle.id, { reason: LAUNCHER_ERROR, code: null, signal: null });\n },\n )\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.emitWarning(`Failed to complete runner ${handle.id}: ${message}`);\n });\n\n return {\n kind: 'promoted',\n id: handle.id,\n name: handle.name,\n pid: handle.pid,\n logPath: handle.logPath,\n backend: handle.backend,\n reason,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/bashRunService.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bashRunService = require("./bashRunService-
|
|
2
|
+
const require_bashRunService = require("./bashRunService-DLpFoP81.cjs");
|
|
3
3
|
exports.BashRunService = require_bashRunService.BashRunService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashRunService.d.mts","names":[],"sources":["../src/services/bashRunService/index.ts"],"mappings":";;;;;;;;;qBA0Ca,0BAA0B;mBAElB;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EATnB,YACmB,UAAU,WACV,aAAa,cACb,OAAO,cACP,UAAU,iBACV,OAAO,QACP,cAAc,eACd,cACA,MAAK,SAAS,qCACd,kBAAkB;EAG/B,IAAI,SAAS,iBAAiB,QAAQ;
|
|
1
|
+
{"version":3,"file":"bashRunService.d.mts","names":[],"sources":["../src/services/bashRunService/index.ts"],"mappings":";;;;;;;;;qBA0Ca,0BAA0B;mBAElB;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EATnB,YACmB,UAAU,WACV,aAAa,cACb,OAAO,cACP,UAAU,iBACV,OAAO,QACP,cAAc,eACd,cACA,MAAK,SAAS,qCACd,kBAAkB;EAG/B,IAAI,SAAS,iBAAiB,QAAQ;UA6J9B;UAWN;;;;;;;;UAqCM;UAkDA"}
|
package/dist/bashRunService.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as BashRunService } from "./bashRunService-
|
|
1
|
+
export { t as BashRunService } from "./bashRunService-CmjnipLE.mjs";
|
package/dist/bashSchema.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bashTool = require("./bashTool-
|
|
2
|
+
const require_bashTool = require("./bashTool-CfNNdq62.cjs");
|
|
3
3
|
exports.BASH_TOOL_LABEL = require_bashTool.BASH_TOOL_LABEL;
|
|
4
4
|
exports.BASH_TOOL_NAME = require_bashTool.BASH_TOOL_NAME;
|
|
5
5
|
exports.BashParamsSchema = require_bashTool.BashParamsSchema;
|
package/dist/bashSchema.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as BashParamsSchema, t as BashParams } from "./bashTool-
|
|
1
|
+
import { n as BashParamsSchema, t as BashParams } from "./bashTool-Dc1ld2E3.mjs";
|
|
2
2
|
//#region src/constants/bashTool.d.ts
|
|
3
3
|
export declare const BASH_TOOL_NAME = "bash";
|
|
4
4
|
export declare const BASH_TOOL_LABEL = "bash";
|
package/dist/bashSchema.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as BASH_TOOL_LABEL, n as BASH_TOOL_NAME, r as BashParamsSchema } from "./bashTool-
|
|
1
|
+
export { t as BASH_TOOL_LABEL, n as BASH_TOOL_NAME, r as BashParamsSchema } from "./bashTool-DRW3lseL.mjs";
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
const require_runnerSequence = require("./runnerSequence-ZTYgZ_2W.cjs");
|
|
2
2
|
let typebox = require("typebox");
|
|
3
3
|
//#region src/schemas/bashTool.ts
|
|
4
|
-
/** Replaces pi's built-in tool
|
|
5
|
-
/**
|
|
6
|
-
* Built-in bash parameters plus the backgrounding controls.
|
|
7
|
-
*
|
|
8
|
-
* `command` and `timeout` keep their original names and wording so the tool is
|
|
9
|
-
* a drop-in replacement. Every `description` is prompt copy the model reads.
|
|
10
|
-
*/
|
|
4
|
+
/** Replaces pi's built-in `bash` tool. Descriptions are agent-facing prompt copy. */
|
|
11
5
|
const BashParamsSchema = typebox.Type.Object({
|
|
12
|
-
command: typebox.Type.
|
|
6
|
+
command: typebox.Type.Array(typebox.Type.String({
|
|
13
7
|
minLength: 1,
|
|
14
8
|
maxLength: require_runnerSequence.MAX_SEQUENCE_COMMAND_LENGTH
|
|
15
9
|
}), {
|
|
16
10
|
minItems: 1,
|
|
17
11
|
maxItems: 32,
|
|
18
|
-
description: "
|
|
19
|
-
})
|
|
12
|
+
description: "Bash commands to run in order, stopping on first failure. Use a one-item array for one command. Each command gets a full log; return all log paths and only the last executed result. Do not pipe or redirect output to a file, head, or tail. Logs are saved automatically and returned output is bounded."
|
|
13
|
+
}),
|
|
20
14
|
timeout: typebox.Type.Optional(typebox.Type.Number({ description: "Timeout in seconds for each command (optional, no default timeout)" })),
|
|
21
|
-
background: typebox.Type.Optional(typebox.Type.Boolean({ description: "Start the command in the background immediately
|
|
22
|
-
interactive: typebox.Type.Optional(typebox.Type.Boolean({ description: "Run
|
|
15
|
+
background: typebox.Type.Optional(typebox.Type.Boolean({ description: "Start the command sequence in the background immediately. Use for dev servers, watchers and other commands you already know will not finish." })),
|
|
16
|
+
interactive: typebox.Type.Optional(typebox.Type.Boolean({ description: "Run only the last command under a pseudo terminal when it needs input. Earlier commands are noninteractive. Send input to the last stage runner ID with runner.input in code mode, or po-runner input without code mode." })),
|
|
23
17
|
name: typebox.Type.Optional(typebox.Type.String({ description: "Preferred runner name if the command ends up in the background. A name in use gets a suffix." }))
|
|
24
18
|
});
|
|
25
19
|
//#endregion
|
|
@@ -46,4 +40,4 @@ Object.defineProperty(exports, "BashParamsSchema", {
|
|
|
46
40
|
}
|
|
47
41
|
});
|
|
48
42
|
|
|
49
|
-
//# sourceMappingURL=bashTool-
|
|
43
|
+
//# sourceMappingURL=bashTool-CfNNdq62.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashTool-CfNNdq62.cjs","names":["Type","MAX_SEQUENCE_COMMAND_LENGTH"],"sources":["../src/schemas/bashTool.ts","../src/constants/bashTool.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\nimport { MAX_SEQUENCE_COMMANDS, MAX_SEQUENCE_COMMAND_LENGTH } from '../constants/runnerSequence';\n\n/** Replaces pi's built-in `bash` tool. Descriptions are agent-facing prompt copy. */\nexport const BashParamsSchema = Type.Object({\n command: Type.Array(Type.String({ minLength: 1, maxLength: MAX_SEQUENCE_COMMAND_LENGTH }), {\n minItems: 1,\n maxItems: MAX_SEQUENCE_COMMANDS,\n description:\n 'Bash commands to run in order, stopping on first failure. Use a one-item array for one command. Each command gets a full log; return all log paths and only the last executed result. Do not pipe or redirect output to a file, head, or tail. Logs are saved automatically and returned output is bounded.',\n }),\n timeout: Type.Optional(\n Type.Number({ description: 'Timeout in seconds for each command (optional, no default timeout)' }),\n ),\n background: Type.Optional(\n Type.Boolean({\n description:\n 'Start the command sequence in the background immediately. Use for dev servers, watchers and other commands you already know will not finish.',\n }),\n ),\n interactive: Type.Optional(\n Type.Boolean({\n description:\n 'Run only the last command under a pseudo terminal when it needs input. Earlier commands are noninteractive. Send input to the last stage runner ID with runner.input in code mode, or po-runner input without code mode.',\n }),\n ),\n name: Type.Optional(\n Type.String({\n description: 'Preferred runner name if the command ends up in the background. A name in use gets a suffix.',\n }),\n ),\n});\n\nexport type BashParams = Static<typeof BashParamsSchema>;\n","export const BASH_TOOL_NAME = 'bash';\nexport const BASH_TOOL_LABEL = 'bash';\n\nexport const MS_PER_SECOND = 1000;\n"],"mappings":";;;;AAKA,MAAa,mBAAmBA,QAAAA,KAAK,OAAO;CAC1C,SAASA,QAAAA,KAAK,MAAMA,QAAAA,KAAK,OAAO;EAAE,WAAW;EAAG,WAAWC,uBAAAA;CAA4B,CAAC,GAAG;EACzF,UAAU;EACV,UAAA;EACA,aACE;CACJ,CAAC;CACD,SAASD,QAAAA,KAAK,SACZA,QAAAA,KAAK,OAAO,EAAE,aAAa,qEAAqE,CAAC,CACnG;CACA,YAAYA,QAAAA,KAAK,SACfA,QAAAA,KAAK,QAAQ,EACX,aACE,+IACJ,CAAC,CACH;CACA,aAAaA,QAAAA,KAAK,SAChBA,QAAAA,KAAK,QAAQ,EACX,aACE,2NACJ,CAAC,CACH;CACA,MAAMA,QAAAA,KAAK,SACTA,QAAAA,KAAK,OAAO,EACV,aAAa,+FACf,CAAC,CACH;AACF,CAAC;;;AChCD,MAAa,iBAAiB;AAC9B,MAAa,kBAAkB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { t as MAX_SEQUENCE_COMMAND_LENGTH } from "./runnerSequence-k-_Fd77y.mjs";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
//#region src/schemas/bashTool.ts
|
|
4
|
+
/** Replaces pi's built-in `bash` tool. Descriptions are agent-facing prompt copy. */
|
|
5
|
+
const BashParamsSchema = Type.Object({
|
|
6
|
+
command: Type.Array(Type.String({
|
|
7
|
+
minLength: 1,
|
|
8
|
+
maxLength: MAX_SEQUENCE_COMMAND_LENGTH
|
|
9
|
+
}), {
|
|
10
|
+
minItems: 1,
|
|
11
|
+
maxItems: 32,
|
|
12
|
+
description: "Bash commands to run in order, stopping on first failure. Use a one-item array for one command. Each command gets a full log; return all log paths and only the last executed result. Do not pipe or redirect output to a file, head, or tail. Logs are saved automatically and returned output is bounded."
|
|
13
|
+
}),
|
|
14
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds for each command (optional, no default timeout)" })),
|
|
15
|
+
background: Type.Optional(Type.Boolean({ description: "Start the command sequence in the background immediately. Use for dev servers, watchers and other commands you already know will not finish." })),
|
|
16
|
+
interactive: Type.Optional(Type.Boolean({ description: "Run only the last command under a pseudo terminal when it needs input. Earlier commands are noninteractive. Send input to the last stage runner ID with runner.input in code mode, or po-runner input without code mode." })),
|
|
17
|
+
name: Type.Optional(Type.String({ description: "Preferred runner name if the command ends up in the background. A name in use gets a suffix." }))
|
|
18
|
+
});
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/constants/bashTool.ts
|
|
21
|
+
const BASH_TOOL_NAME = "bash";
|
|
22
|
+
const BASH_TOOL_LABEL = "bash";
|
|
23
|
+
//#endregion
|
|
24
|
+
export { BASH_TOOL_NAME as n, BashParamsSchema as r, BASH_TOOL_LABEL as t };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=bashTool-DRW3lseL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashTool-DRW3lseL.mjs","names":[],"sources":["../src/schemas/bashTool.ts","../src/constants/bashTool.ts"],"sourcesContent":["import { type Static, Type } from 'typebox';\n\nimport { MAX_SEQUENCE_COMMANDS, MAX_SEQUENCE_COMMAND_LENGTH } from '../constants/runnerSequence';\n\n/** Replaces pi's built-in `bash` tool. Descriptions are agent-facing prompt copy. */\nexport const BashParamsSchema = Type.Object({\n command: Type.Array(Type.String({ minLength: 1, maxLength: MAX_SEQUENCE_COMMAND_LENGTH }), {\n minItems: 1,\n maxItems: MAX_SEQUENCE_COMMANDS,\n description:\n 'Bash commands to run in order, stopping on first failure. Use a one-item array for one command. Each command gets a full log; return all log paths and only the last executed result. Do not pipe or redirect output to a file, head, or tail. Logs are saved automatically and returned output is bounded.',\n }),\n timeout: Type.Optional(\n Type.Number({ description: 'Timeout in seconds for each command (optional, no default timeout)' }),\n ),\n background: Type.Optional(\n Type.Boolean({\n description:\n 'Start the command sequence in the background immediately. Use for dev servers, watchers and other commands you already know will not finish.',\n }),\n ),\n interactive: Type.Optional(\n Type.Boolean({\n description:\n 'Run only the last command under a pseudo terminal when it needs input. Earlier commands are noninteractive. Send input to the last stage runner ID with runner.input in code mode, or po-runner input without code mode.',\n }),\n ),\n name: Type.Optional(\n Type.String({\n description: 'Preferred runner name if the command ends up in the background. A name in use gets a suffix.',\n }),\n ),\n});\n\nexport type BashParams = Static<typeof BashParamsSchema>;\n","export const BASH_TOOL_NAME = 'bash';\nexport const BASH_TOOL_LABEL = 'bash';\n\nexport const MS_PER_SECOND = 1000;\n"],"mappings":";;;;AAKA,MAAa,mBAAmB,KAAK,OAAO;CAC1C,SAAS,KAAK,MAAM,KAAK,OAAO;EAAE,WAAW;EAAG,WAAW;CAA4B,CAAC,GAAG;EACzF,UAAU;EACV,UAAA;EACA,aACE;CACJ,CAAC;CACD,SAAS,KAAK,SACZ,KAAK,OAAO,EAAE,aAAa,qEAAqE,CAAC,CACnG;CACA,YAAY,KAAK,SACf,KAAK,QAAQ,EACX,aACE,+IACJ,CAAC,CACH;CACA,aAAa,KAAK,SAChB,KAAK,QAAQ,EACX,aACE,2NACJ,CAAC,CACH;CACA,MAAM,KAAK,SACT,KAAK,OAAO,EACV,aAAa,+FACf,CAAC,CACH;AACF,CAAC;;;AChCD,MAAa,iBAAiB;AAC9B,MAAa,kBAAkB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Static, Type } from "typebox";
|
|
2
|
+
//#region src/schemas/bashTool.d.ts
|
|
3
|
+
/** Replaces pi's built-in `bash` tool. Descriptions are agent-facing prompt copy. */
|
|
4
|
+
declare const BashParamsSchema: Type.TObject<{
|
|
5
|
+
command: Type.TArray<Type.TString>;
|
|
6
|
+
timeout: Type.TOptional<Type.TNumber>;
|
|
7
|
+
background: Type.TOptional<Type.TBoolean>;
|
|
8
|
+
interactive: Type.TOptional<Type.TBoolean>;
|
|
9
|
+
name: Type.TOptional<Type.TString>;
|
|
10
|
+
}>;
|
|
11
|
+
type BashParams = Static<typeof BashParamsSchema>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { BashParamsSchema as n, BashParams as t };
|
|
14
|
+
//# sourceMappingURL=bashTool-Dc1ld2E3.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashTool-Dc1ld2E3.d.mts","names":[],"sources":["../src/schemas/bashTool.ts"],"mappings":";;;cAKa,kBAAgB,KAAA;;;;;;;KA6BjB,aAAa,cAAc"}
|
package/dist/bashTool.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_bashResult = require("./bashResult-CxttmwR5.cjs");
|
|
3
|
-
const require_logReader = require("./logReader-
|
|
4
|
-
const require_headless = require("./headless-
|
|
3
|
+
const require_logReader = require("./logReader-3RzQjCs4.cjs");
|
|
4
|
+
const require_headless = require("./headless-BlgjJiv0.cjs");
|
|
5
5
|
//#region src/services/runnerResult/index.ts
|
|
6
6
|
function formatRunnerResult(result, budget = {}) {
|
|
7
7
|
return require_bashResult.formatRunResult(result, budget, require_logReader.summarizeLog);
|
package/dist/bashTool.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as BashRunResult } from "./bashRunService-CmdDhaTn.mjs";
|
|
2
2
|
import { a as ResultBudget, s as ToolResult } from "./bashResult-DcrRaBLv.mjs";
|
|
3
|
-
import { t as createHeadlessBashTool } from "./index-
|
|
3
|
+
import { t as createHeadlessBashTool } from "./index-BhS6r6Eq.mjs";
|
|
4
4
|
//#region src/services/runnerResult/index.d.ts
|
|
5
5
|
declare function formatRunnerResult(result: BashRunResult, budget?: ResultBudget): ToolResult;
|
|
6
6
|
//#endregion
|
package/dist/bashTool.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as formatRunResult } from "./bashResult-sEZrlBz3.mjs";
|
|
2
|
-
import { r as summarizeLog } from "./logReader-
|
|
3
|
-
import { t as createHeadlessBashTool } from "./headless-
|
|
2
|
+
import { r as summarizeLog } from "./logReader-DpO_fcDj.mjs";
|
|
3
|
+
import { t as createHeadlessBashTool } from "./headless-kp9-KBp3.mjs";
|
|
4
4
|
//#region src/services/runnerResult/index.ts
|
|
5
5
|
function formatRunnerResult(result, budget = {}) {
|
|
6
6
|
return formatRunResult(result, budget, summarizeLog);
|
package/dist/bin/cli.cjs
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const require_runnerSequenceStore = require("../runnerSequenceStore-BtwVilKx.cjs");
|
|
4
4
|
const require_cliApp = require("../cliApp-DonQNLT8.cjs");
|
|
5
5
|
const require_session = require("../session-BvqzhXZY.cjs");
|
|
6
|
-
const require_runnerDependencies = require("../runnerDependencies-
|
|
6
|
+
const require_runnerDependencies = require("../runnerDependencies-DOY30X-w.cjs");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_url = require("node:url");
|
|
9
9
|
let _agimon_ai_po_core_telemetry = require("@agimon-ai/po-core/telemetry");
|
package/dist/bin/cli.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { t as createRunnerSequenceStore } from "../runnerSequenceStore-CaY7S_Sd.mjs";
|
|
3
3
|
import { n as runnerCliHelp, t as runCli } from "../cliApp-BDJl6JPc.mjs";
|
|
4
4
|
import { t as inheritedSessionId } from "../session-BKYnH4R6.mjs";
|
|
5
|
-
import { t as createRunnerDependencies } from "../runnerDependencies-
|
|
5
|
+
import { t as createRunnerDependencies } from "../runnerDependencies-C6K2P-ID.mjs";
|
|
6
6
|
import { existsSync, realpathSync } from "node:fs";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { createPoTelemetry } from "@agimon-ai/po-core/telemetry";
|
package/dist/cliApp.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as ILauncher } from "./launcher-BG5t9nvG.mjs";
|
|
2
2
|
import { t as IRmuxBackend } from "./rmuxBackend-CaEWooWn.mjs";
|
|
3
3
|
import { n as IRunnerRegistry } from "./runnerRegistry-V-Ocaf4N.mjs";
|
|
4
|
-
import { t as ILogReader } from "./logReader-
|
|
4
|
+
import { t as ILogReader } from "./logReader-wZC8OH3h.mjs";
|
|
5
5
|
import { t as RunnerSequenceStore } from "./index-CpeSnckG.mjs";
|
|
6
6
|
//#region src/services/cliApp/index.d.ts
|
|
7
7
|
export interface CliDependencies {
|