@pleri/olam-cli 0.1.158 → 0.1.160
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/dist/agent-stream/agent-sdk-to-chunks.js +3 -0
- package/dist/agent-stream/driver-runner.js +9 -4
- package/dist/agent-stream/host-driver-launch.js +48 -0
- package/dist/commands/doctor.d.ts +21 -10
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +95 -39
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.d.ts +30 -2
- package/dist/commands/flywheel/check-persona-skeleton.d.ts.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.js +143 -6
- package/dist/commands/flywheel/check-persona-skeleton.js.map +1 -1
- package/dist/commands/flywheel/diversity-check.d.ts +12 -2
- package/dist/commands/flywheel/diversity-check.d.ts.map +1 -1
- package/dist/commands/flywheel/diversity-check.js +56 -6
- package/dist/commands/flywheel/diversity-check.js.map +1 -1
- package/dist/commands/flywheel/index.d.ts.map +1 -1
- package/dist/commands/flywheel/index.js +2 -0
- package/dist/commands/flywheel/index.js.map +1 -1
- package/dist/commands/flywheel/install-shims.d.ts +36 -3
- package/dist/commands/flywheel/install-shims.d.ts.map +1 -1
- package/dist/commands/flywheel/install-shims.js +118 -7
- package/dist/commands/flywheel/install-shims.js.map +1 -1
- package/dist/commands/flywheel/k10-measure.d.ts +12 -2
- package/dist/commands/flywheel/k10-measure.d.ts.map +1 -1
- package/dist/commands/flywheel/k10-measure.js +55 -6
- package/dist/commands/flywheel/k10-measure.js.map +1 -1
- package/dist/commands/flywheel/migrate-overlays.d.ts +115 -0
- package/dist/commands/flywheel/migrate-overlays.d.ts.map +1 -0
- package/dist/commands/flywheel/migrate-overlays.js +766 -0
- package/dist/commands/flywheel/migrate-overlays.js.map +1 -0
- package/dist/commands/flywheel/sanitize-persona-output.d.ts +33 -2
- package/dist/commands/flywheel/sanitize-persona-output.d.ts.map +1 -1
- package/dist/commands/flywheel/sanitize-persona-output.js +94 -6
- package/dist/commands/flywheel/sanitize-persona-output.js.map +1 -1
- package/dist/commands/memory/index.d.ts.map +1 -1
- package/dist/commands/memory/index.js +2 -0
- package/dist/commands/memory/index.js.map +1 -1
- package/dist/commands/memory/install-hooks.d.ts +22 -0
- package/dist/commands/memory/install-hooks.d.ts.map +1 -0
- package/dist/commands/memory/install-hooks.js +156 -0
- package/dist/commands/memory/install-hooks.js.map +1 -0
- package/dist/commands/skills-doctor.js +2 -2
- package/dist/commands/skills-doctor.js.map +1 -1
- package/dist/commands/skills-source.d.ts.map +1 -1
- package/dist/commands/skills-source.js +10 -0
- package/dist/commands/skills-source.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +169 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/image-digests.json +7 -7
- package/dist/index.js +3592 -905
- package/dist/index.js.map +1 -1
- package/dist/lib/flywheel-probes.d.ts +58 -0
- package/dist/lib/flywheel-probes.d.ts.map +1 -0
- package/dist/lib/flywheel-probes.js +163 -0
- package/dist/lib/flywheel-probes.js.map +1 -0
- package/dist/lib/host-side-proxy.d.ts +67 -0
- package/dist/lib/host-side-proxy.d.ts.map +1 -0
- package/dist/lib/host-side-proxy.js +177 -0
- package/dist/lib/host-side-proxy.js.map +1 -0
- package/dist/lib/shim-generator.d.ts +51 -0
- package/dist/lib/shim-generator.d.ts.map +1 -0
- package/dist/lib/shim-generator.js +88 -0
- package/dist/lib/shim-generator.js.map +1 -0
- package/dist/lib/skills-apply-overlays.d.ts +35 -0
- package/dist/lib/skills-apply-overlays.d.ts.map +1 -0
- package/dist/lib/skills-apply-overlays.js +243 -0
- package/dist/lib/skills-apply-overlays.js.map +1 -0
- package/dist/lib/upgrade-kubernetes.d.ts +13 -12
- package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
- package/dist/lib/upgrade-kubernetes.js +87 -134
- package/dist/lib/upgrade-kubernetes.js.map +1 -1
- package/dist/mcp-server.js +1106 -453
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/host-side/docker-socket-proxy.compose.yaml +58 -0
- package/host-cp/k8s/manifests/50-deployment.yaml +47 -70
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/docker-socket-proxy/60-service.yaml +37 -0
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/30-configmap.yaml +11 -0
- package/host-cp/k8s/manifests/memory-service/35-configmap-iii-config.yaml +76 -0
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +11 -1
- package/host-cp/src/crystallize-planning.mjs +261 -0
- package/host-cp/src/plan-chat-service.mjs +84 -2
- package/host-cp/src/planning-sessions.mjs +270 -0
- package/host-cp/src/server.mjs +9 -0
- package/host-cp/src/tasks-route.mjs +191 -0
- package/package.json +1 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// packages/host-cp/src/tasks-route.mjs
|
|
2
|
+
//
|
|
3
|
+
// B2.2: mount @olam/tasks-write-api's framework-neutral handlers under
|
|
4
|
+
// /api/tasks/*. host-cp owns the pg.Pool (per D-B-19 olam-local-PG-primary);
|
|
5
|
+
// wraps it via pgPoolExecutor (B2.1.1 adapter) and passes as HandlerDeps.pglite
|
|
6
|
+
// (duck-typed; PgExecutor's query/exec/transaction match PGlite's shape).
|
|
7
|
+
//
|
|
8
|
+
// Auth model: leverages host-cp's existing StartupToken bearer gate (Authorization:
|
|
9
|
+
// Bearer <token>). Per-request scopes + olamNodeId come from headers:
|
|
10
|
+
// X-Olam-Node-Id: UUID of the caller's olam node (sets RLS scope per D-B-23)
|
|
11
|
+
// X-Olam-Session-Id: UUID of the caller's session row (FK for task_claims)
|
|
12
|
+
// X-Olam-Tasks-Scopes: comma-separated scope list (tasks-create,tasks-claim,
|
|
13
|
+
// tasks-state-update,tasks-query). Trust model: bearer
|
|
14
|
+
// token gates access; scope header lets the caller declare
|
|
15
|
+
// narrower intent.
|
|
16
|
+
//
|
|
17
|
+
// Deviation from B2.2 plan spec: spec called for JWT + auth-service integration;
|
|
18
|
+
// host-cp uses opaque tokens (StartupToken) and HTTP calls auth-service via HTTP.
|
|
19
|
+
// JWT scope encoding deferred to Phase D++ when multi-user auth lands; for v1,
|
|
20
|
+
// the existing bearer + per-request header model is sufficient (single-operator;
|
|
21
|
+
// 127.0.0.1:19000 only per host-cp threat model).
|
|
22
|
+
|
|
23
|
+
import pg from 'pg';
|
|
24
|
+
|
|
25
|
+
// Treat BIGINT (OID 20) as Number, not the default string. The tasks schema's
|
|
26
|
+
// `version` column is BIGINT but stays well within Number-safe range; without
|
|
27
|
+
// this parser pg returns the value as a string, and the task-store types
|
|
28
|
+
// declare it as `number`, letting a stray BigInt propagate (PGlite returns
|
|
29
|
+
// BigInt by default). JSON.stringify on BigInt throws — caused /api/tasks
|
|
30
|
+
// 500s with "Do not know how to serialize a BigInt" during the CLI E2E proof.
|
|
31
|
+
pg.types.setTypeParser(20, (v) => (v == null ? null : Number.parseInt(v, 10)));
|
|
32
|
+
|
|
33
|
+
let writeApi = null; // lazy-load tasks-write-api to keep cold-path light
|
|
34
|
+
let executor = null;
|
|
35
|
+
let pool = null;
|
|
36
|
+
|
|
37
|
+
const VALID_SCOPES = new Set(['tasks-create', 'tasks-claim', 'tasks-state-update', 'tasks-query']);
|
|
38
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
39
|
+
|
|
40
|
+
async function ensureWriteApi() {
|
|
41
|
+
if (writeApi) return writeApi;
|
|
42
|
+
// Dynamic import: tasks-write-api is built TS (ESM dist). Fail-loud if not
|
|
43
|
+
// built — operator must `npm run build --workspace=@olam/tasks-write-api`
|
|
44
|
+
// before host-cp starts.
|
|
45
|
+
writeApi = await import('@olam/tasks-write-api');
|
|
46
|
+
return writeApi;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function ensureExecutor() {
|
|
50
|
+
if (executor) return executor;
|
|
51
|
+
const connectionString = process.env.OLAM_LOCAL_PG_URL;
|
|
52
|
+
if (!connectionString) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
'tasks-route: OLAM_LOCAL_PG_URL not set. Bring up Docker PG: docker compose -f packages/infra/docker-compose.local-electric.yml up -d, then export OLAM_LOCAL_PG_URL=postgres://postgres:olam@localhost:54331/olam_tasks',
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
pool = new pg.Pool({ connectionString, max: 8 });
|
|
58
|
+
// Lazy require pgPoolExecutor from the same dynamic-imported module.
|
|
59
|
+
// ensureWriteApi must have run first; tasks-route's dispatch order guarantees it.
|
|
60
|
+
return writeApi.pgPoolExecutor(pool);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parseAuth(req) {
|
|
64
|
+
const olamNodeId = req.headers['x-olam-node-id'];
|
|
65
|
+
const sessionId = req.headers['x-olam-session-id'];
|
|
66
|
+
const scopesHeader = req.headers['x-olam-tasks-scopes'] ?? '';
|
|
67
|
+
const scopes = String(scopesHeader)
|
|
68
|
+
.split(',')
|
|
69
|
+
.map((s) => s.trim())
|
|
70
|
+
.filter((s) => VALID_SCOPES.has(s));
|
|
71
|
+
if (!olamNodeId || !UUID_RE.test(String(olamNodeId))) return null;
|
|
72
|
+
if (!sessionId || !UUID_RE.test(String(sessionId))) return null;
|
|
73
|
+
if (scopes.length === 0) return null;
|
|
74
|
+
return { olamNodeId: String(olamNodeId), sessionId: String(sessionId), scopes };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function readBody(req) {
|
|
78
|
+
if (req.method === 'GET' || req.method === 'HEAD') return {};
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
let raw = '';
|
|
81
|
+
req.on('data', (chunk) => (raw += chunk));
|
|
82
|
+
req.on('end', () => {
|
|
83
|
+
if (!raw) return resolve({});
|
|
84
|
+
try {
|
|
85
|
+
resolve(JSON.parse(raw));
|
|
86
|
+
} catch {
|
|
87
|
+
resolve({ __invalid: true });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
req.on('error', reject);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function sendEnvelope(res, status, envelope) {
|
|
95
|
+
res.statusCode = status;
|
|
96
|
+
res.setHeader('Content-Type', 'application/json');
|
|
97
|
+
// BigInt-safe serialization. @olam/tasks's task-store wraps `version`
|
|
98
|
+
// (and any future BIGINT fields) in BigInt() during row→Task mapping;
|
|
99
|
+
// default JSON.stringify throws on BigInt. The values stay safely
|
|
100
|
+
// within Number range (version starts at 0, increments per mutation),
|
|
101
|
+
// so emitting as a JSON number is lossless for any realistic load.
|
|
102
|
+
res.end(JSON.stringify(envelope, (_key, value) =>
|
|
103
|
+
typeof value === 'bigint' ? Number(value) : value,
|
|
104
|
+
));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Dispatch a /api/tasks/* request. Returns true if handled; false if route
|
|
109
|
+
* doesn't match (caller continues to next dispatcher in server.mjs).
|
|
110
|
+
*/
|
|
111
|
+
export async function dispatchTasksRoute(req, res, url) {
|
|
112
|
+
const pathname = url.pathname;
|
|
113
|
+
if (!pathname.startsWith('/api/tasks')) return false;
|
|
114
|
+
|
|
115
|
+
// Lazy initialise on first request (avoids boot-time crash when PG not up).
|
|
116
|
+
let api;
|
|
117
|
+
try {
|
|
118
|
+
api = await ensureWriteApi();
|
|
119
|
+
} catch (e) {
|
|
120
|
+
sendEnvelope(res, 500, { success: false, data: null, error: `tasks-write-api unbuilt: ${e.message}` });
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
let exec;
|
|
124
|
+
try {
|
|
125
|
+
exec = ensureExecutor();
|
|
126
|
+
} catch (e) {
|
|
127
|
+
sendEnvelope(res, 503, { success: false, data: null, error: e.message });
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const auth = parseAuth(req);
|
|
132
|
+
if (!auth) {
|
|
133
|
+
sendEnvelope(res, 401, {
|
|
134
|
+
success: false,
|
|
135
|
+
data: null,
|
|
136
|
+
error: 'Missing or malformed X-Olam-Node-Id / X-Olam-Session-Id / X-Olam-Tasks-Scopes headers',
|
|
137
|
+
});
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const body = await readBody(req);
|
|
142
|
+
if (body && body.__invalid) {
|
|
143
|
+
sendEnvelope(res, 400, { success: false, data: null, error: 'Invalid JSON body' });
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Route matching — minimal pattern (host-cp's existing if-ladder style).
|
|
148
|
+
const segments = pathname.split('/').filter(Boolean); // ['api','tasks',...]
|
|
149
|
+
const ctx = { auth, params: {}, query: Object.fromEntries(url.searchParams) };
|
|
150
|
+
const deps = { pglite: exec };
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
let response;
|
|
154
|
+
if (segments.length === 2 && req.method === 'POST') {
|
|
155
|
+
response = await api.createHandler({ ...ctx, body }, deps);
|
|
156
|
+
} else if (segments.length === 2 && req.method === 'GET') {
|
|
157
|
+
response = await api.queryHandler({ ...ctx, body }, deps);
|
|
158
|
+
} else if (segments.length === 3 && segments[2] === 'claim' && req.method === 'POST') {
|
|
159
|
+
response = await api.claimHandler({ ...ctx, body }, deps);
|
|
160
|
+
} else if (segments.length === 3 && segments[2] === 'distill' && req.method === 'GET') {
|
|
161
|
+
response = await api.distillHandler({ ...ctx, body }, deps);
|
|
162
|
+
} else if (segments.length === 4 && segments[3] === 'heartbeat' && req.method === 'POST') {
|
|
163
|
+
ctx.params.id = segments[2];
|
|
164
|
+
response = await api.heartbeatHandler({ ...ctx, body }, deps);
|
|
165
|
+
} else if (segments.length === 4 && segments[3] === 'complete' && req.method === 'POST') {
|
|
166
|
+
ctx.params.id = segments[2];
|
|
167
|
+
response = await api.completeHandler({ ...ctx, body }, deps);
|
|
168
|
+
} else if (segments.length === 4 && segments[3] === 'update' && req.method === 'POST') {
|
|
169
|
+
ctx.params.id = segments[2];
|
|
170
|
+
response = await api.updateHandler({ ...ctx, body }, deps);
|
|
171
|
+
} else {
|
|
172
|
+
sendEnvelope(res, 404, { success: false, data: null, error: `Unknown /api/tasks route: ${req.method} ${pathname}` });
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
sendEnvelope(res, response.status, response.envelope);
|
|
177
|
+
return true;
|
|
178
|
+
} catch (e) {
|
|
179
|
+
console.error('[tasks-route] handler error:', e);
|
|
180
|
+
sendEnvelope(res, 500, { success: false, data: null, error: e?.message ?? 'internal error' });
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Test surface — for unit tests to reset module state between cases.
|
|
186
|
+
export function _resetForTests() {
|
|
187
|
+
writeApi = null;
|
|
188
|
+
executor = null;
|
|
189
|
+
if (pool) pool.end().catch(() => undefined);
|
|
190
|
+
pool = null;
|
|
191
|
+
}
|