@agimon-ai/po-runner 0.0.0-alpha.2 → 0.0.0-alpha.21
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/LICENSE +149 -21
- package/README.md +17 -17
- package/dist/ansiScrub.mjs +1 -2
- package/dist/apiContracts.cjs +1 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs +1 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/{bashResult-bIVSzoj-.mjs → bashResult-BqDa7sbC.mjs} +10 -9
- package/dist/bashResult-BqDa7sbC.mjs.map +1 -0
- package/dist/{bashResult-DNgtahGR.cjs → bashResult-C2iKhHpD.cjs} +10 -9
- package/dist/bashResult-C2iKhHpD.cjs.map +1 -0
- package/dist/{bashRunService-CJ02XaAq.mjs → bashRunService-Cl3pYccr.mjs} +2 -2
- package/dist/bashRunService-Cl3pYccr.mjs.map +1 -0
- package/dist/{bashRunService-DyqxOSlx.cjs → bashRunService-DjOH5kye.cjs} +2 -2
- package/dist/bashRunService-DjOH5kye.cjs.map +1 -0
- package/dist/bashRunService.cjs +1 -1
- package/dist/bashRunService.d.mts +3 -3
- package/dist/bashRunService.mjs +1 -2
- package/dist/bashSchema.cjs +1 -1
- package/dist/bashSchema.mjs +1 -2
- package/dist/{bashTool-C-k7fmyh.mjs → bashTool-BvC3YOgG.mjs} +2 -2
- package/dist/{bashTool-C-k7fmyh.mjs.map → bashTool-BvC3YOgG.mjs.map} +1 -1
- package/dist/{bashTool-CdgtqVFD.cjs → bashTool-euL6zMDl.cjs} +2 -2
- package/dist/{bashTool-CdgtqVFD.cjs.map → bashTool-euL6zMDl.cjs.map} +1 -1
- package/dist/bashTool.cjs +3 -3
- package/dist/bashTool.d.mts +1 -1
- package/dist/bashTool.mjs +3 -3
- package/dist/bin/cli.cjs +6 -6
- package/dist/bin/cli.cjs.map +1 -1
- package/dist/bin/cli.mjs +7 -7
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/bin/logSink.cjs +6 -6
- package/dist/bin/logSink.cjs.map +1 -1
- package/dist/bin/logSink.mjs +7 -7
- package/dist/bin/logSink.mjs.map +1 -1
- package/dist/bin/runnerHost.cjs +4 -4
- package/dist/bin/runnerHost.cjs.map +1 -1
- package/dist/bin/runnerHost.mjs +5 -5
- package/dist/bin/runnerHost.mjs.map +1 -1
- package/dist/{cliApp-Dj9nwaOv.cjs → cliApp-T8Fx_-1j.cjs} +6 -6
- package/dist/cliApp-T8Fx_-1j.cjs.map +1 -0
- package/dist/{cliApp-v8Z3rMCi.mjs → cliApp-q97eVh4E.mjs} +6 -6
- package/dist/cliApp-q97eVh4E.mjs.map +1 -0
- package/dist/cliApp.cjs +1 -1
- package/dist/cliApp.d.mts +1 -1
- package/dist/cliApp.mjs +1 -2
- package/dist/clock.mjs +1 -2
- package/dist/{compaction-4QSUsBxq.cjs → compaction-Cduebib_.cjs} +3 -3
- package/dist/compaction-Cduebib_.cjs.map +1 -0
- package/dist/{compaction-DCw80VZj.mjs → compaction-nNlE6e5I.mjs} +3 -3
- package/dist/compaction-nNlE6e5I.mjs.map +1 -0
- package/dist/compaction.cjs +1 -1
- package/dist/compaction.d.mts +1 -1
- package/dist/compaction.mjs +1 -2
- package/dist/config.cjs +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -2
- package/dist/extensions/mcp-ui.mjs.map +1 -1
- package/dist/extensions/mcp.cjs +8 -7
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.d.mts +1 -1
- package/dist/extensions/mcp.mjs +7 -6
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/native.mjs +1 -1
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +233 -119
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +233 -119
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +88 -62
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/{headless-BGYfIlNk.mjs → headless-DOlCixyf.mjs} +5 -5
- package/dist/headless-DOlCixyf.mjs.map +1 -0
- package/dist/{headless-CHUsBGhg.cjs → headless-Dko_yBiy.cjs} +5 -5
- package/dist/headless-Dko_yBiy.cjs.map +1 -0
- package/dist/{index-Dhi8asLH.d.mts → index--xF7DvsE.d.mts} +4 -4
- package/dist/{index-Dhi8asLH.d.mts.map → index--xF7DvsE.d.mts.map} +1 -1
- package/dist/{index-BZL7keVW.d.mts → index-BCCF1sGD.d.mts} +2 -2
- package/dist/{index-BZL7keVW.d.mts.map → index-BCCF1sGD.d.mts.map} +1 -1
- package/dist/{index-BwB_jTI9.d.mts → index-BzeXJk6V.d.mts} +5 -5
- package/dist/index-BzeXJk6V.d.mts.map +1 -0
- package/dist/{index-D9-IXax4.d.mts → index-C-IC35d9.d.mts} +2 -2
- package/dist/{index-D9-IXax4.d.mts.map → index-C-IC35d9.d.mts.map} +1 -1
- package/dist/{index-DBz0DxnL.d.mts → index-CzCF_OP9.d.mts} +3 -4
- package/dist/index-CzCF_OP9.d.mts.map +1 -0
- package/dist/index.cjs +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +5 -5
- package/dist/{launcher-BDm6-DiQ.mjs → launcher-CCYsFBM9.mjs} +3 -3
- package/dist/{launcher-BDm6-DiQ.mjs.map → launcher-CCYsFBM9.mjs.map} +1 -1
- package/dist/{launcher-SlyE8R3b.cjs → launcher-ZgDdyXpq.cjs} +8 -2
- package/dist/{launcher-SlyE8R3b.cjs.map → launcher-ZgDdyXpq.cjs.map} +1 -1
- package/dist/launcher.cjs +1 -1
- package/dist/launcher.d.mts +1 -1
- package/dist/launcher.mjs +1 -2
- package/dist/{lifeline-BZaQA0rm.mjs → lifeline-Bm-bHIjS.mjs} +6 -6
- package/dist/lifeline-Bm-bHIjS.mjs.map +1 -0
- package/dist/{lifeline-BuV_erib.cjs → lifeline-m7laIzIP.cjs} +6 -6
- package/dist/lifeline-m7laIzIP.cjs.map +1 -0
- package/dist/lifeline.cjs +1 -1
- package/dist/lifeline.d.mts +1 -1
- package/dist/lifeline.mjs +1 -1
- package/dist/{logFile-CNvepZh0.cjs → logFile-CnPKtxPy.cjs} +2 -2
- package/dist/{logFile-CNvepZh0.cjs.map → logFile-CnPKtxPy.cjs.map} +1 -1
- package/dist/{logFile-KKPbkC-a.mjs → logFile-XcDHBwu1.mjs} +2 -2
- package/dist/{logFile-KKPbkC-a.mjs.map → logFile-XcDHBwu1.mjs.map} +1 -1
- package/dist/logFile.cjs +1 -1
- package/dist/logFile.d.mts +1 -1
- package/dist/logFile.mjs +1 -2
- package/dist/{logReader-B6J7L7Ua.cjs → logReader-DHCK2BEr.cjs} +4 -4
- package/dist/{logReader-B6J7L7Ua.cjs.map → logReader-DHCK2BEr.cjs.map} +1 -1
- package/dist/{logReader-UfbDbwQl.mjs → logReader-mq9uVurh.mjs} +4 -4
- package/dist/{logReader-UfbDbwQl.mjs.map → logReader-mq9uVurh.mjs.map} +1 -1
- package/dist/logReader.cjs +1 -1
- package/dist/logReader.mjs +1 -2
- package/dist/processControl.mjs +1 -2
- package/dist/{ptyHost-DlQtTB8F.mjs → ptyHost-CwbLLr90.mjs} +2 -2
- package/dist/{ptyHost-DlQtTB8F.mjs.map → ptyHost-CwbLLr90.mjs.map} +1 -1
- package/dist/{ptyHost-MI2Z6WTG.cjs → ptyHost-D35hNmtd.cjs} +2 -2
- package/dist/{ptyHost-MI2Z6WTG.cjs.map → ptyHost-D35hNmtd.cjs.map} +1 -1
- package/dist/ptyHost.cjs +1 -1
- package/dist/ptyHost.mjs +1 -2
- package/dist/{ptySpawner-DEi1KOnd.mjs → ptySpawner-C375NJnj.mjs} +2 -2
- package/dist/ptySpawner-C375NJnj.mjs.map +1 -0
- package/dist/{ptySpawner-ijw0g5_T.cjs → ptySpawner-C39IzbRo.cjs} +2 -2
- package/dist/ptySpawner-C39IzbRo.cjs.map +1 -0
- package/dist/ptySpawner.cjs +1 -1
- package/dist/ptySpawner.d.mts +1 -1
- package/dist/ptySpawner.mjs +1 -2
- package/dist/{reconcile-DMeNSxwn.mjs → reconcile-5cZ11jSD.cjs} +12 -42
- package/dist/reconcile-5cZ11jSD.cjs.map +1 -0
- package/dist/{reconcile-BugwYFbV.cjs → reconcile-wNYQJZF-.mjs} +2 -62
- package/dist/reconcile-wNYQJZF-.mjs.map +1 -0
- package/dist/reconcile.cjs +1 -2
- package/dist/reconcile.d.mts +2 -9
- package/dist/reconcile.d.mts.map +1 -1
- package/dist/reconcile.mjs +1 -2
- package/dist/responseEnvelope.cjs +2 -2
- package/dist/responseEnvelope.d.mts +3 -3
- package/dist/responseEnvelope.mjs +2 -2
- package/dist/{rmuxBackend-DlxgqRZ1.cjs → rmuxBackend-Dh0CYVAL.cjs} +5 -5
- package/dist/rmuxBackend-Dh0CYVAL.cjs.map +1 -0
- package/dist/{rmuxBackend-DfyQwJrc.mjs → rmuxBackend-rjrVTG6K.mjs} +4 -4
- package/dist/rmuxBackend-rjrVTG6K.mjs.map +1 -0
- package/dist/rmuxBackend.cjs +1 -1
- package/dist/rmuxBackend.d.mts +1 -1
- package/dist/rmuxBackend.mjs +1 -2
- package/dist/{rtkProcessor-Bc4L4o_8.cjs → rtkProcessor-DSGbM-Cm.cjs} +4 -4
- package/dist/rtkProcessor-DSGbM-Cm.cjs.map +1 -0
- package/dist/{rtkProcessor-B9KPdyzr.mjs → rtkProcessor-Iw9gP5Xp.mjs} +3 -3
- package/dist/rtkProcessor-Iw9gP5Xp.mjs.map +1 -0
- package/dist/rtkProcessor.cjs +1 -1
- package/dist/rtkProcessor.d.mts +1 -1
- package/dist/rtkProcessor.mjs +1 -1
- package/dist/{runnerConfig-D2tGq5ZM.cjs → runnerConfig-BoLMinlx.cjs} +11 -11
- package/dist/runnerConfig-BoLMinlx.cjs.map +1 -0
- package/dist/{runnerConfig-BjtulXBI.d.mts → runnerConfig-DuWL6TJx.d.mts} +10 -10
- package/dist/{runnerConfig-BjtulXBI.d.mts.map → runnerConfig-DuWL6TJx.d.mts.map} +1 -1
- package/dist/{runnerConfig-BQBlVAXn.mjs → runnerConfig-XXMq4VQA.mjs} +11 -11
- package/dist/runnerConfig-XXMq4VQA.mjs.map +1 -0
- package/dist/{runnerDependencies-DruByBGS.mjs → runnerDependencies-7h_cxOva.mjs} +17 -17
- package/dist/runnerDependencies-7h_cxOva.mjs.map +1 -0
- package/dist/{runnerDependencies-KMZigIxB.cjs → runnerDependencies-DSun3xO-.cjs} +17 -17
- package/dist/runnerDependencies-DSun3xO-.cjs.map +1 -0
- package/dist/runnerDependencies.cjs +1 -1
- package/dist/runnerDependencies.d.mts +1 -1
- package/dist/runnerDependencies.mjs +1 -2
- package/dist/runnerNamer.d.mts +1 -1
- package/dist/runnerNamer.mjs +1 -2
- package/dist/{runnerPaths-BTEuzxw0.cjs → runnerPaths-B41rMOY6.cjs} +20 -38
- package/dist/runnerPaths-B41rMOY6.cjs.map +1 -0
- package/dist/{runnerPaths-B_dAAeco.mjs → runnerPaths-Dibbvyx_.mjs} +20 -38
- package/dist/runnerPaths-Dibbvyx_.mjs.map +1 -0
- package/dist/runnerPaths.cjs +1 -1
- package/dist/runnerPaths.d.mts +5 -7
- package/dist/runnerPaths.d.mts.map +1 -1
- package/dist/runnerPaths.mjs +1 -2
- package/dist/{runnerRegistry-CeOHEjBv.mjs → runnerRegistry-BgaR5O86.mjs} +12 -11
- package/dist/runnerRegistry-BgaR5O86.mjs.map +1 -0
- package/dist/{runnerRegistry-CtJiD02R.d.mts → runnerRegistry-V-Ocaf4N.d.mts} +1 -3
- package/dist/{runnerRegistry-CtJiD02R.d.mts.map → runnerRegistry-V-Ocaf4N.d.mts.map} +1 -1
- package/dist/{runnerRegistry-BmkZTJHi.cjs → runnerRegistry-dQYlMSpQ.cjs} +23 -10
- package/dist/runnerRegistry-dQYlMSpQ.cjs.map +1 -0
- package/dist/runnerRegistry.cjs +1 -1
- package/dist/runnerRegistry.d.mts +2 -2
- package/dist/runnerRegistry.mjs +1 -2
- package/dist/services/lifeline/client.cjs +2 -2
- package/dist/services/lifeline/client.cjs.map +1 -1
- package/dist/services/lifeline/client.d.mts +1 -1
- package/dist/services/lifeline/client.mjs +2 -2
- package/dist/services/lifeline/client.mjs.map +1 -1
- package/dist/{session-Chsb_Nh2.mjs → session-BKYnH4R6.mjs} +2 -2
- package/dist/{session-Chsb_Nh2.mjs.map → session-BKYnH4R6.mjs.map} +1 -1
- package/dist/{session-BC43uEyG.cjs → session-BvqzhXZY.cjs} +2 -2
- package/dist/{session-BC43uEyG.cjs.map → session-BvqzhXZY.cjs.map} +1 -1
- package/dist/session.cjs +1 -1
- package/dist/session.mjs +1 -1
- package/dist/spawner.mjs +1 -2
- package/dist/{type-C31e1gla.d.mts → type-Do0YxwVQ.d.mts} +4 -4
- package/dist/{type-C31e1gla.d.mts.map → type-Do0YxwVQ.d.mts.map} +1 -1
- package/dist/{type-BXM03qSw.d.mts → type-DwMZoINK.d.mts} +8 -8
- package/dist/{type-BXM03qSw.d.mts.map → type-DwMZoINK.d.mts.map} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +31 -34
- package/skills/{doom-runner → po-runner}/SKILL.md +15 -15
- package/src/prompts/po-use-runner/SKILL.md +11 -11
- package/dist/bashResult-DNgtahGR.cjs.map +0 -1
- package/dist/bashResult-bIVSzoj-.mjs.map +0 -1
- package/dist/bashRunService-CJ02XaAq.mjs.map +0 -1
- package/dist/bashRunService-DyqxOSlx.cjs.map +0 -1
- package/dist/cliApp-Dj9nwaOv.cjs.map +0 -1
- package/dist/cliApp-v8Z3rMCi.mjs.map +0 -1
- package/dist/compaction-4QSUsBxq.cjs.map +0 -1
- package/dist/compaction-DCw80VZj.mjs.map +0 -1
- package/dist/headless-BGYfIlNk.mjs.map +0 -1
- package/dist/headless-CHUsBGhg.cjs.map +0 -1
- package/dist/index-BwB_jTI9.d.mts.map +0 -1
- package/dist/index-DBz0DxnL.d.mts.map +0 -1
- package/dist/lifeline-BZaQA0rm.mjs.map +0 -1
- package/dist/lifeline-BuV_erib.cjs.map +0 -1
- package/dist/ptySpawner-DEi1KOnd.mjs.map +0 -1
- package/dist/ptySpawner-ijw0g5_T.cjs.map +0 -1
- package/dist/reconcile-BugwYFbV.cjs.map +0 -1
- package/dist/reconcile-DMeNSxwn.mjs.map +0 -1
- package/dist/rmuxBackend-DfyQwJrc.mjs.map +0 -1
- package/dist/rmuxBackend-DlxgqRZ1.cjs.map +0 -1
- package/dist/rtkProcessor-B9KPdyzr.mjs.map +0 -1
- package/dist/rtkProcessor-Bc4L4o_8.cjs.map +0 -1
- package/dist/runnerConfig-BQBlVAXn.mjs.map +0 -1
- package/dist/runnerConfig-D2tGq5ZM.cjs.map +0 -1
- package/dist/runnerDependencies-DruByBGS.mjs.map +0 -1
- package/dist/runnerDependencies-KMZigIxB.cjs.map +0 -1
- package/dist/runnerPaths-BTEuzxw0.cjs.map +0 -1
- package/dist/runnerPaths-B_dAAeco.mjs.map +0 -1
- package/dist/runnerRegistry-BmkZTJHi.cjs.map +0 -1
- package/dist/runnerRegistry-CeOHEjBv.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
2
|
-
const require_runnerConfig = require("./runnerConfig-
|
|
3
|
-
const require_session = require("./session-
|
|
2
|
+
const require_runnerConfig = require("./runnerConfig-BoLMinlx.cjs");
|
|
3
|
+
const require_session = require("./session-BvqzhXZY.cjs");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
6
6
|
let node_path = require("node:path");
|
|
@@ -8,7 +8,7 @@ node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
|
8
8
|
let node_child_process = require("node:child_process");
|
|
9
9
|
let _agimon_ai_po_core_piSettings = require("@agimon-ai/po-core/piSettings");
|
|
10
10
|
//#region src/constants/runnerPaths.ts
|
|
11
|
-
const STORE_DIR_NAME = "
|
|
11
|
+
const STORE_DIR_NAME = "po-runner";
|
|
12
12
|
const LOG_DIR_NAME = "logs";
|
|
13
13
|
const STATE_DIR_NAME = "runs";
|
|
14
14
|
const LOG_EXTENSION = ".log";
|
|
@@ -156,7 +156,7 @@ async function isEmptySessionAsync(directory) {
|
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
158
|
* The root every session's runner state lives under, before any log-directory
|
|
159
|
-
* override: `<agent dir>/
|
|
159
|
+
* override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in
|
|
160
160
|
* another process, such as the cockpit hub, resolves the same root from its
|
|
161
161
|
* own environment. A relative agent directory resolves against home, not the cwd.
|
|
162
162
|
*/
|
|
@@ -183,7 +183,7 @@ var RunnerPaths = class {
|
|
|
183
183
|
}
|
|
184
184
|
setSessionId(sessionId) {
|
|
185
185
|
const trimmed = sessionId.trim();
|
|
186
|
-
if (!trimmed) throw new Error("
|
|
186
|
+
if (!trimmed) throw new Error("po-runner session id cannot be blank");
|
|
187
187
|
this.adoptedSessionId = trimmed;
|
|
188
188
|
}
|
|
189
189
|
logDirectory(sessionId) {
|
|
@@ -212,13 +212,14 @@ var RunnerPaths = class {
|
|
|
212
212
|
node_fs.default.mkdirSync(this.logDirectory(sessionId), { recursive: true });
|
|
213
213
|
node_fs.default.mkdirSync(this.stateDirectory(sessionId), { recursive: true });
|
|
214
214
|
}
|
|
215
|
-
sweepHistory(ttlMs, now = Date.now()) {
|
|
215
|
+
sweepHistory(ttlMs, now = Date.now(), live = this.liveSessions()) {
|
|
216
216
|
const result = {
|
|
217
217
|
removed: [],
|
|
218
218
|
errors: []
|
|
219
219
|
};
|
|
220
|
-
if (this.env["
|
|
221
|
-
|
|
220
|
+
if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
|
|
221
|
+
const owner = [...live][0] ?? this.sessionId();
|
|
222
|
+
this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);
|
|
222
223
|
return result;
|
|
223
224
|
}
|
|
224
225
|
const root = this.storeDirectory();
|
|
@@ -230,9 +231,8 @@ var RunnerPaths = class {
|
|
|
230
231
|
result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
|
|
231
232
|
return result;
|
|
232
233
|
}
|
|
233
|
-
const active = this.currentSessionId();
|
|
234
234
|
for (const sessionId of sessions) {
|
|
235
|
-
if (sessionId
|
|
235
|
+
if (live.has(sessionId)) {
|
|
236
236
|
this.sweepActiveSession(sessionId, ttlMs, now, result);
|
|
237
237
|
continue;
|
|
238
238
|
}
|
|
@@ -240,13 +240,14 @@ var RunnerPaths = class {
|
|
|
240
240
|
}
|
|
241
241
|
return result;
|
|
242
242
|
}
|
|
243
|
-
async sweepHistoryAsync(ttlMs, now = Date.now()) {
|
|
243
|
+
async sweepHistoryAsync(ttlMs, now = Date.now(), live = this.liveSessions()) {
|
|
244
244
|
const result = {
|
|
245
245
|
removed: [],
|
|
246
246
|
errors: []
|
|
247
247
|
};
|
|
248
|
-
if (this.env["
|
|
249
|
-
|
|
248
|
+
if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
|
|
249
|
+
const owner = [...live][0] ?? this.sessionId();
|
|
250
|
+
await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);
|
|
250
251
|
return result;
|
|
251
252
|
}
|
|
252
253
|
const root = this.storeDirectory();
|
|
@@ -258,9 +259,8 @@ var RunnerPaths = class {
|
|
|
258
259
|
result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
|
|
259
260
|
return result;
|
|
260
261
|
}
|
|
261
|
-
const active = this.currentSessionId();
|
|
262
262
|
for (const sessionId of sessions) {
|
|
263
|
-
if (sessionId
|
|
263
|
+
if (live.has(sessionId)) {
|
|
264
264
|
await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);
|
|
265
265
|
continue;
|
|
266
266
|
}
|
|
@@ -268,30 +268,12 @@ var RunnerPaths = class {
|
|
|
268
268
|
}
|
|
269
269
|
return result;
|
|
270
270
|
}
|
|
271
|
-
legacyDirectory() {
|
|
272
|
-
const commonDirectory = git([
|
|
273
|
-
"rev-parse",
|
|
274
|
-
"--path-format=absolute",
|
|
275
|
-
"--git-common-dir"
|
|
276
|
-
], this.cwd);
|
|
277
|
-
if (!commonDirectory || !git(["rev-parse", "--show-toplevel"], this.cwd)) return void 0;
|
|
278
|
-
return node_path.default.join(realPath(commonDirectory), STORE_DIR_NAME);
|
|
279
|
-
}
|
|
280
|
-
removeLegacyStore() {
|
|
281
|
-
const target = this.legacyDirectory();
|
|
282
|
-
if (!target || node_path.default.basename(target) !== "doom-runner" || !node_fs.default.existsSync(target)) return void 0;
|
|
283
|
-
node_fs.default.rmSync(target, {
|
|
284
|
-
recursive: true,
|
|
285
|
-
force: true
|
|
286
|
-
});
|
|
287
|
-
return target;
|
|
288
|
-
}
|
|
289
271
|
/** The live session, if one is known, so a sweep never deletes underneath itself. */
|
|
290
|
-
|
|
272
|
+
liveSessions() {
|
|
291
273
|
try {
|
|
292
|
-
return this.sessionId();
|
|
274
|
+
return /* @__PURE__ */ new Set([this.sessionId()]);
|
|
293
275
|
} catch {
|
|
294
|
-
return;
|
|
276
|
+
return /* @__PURE__ */ new Set();
|
|
295
277
|
}
|
|
296
278
|
}
|
|
297
279
|
/**
|
|
@@ -357,7 +339,7 @@ var RunnerPaths = class {
|
|
|
357
339
|
}
|
|
358
340
|
sessionId(explicit) {
|
|
359
341
|
const sessionId = explicit?.trim() || this.adoptedSessionId || require_session.inheritedSessionId(this.env);
|
|
360
|
-
if (!sessionId) throw new Error("PI_SESSION_ID is required for
|
|
342
|
+
if (!sessionId) throw new Error("PI_SESSION_ID is required for po-runner storage");
|
|
361
343
|
return sessionId;
|
|
362
344
|
}
|
|
363
345
|
storeDirectory() {
|
|
@@ -468,4 +450,4 @@ Object.defineProperty(exports, "runnerStateDirFor", {
|
|
|
468
450
|
}
|
|
469
451
|
});
|
|
470
452
|
|
|
471
|
-
//# sourceMappingURL=runnerPaths-
|
|
453
|
+
//# sourceMappingURL=runnerPaths-B41rMOY6.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerPaths-B41rMOY6.cjs","names":["execFileSync","fs","path","piAgentDirectory","LOG_DIR_ENV","inheritedSessionId","getMaxCompletedRunners"],"sources":["../src/constants/runnerPaths.ts","../src/services/runnerPaths/index.ts"],"sourcesContent":["export const STORE_DIR_NAME = 'po-runner';\nexport const LOG_DIR_NAME = 'logs';\nexport const STATE_DIR_NAME = 'runs';\nexport const LOG_EXTENSION = '.log';\nexport const STATE_EXTENSION = '.json';\nexport const ROTATED_SUFFIX = '.1';\nexport const RAW_SUFFIX = '.raw';\nexport const PI_CODING_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nexport const FILE_ENCODING = 'utf8';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\nexport const EMPTY_SESSION_GRACE_MS = 300_000;\n","import { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { piAgentDirectory } from '@agimon-ai/po-core/piSettings';\n\nimport { LOG_DIR_ENV } from '../../constants/runnerConfig';\nimport {\n EMPTY_SESSION_GRACE_MS,\n FILE_ENCODING,\n LOG_DIR_NAME,\n LOG_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n RAW_SUFFIX,\n ROTATED_SUFFIX,\n STATE_DIR_NAME,\n STATE_EXTENSION,\n STORE_DIR_NAME,\n} from '../../constants/runnerPaths';\nimport { getMaxCompletedRunners } from '../runnerConfig';\nimport { inheritedSessionId } from '../session';\nimport type { IRunnerPaths, LogSweepResult } from './type';\n\n/** Unscrubbed pane bytes, kept beside the log so an attached terminal can replay them. */\n/**\n * How long an entirely empty session directory is left alone before it counts\n * as an orphan. A session that has started but not yet run anything owns such a\n * directory for a moment, and reclaiming it out from under that session would\n * be churn for no gain.\n */\n\nfunction git(args: string[], cwd: string): string | undefined {\n try {\n const output = execFileSync('git', args, { cwd, encoding: FILE_ENCODING, stdio: ['ignore', 'pipe', 'ignore'] });\n const trimmed = output.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction realPath(target: string): string {\n try {\n return fs.realpathSync(target);\n } catch {\n return target;\n }\n}\n\n/**\n * Newest mtime anywhere one level inside the session, falling back to the\n * directory itself. A session still being written to therefore always looks\n * recent, whatever state its individual records are in.\n */\nfunction newestEntryTime(directory: string): number {\n let newest = fs.statSync(directory).mtimeMs;\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, fs.statSync(target).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of fs.readdirSync(target)) {\n newest = Math.max(newest, fs.statSync(path.join(target, child)).mtimeMs);\n }\n }\n return newest;\n}\n\nasync function newestEntryTimeAsync(directory: string): Promise<number> {\n let newest = (await fs.promises.stat(directory)).mtimeMs;\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, (await fs.promises.stat(target)).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of await fs.promises.readdir(target)) {\n newest = Math.max(newest, (await fs.promises.stat(path.join(target, child))).mtimeMs);\n }\n }\n return newest;\n}\n\n/**\n * Whether any run in this session names a pi process that is still running.\n *\n * One live record is enough: records are only ever written by their owner, so a\n * live host pid means the session is still in use however old its files look.\n */\nfunction ownerAlive(stateDirectory: string): boolean {\n let entries: string[];\n try {\n entries = fs.readdirSync(stateDirectory);\n } catch {\n // No records left to consult, so nothing claims the directory.\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(fs.readFileSync(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nasync function ownerAliveAsync(stateDirectory: string): Promise<boolean> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(stateDirectory);\n } catch {\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nfunction completedAt(value: unknown): number | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as { state?: unknown; exit?: { finishedAt?: unknown } };\n if (record.state !== 'completed' || typeof record.exit?.finishedAt !== 'string') return undefined;\n const timestamp = Date.parse(record.exit.finishedAt);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n}\n\ninterface CompletedRecord {\n readonly id: string;\n readonly statePath: string;\n readonly finishedAt: number;\n}\n\n/**\n * Completed records a sweep may delete: everything past the TTL, and everything\n * beyond the newest `keep`.\n *\n * The count bound is what keeps a live session from growing without limit. Its\n * records only reach a multi-day TTL long after the session that is still\n * writing them would have filled its directory, so age alone bounds nothing\n * while the session lasts.\n */\nfunction expiredCompletedRecords(\n records: readonly CompletedRecord[],\n ttlMs: number,\n now: number,\n keep: number,\n): CompletedRecord[] {\n return [...records]\n .sort((left, right) => right.finishedAt - left.finishedAt)\n .filter((record, index) => index >= keep || now - record.finishedAt > ttlMs);\n}\n\n/**\n * Whether the directory holds no files at all, only empty subdirectories.\n *\n * A session that ran something leaves metadata behind, and a live session keeps\n * its lifeline socket in the state directory, so an entirely empty tree names\n * no owner and no history.\n */\nfunction isEmptySession(directory: string): boolean {\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if (fs.readdirSync(path.join(directory, entry.name)).length > 0) return false;\n }\n return true;\n}\n\nasync function isEmptySessionAsync(directory: string): Promise<boolean> {\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if ((await fs.promises.readdir(path.join(directory, entry.name))).length > 0) return false;\n }\n return true;\n}\n\n/**\n * The root every session's runner state lives under, before any log-directory\n * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in\n * another process, such as the cockpit hub, resolves the same root from its\n * own environment. A relative agent directory resolves against home, not the cwd.\n */\nexport function resolveRunnerStoreDirectory(env: Readonly<Record<string, string | undefined>>): string {\n return path.join(piAgentDirectory(env), STORE_DIR_NAME);\n}\n\n/** Durable metadata directory for one session. Used by APIs and history reads, not live transport. */\nexport function runnerStateDirFor(storeDir: string, sessionId: string): string {\n return path.join(storeDir, sessionId, STATE_DIR_NAME);\n}\n\n/** Session-scoped runner storage under the Pi agent directory. */\nexport class RunnerPaths implements IRunnerPaths {\n private adoptedSessionId: string | undefined;\n private repository: string | undefined;\n\n constructor(\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = { ...process.env },\n ) {}\n\n repositoryPath(): string {\n this.repository ??= realPath(git(['rev-parse', '--show-toplevel'], this.cwd) ?? this.cwd);\n return this.repository;\n }\n\n setSessionId(sessionId: string): void {\n const trimmed = sessionId.trim();\n if (!trimmed) throw new Error('po-runner session id cannot be blank');\n this.adoptedSessionId = trimmed;\n }\n\n logDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.resolve(this.cwd, override);\n return path.join(this.sessionDirectory(sessionId), LOG_DIR_NAME);\n }\n\n stateDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.join(path.resolve(this.cwd, override), '..', STATE_DIR_NAME);\n return path.join(this.sessionDirectory(sessionId), STATE_DIR_NAME);\n }\n\n logPathFor(id: string, sessionId?: string): string {\n return path.join(this.logDirectory(sessionId), `${id}${LOG_EXTENSION}`);\n }\n\n rotatedLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${ROTATED_SUFFIX}`;\n }\n\n rawLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${RAW_SUFFIX}`;\n }\n\n statePathFor(id: string, sessionId?: string): string {\n return path.join(this.stateDirectory(sessionId), `${id}${STATE_EXTENSION}`);\n }\n\n ensureDirectories(sessionId?: string): void {\n fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });\n fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });\n }\n\n sweepHistory(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): LogSweepResult {\n const result: LogSweepResult = { removed: [], errors: [] };\n // A pinned log directory belongs to whoever pinned it, so that branch only\n // ever removes the files this package put there.\n if (this.env[LOG_DIR_ENV]?.trim()) {\n // Without a live session there is no owner to sweep for, as before.\n const owner = [...live][0] ?? this.sessionId();\n this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = fs.readdirSync(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n // Sweeping whole session directories rather than the three files a completed\n // record names is what keeps sockets, sidecars, runs that never reached a\n // terminal state, and the emptied directories themselves from accumulating.\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n this.sweepActiveSession(sessionId, ttlMs, now, result);\n continue;\n }\n this.sweepSessionDirectory(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n async sweepHistoryAsync(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): Promise<LogSweepResult> {\n const result: LogSweepResult = { removed: [], errors: [] };\n if (this.env[LOG_DIR_ENV]?.trim()) {\n const owner = [...live][0] ?? this.sessionId();\n await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = await fs.promises.readdir(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);\n continue;\n }\n await this.sweepSessionDirectoryAsync(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n /** The live session, if one is known, so a sweep never deletes underneath itself. */\n private liveSessions(): ReadonlySet<string> {\n try {\n return new Set([this.sessionId()]);\n } catch {\n // A CLI invocation outside a session still sweeps; it just has nothing to spare.\n return new Set();\n }\n }\n\n /**\n * Retention inside the session that is still running.\n *\n * The whole-directory sweep cannot be pointed at the live session: it would\n * take the lifeline socket, the supervisor sidecars and the running runners'\n * own metadata with it. Per-record retention is safe there because it only\n * ever removes a record whose state is `completed` together with the two log\n * files that record names, and never the directory itself. A running record\n * has no `exit.finishedAt`, so it is not a candidate at any age.\n */\n private sweepActiveSession(sessionId: string, ttlMs: number, now: number, result: LogSweepResult): void {\n this.sweepStateDirectory(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n private async sweepActiveSessionAsync(\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n await this.sweepStateDirectoryAsync(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n /** Removes a session's whole directory once its newest entry is past the TTL. */\n private sweepSessionDirectory(directory: string, ttlMs: number, now: number, result: LogSweepResult): void {\n try {\n const newest = newestEntryTime(directory);\n // An orphan left by a session that never ran anything holds nothing worth\n // a retention window, so it goes as soon as it is clearly not in use.\n if (now - newest > EMPTY_SESSION_GRACE_MS && isEmptySession(directory)) {\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n // An idle session can go quiet for longer than the TTL, and deleting one\n // takes its lifeline socket with it, which would read to its own runners\n // as an owner that had died. Its records name the owner, so ask.\n if (ownerAlive(path.join(directory, STATE_DIR_NAME))) return;\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private async sweepSessionDirectoryAsync(\n directory: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n try {\n const newest = await newestEntryTimeAsync(directory);\n if (now - newest > EMPTY_SESSION_GRACE_MS && (await isEmptySessionAsync(directory))) {\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n if (await ownerAliveAsync(path.join(directory, STATE_DIR_NAME))) return;\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private sessionId(explicit?: string): string {\n const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);\n if (!sessionId) throw new Error('PI_SESSION_ID is required for po-runner storage');\n return sessionId;\n }\n\n storeDirectory(): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.dirname(path.resolve(this.cwd, override));\n return resolveRunnerStoreDirectory(this.env);\n }\n\n private sessionDirectory(sessionId?: string): string {\n return path.join(this.storeDirectory(), this.sessionId(sessionId));\n }\n\n private sweepStateDirectory(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): void {\n let entries: string[];\n try {\n entries = fs.readdirSync(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(fs.readFileSync(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n this.removeHistoryFiles(sessionId, record.id, record.statePath, result);\n }\n }\n\n private async sweepStateDirectoryAsync(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n await this.removeHistoryFilesAsync(sessionId, record.id, record.statePath, result);\n }\n }\n\n private removeHistoryFiles(sessionId: string, id: string, statePath: string, result: LogSweepResult): void {\n const candidates = [\n statePath,\n this.logPathFor(id, sessionId),\n this.rotatedLogPathFor(id, sessionId),\n this.rawLogPathFor(id, sessionId),\n ];\n for (const candidate of candidates) {\n try {\n fs.unlinkSync(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n\n private async removeHistoryFilesAsync(\n sessionId: string,\n id: string,\n statePath: string,\n result: LogSweepResult,\n ): Promise<void> {\n const candidates = [statePath, this.logPathFor(id, sessionId), this.rotatedLogPathFor(id, sessionId)];\n for (const candidate of candidates) {\n try {\n await fs.promises.unlink(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { M as LOG_DIR_ENV, l as getMaxCompletedRunners } from "./runnerConfig-
|
|
2
|
-
import { t as inheritedSessionId } from "./session-
|
|
1
|
+
import { M as LOG_DIR_ENV, l as getMaxCompletedRunners } from "./runnerConfig-XXMq4VQA.mjs";
|
|
2
|
+
import { t as inheritedSessionId } from "./session-BKYnH4R6.mjs";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
6
|
import { piAgentDirectory } from "@agimon-ai/po-core/piSettings";
|
|
7
7
|
//#region src/constants/runnerPaths.ts
|
|
8
|
-
const STORE_DIR_NAME = "
|
|
8
|
+
const STORE_DIR_NAME = "po-runner";
|
|
9
9
|
const LOG_DIR_NAME = "logs";
|
|
10
10
|
const STATE_DIR_NAME = "runs";
|
|
11
11
|
const LOG_EXTENSION = ".log";
|
|
@@ -153,7 +153,7 @@ async function isEmptySessionAsync(directory) {
|
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
155
|
* The root every session's runner state lives under, before any log-directory
|
|
156
|
-
* override: `<agent dir>/
|
|
156
|
+
* override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in
|
|
157
157
|
* another process, such as the cockpit hub, resolves the same root from its
|
|
158
158
|
* own environment. A relative agent directory resolves against home, not the cwd.
|
|
159
159
|
*/
|
|
@@ -180,7 +180,7 @@ var RunnerPaths = class {
|
|
|
180
180
|
}
|
|
181
181
|
setSessionId(sessionId) {
|
|
182
182
|
const trimmed = sessionId.trim();
|
|
183
|
-
if (!trimmed) throw new Error("
|
|
183
|
+
if (!trimmed) throw new Error("po-runner session id cannot be blank");
|
|
184
184
|
this.adoptedSessionId = trimmed;
|
|
185
185
|
}
|
|
186
186
|
logDirectory(sessionId) {
|
|
@@ -209,13 +209,14 @@ var RunnerPaths = class {
|
|
|
209
209
|
fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });
|
|
210
210
|
fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });
|
|
211
211
|
}
|
|
212
|
-
sweepHistory(ttlMs, now = Date.now()) {
|
|
212
|
+
sweepHistory(ttlMs, now = Date.now(), live = this.liveSessions()) {
|
|
213
213
|
const result = {
|
|
214
214
|
removed: [],
|
|
215
215
|
errors: []
|
|
216
216
|
};
|
|
217
|
-
if (this.env["
|
|
218
|
-
|
|
217
|
+
if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
|
|
218
|
+
const owner = [...live][0] ?? this.sessionId();
|
|
219
|
+
this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);
|
|
219
220
|
return result;
|
|
220
221
|
}
|
|
221
222
|
const root = this.storeDirectory();
|
|
@@ -227,9 +228,8 @@ var RunnerPaths = class {
|
|
|
227
228
|
result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
|
|
228
229
|
return result;
|
|
229
230
|
}
|
|
230
|
-
const active = this.currentSessionId();
|
|
231
231
|
for (const sessionId of sessions) {
|
|
232
|
-
if (sessionId
|
|
232
|
+
if (live.has(sessionId)) {
|
|
233
233
|
this.sweepActiveSession(sessionId, ttlMs, now, result);
|
|
234
234
|
continue;
|
|
235
235
|
}
|
|
@@ -237,13 +237,14 @@ var RunnerPaths = class {
|
|
|
237
237
|
}
|
|
238
238
|
return result;
|
|
239
239
|
}
|
|
240
|
-
async sweepHistoryAsync(ttlMs, now = Date.now()) {
|
|
240
|
+
async sweepHistoryAsync(ttlMs, now = Date.now(), live = this.liveSessions()) {
|
|
241
241
|
const result = {
|
|
242
242
|
removed: [],
|
|
243
243
|
errors: []
|
|
244
244
|
};
|
|
245
|
-
if (this.env["
|
|
246
|
-
|
|
245
|
+
if (this.env["PO_RUNNER_LOG_DIR"]?.trim()) {
|
|
246
|
+
const owner = [...live][0] ?? this.sessionId();
|
|
247
|
+
await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);
|
|
247
248
|
return result;
|
|
248
249
|
}
|
|
249
250
|
const root = this.storeDirectory();
|
|
@@ -255,9 +256,8 @@ var RunnerPaths = class {
|
|
|
255
256
|
result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);
|
|
256
257
|
return result;
|
|
257
258
|
}
|
|
258
|
-
const active = this.currentSessionId();
|
|
259
259
|
for (const sessionId of sessions) {
|
|
260
|
-
if (sessionId
|
|
260
|
+
if (live.has(sessionId)) {
|
|
261
261
|
await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);
|
|
262
262
|
continue;
|
|
263
263
|
}
|
|
@@ -265,30 +265,12 @@ var RunnerPaths = class {
|
|
|
265
265
|
}
|
|
266
266
|
return result;
|
|
267
267
|
}
|
|
268
|
-
legacyDirectory() {
|
|
269
|
-
const commonDirectory = git([
|
|
270
|
-
"rev-parse",
|
|
271
|
-
"--path-format=absolute",
|
|
272
|
-
"--git-common-dir"
|
|
273
|
-
], this.cwd);
|
|
274
|
-
if (!commonDirectory || !git(["rev-parse", "--show-toplevel"], this.cwd)) return void 0;
|
|
275
|
-
return path.join(realPath(commonDirectory), STORE_DIR_NAME);
|
|
276
|
-
}
|
|
277
|
-
removeLegacyStore() {
|
|
278
|
-
const target = this.legacyDirectory();
|
|
279
|
-
if (!target || path.basename(target) !== "doom-runner" || !fs.existsSync(target)) return void 0;
|
|
280
|
-
fs.rmSync(target, {
|
|
281
|
-
recursive: true,
|
|
282
|
-
force: true
|
|
283
|
-
});
|
|
284
|
-
return target;
|
|
285
|
-
}
|
|
286
268
|
/** The live session, if one is known, so a sweep never deletes underneath itself. */
|
|
287
|
-
|
|
269
|
+
liveSessions() {
|
|
288
270
|
try {
|
|
289
|
-
return this.sessionId();
|
|
271
|
+
return /* @__PURE__ */ new Set([this.sessionId()]);
|
|
290
272
|
} catch {
|
|
291
|
-
return;
|
|
273
|
+
return /* @__PURE__ */ new Set();
|
|
292
274
|
}
|
|
293
275
|
}
|
|
294
276
|
/**
|
|
@@ -354,7 +336,7 @@ var RunnerPaths = class {
|
|
|
354
336
|
}
|
|
355
337
|
sessionId(explicit) {
|
|
356
338
|
const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);
|
|
357
|
-
if (!sessionId) throw new Error("PI_SESSION_ID is required for
|
|
339
|
+
if (!sessionId) throw new Error("PI_SESSION_ID is required for po-runner storage");
|
|
358
340
|
return sessionId;
|
|
359
341
|
}
|
|
360
342
|
storeDirectory() {
|
|
@@ -448,4 +430,4 @@ var RunnerPaths = class {
|
|
|
448
430
|
//#endregion
|
|
449
431
|
export { resolveRunnerStoreDirectory as n, runnerStateDirFor as r, RunnerPaths as t };
|
|
450
432
|
|
|
451
|
-
//# sourceMappingURL=runnerPaths-
|
|
433
|
+
//# sourceMappingURL=runnerPaths-Dibbvyx_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerPaths-Dibbvyx_.mjs","names":[],"sources":["../src/constants/runnerPaths.ts","../src/services/runnerPaths/index.ts"],"sourcesContent":["export const STORE_DIR_NAME = 'po-runner';\nexport const LOG_DIR_NAME = 'logs';\nexport const STATE_DIR_NAME = 'runs';\nexport const LOG_EXTENSION = '.log';\nexport const STATE_EXTENSION = '.json';\nexport const ROTATED_SUFFIX = '.1';\nexport const RAW_SUFFIX = '.raw';\nexport const PI_CODING_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nexport const FILE_ENCODING = 'utf8';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\nexport const EMPTY_SESSION_GRACE_MS = 300_000;\n","import { execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { piAgentDirectory } from '@agimon-ai/po-core/piSettings';\n\nimport { LOG_DIR_ENV } from '../../constants/runnerConfig';\nimport {\n EMPTY_SESSION_GRACE_MS,\n FILE_ENCODING,\n LOG_DIR_NAME,\n LOG_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n RAW_SUFFIX,\n ROTATED_SUFFIX,\n STATE_DIR_NAME,\n STATE_EXTENSION,\n STORE_DIR_NAME,\n} from '../../constants/runnerPaths';\nimport { getMaxCompletedRunners } from '../runnerConfig';\nimport { inheritedSessionId } from '../session';\nimport type { IRunnerPaths, LogSweepResult } from './type';\n\n/** Unscrubbed pane bytes, kept beside the log so an attached terminal can replay them. */\n/**\n * How long an entirely empty session directory is left alone before it counts\n * as an orphan. A session that has started but not yet run anything owns such a\n * directory for a moment, and reclaiming it out from under that session would\n * be churn for no gain.\n */\n\nfunction git(args: string[], cwd: string): string | undefined {\n try {\n const output = execFileSync('git', args, { cwd, encoding: FILE_ENCODING, stdio: ['ignore', 'pipe', 'ignore'] });\n const trimmed = output.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction realPath(target: string): string {\n try {\n return fs.realpathSync(target);\n } catch {\n return target;\n }\n}\n\n/**\n * Newest mtime anywhere one level inside the session, falling back to the\n * directory itself. A session still being written to therefore always looks\n * recent, whatever state its individual records are in.\n */\nfunction newestEntryTime(directory: string): number {\n let newest = fs.statSync(directory).mtimeMs;\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, fs.statSync(target).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of fs.readdirSync(target)) {\n newest = Math.max(newest, fs.statSync(path.join(target, child)).mtimeMs);\n }\n }\n return newest;\n}\n\nasync function newestEntryTimeAsync(directory: string): Promise<number> {\n let newest = (await fs.promises.stat(directory)).mtimeMs;\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n const target = path.join(directory, entry.name);\n newest = Math.max(newest, (await fs.promises.stat(target)).mtimeMs);\n if (!entry.isDirectory()) continue;\n for (const child of await fs.promises.readdir(target)) {\n newest = Math.max(newest, (await fs.promises.stat(path.join(target, child))).mtimeMs);\n }\n }\n return newest;\n}\n\n/**\n * Whether any run in this session names a pi process that is still running.\n *\n * One live record is enough: records are only ever written by their owner, so a\n * live host pid means the session is still in use however old its files look.\n */\nfunction ownerAlive(stateDirectory: string): boolean {\n let entries: string[];\n try {\n entries = fs.readdirSync(stateDirectory);\n } catch {\n // No records left to consult, so nothing claims the directory.\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(fs.readFileSync(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nasync function ownerAliveAsync(stateDirectory: string): Promise<boolean> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(stateDirectory);\n } catch {\n return false;\n }\n\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(path.join(stateDirectory, entry), FILE_ENCODING));\n const hostPid = (value as { hostPid?: unknown }).hostPid;\n if (typeof hostPid !== 'number') continue;\n process.kill(hostPid, 0);\n return true;\n } catch {\n // An unreadable record and a dead pid mean the same thing here: no claim.\n }\n }\n return false;\n}\n\nfunction completedAt(value: unknown): number | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as { state?: unknown; exit?: { finishedAt?: unknown } };\n if (record.state !== 'completed' || typeof record.exit?.finishedAt !== 'string') return undefined;\n const timestamp = Date.parse(record.exit.finishedAt);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n}\n\ninterface CompletedRecord {\n readonly id: string;\n readonly statePath: string;\n readonly finishedAt: number;\n}\n\n/**\n * Completed records a sweep may delete: everything past the TTL, and everything\n * beyond the newest `keep`.\n *\n * The count bound is what keeps a live session from growing without limit. Its\n * records only reach a multi-day TTL long after the session that is still\n * writing them would have filled its directory, so age alone bounds nothing\n * while the session lasts.\n */\nfunction expiredCompletedRecords(\n records: readonly CompletedRecord[],\n ttlMs: number,\n now: number,\n keep: number,\n): CompletedRecord[] {\n return [...records]\n .sort((left, right) => right.finishedAt - left.finishedAt)\n .filter((record, index) => index >= keep || now - record.finishedAt > ttlMs);\n}\n\n/**\n * Whether the directory holds no files at all, only empty subdirectories.\n *\n * A session that ran something leaves metadata behind, and a live session keeps\n * its lifeline socket in the state directory, so an entirely empty tree names\n * no owner and no history.\n */\nfunction isEmptySession(directory: string): boolean {\n for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if (fs.readdirSync(path.join(directory, entry.name)).length > 0) return false;\n }\n return true;\n}\n\nasync function isEmptySessionAsync(directory: string): Promise<boolean> {\n for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n if (!entry.isDirectory()) return false;\n if ((await fs.promises.readdir(path.join(directory, entry.name))).length > 0) return false;\n }\n return true;\n}\n\n/**\n * The root every session's runner state lives under, before any log-directory\n * override: `<agent dir>/po-runner/<session id>/{runs,logs}`. A reader in\n * another process, such as the cockpit hub, resolves the same root from its\n * own environment. A relative agent directory resolves against home, not the cwd.\n */\nexport function resolveRunnerStoreDirectory(env: Readonly<Record<string, string | undefined>>): string {\n return path.join(piAgentDirectory(env), STORE_DIR_NAME);\n}\n\n/** Durable metadata directory for one session. Used by APIs and history reads, not live transport. */\nexport function runnerStateDirFor(storeDir: string, sessionId: string): string {\n return path.join(storeDir, sessionId, STATE_DIR_NAME);\n}\n\n/** Session-scoped runner storage under the Pi agent directory. */\nexport class RunnerPaths implements IRunnerPaths {\n private adoptedSessionId: string | undefined;\n private repository: string | undefined;\n\n constructor(\n private readonly cwd: string = process.cwd(),\n private readonly env: Readonly<Record<string, string | undefined>> = { ...process.env },\n ) {}\n\n repositoryPath(): string {\n this.repository ??= realPath(git(['rev-parse', '--show-toplevel'], this.cwd) ?? this.cwd);\n return this.repository;\n }\n\n setSessionId(sessionId: string): void {\n const trimmed = sessionId.trim();\n if (!trimmed) throw new Error('po-runner session id cannot be blank');\n this.adoptedSessionId = trimmed;\n }\n\n logDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.resolve(this.cwd, override);\n return path.join(this.sessionDirectory(sessionId), LOG_DIR_NAME);\n }\n\n stateDirectory(sessionId?: string): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.join(path.resolve(this.cwd, override), '..', STATE_DIR_NAME);\n return path.join(this.sessionDirectory(sessionId), STATE_DIR_NAME);\n }\n\n logPathFor(id: string, sessionId?: string): string {\n return path.join(this.logDirectory(sessionId), `${id}${LOG_EXTENSION}`);\n }\n\n rotatedLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${ROTATED_SUFFIX}`;\n }\n\n rawLogPathFor(id: string, sessionId?: string): string {\n return `${this.logPathFor(id, sessionId)}${RAW_SUFFIX}`;\n }\n\n statePathFor(id: string, sessionId?: string): string {\n return path.join(this.stateDirectory(sessionId), `${id}${STATE_EXTENSION}`);\n }\n\n ensureDirectories(sessionId?: string): void {\n fs.mkdirSync(this.logDirectory(sessionId), { recursive: true });\n fs.mkdirSync(this.stateDirectory(sessionId), { recursive: true });\n }\n\n sweepHistory(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): LogSweepResult {\n const result: LogSweepResult = { removed: [], errors: [] };\n // A pinned log directory belongs to whoever pinned it, so that branch only\n // ever removes the files this package put there.\n if (this.env[LOG_DIR_ENV]?.trim()) {\n // Without a live session there is no owner to sweep for, as before.\n const owner = [...live][0] ?? this.sessionId();\n this.sweepStateDirectory(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = fs.readdirSync(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n // Sweeping whole session directories rather than the three files a completed\n // record names is what keeps sockets, sidecars, runs that never reached a\n // terminal state, and the emptied directories themselves from accumulating.\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n this.sweepActiveSession(sessionId, ttlMs, now, result);\n continue;\n }\n this.sweepSessionDirectory(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n async sweepHistoryAsync(\n ttlMs: number,\n now: number = Date.now(),\n live: ReadonlySet<string> = this.liveSessions(),\n ): Promise<LogSweepResult> {\n const result: LogSweepResult = { removed: [], errors: [] };\n if (this.env[LOG_DIR_ENV]?.trim()) {\n const owner = [...live][0] ?? this.sessionId();\n await this.sweepStateDirectoryAsync(this.stateDirectory(owner), owner, ttlMs, now, result);\n return result;\n }\n\n const root = this.storeDirectory();\n let sessions: string[];\n try {\n sessions = await fs.promises.readdir(root);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n result.errors.push(`Could not read runner history directory ${root}: ${String(error)}`);\n return result;\n }\n\n for (const sessionId of sessions) {\n if (live.has(sessionId)) {\n await this.sweepActiveSessionAsync(sessionId, ttlMs, now, result);\n continue;\n }\n await this.sweepSessionDirectoryAsync(path.join(root, sessionId), ttlMs, now, result);\n }\n return result;\n }\n\n /** The live session, if one is known, so a sweep never deletes underneath itself. */\n private liveSessions(): ReadonlySet<string> {\n try {\n return new Set([this.sessionId()]);\n } catch {\n // A CLI invocation outside a session still sweeps; it just has nothing to spare.\n return new Set();\n }\n }\n\n /**\n * Retention inside the session that is still running.\n *\n * The whole-directory sweep cannot be pointed at the live session: it would\n * take the lifeline socket, the supervisor sidecars and the running runners'\n * own metadata with it. Per-record retention is safe there because it only\n * ever removes a record whose state is `completed` together with the two log\n * files that record names, and never the directory itself. A running record\n * has no `exit.finishedAt`, so it is not a candidate at any age.\n */\n private sweepActiveSession(sessionId: string, ttlMs: number, now: number, result: LogSweepResult): void {\n this.sweepStateDirectory(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n private async sweepActiveSessionAsync(\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n await this.sweepStateDirectoryAsync(this.stateDirectory(sessionId), sessionId, ttlMs, now, result);\n }\n\n /** Removes a session's whole directory once its newest entry is past the TTL. */\n private sweepSessionDirectory(directory: string, ttlMs: number, now: number, result: LogSweepResult): void {\n try {\n const newest = newestEntryTime(directory);\n // An orphan left by a session that never ran anything holds nothing worth\n // a retention window, so it goes as soon as it is clearly not in use.\n if (now - newest > EMPTY_SESSION_GRACE_MS && isEmptySession(directory)) {\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n // An idle session can go quiet for longer than the TTL, and deleting one\n // takes its lifeline socket with it, which would read to its own runners\n // as an owner that had died. Its records name the owner, so ask.\n if (ownerAlive(path.join(directory, STATE_DIR_NAME))) return;\n fs.rmSync(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private async sweepSessionDirectoryAsync(\n directory: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n try {\n const newest = await newestEntryTimeAsync(directory);\n if (now - newest > EMPTY_SESSION_GRACE_MS && (await isEmptySessionAsync(directory))) {\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n return;\n }\n if (now - newest <= ttlMs) return;\n if (await ownerAliveAsync(path.join(directory, STATE_DIR_NAME))) return;\n await fs.promises.rm(directory, { recursive: true, force: true });\n result.removed.push(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not sweep runner session ${directory}: ${String(error)}`);\n }\n }\n }\n\n private sessionId(explicit?: string): string {\n const sessionId = explicit?.trim() || this.adoptedSessionId || inheritedSessionId(this.env);\n if (!sessionId) throw new Error('PI_SESSION_ID is required for po-runner storage');\n return sessionId;\n }\n\n storeDirectory(): string {\n const override = this.env[LOG_DIR_ENV]?.trim();\n if (override) return path.dirname(path.resolve(this.cwd, override));\n return resolveRunnerStoreDirectory(this.env);\n }\n\n private sessionDirectory(sessionId?: string): string {\n return path.join(this.storeDirectory(), this.sessionId(sessionId));\n }\n\n private sweepStateDirectory(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): void {\n let entries: string[];\n try {\n entries = fs.readdirSync(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(fs.readFileSync(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n this.removeHistoryFiles(sessionId, record.id, record.statePath, result);\n }\n }\n\n private async sweepStateDirectoryAsync(\n directory: string,\n sessionId: string,\n ttlMs: number,\n now: number,\n result: LogSweepResult,\n ): Promise<void> {\n let entries: string[];\n try {\n entries = await fs.promises.readdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not read runner state directory ${directory}: ${String(error)}`);\n }\n return;\n }\n\n const completed: CompletedRecord[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(STATE_EXTENSION)) continue;\n const statePath = path.join(directory, entry);\n try {\n const value: unknown = JSON.parse(await fs.promises.readFile(statePath, FILE_ENCODING));\n const finishedAt = completedAt(value);\n if (finishedAt === undefined) continue;\n completed.push({ id: entry.slice(0, -STATE_EXTENSION.length), statePath, finishedAt });\n } catch (error) {\n result.errors.push(`Could not sweep runner metadata ${statePath}: ${String(error)}`);\n }\n }\n\n for (const record of expiredCompletedRecords(completed, ttlMs, now, getMaxCompletedRunners(this.env))) {\n await this.removeHistoryFilesAsync(sessionId, record.id, record.statePath, result);\n }\n }\n\n private removeHistoryFiles(sessionId: string, id: string, statePath: string, result: LogSweepResult): void {\n const candidates = [\n statePath,\n this.logPathFor(id, sessionId),\n this.rotatedLogPathFor(id, sessionId),\n this.rawLogPathFor(id, sessionId),\n ];\n for (const candidate of candidates) {\n try {\n fs.unlinkSync(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n\n private async removeHistoryFilesAsync(\n sessionId: string,\n id: string,\n statePath: string,\n result: LogSweepResult,\n ): Promise<void> {\n const candidates = [statePath, this.logPathFor(id, sessionId), this.rotatedLogPathFor(id, sessionId)];\n for (const candidate of candidates) {\n try {\n await fs.promises.unlink(candidate);\n result.removed.push(candidate);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n result.errors.push(`Could not remove runner history ${candidate}: ${String(error)}`);\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/runnerPaths.cjs
CHANGED
package/dist/runnerPaths.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as LogSweepResult, t as IRunnerPaths } from "./type-
|
|
1
|
+
import { n as LogSweepResult, t as IRunnerPaths } from "./type-DwMZoINK.mjs";
|
|
2
2
|
//#region src/services/runnerPaths/index.d.ts
|
|
3
3
|
/** Session-scoped runner storage under the Pi agent directory. */
|
|
4
4
|
export declare class RunnerPaths implements IRunnerPaths {
|
|
@@ -16,12 +16,10 @@ export declare class RunnerPaths implements IRunnerPaths {
|
|
|
16
16
|
rawLogPathFor(id: string, sessionId?: string): string;
|
|
17
17
|
statePathFor(id: string, sessionId?: string): string;
|
|
18
18
|
ensureDirectories(sessionId?: string): void;
|
|
19
|
-
sweepHistory(ttlMs: number, now?: number): LogSweepResult;
|
|
20
|
-
sweepHistoryAsync(ttlMs: number, now?: number): Promise<LogSweepResult>;
|
|
21
|
-
legacyDirectory(): string | undefined;
|
|
22
|
-
removeLegacyStore(): string | undefined;
|
|
19
|
+
sweepHistory(ttlMs: number, now?: number, live?: ReadonlySet<string>): LogSweepResult;
|
|
20
|
+
sweepHistoryAsync(ttlMs: number, now?: number, live?: ReadonlySet<string>): Promise<LogSweepResult>;
|
|
23
21
|
/** The live session, if one is known, so a sweep never deletes underneath itself. */
|
|
24
|
-
private
|
|
22
|
+
private liveSessions;
|
|
25
23
|
/**
|
|
26
24
|
* Retention inside the session that is still running.
|
|
27
25
|
*
|
|
@@ -38,7 +36,7 @@ export declare class RunnerPaths implements IRunnerPaths {
|
|
|
38
36
|
private sweepSessionDirectory;
|
|
39
37
|
private sweepSessionDirectoryAsync;
|
|
40
38
|
private sessionId;
|
|
41
|
-
|
|
39
|
+
storeDirectory(): string;
|
|
42
40
|
private sessionDirectory;
|
|
43
41
|
private sweepStateDirectory;
|
|
44
42
|
private sweepStateDirectoryAsync;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerPaths.d.mts","names":[],"sources":["../src/services/runnerPaths/index.ts"],"mappings":";;;qBA8Ma,uBAAuB;mBAKf;mBACA;UALX;UACA;EAER,YACmB,cACA,MAAK,SAAS;EAGjC;EAKA,aAAa;EAMb,aAAa;EAMb,eAAe;EAMf,WAAW,YAAY;EAIvB,kBAAkB,YAAY;EAI9B,cAAc,YAAY;EAI1B,aAAa,YAAY;EAIzB,kBAAkB;EAKlB,
|
|
1
|
+
{"version":3,"file":"runnerPaths.d.mts","names":[],"sources":["../src/services/runnerPaths/index.ts"],"mappings":";;;qBA8Ma,uBAAuB;mBAKf;mBACA;UALX;UACA;EAER,YACmB,cACA,MAAK,SAAS;EAGjC;EAKA,aAAa;EAMb,aAAa;EAMb,eAAe;EAMf,WAAW,YAAY;EAIvB,kBAAkB,YAAY;EAI9B,cAAc,YAAY;EAI1B,aAAa,YAAY;EAIzB,kBAAkB;EAKlB,aACE,eACA,cACA,OAAM,sBACL;EAiCG,kBACJ,eACA,cACA,OAAM,sBACL,QAAQ;;UA6BH;;;;;;;;;;;UAmBA;UAIM;;UAUN;UAwBM;UAwBN;EAMR;UAMQ;UAIA;UAoCM;UAoCN;UAmBM"}
|
package/dist/runnerPaths.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { RunnerPaths };
|
|
1
|
+
export { t as RunnerPaths } from "./runnerPaths-Dibbvyx_.mjs";
|
|
@@ -6,8 +6,8 @@ import { createProcessRegistryService, normalizeRepositoryPath, resolveProcessTa
|
|
|
6
6
|
import { resolveRootSessionId } from "@agimon-ai/po-core/childProcess";
|
|
7
7
|
//#region src/constants/runnerRegistry.ts
|
|
8
8
|
const SERVICE_TYPE = "tool";
|
|
9
|
-
const SERVICE_PREFIX = "
|
|
10
|
-
const RUNNER_TAG = "
|
|
9
|
+
const SERVICE_PREFIX = "po-runner:";
|
|
10
|
+
const RUNNER_TAG = "po-runner";
|
|
11
11
|
const REGISTRY_PATH_ENV = "PROCESS_REGISTRY_PATH";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/services/runnerRecord/index.ts
|
|
@@ -25,9 +25,16 @@ function formatRunnerFinished(record) {
|
|
|
25
25
|
`Background runner ${record.name} exited: ${outcome}${code}.`,
|
|
26
26
|
`Runner ID: ${record.id}`,
|
|
27
27
|
`Log: ${record.logPath}`,
|
|
28
|
-
`Inspect:
|
|
28
|
+
`Inspect: po-runner logs ${record.id}`
|
|
29
29
|
].join("\n");
|
|
30
30
|
}
|
|
31
|
+
/** The one line the person sees in the transcript for the same exit. */
|
|
32
|
+
function formatRunnerFinishedNotice(record) {
|
|
33
|
+
const reason = record.exit?.reason ?? record.state;
|
|
34
|
+
const code = record.exit?.code === null || record.exit?.code === void 0 ? "" : `exit ${record.exit.code}`;
|
|
35
|
+
const outcome = reason === "completed" ? code : [reason, code].filter(Boolean).join(", ");
|
|
36
|
+
return `Background runner ${record.name} finished${outcome ? ` · ${outcome}` : ""}`;
|
|
37
|
+
}
|
|
31
38
|
/** Compact footer text. An absent value removes the group entirely. */
|
|
32
39
|
function formatRunnerStatus(count) {
|
|
33
40
|
return count > 0 ? `Runners ${count} ●` : void 0;
|
|
@@ -150,12 +157,6 @@ var RunnerRegistry = class {
|
|
|
150
157
|
tags: resolveProcessTags([RUNNER_TAG])
|
|
151
158
|
})).map(toRunnerRecord);
|
|
152
159
|
}
|
|
153
|
-
async listAcrossRepositories() {
|
|
154
|
-
return (await this.registry.listProcesses({
|
|
155
|
-
serviceType: SERVICE_TYPE,
|
|
156
|
-
tags: resolveProcessTags([RUNNER_TAG])
|
|
157
|
-
})).map(toRunnerRecord);
|
|
158
|
-
}
|
|
159
160
|
async listBySession(sessionId) {
|
|
160
161
|
return (await this.list()).filter((record) => record.sessionId === sessionId);
|
|
161
162
|
}
|
|
@@ -334,6 +335,6 @@ function isPrimaryMetadataEntry(entry) {
|
|
|
334
335
|
return entry.endsWith(".json") && !entry.endsWith(".command.json") && !entry.endsWith(".exit.json");
|
|
335
336
|
}
|
|
336
337
|
//#endregion
|
|
337
|
-
export {
|
|
338
|
+
export { formatRunnerStatus as a, formatRunnerFinishedNotice as i, createDefaultProcessRegistry as n, isRunnerRecord as o, formatRunnerFinished as r, REGISTRY_PATH_ENV as s, RunnerRegistry as t };
|
|
338
339
|
|
|
339
|
-
//# sourceMappingURL=runnerRegistry-
|
|
340
|
+
//# sourceMappingURL=runnerRegistry-BgaR5O86.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerRegistry-BgaR5O86.mjs","names":[],"sources":["../src/constants/runnerRegistry.ts","../src/services/runnerRecord/index.ts","../src/services/runnerRegistry/index.ts"],"sourcesContent":["export const SERVICE_TYPE = 'tool';\nexport const SERVICE_PREFIX = 'po-runner:';\nexport const RUNNER_TAG = 'po-runner';\nexport const REGISTRY_PATH_ENV = 'PROCESS_REGISTRY_PATH';\nexport const JSON_EXTENSION = '.json';\nexport const COMMAND_SIDECAR_SUFFIX = '.command.json';\nexport const EXIT_SIDECAR_SUFFIX = '.exit.json';\nexport const NOT_FOUND_ERROR_CODE = 'ENOENT';\n","import type { RunnerRecord } from '../../types/runnerRegistry';\n\n/** The disk record's shape guard, shared by the registry and every reader of its files. */\nexport function isRunnerRecord(value: unknown): value is RunnerRecord {\n if (typeof value !== 'object' || value === null) return false;\n const record = value as Partial<RunnerRecord>;\n return (\n typeof record.id === 'string' &&\n typeof record.name === 'string' &&\n typeof record.pid === 'number' &&\n typeof record.command === 'string' &&\n typeof record.cwd === 'string' &&\n typeof record.logPath === 'string' &&\n typeof record.sessionId === 'string' &&\n typeof record.startedAt === 'string' &&\n (record.state === 'running' || record.state === 'completed') &&\n typeof record.promoted === 'boolean' &&\n (record.backend === 'rmux' || record.backend === 'tmux' || record.backend === 'native')\n );\n}\n\n/** What the agent reads when a runner it sent to the background exits. Shared by the Pi and server hosts. */\nexport function formatRunnerFinished(record: RunnerRecord): string {\n const outcome = record.exit?.reason ?? record.state;\n const code = record.exit?.code === null || record.exit?.code === undefined ? '' : `, exit code ${record.exit.code}`;\n return [\n `Background runner ${record.name} exited: ${outcome}${code}.`,\n `Runner ID: ${record.id}`,\n `Log: ${record.logPath}`,\n `Inspect: po-runner logs ${record.id}`,\n ].join('\\n');\n}\n\n/** The one line the person sees in the transcript for the same exit. */\nexport function formatRunnerFinishedNotice(record: RunnerRecord): string {\n const reason = record.exit?.reason ?? record.state;\n const code = record.exit?.code === null || record.exit?.code === undefined ? '' : `exit ${record.exit.code}`;\n const outcome = reason === 'completed' ? code : [reason, code].filter(Boolean).join(', ');\n return `Background runner ${record.name} finished${outcome ? ` · ${outcome}` : ''}`;\n}\n/** Compact footer text. An absent value removes the group entirely. */\nexport function formatRunnerStatus(count: number): string | undefined {\n return count > 0 ? `Runners ${count} ●` : undefined;\n}\n\nexport function formatRunnerFooterContribution(count: number): { fullText: string; compactText: string } | undefined {\n return count > 0 ? { fullText: `Runner ${count}`, compactText: `R${count}` } : undefined;\n}\n","import { execFile } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport {\n createProcessRegistryService,\n normalizeRepositoryPath,\n type ProcessRegistryRecord,\n type ProcessRegistryService,\n resolveProcessTags,\n} from '@agimon-ai/foundation-process-registry';\nimport { resolveRootSessionId } from '@agimon-ai/po-core/childProcess';\n\nimport {\n COMMAND_SIDECAR_SUFFIX,\n EXIT_SIDECAR_SUFFIX,\n JSON_EXTENSION,\n NOT_FOUND_ERROR_CODE,\n REGISTRY_PATH_ENV,\n RUNNER_TAG,\n SERVICE_PREFIX,\n SERVICE_TYPE,\n} from '../../constants/runnerRegistry';\nimport type { IProcessControl } from '../../types/processControl';\nimport type {\n CompleteRunnerInput,\n IRunnerRegistry,\n RegisterRunnerInput,\n RunnerRecord,\n RunnerTerminationIntent,\n} from '../../types/runnerRegistry';\nimport type { IRunnerPaths } from '../runnerPaths/type';\nimport { isRunnerRecord } from '../runnerRecord';\n\n/** The slice of the shared registry service this wrapper depends on. */\nexport type ProcessRegistryPort = Pick<\n ProcessRegistryService,\n 'registerProcess' | 'releaseProcess' | 'listProcesses' | 'close'\n>;\n\n/** Opens the SQLite-backed registry the rest of the monorepo already shares. */\nexport function createDefaultProcessRegistry(\n env: Readonly<Record<string, string | undefined>> = process.env,\n): ProcessRegistryPort {\n return createProcessRegistryService(env[REGISTRY_PATH_ENV]);\n}\n\nfunction sessionTag(sessionId: string): string {\n return `session:${sessionId}`;\n}\n\nfunction readString(record: ProcessRegistryRecord, key: string): string {\n const value = record.metadata?.[key];\n return typeof value === 'string' ? value : '';\n}\n\nfunction readNumber(record: ProcessRegistryRecord, key: string): number {\n const value = record.metadata?.[key];\n return typeof value === 'number' ? value : 0;\n}\n\nconst runCommand = promisify(execFile);\n\n/**\n * The process start time the registry stores to prove a pid is still the\n * process it registered.\n *\n * The registry resolves it itself when the caller omits it, and it does so with\n * `execFileSync`, which stops this process for the length of a `ps` on every\n * runner that starts. Reading it here costs the same subprocess and blocks\n * nothing: the command is already running by the time a runner is registered.\n *\n * The value has to match what the registry would have read, so the command and\n * the trimming are deliberately identical to its own.\n */\nasync function processStartedAt(pid: number): Promise<string | undefined> {\n if (process.platform === 'win32') return undefined;\n try {\n const { stdout } = await runCommand('ps', ['-o', 'lstart=', '-p', String(pid)], { encoding: 'utf8' });\n return stdout.trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ListenerRegistration = Readonly<{ key: string; listener: () => void }>;\n\n// Server plugin replacement can leave an in-flight tool and its publisher on different registry instances.\nconst listenersBySession = new Map<string, Set<() => void>>();\n\nexport class RunnerRegistry implements IRunnerRegistry {\n private readonly subscriptions = new Set<ListenerRegistration>();\n\n constructor(\n private readonly paths: IRunnerPaths,\n private readonly processControl: IProcessControl,\n private readonly registry: ProcessRegistryPort,\n private readonly environment: Readonly<Record<string, string | undefined>>,\n ) {}\n\n async register(input: RegisterRunnerInput): Promise<RunnerRecord> {\n const startedAt = new Date().toISOString();\n const rootSessionId = resolveRootSessionId(input.sessionId, this.environment);\n const identity = await processStartedAt(input.pid);\n const response = await this.registry.registerProcess({\n repositoryPath: this.repositoryPath(),\n serviceName: `${SERVICE_PREFIX}${input.id}`,\n serviceType: SERVICE_TYPE,\n pid: input.pid,\n command: input.command,\n ...(identity === undefined ? {} : { processStartedAt: identity }),\n tags: resolveProcessTags([RUNNER_TAG, `runner:${input.id}`, sessionTag(input.sessionId)]),\n metadata: {\n id: input.id,\n name: input.name,\n command: input.command,\n cwd: input.cwd,\n logPath: input.logPath,\n interactive: input.interactive,\n sessionId: input.sessionId,\n rootSessionId,\n backend: input.backend,\n ...(input.backendTarget ? { backendTarget: input.backendTarget } : {}),\n startedAt,\n hostPid: process.pid,\n },\n // The caller has already resolved name collisions against live records,\n // so anything still holding this name is stale.\n force: true,\n });\n if (!response.success) throw new Error(response.error ?? `Failed to register runner ${input.name}`);\n const record: RunnerRecord = {\n id: input.id,\n name: input.name,\n pid: input.pid,\n command: input.command,\n cwd: input.cwd,\n logPath: input.logPath,\n interactive: input.interactive,\n sessionId: input.sessionId,\n rootSessionId,\n startedAt,\n state: 'running',\n promoted: false,\n backend: input.backend,\n ...(input.backendTarget ? { backendTarget: input.backendTarget } : {}),\n hostPid: process.pid,\n };\n this.writeRecord(record);\n this.notify(record.sessionId);\n return record;\n }\n\n async list(): Promise<RunnerRecord[]> {\n const records = await this.registry.listProcesses({\n repositoryPath: this.repositoryPath(),\n serviceType: SERVICE_TYPE,\n tags: resolveProcessTags([RUNNER_TAG]),\n });\n return records.map(toRunnerRecord);\n }\n\n async listBySession(sessionId: string): Promise<RunnerRecord[]> {\n const records = await this.list();\n return records.filter((record) => record.sessionId === sessionId);\n }\n\n async listByRootSession(rootSessionId: string): Promise<RunnerRecord[]> {\n const records = await this.list();\n return records.filter((record) => (record.rootSessionId ?? record.sessionId) === rootSessionId);\n }\n\n async listAll(sessionId?: string): Promise<RunnerRecord[]> {\n this.paths.ensureDirectories(sessionId);\n const records: RunnerRecord[] = [];\n const directory = this.paths.stateDirectory(sessionId);\n for (const entry of fs.readdirSync(directory)) {\n if (!isPrimaryMetadataEntry(entry)) continue;\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(`${directory}/${entry}`, 'utf8'));\n if (isRunnerRecord(parsed)) records.push(parsed);\n } catch (error) {\n process.emitWarning(`Could not read runner metadata ${entry}: ${String(error)}`);\n }\n }\n return records.sort((left, right) => right.startedAt.localeCompare(left.startedAt));\n }\n\n async get(id: string, sessionId?: string): Promise<RunnerRecord | undefined> {\n const target = this.paths.statePathFor(id, sessionId);\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(target, 'utf8'));\n if (!isRunnerRecord(parsed) || parsed.id !== id) {\n process.emitWarning(`Could not read runner metadata ${path.basename(target)}: invalid runner record`);\n return undefined;\n }\n return parsed;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return undefined;\n process.emitWarning(`Could not read runner metadata ${path.basename(target)}: ${String(error)}`);\n return undefined;\n }\n }\n\n async markPromoted(id: string): Promise<RunnerRecord | undefined> {\n const record = await this.get(id);\n if (!record) return undefined;\n const promoted = { ...record, promoted: true };\n this.writeRecord(promoted);\n this.notify(promoted.sessionId);\n return promoted;\n }\n\n async requestTermination(\n id: string,\n intent: RunnerTerminationIntent | undefined,\n sessionId?: string,\n ): Promise<RunnerRecord | undefined> {\n const record = await this.get(id, sessionId);\n if (!record) return undefined;\n if (record.state === 'completed') return record;\n if (intent !== undefined && record.terminationIntent !== undefined) return record;\n const { terminationIntent: _previous, ...rest } = record;\n const updated: RunnerRecord = { ...rest, ...(intent ? { terminationIntent: intent } : {}) };\n this.writeRecord(updated);\n return updated;\n }\n\n async complete(id: string, outcome: CompleteRunnerInput, sessionId?: string): Promise<RunnerRecord | undefined> {\n const persisted = await this.get(id, sessionId);\n if (persisted?.state === 'completed') {\n await this.release(id, persisted.sessionId);\n return persisted;\n }\n const active = await this.list();\n const record =\n persisted ??\n active.find((candidate) => candidate.id === id && (sessionId === undefined || candidate.sessionId === sessionId));\n if (!record) {\n const belongsToAnotherSession =\n sessionId !== undefined && active.some((candidate) => candidate.id === id && candidate.sessionId !== sessionId);\n if (!belongsToAnotherSession) await this.release(id, sessionId);\n return undefined;\n }\n const completed: RunnerRecord = {\n ...record,\n state: 'completed',\n exit: {\n ...outcome,\n ...(outcome.signal !== null && outcome.terminationReason === undefined && record.terminationIntent === undefined\n ? { terminationReason: 'external_signal' as const }\n : {}),\n ...record.terminationIntent,\n finishedAt: new Date().toISOString(),\n },\n };\n this.writeRecord(completed);\n await this.release(id, completed.sessionId);\n return completed;\n }\n\n async release(id: string, sessionId?: string): Promise<void> {\n const activeSessionId = sessionId ?? (await this.list()).find((record) => record.id === id)?.sessionId;\n const ownedSessionId = activeSessionId ?? (await this.get(id))?.sessionId;\n const response = await this.registry.releaseProcess({\n repositoryPath: this.repositoryPath(),\n serviceName: `${SERVICE_PREFIX}${id}`,\n serviceType: SERVICE_TYPE,\n kill: false,\n releasePort: false,\n force: true,\n });\n if (!response.success && !response.error?.includes('No matching process entry')) {\n throw new Error(response.error ?? `Failed to release runner ${id}`);\n }\n if (ownedSessionId !== undefined) this.notify(ownedSessionId);\n }\n\n async pruneDead(): Promise<string[]> {\n const dead = (await this.list()).filter((record) => !this.processControl.isAlive(record.pid));\n for (const record of dead) {\n await this.complete(record.id, { reason: 'backend_lost', code: null, signal: null }, record.sessionId);\n }\n return dead.map((record) => record.id);\n }\n\n subscribe(listener: () => void, sessionId: string): () => void {\n const subscribed = (): void => listener();\n const registration = { key: this.subscriptionKey(sessionId), listener: subscribed };\n const listeners = listenersBySession.get(registration.key) ?? new Set<() => void>();\n listeners.add(subscribed);\n listenersBySession.set(registration.key, listeners);\n this.subscriptions.add(registration);\n return () => this.removeSubscription(registration);\n }\n\n close(): void {\n for (const registration of this.subscriptions) this.removeSubscription(registration);\n this.registry.close();\n }\n\n private notify(sessionId: string): void {\n for (const listener of listenersBySession.get(this.subscriptionKey(sessionId)) ?? []) {\n try {\n listener();\n } catch (error) {\n process.emitWarning(`Runner registry listener failed: ${String(error)}`);\n }\n }\n }\n\n private removeSubscription(registration: ListenerRegistration): void {\n const listeners = listenersBySession.get(registration.key);\n listeners?.delete(registration.listener);\n if (listeners?.size === 0) listenersBySession.delete(registration.key);\n this.subscriptions.delete(registration);\n }\n\n private subscriptionKey(sessionId: string): string {\n return JSON.stringify([path.resolve(this.paths.stateDirectory(sessionId)), sessionId]);\n }\n\n private repositoryPath(): string {\n return normalizeRepositoryPath(this.paths.repositoryPath());\n }\n\n private writeRecord(record: RunnerRecord): void {\n this.paths.ensureDirectories(record.sessionId);\n const target = this.paths.statePathFor(record.id, record.sessionId);\n const temporary = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(temporary, `${JSON.stringify(record, null, 2)}\\n`, 'utf8');\n fs.renameSync(temporary, target);\n }\n}\n\n/** Every field is read back from metadata this class wrote on registration. */\nfunction toRunnerRecord(record: ProcessRegistryRecord): RunnerRecord {\n return {\n id: readString(record, 'id'),\n name: readString(record, 'name'),\n pid: record.pid,\n command: readString(record, 'command'),\n cwd: readString(record, 'cwd'),\n logPath: readString(record, 'logPath'),\n interactive: record.metadata?.interactive === true,\n sessionId: readString(record, 'sessionId'),\n ...(readString(record, 'rootSessionId') ? { rootSessionId: readString(record, 'rootSessionId') } : {}),\n startedAt: readString(record, 'startedAt'),\n state: 'running',\n promoted: false,\n backend: readBackend(record.metadata?.backend),\n ...(readString(record, 'backendTarget') ? { backendTarget: readString(record, 'backendTarget') } : {}),\n hostPid: readNumber(record, 'hostPid'),\n };\n}\n\nfunction readBackend(value: unknown): RunnerRecord['backend'] {\n return value === 'rmux' || value === 'tmux' ? value : 'native';\n}\n\nfunction isPrimaryMetadataEntry(entry: string): boolean {\n return (\n entry.endsWith(JSON_EXTENSION) && !entry.endsWith(COMMAND_SIDECAR_SUFFIX) && !entry.endsWith(EXIT_SIDECAR_SUFFIX)\n );\n}\n"],"mappings":"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"}
|
|
@@ -63,8 +63,6 @@ interface CompleteRunnerInput {
|
|
|
63
63
|
interface IRunnerRegistry {
|
|
64
64
|
register(input: RegisterRunnerInput): Promise<RunnerRecord>;
|
|
65
65
|
list(): Promise<RunnerRecord[]>;
|
|
66
|
-
/** Active doom-runner records across repository scopes, used only for safe legacy-store cleanup. */
|
|
67
|
-
listAcrossRepositories(): Promise<RunnerRecord[]>;
|
|
68
66
|
/** Active records started by one session, used for scoped bulk stop and shutdown. */
|
|
69
67
|
listBySession(sessionId: string): Promise<RunnerRecord[]>;
|
|
70
68
|
/** Active records visible to every descendant of one root Pi session. */
|
|
@@ -85,4 +83,4 @@ interface IRunnerRegistry {
|
|
|
85
83
|
}
|
|
86
84
|
//#endregion
|
|
87
85
|
export { RunnerTerminationIntent as a, RunnerRecord as i, IRunnerRegistry as n, RegisterRunnerInput as r, CompleteRunnerInput as t };
|
|
88
|
-
//# sourceMappingURL=runnerRegistry-
|
|
86
|
+
//# sourceMappingURL=runnerRegistry-V-Ocaf4N.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerRegistry-
|
|
1
|
+
{"version":3,"file":"runnerRegistry-V-Ocaf4N.d.mts","names":[],"sources":["../src/types/runnerRegistry.ts"],"mappings":";KAAY;KACA;KACA;KASA;KAOA;EACV;EACA,mBAAmB,QAAQ;EAC3B;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;EACA;;;UAIe;EACf;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA,OAAO;EACP;EACA,SAAS;EACT;EACA,OAAO;;EAEP,oBAAoB;;EAEpB;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;;UAGe;EACf,QAAQ;EACR;EACA,QAAQ,OAAO;EACf,oBAAoB;EACpB;;;UAIe;EACf,SAAS,OAAO,sBAAsB,QAAQ;EAC9C,QAAQ,QAAQ;;EAEhB,cAAc,oBAAoB,QAAQ;;EAE1C,kBAAkB,wBAAwB,QAAQ;;EAElD,QAAQ,qBAAqB,QAAQ;EACrC,IAAI,YAAY,qBAAqB,QAAQ;EAC7C,aAAa,aAAa,QAAQ;EAClC,mBACE,YACA,QAAQ,qCACR,qBACC,QAAQ;EACX,SAAS,YAAY,SAAS,qBAAqB,qBAAqB,QAAQ;;EAEhF,QAAQ,YAAY,qBAAqB;;EAEzC,aAAa;;EAEb,UAAU,sBAAsB;EAChC"}
|