@elpapi42/pi-fleet 0.1.0-beta.10 → 0.1.0-beta.13
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/CHANGELOG.md +28 -1
- package/README.md +99 -167
- package/dist/cli-meta.json +313 -315
- package/dist/cli.mjs +2504 -1812
- package/dist/cli.mjs.map +4 -4
- package/dist/client/agent-target.d.ts +33 -0
- package/dist/client/contracts.d.ts +81 -0
- package/dist/client/fleet-client.d.ts +118 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/sdk-connector.d.ts +7 -0
- package/dist/client/sdk-facade.d.ts +84 -0
- package/dist/client/sdk-transport.d.ts +24 -0
- package/dist/client/shared-client.d.ts +18 -0
- package/dist/client/socket-fleet-client.d.ts +21 -0
- package/dist/client-meta.json +5736 -0
- package/dist/client.mjs +4434 -0
- package/dist/client.mjs.map +7 -0
- package/dist/installer-meta.json +7 -7
- package/dist/installer.mjs +47 -13
- package/dist/installer.mjs.map +2 -2
- package/dist/journal-sqlite-worker-meta.json +149 -0
- package/dist/journal-sqlite-worker.mjs +1110 -0
- package/dist/journal-sqlite-worker.mjs.map +7 -0
- package/dist/pi/external-installation.d.ts +23 -0
- package/dist/platform/client/start-runtime.d.ts +25 -0
- package/dist/platform/install/runtime-release.d.ts +8 -0
- package/dist/platform/install/tree-integrity.d.ts +7 -0
- package/dist/platform/shared/paths.d.ts +8 -0
- package/dist/platform/shared/runtime-ownership.d.ts +14 -0
- package/dist/protocol/jsonl.d.ts +3 -0
- package/dist/protocol/pi-identity.d.ts +16 -0
- package/dist/protocol/semantic-segmentation.d.ts +22 -0
- package/dist/protocol/version.d.ts +2 -0
- package/dist/runtime/semantic-events.d.ts +43 -0
- package/dist/runtime-manifest.json +156 -31
- package/dist/runtime-meta.json +378 -53
- package/dist/runtime.mjs +3161 -581
- package/dist/runtime.mjs.map +4 -4
- package/dist/shared/result.d.ts +9 -0
- package/package.json +14 -1
- package/dist/sqlite-worker-meta.json +0 -84
- package/dist/sqlite-worker.mjs +0 -359
- package/dist/sqlite-worker.mjs.map +0 -7
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type Result<Value, Error> = {
|
|
2
|
+
readonly ok: true;
|
|
3
|
+
readonly value: Value;
|
|
4
|
+
} | {
|
|
5
|
+
readonly ok: false;
|
|
6
|
+
readonly error: Error;
|
|
7
|
+
};
|
|
8
|
+
export declare function ok<Value>(value: Value): Result<Value, never>;
|
|
9
|
+
export declare function err<Error>(error: Error): Result<never, Error>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elpapi42/pi-fleet",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.13",
|
|
4
4
|
"description": "Pi-native execution infrastructure for programmatic agent orchestration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "elpapi42",
|
|
@@ -26,7 +26,19 @@
|
|
|
26
26
|
"access": "public",
|
|
27
27
|
"tag": "beta"
|
|
28
28
|
},
|
|
29
|
+
"pifleet": {
|
|
30
|
+
"protocolVersion": 3,
|
|
31
|
+
"journalSchemaVersion": 3,
|
|
32
|
+
"clientExport": "./client"
|
|
33
|
+
},
|
|
29
34
|
"type": "module",
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"exports": {
|
|
37
|
+
"./client": {
|
|
38
|
+
"types": "./dist/client/index.d.ts",
|
|
39
|
+
"import": "./dist/client.mjs"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
30
42
|
"engines": {
|
|
31
43
|
"node": "^22.19.0 || ^24.0.0"
|
|
32
44
|
},
|
|
@@ -49,6 +61,7 @@
|
|
|
49
61
|
"test:faults": "npm run build && vitest run test/faults --maxWorkers=1",
|
|
50
62
|
"test:process": "vitest run test/process --maxWorkers=1",
|
|
51
63
|
"test:package": "npm run build && vitest run test/package --maxWorkers=1",
|
|
64
|
+
"test:client-types": "npm run build && tsc --project tsconfig.client-consumer.json",
|
|
52
65
|
"test:platform": "vitest run test/integration/service-installer.test.ts test/process/process-tree.test.ts --maxWorkers=1",
|
|
53
66
|
"test:compat": "vitest run test/compat --maxWorkers=1",
|
|
54
67
|
"test:version-matrix": "npm run build && VITEST_VERSION_MATRIX=1 vitest run test/package/runtime-version-matrix.test.ts --maxWorkers=1",
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"inputs": {
|
|
3
|
-
"src/store/sqlite-store.ts": {
|
|
4
|
-
"bytes": 14146,
|
|
5
|
-
"imports": [
|
|
6
|
-
{
|
|
7
|
-
"path": "node:fs",
|
|
8
|
-
"kind": "import-statement",
|
|
9
|
-
"external": true
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"path": "node:path",
|
|
13
|
-
"kind": "import-statement",
|
|
14
|
-
"external": true
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"path": "node:sqlite",
|
|
18
|
-
"kind": "import-statement",
|
|
19
|
-
"external": true
|
|
20
|
-
}
|
|
21
|
-
],
|
|
22
|
-
"format": "esm"
|
|
23
|
-
},
|
|
24
|
-
"src/store/sqlite-worker.ts": {
|
|
25
|
-
"bytes": 2757,
|
|
26
|
-
"imports": [
|
|
27
|
-
{
|
|
28
|
-
"path": "node:worker_threads",
|
|
29
|
-
"kind": "import-statement",
|
|
30
|
-
"external": true
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"path": "src/store/sqlite-store.ts",
|
|
34
|
-
"kind": "import-statement",
|
|
35
|
-
"original": "./sqlite-store.js"
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"format": "esm"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"outputs": {
|
|
42
|
-
"dist/sqlite-worker.mjs.map": {
|
|
43
|
-
"imports": [],
|
|
44
|
-
"exports": [],
|
|
45
|
-
"inputs": {},
|
|
46
|
-
"bytes": 24288
|
|
47
|
-
},
|
|
48
|
-
"dist/sqlite-worker.mjs": {
|
|
49
|
-
"imports": [
|
|
50
|
-
{
|
|
51
|
-
"path": "node:worker_threads",
|
|
52
|
-
"kind": "import-statement",
|
|
53
|
-
"external": true
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"path": "node:fs",
|
|
57
|
-
"kind": "import-statement",
|
|
58
|
-
"external": true
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"path": "node:path",
|
|
62
|
-
"kind": "import-statement",
|
|
63
|
-
"external": true
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"path": "node:sqlite",
|
|
67
|
-
"kind": "import-statement",
|
|
68
|
-
"external": true
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
"exports": [],
|
|
72
|
-
"entryPoint": "src/store/sqlite-worker.ts",
|
|
73
|
-
"inputs": {
|
|
74
|
-
"src/store/sqlite-worker.ts": {
|
|
75
|
-
"bytesInOutput": 2152
|
|
76
|
-
},
|
|
77
|
-
"src/store/sqlite-store.ts": {
|
|
78
|
-
"bytesInOutput": 12211
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
"bytes": 14497
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
package/dist/sqlite-worker.mjs
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
// src/store/sqlite-worker.ts
|
|
2
|
-
import { parentPort, workerData } from "node:worker_threads";
|
|
3
|
-
|
|
4
|
-
// src/store/sqlite-store.ts
|
|
5
|
-
import { mkdirSync } from "node:fs";
|
|
6
|
-
import { dirname } from "node:path";
|
|
7
|
-
import { DatabaseSync } from "node:sqlite";
|
|
8
|
-
var MIGRATIONS = [
|
|
9
|
-
{
|
|
10
|
-
version: 1,
|
|
11
|
-
checksum: "001_initial_v1",
|
|
12
|
-
statements: `
|
|
13
|
-
CREATE TABLE runtime_metadata(
|
|
14
|
-
singleton_key INTEGER PRIMARY KEY CHECK(singleton_key = 1),
|
|
15
|
-
clean_shutdown INTEGER NOT NULL CHECK(clean_shutdown IN (0, 1))
|
|
16
|
-
);
|
|
17
|
-
CREATE TABLE agents(
|
|
18
|
-
agent_id TEXT NOT NULL,
|
|
19
|
-
name TEXT PRIMARY KEY,
|
|
20
|
-
state TEXT NOT NULL CHECK(state IN ('restoring','working','idle','failed','destroying')),
|
|
21
|
-
process_state TEXT NOT NULL CHECK(process_state IN ('resident','starting','absent','cleanup_uncertain')),
|
|
22
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
23
|
-
);
|
|
24
|
-
CREATE TABLE operations(
|
|
25
|
-
operation_id TEXT PRIMARY KEY,
|
|
26
|
-
method TEXT NOT NULL CHECK(method IN ('create','send','destroy')),
|
|
27
|
-
state TEXT NOT NULL CHECK(state IN ('pending','completed')),
|
|
28
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
29
|
-
);
|
|
30
|
-
CREATE TABLE send_records(
|
|
31
|
-
send_id TEXT PRIMARY KEY,
|
|
32
|
-
agent_name TEXT NOT NULL,
|
|
33
|
-
state TEXT NOT NULL CHECK(state IN ('pending','dispatching','acknowledged','failed','uncertain')),
|
|
34
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
35
|
-
);
|
|
36
|
-
CREATE TABLE incarnations(
|
|
37
|
-
incarnation_id TEXT PRIMARY KEY,
|
|
38
|
-
agent_name TEXT NOT NULL,
|
|
39
|
-
pid INTEGER,
|
|
40
|
-
state TEXT NOT NULL CHECK(state IN ('starting','live','stopping','cleanup_uncertain','gone')),
|
|
41
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
42
|
-
);
|
|
43
|
-
`
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
version: 2,
|
|
47
|
-
checksum: "002_compact_v1",
|
|
48
|
-
statements: `
|
|
49
|
-
ALTER TABLE operations RENAME TO operations_v1;
|
|
50
|
-
CREATE TABLE operations(
|
|
51
|
-
operation_id TEXT PRIMARY KEY,
|
|
52
|
-
method TEXT NOT NULL CHECK(method IN ('create','send','destroy','compact')),
|
|
53
|
-
state TEXT NOT NULL CHECK(state IN ('pending','completed')),
|
|
54
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
55
|
-
);
|
|
56
|
-
INSERT INTO operations(operation_id, method, state, data_json)
|
|
57
|
-
SELECT operation_id, method, state, data_json FROM operations_v1;
|
|
58
|
-
DROP TABLE operations_v1;
|
|
59
|
-
CREATE TABLE compact_records(
|
|
60
|
-
compact_id TEXT PRIMARY KEY,
|
|
61
|
-
agent_name TEXT NOT NULL,
|
|
62
|
-
state TEXT NOT NULL CHECK(state IN ('pending','dispatching','completed','failed','uncertain')),
|
|
63
|
-
data_json TEXT NOT NULL CHECK(json_valid(data_json))
|
|
64
|
-
);
|
|
65
|
-
CREATE INDEX compact_records_nonterminal ON compact_records(state, agent_name);
|
|
66
|
-
`
|
|
67
|
-
}
|
|
68
|
-
];
|
|
69
|
-
var SqliteFleetStore = class {
|
|
70
|
-
#database;
|
|
71
|
-
#closed = false;
|
|
72
|
-
constructor(path2) {
|
|
73
|
-
mkdirSync(dirname(path2), { recursive: true, mode: 448 });
|
|
74
|
-
this.#database = new DatabaseSync(path2);
|
|
75
|
-
this.#database.exec(
|
|
76
|
-
"PRAGMA foreign_keys=ON; PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL;"
|
|
77
|
-
);
|
|
78
|
-
try {
|
|
79
|
-
this.#migrate();
|
|
80
|
-
const metadata = this.#database.prepare("SELECT clean_shutdown FROM runtime_metadata WHERE singleton_key = 1").get();
|
|
81
|
-
if (metadata?.clean_shutdown === 0) {
|
|
82
|
-
this.#verifyIntegrity();
|
|
83
|
-
this.#database.exec(`
|
|
84
|
-
UPDATE agents
|
|
85
|
-
SET state = 'failed', process_state = 'cleanup_uncertain',
|
|
86
|
-
data_json = json_set(data_json,
|
|
87
|
-
'$.summary.state', 'failed',
|
|
88
|
-
'$.summary.process.state', 'cleanup_uncertain',
|
|
89
|
-
'$.summary.error.code',
|
|
90
|
-
CASE WHEN state IN ('working', 'restoring')
|
|
91
|
-
THEN 'runtime_interrupted'
|
|
92
|
-
ELSE 'incarnation_cleanup_uncertain'
|
|
93
|
-
END)
|
|
94
|
-
WHERE process_state IN ('resident', 'starting');
|
|
95
|
-
UPDATE incarnations
|
|
96
|
-
SET state = 'cleanup_uncertain',
|
|
97
|
-
data_json = json_set(data_json, '$.state', 'cleanup_uncertain')
|
|
98
|
-
WHERE state IN ('starting', 'live', 'stopping');
|
|
99
|
-
`);
|
|
100
|
-
} else if (metadata?.clean_shutdown === 1) {
|
|
101
|
-
this.#database.exec(`
|
|
102
|
-
UPDATE agents
|
|
103
|
-
SET state = CASE WHEN state = 'idle' THEN 'idle' ELSE 'failed' END,
|
|
104
|
-
process_state = 'absent',
|
|
105
|
-
data_json = json_set(data_json,
|
|
106
|
-
'$.summary.state', CASE WHEN state = 'idle' THEN 'idle' ELSE 'failed' END,
|
|
107
|
-
'$.summary.process.state', 'absent')
|
|
108
|
-
WHERE process_state IN ('resident', 'starting');
|
|
109
|
-
UPDATE incarnations
|
|
110
|
-
SET state = 'gone', data_json = json_set(data_json, '$.state', 'gone')
|
|
111
|
-
WHERE state IN ('starting', 'live', 'stopping');
|
|
112
|
-
`);
|
|
113
|
-
}
|
|
114
|
-
this.#database.prepare(
|
|
115
|
-
`INSERT INTO runtime_metadata(singleton_key, clean_shutdown)
|
|
116
|
-
VALUES(1, 0)
|
|
117
|
-
ON CONFLICT(singleton_key) DO UPDATE SET clean_shutdown = 0`
|
|
118
|
-
).run();
|
|
119
|
-
} catch (error) {
|
|
120
|
-
this.#database.close();
|
|
121
|
-
this.#closed = true;
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
async createAgent(agent) {
|
|
126
|
-
const result = this.#database.prepare(
|
|
127
|
-
`INSERT OR IGNORE INTO agents(agent_id, name, state, process_state, data_json)
|
|
128
|
-
VALUES(?, ?, ?, ?, ?)`
|
|
129
|
-
).run(
|
|
130
|
-
agent.summary.id,
|
|
131
|
-
agent.summary.name,
|
|
132
|
-
agent.summary.state,
|
|
133
|
-
agent.summary.process.state,
|
|
134
|
-
JSON.stringify(agent)
|
|
135
|
-
);
|
|
136
|
-
return result.changes === 1;
|
|
137
|
-
}
|
|
138
|
-
async getAgent(name) {
|
|
139
|
-
const row = this.#database.prepare("SELECT data_json FROM agents WHERE name = ?").get(name);
|
|
140
|
-
return row === void 0 ? null : JSON.parse(row.data_json);
|
|
141
|
-
}
|
|
142
|
-
async listAgents() {
|
|
143
|
-
const rows = this.#database.prepare("SELECT data_json FROM agents ORDER BY name").all();
|
|
144
|
-
return rows.map((row) => JSON.parse(row.data_json));
|
|
145
|
-
}
|
|
146
|
-
async putAgent(agent) {
|
|
147
|
-
this.#database.prepare(
|
|
148
|
-
`INSERT INTO agents(agent_id, name, state, process_state, data_json)
|
|
149
|
-
VALUES(?, ?, ?, ?, ?)
|
|
150
|
-
ON CONFLICT(name) DO UPDATE SET
|
|
151
|
-
agent_id=excluded.agent_id,
|
|
152
|
-
state=excluded.state,
|
|
153
|
-
process_state=excluded.process_state,
|
|
154
|
-
data_json=excluded.data_json`
|
|
155
|
-
).run(
|
|
156
|
-
agent.summary.id,
|
|
157
|
-
agent.summary.name,
|
|
158
|
-
agent.summary.state,
|
|
159
|
-
agent.summary.process.state,
|
|
160
|
-
JSON.stringify(agent)
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
async deleteAgent(name) {
|
|
164
|
-
const existing = await this.getAgent(name);
|
|
165
|
-
if (existing !== null) this.#database.prepare("DELETE FROM agents WHERE name = ?").run(name);
|
|
166
|
-
return existing;
|
|
167
|
-
}
|
|
168
|
-
async getOperation(operationId) {
|
|
169
|
-
const row = this.#database.prepare("SELECT data_json FROM operations WHERE operation_id = ?").get(operationId);
|
|
170
|
-
return row === void 0 ? null : JSON.parse(row.data_json);
|
|
171
|
-
}
|
|
172
|
-
async putOperation(operation) {
|
|
173
|
-
this.#database.prepare(
|
|
174
|
-
`INSERT INTO operations(operation_id, method, state, data_json)
|
|
175
|
-
VALUES(?, ?, ?, ?)
|
|
176
|
-
ON CONFLICT(operation_id) DO UPDATE SET
|
|
177
|
-
method=excluded.method, state=excluded.state, data_json=excluded.data_json`
|
|
178
|
-
).run(operation.operationId, operation.method, operation.state, JSON.stringify(operation));
|
|
179
|
-
}
|
|
180
|
-
async listPendingOperations() {
|
|
181
|
-
const rows = this.#database.prepare("SELECT data_json FROM operations WHERE state = 'pending'").all();
|
|
182
|
-
return rows.map((row) => JSON.parse(row.data_json));
|
|
183
|
-
}
|
|
184
|
-
async deleteOperation(operationId) {
|
|
185
|
-
this.#database.prepare("DELETE FROM operations WHERE operation_id = ?").run(operationId);
|
|
186
|
-
}
|
|
187
|
-
async getSend(sendId) {
|
|
188
|
-
const row = this.#database.prepare("SELECT data_json FROM send_records WHERE send_id = ?").get(sendId);
|
|
189
|
-
return row === void 0 ? null : JSON.parse(row.data_json);
|
|
190
|
-
}
|
|
191
|
-
async nextSendOrdinal(agentName) {
|
|
192
|
-
const row = this.#database.prepare(
|
|
193
|
-
`SELECT COALESCE(MAX(CAST(json_extract(data_json, '$.ordinal') AS INTEGER)), 0) + 1 AS ordinal
|
|
194
|
-
FROM send_records WHERE agent_name = ?`
|
|
195
|
-
).get(agentName);
|
|
196
|
-
return row.ordinal;
|
|
197
|
-
}
|
|
198
|
-
async putSend(send) {
|
|
199
|
-
this.#database.prepare(
|
|
200
|
-
`INSERT INTO send_records(send_id, agent_name, state, data_json)
|
|
201
|
-
VALUES(?, ?, ?, ?)
|
|
202
|
-
ON CONFLICT(send_id) DO UPDATE SET state=excluded.state, data_json=excluded.data_json`
|
|
203
|
-
).run(send.sendId, send.agentName, send.state, JSON.stringify(send));
|
|
204
|
-
}
|
|
205
|
-
async listNonterminalSends() {
|
|
206
|
-
const rows = this.#database.prepare(
|
|
207
|
-
`SELECT data_json FROM send_records WHERE state IN ('pending', 'dispatching')
|
|
208
|
-
ORDER BY agent_name, COALESCE(CAST(json_extract(data_json, '$.ordinal') AS INTEGER), 0), rowid`
|
|
209
|
-
).all();
|
|
210
|
-
return rows.map((row) => JSON.parse(row.data_json));
|
|
211
|
-
}
|
|
212
|
-
async getCompact(compactId) {
|
|
213
|
-
const row = this.#database.prepare("SELECT data_json FROM compact_records WHERE compact_id = ?").get(compactId);
|
|
214
|
-
return row === void 0 ? null : JSON.parse(row.data_json);
|
|
215
|
-
}
|
|
216
|
-
async putCompact(compact) {
|
|
217
|
-
this.#database.prepare(
|
|
218
|
-
`INSERT INTO compact_records(compact_id, agent_name, state, data_json)
|
|
219
|
-
VALUES(?, ?, ?, ?)
|
|
220
|
-
ON CONFLICT(compact_id) DO UPDATE SET state=excluded.state, data_json=excluded.data_json`
|
|
221
|
-
).run(compact.compactId, compact.agentName, compact.state, JSON.stringify(compact));
|
|
222
|
-
}
|
|
223
|
-
async listNonterminalCompacts() {
|
|
224
|
-
const rows = this.#database.prepare(
|
|
225
|
-
"SELECT data_json FROM compact_records WHERE state IN ('pending','dispatching') ORDER BY rowid"
|
|
226
|
-
).all();
|
|
227
|
-
return rows.map((row) => JSON.parse(row.data_json));
|
|
228
|
-
}
|
|
229
|
-
async putIncarnation(incarnation) {
|
|
230
|
-
this.#database.prepare(
|
|
231
|
-
`INSERT INTO incarnations(incarnation_id, agent_name, pid, state, data_json)
|
|
232
|
-
VALUES(?, ?, ?, ?, ?)
|
|
233
|
-
ON CONFLICT(incarnation_id) DO UPDATE SET
|
|
234
|
-
pid=excluded.pid, state=excluded.state, data_json=excluded.data_json`
|
|
235
|
-
).run(
|
|
236
|
-
incarnation.incarnationId,
|
|
237
|
-
incarnation.agentName,
|
|
238
|
-
incarnation.pid,
|
|
239
|
-
incarnation.state,
|
|
240
|
-
JSON.stringify(incarnation)
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
async listActiveIncarnations() {
|
|
244
|
-
const rows = this.#database.prepare(
|
|
245
|
-
"SELECT data_json FROM incarnations WHERE state IN ('starting','live','stopping','cleanup_uncertain')"
|
|
246
|
-
).all();
|
|
247
|
-
return rows.map((row) => JSON.parse(row.data_json));
|
|
248
|
-
}
|
|
249
|
-
async close(cleanShutdown = true) {
|
|
250
|
-
if (this.#closed) return;
|
|
251
|
-
this.#database.prepare("UPDATE runtime_metadata SET clean_shutdown = ? WHERE singleton_key = 1").run(cleanShutdown ? 1 : 0);
|
|
252
|
-
this.#database.close();
|
|
253
|
-
this.#closed = true;
|
|
254
|
-
}
|
|
255
|
-
#verifyIntegrity() {
|
|
256
|
-
const rows = this.#database.prepare("PRAGMA quick_check").all();
|
|
257
|
-
if (rows.length !== 1 || Object.values(rows[0] ?? {}).length !== 1 || Object.values(rows[0] ?? {})[0] !== "ok") {
|
|
258
|
-
throw new Error("pi-fleet database integrity check failed after an unclean shutdown");
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
#migrate() {
|
|
262
|
-
this.#database.exec("BEGIN IMMEDIATE");
|
|
263
|
-
try {
|
|
264
|
-
this.#database.exec(`
|
|
265
|
-
CREATE TABLE IF NOT EXISTS schema_migrations(
|
|
266
|
-
version INTEGER PRIMARY KEY,
|
|
267
|
-
checksum TEXT NOT NULL,
|
|
268
|
-
applied_at TEXT NOT NULL
|
|
269
|
-
);
|
|
270
|
-
`);
|
|
271
|
-
const applied = this.#database.prepare("SELECT version, checksum FROM schema_migrations ORDER BY version").all();
|
|
272
|
-
const latestSupported = MIGRATIONS.at(-1)?.version ?? 0;
|
|
273
|
-
const newer = applied.find((migration) => migration.version > latestSupported);
|
|
274
|
-
if (newer !== void 0) {
|
|
275
|
-
throw new Error(
|
|
276
|
-
`pi-fleet database schema ${String(newer.version)} is newer than this runtime`
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
for (const existing of applied) {
|
|
280
|
-
const expected = MIGRATIONS.find((migration) => migration.version === existing.version);
|
|
281
|
-
if (expected === void 0 || expected.checksum !== existing.checksum) {
|
|
282
|
-
throw new Error(
|
|
283
|
-
`pi-fleet database migration ${String(existing.version)} checksum mismatch`
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
for (const migration of MIGRATIONS) {
|
|
288
|
-
if (applied.some((existing) => existing.version === migration.version)) continue;
|
|
289
|
-
this.#database.exec(migration.statements);
|
|
290
|
-
this.#database.prepare("INSERT INTO schema_migrations(version, checksum, applied_at) VALUES(?, ?, ?)").run(migration.version, migration.checksum, (/* @__PURE__ */ new Date()).toISOString());
|
|
291
|
-
}
|
|
292
|
-
this.#database.exec("COMMIT");
|
|
293
|
-
} catch (error) {
|
|
294
|
-
this.#database.exec("ROLLBACK");
|
|
295
|
-
throw error;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
// src/store/sqlite-worker.ts
|
|
301
|
-
var port = parentPort;
|
|
302
|
-
if (port === null) throw new Error("SQLite worker requires a parent port");
|
|
303
|
-
var path = workerData.path;
|
|
304
|
-
if (typeof path !== "string") throw new Error("SQLite worker requires a database path");
|
|
305
|
-
var store = new SqliteFleetStore(path);
|
|
306
|
-
port.on("message", (request) => {
|
|
307
|
-
void dispatch(request).then((value) => port.postMessage({ id: request.id, ok: true, value })).catch(
|
|
308
|
-
(error) => port.postMessage({
|
|
309
|
-
id: request.id,
|
|
310
|
-
ok: false,
|
|
311
|
-
error: error instanceof Error ? error.message : "SQLite worker failed"
|
|
312
|
-
})
|
|
313
|
-
);
|
|
314
|
-
});
|
|
315
|
-
async function dispatch(request) {
|
|
316
|
-
switch (request.method) {
|
|
317
|
-
case "createAgent":
|
|
318
|
-
return store.createAgent(request.args[0]);
|
|
319
|
-
case "getAgent":
|
|
320
|
-
return store.getAgent(request.args[0]);
|
|
321
|
-
case "listAgents":
|
|
322
|
-
return store.listAgents();
|
|
323
|
-
case "putAgent":
|
|
324
|
-
return store.putAgent(request.args[0]);
|
|
325
|
-
case "deleteAgent":
|
|
326
|
-
return store.deleteAgent(request.args[0]);
|
|
327
|
-
case "getOperation":
|
|
328
|
-
return store.getOperation(request.args[0]);
|
|
329
|
-
case "putOperation":
|
|
330
|
-
return store.putOperation(request.args[0]);
|
|
331
|
-
case "listPendingOperations":
|
|
332
|
-
return store.listPendingOperations();
|
|
333
|
-
case "deleteOperation":
|
|
334
|
-
return store.deleteOperation(request.args[0]);
|
|
335
|
-
case "getSend":
|
|
336
|
-
return store.getSend(request.args[0]);
|
|
337
|
-
case "nextSendOrdinal":
|
|
338
|
-
return store.nextSendOrdinal(request.args[0]);
|
|
339
|
-
case "putSend":
|
|
340
|
-
return store.putSend(request.args[0]);
|
|
341
|
-
case "listNonterminalSends":
|
|
342
|
-
return store.listNonterminalSends();
|
|
343
|
-
case "getCompact":
|
|
344
|
-
return store.getCompact(request.args[0]);
|
|
345
|
-
case "putCompact":
|
|
346
|
-
return store.putCompact(request.args[0]);
|
|
347
|
-
case "listNonterminalCompacts":
|
|
348
|
-
return store.listNonterminalCompacts();
|
|
349
|
-
case "putIncarnation":
|
|
350
|
-
return store.putIncarnation(request.args[0]);
|
|
351
|
-
case "listActiveIncarnations":
|
|
352
|
-
return store.listActiveIncarnations();
|
|
353
|
-
case "close":
|
|
354
|
-
return store.close(request.args[0]);
|
|
355
|
-
default:
|
|
356
|
-
throw new Error(`Unknown SQLite worker method ${request.method}`);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
//# sourceMappingURL=sqlite-worker.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/store/sqlite-worker.ts", "../src/store/sqlite-store.ts"],
|
|
4
|
-
"sourcesContent": ["import { parentPort, workerData } from \"node:worker_threads\";\n\nimport type {\n StoredAgent,\n StoredCompact,\n StoredIncarnation,\n StoredOperation,\n StoredSend,\n} from \"./fleet-store.js\";\nimport { SqliteFleetStore } from \"./sqlite-store.js\";\n\ninterface WorkerRequest {\n readonly id: string;\n readonly method: string;\n readonly args: readonly unknown[];\n}\n\nconst port = parentPort;\nif (port === null) throw new Error(\"SQLite worker requires a parent port\");\nconst path = (workerData as { path?: unknown }).path;\nif (typeof path !== \"string\") throw new Error(\"SQLite worker requires a database path\");\nconst store = new SqliteFleetStore(path);\n\nport.on(\"message\", (request: WorkerRequest) => {\n void dispatch(request)\n .then((value) => port.postMessage({ id: request.id, ok: true, value }))\n .catch((error: unknown) =>\n port.postMessage({\n id: request.id,\n ok: false,\n error: error instanceof Error ? error.message : \"SQLite worker failed\",\n }),\n );\n});\n\nasync function dispatch(request: WorkerRequest): Promise<unknown> {\n switch (request.method) {\n case \"createAgent\":\n return store.createAgent(request.args[0] as StoredAgent);\n case \"getAgent\":\n return store.getAgent(request.args[0] as string);\n case \"listAgents\":\n return store.listAgents();\n case \"putAgent\":\n return store.putAgent(request.args[0] as StoredAgent);\n case \"deleteAgent\":\n return store.deleteAgent(request.args[0] as string);\n case \"getOperation\":\n return store.getOperation(request.args[0] as string);\n case \"putOperation\":\n return store.putOperation(request.args[0] as StoredOperation);\n case \"listPendingOperations\":\n return store.listPendingOperations();\n case \"deleteOperation\":\n return store.deleteOperation(request.args[0] as string);\n case \"getSend\":\n return store.getSend(request.args[0] as string);\n case \"nextSendOrdinal\":\n return store.nextSendOrdinal(request.args[0] as string);\n case \"putSend\":\n return store.putSend(request.args[0] as StoredSend);\n case \"listNonterminalSends\":\n return store.listNonterminalSends();\n case \"getCompact\":\n return store.getCompact(request.args[0] as string);\n case \"putCompact\":\n return store.putCompact(request.args[0] as StoredCompact);\n case \"listNonterminalCompacts\":\n return store.listNonterminalCompacts();\n case \"putIncarnation\":\n return store.putIncarnation(request.args[0] as StoredIncarnation);\n case \"listActiveIncarnations\":\n return store.listActiveIncarnations();\n case \"close\":\n return store.close(request.args[0] as boolean | undefined);\n default:\n throw new Error(`Unknown SQLite worker method ${request.method}`);\n }\n}\n", "import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { DatabaseSync } from \"node:sqlite\";\n\nimport type {\n FleetStore,\n StoredAgent,\n StoredCompact,\n StoredIncarnation,\n StoredOperation,\n StoredSend,\n} from \"./fleet-store.js\";\n\ninterface JsonRow {\n readonly data_json: string;\n}\n\nconst MIGRATIONS = [\n {\n version: 1,\n checksum: \"001_initial_v1\",\n statements: `\n CREATE TABLE runtime_metadata(\n singleton_key INTEGER PRIMARY KEY CHECK(singleton_key = 1),\n clean_shutdown INTEGER NOT NULL CHECK(clean_shutdown IN (0, 1))\n );\n CREATE TABLE agents(\n agent_id TEXT NOT NULL,\n name TEXT PRIMARY KEY,\n state TEXT NOT NULL CHECK(state IN ('restoring','working','idle','failed','destroying')),\n process_state TEXT NOT NULL CHECK(process_state IN ('resident','starting','absent','cleanup_uncertain')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE operations(\n operation_id TEXT PRIMARY KEY,\n method TEXT NOT NULL CHECK(method IN ('create','send','destroy')),\n state TEXT NOT NULL CHECK(state IN ('pending','completed')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE send_records(\n send_id TEXT PRIMARY KEY,\n agent_name TEXT NOT NULL,\n state TEXT NOT NULL CHECK(state IN ('pending','dispatching','acknowledged','failed','uncertain')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE incarnations(\n incarnation_id TEXT PRIMARY KEY,\n agent_name TEXT NOT NULL,\n pid INTEGER,\n state TEXT NOT NULL CHECK(state IN ('starting','live','stopping','cleanup_uncertain','gone')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n `,\n },\n {\n version: 2,\n checksum: \"002_compact_v1\",\n statements: `\n ALTER TABLE operations RENAME TO operations_v1;\n CREATE TABLE operations(\n operation_id TEXT PRIMARY KEY,\n method TEXT NOT NULL CHECK(method IN ('create','send','destroy','compact')),\n state TEXT NOT NULL CHECK(state IN ('pending','completed')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n INSERT INTO operations(operation_id, method, state, data_json)\n SELECT operation_id, method, state, data_json FROM operations_v1;\n DROP TABLE operations_v1;\n CREATE TABLE compact_records(\n compact_id TEXT PRIMARY KEY,\n agent_name TEXT NOT NULL,\n state TEXT NOT NULL CHECK(state IN ('pending','dispatching','completed','failed','uncertain')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE INDEX compact_records_nonterminal ON compact_records(state, agent_name);\n `,\n },\n] as const;\n\nexport class SqliteFleetStore implements FleetStore {\n readonly #database: DatabaseSync;\n #closed = false;\n\n constructor(path: string) {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n this.#database = new DatabaseSync(path);\n this.#database.exec(\n \"PRAGMA foreign_keys=ON; PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL;\",\n );\n try {\n this.#migrate();\n const metadata = this.#database\n .prepare(\"SELECT clean_shutdown FROM runtime_metadata WHERE singleton_key = 1\")\n .get() as { clean_shutdown: number } | undefined;\n if (metadata?.clean_shutdown === 0) {\n this.#verifyIntegrity();\n this.#database.exec(`\n UPDATE agents\n SET state = 'failed', process_state = 'cleanup_uncertain',\n data_json = json_set(data_json,\n '$.summary.state', 'failed',\n '$.summary.process.state', 'cleanup_uncertain',\n '$.summary.error.code',\n CASE WHEN state IN ('working', 'restoring')\n THEN 'runtime_interrupted'\n ELSE 'incarnation_cleanup_uncertain'\n END)\n WHERE process_state IN ('resident', 'starting');\n UPDATE incarnations\n SET state = 'cleanup_uncertain',\n data_json = json_set(data_json, '$.state', 'cleanup_uncertain')\n WHERE state IN ('starting', 'live', 'stopping');\n `);\n } else if (metadata?.clean_shutdown === 1) {\n this.#database.exec(`\n UPDATE agents\n SET state = CASE WHEN state = 'idle' THEN 'idle' ELSE 'failed' END,\n process_state = 'absent',\n data_json = json_set(data_json,\n '$.summary.state', CASE WHEN state = 'idle' THEN 'idle' ELSE 'failed' END,\n '$.summary.process.state', 'absent')\n WHERE process_state IN ('resident', 'starting');\n UPDATE incarnations\n SET state = 'gone', data_json = json_set(data_json, '$.state', 'gone')\n WHERE state IN ('starting', 'live', 'stopping');\n `);\n }\n this.#database\n .prepare(\n `INSERT INTO runtime_metadata(singleton_key, clean_shutdown)\n VALUES(1, 0)\n ON CONFLICT(singleton_key) DO UPDATE SET clean_shutdown = 0`,\n )\n .run();\n } catch (error: unknown) {\n this.#database.close();\n this.#closed = true;\n throw error;\n }\n }\n\n async createAgent(agent: StoredAgent): Promise<boolean> {\n const result = this.#database\n .prepare(\n `INSERT OR IGNORE INTO agents(agent_id, name, state, process_state, data_json)\n VALUES(?, ?, ?, ?, ?)`,\n )\n .run(\n agent.summary.id,\n agent.summary.name,\n agent.summary.state,\n agent.summary.process.state,\n JSON.stringify(agent),\n );\n return result.changes === 1;\n }\n\n async getAgent(name: string): Promise<StoredAgent | null> {\n const row = this.#database.prepare(\"SELECT data_json FROM agents WHERE name = ?\").get(name) as\n | JsonRow\n | undefined;\n return row === undefined ? null : (JSON.parse(row.data_json) as StoredAgent);\n }\n\n async listAgents(): Promise<readonly StoredAgent[]> {\n const rows = this.#database\n .prepare(\"SELECT data_json FROM agents ORDER BY name\")\n .all() as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as StoredAgent);\n }\n\n async putAgent(agent: StoredAgent): Promise<void> {\n this.#database\n .prepare(\n `INSERT INTO agents(agent_id, name, state, process_state, data_json)\n VALUES(?, ?, ?, ?, ?)\n ON CONFLICT(name) DO UPDATE SET\n agent_id=excluded.agent_id,\n state=excluded.state,\n process_state=excluded.process_state,\n data_json=excluded.data_json`,\n )\n .run(\n agent.summary.id,\n agent.summary.name,\n agent.summary.state,\n agent.summary.process.state,\n JSON.stringify(agent),\n );\n }\n\n async deleteAgent(name: string): Promise<StoredAgent | null> {\n const existing = await this.getAgent(name);\n if (existing !== null) this.#database.prepare(\"DELETE FROM agents WHERE name = ?\").run(name);\n return existing;\n }\n\n async getOperation(operationId: string): Promise<StoredOperation | null> {\n const row = this.#database\n .prepare(\"SELECT data_json FROM operations WHERE operation_id = ?\")\n .get(operationId) as JsonRow | undefined;\n return row === undefined ? null : (JSON.parse(row.data_json) as StoredOperation);\n }\n\n async putOperation(operation: StoredOperation): Promise<void> {\n this.#database\n .prepare(\n `INSERT INTO operations(operation_id, method, state, data_json)\n VALUES(?, ?, ?, ?)\n ON CONFLICT(operation_id) DO UPDATE SET\n method=excluded.method, state=excluded.state, data_json=excluded.data_json`,\n )\n .run(operation.operationId, operation.method, operation.state, JSON.stringify(operation));\n }\n\n async listPendingOperations(): Promise<readonly StoredOperation[]> {\n const rows = this.#database\n .prepare(\"SELECT data_json FROM operations WHERE state = 'pending'\")\n .all() as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as StoredOperation);\n }\n\n async deleteOperation(operationId: string): Promise<void> {\n this.#database.prepare(\"DELETE FROM operations WHERE operation_id = ?\").run(operationId);\n }\n\n async getSend(sendId: string): Promise<StoredSend | null> {\n const row = this.#database\n .prepare(\"SELECT data_json FROM send_records WHERE send_id = ?\")\n .get(sendId) as JsonRow | undefined;\n return row === undefined ? null : (JSON.parse(row.data_json) as StoredSend);\n }\n\n async nextSendOrdinal(agentName: string): Promise<number> {\n const row = this.#database\n .prepare(\n `SELECT COALESCE(MAX(CAST(json_extract(data_json, '$.ordinal') AS INTEGER)), 0) + 1 AS ordinal\n FROM send_records WHERE agent_name = ?`,\n )\n .get(agentName) as { readonly ordinal: number };\n return row.ordinal;\n }\n\n async putSend(send: StoredSend): Promise<void> {\n this.#database\n .prepare(\n `INSERT INTO send_records(send_id, agent_name, state, data_json)\n VALUES(?, ?, ?, ?)\n ON CONFLICT(send_id) DO UPDATE SET state=excluded.state, data_json=excluded.data_json`,\n )\n .run(send.sendId, send.agentName, send.state, JSON.stringify(send));\n }\n\n async listNonterminalSends(): Promise<readonly StoredSend[]> {\n const rows = this.#database\n .prepare(\n `SELECT data_json FROM send_records WHERE state IN ('pending', 'dispatching')\n ORDER BY agent_name, COALESCE(CAST(json_extract(data_json, '$.ordinal') AS INTEGER), 0), rowid`,\n )\n .all() as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as StoredSend);\n }\n\n async getCompact(compactId: string): Promise<StoredCompact | null> {\n const row = this.#database\n .prepare(\"SELECT data_json FROM compact_records WHERE compact_id = ?\")\n .get(compactId) as JsonRow | undefined;\n return row === undefined ? null : (JSON.parse(row.data_json) as StoredCompact);\n }\n\n async putCompact(compact: StoredCompact): Promise<void> {\n this.#database\n .prepare(\n `INSERT INTO compact_records(compact_id, agent_name, state, data_json)\n VALUES(?, ?, ?, ?)\n ON CONFLICT(compact_id) DO UPDATE SET state=excluded.state, data_json=excluded.data_json`,\n )\n .run(compact.compactId, compact.agentName, compact.state, JSON.stringify(compact));\n }\n\n async listNonterminalCompacts(): Promise<readonly StoredCompact[]> {\n const rows = this.#database\n .prepare(\n \"SELECT data_json FROM compact_records WHERE state IN ('pending','dispatching') ORDER BY rowid\",\n )\n .all() as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as StoredCompact);\n }\n\n async putIncarnation(incarnation: StoredIncarnation): Promise<void> {\n this.#database\n .prepare(\n `INSERT INTO incarnations(incarnation_id, agent_name, pid, state, data_json)\n VALUES(?, ?, ?, ?, ?)\n ON CONFLICT(incarnation_id) DO UPDATE SET\n pid=excluded.pid, state=excluded.state, data_json=excluded.data_json`,\n )\n .run(\n incarnation.incarnationId,\n incarnation.agentName,\n incarnation.pid,\n incarnation.state,\n JSON.stringify(incarnation),\n );\n }\n\n async listActiveIncarnations(): Promise<readonly StoredIncarnation[]> {\n const rows = this.#database\n .prepare(\n \"SELECT data_json FROM incarnations WHERE state IN ('starting','live','stopping','cleanup_uncertain')\",\n )\n .all() as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as StoredIncarnation);\n }\n\n async close(cleanShutdown = true): Promise<void> {\n if (this.#closed) return;\n this.#database\n .prepare(\"UPDATE runtime_metadata SET clean_shutdown = ? WHERE singleton_key = 1\")\n .run(cleanShutdown ? 1 : 0);\n this.#database.close();\n this.#closed = true;\n }\n\n #verifyIntegrity(): void {\n const rows = this.#database.prepare(\"PRAGMA quick_check\").all() as unknown as Array<\n Record<string, unknown>\n >;\n if (\n rows.length !== 1 ||\n Object.values(rows[0] ?? {}).length !== 1 ||\n Object.values(rows[0] ?? {})[0] !== \"ok\"\n ) {\n throw new Error(\"pi-fleet database integrity check failed after an unclean shutdown\");\n }\n }\n\n #migrate(): void {\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n this.#database.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations(\n version INTEGER PRIMARY KEY,\n checksum TEXT NOT NULL,\n applied_at TEXT NOT NULL\n );\n `);\n const applied = this.#database\n .prepare(\"SELECT version, checksum FROM schema_migrations ORDER BY version\")\n .all() as unknown as { readonly version: number; readonly checksum: string }[];\n const latestSupported = MIGRATIONS.at(-1)?.version ?? 0;\n const newer = applied.find((migration) => migration.version > latestSupported);\n if (newer !== undefined) {\n throw new Error(\n `pi-fleet database schema ${String(newer.version)} is newer than this runtime`,\n );\n }\n for (const existing of applied) {\n const expected = MIGRATIONS.find((migration) => migration.version === existing.version);\n if (expected === undefined || expected.checksum !== existing.checksum) {\n throw new Error(\n `pi-fleet database migration ${String(existing.version)} checksum mismatch`,\n );\n }\n }\n for (const migration of MIGRATIONS) {\n if (applied.some((existing) => existing.version === migration.version)) continue;\n this.#database.exec(migration.statements);\n this.#database\n .prepare(\"INSERT INTO schema_migrations(version, checksum, applied_at) VALUES(?, ?, ?)\")\n .run(migration.version, migration.checksum, new Date().toISOString());\n }\n this.#database.exec(\"COMMIT\");\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["path"]
|
|
7
|
-
}
|