@pleri/olam-cli 0.1.175 → 0.1.182
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/bin/olam.cjs +22 -0
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +67 -19
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +93 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/destroy.d.ts +41 -0
- package/dist/commands/destroy.d.ts.map +1 -1
- package/dist/commands/destroy.js +81 -33
- package/dist/commands/destroy.js.map +1 -1
- package/dist/commands/dispatch-resolve.d.ts +54 -0
- package/dist/commands/dispatch-resolve.d.ts.map +1 -0
- package/dist/commands/dispatch-resolve.js +105 -0
- package/dist/commands/dispatch-resolve.js.map +1 -0
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/dispatch.js +40 -9
- package/dist/commands/dispatch.js.map +1 -1
- package/dist/commands/flywheel/index.d.ts.map +1 -1
- package/dist/commands/flywheel/index.js +4 -0
- package/dist/commands/flywheel/index.js.map +1 -1
- package/dist/commands/flywheel/install-sessionstart-hook.d.ts +64 -0
- package/dist/commands/flywheel/install-sessionstart-hook.d.ts.map +1 -0
- package/dist/commands/flywheel/install-sessionstart-hook.js +197 -0
- package/dist/commands/flywheel/install-sessionstart-hook.js.map +1 -0
- package/dist/commands/flywheel/k5-validate.d.ts +31 -0
- package/dist/commands/flywheel/k5-validate.d.ts.map +1 -1
- package/dist/commands/flywheel/k5-validate.js +80 -19
- package/dist/commands/flywheel/k5-validate.js.map +1 -1
- package/dist/commands/flywheel/session-start.d.ts +26 -0
- package/dist/commands/flywheel/session-start.d.ts.map +1 -0
- package/dist/commands/flywheel/session-start.js +119 -0
- package/dist/commands/flywheel/session-start.js.map +1 -0
- package/dist/commands/host-cp.d.ts +0 -3
- package/dist/commands/host-cp.d.ts.map +1 -1
- package/dist/commands/host-cp.js +27 -2
- package/dist/commands/host-cp.js.map +1 -1
- package/dist/commands/kg-classify.d.ts.map +1 -1
- package/dist/commands/kg-classify.js +20 -0
- package/dist/commands/kg-classify.js.map +1 -1
- package/dist/commands/kg-doctor.d.ts +67 -6
- package/dist/commands/kg-doctor.d.ts.map +1 -1
- package/dist/commands/kg-doctor.js +126 -46
- package/dist/commands/kg-doctor.js.map +1 -1
- package/dist/commands/list.d.ts +27 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +67 -19
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/memory/status.d.ts +18 -0
- package/dist/commands/memory/status.d.ts.map +1 -1
- package/dist/commands/memory/status.js +38 -2
- package/dist/commands/memory/status.js.map +1 -1
- package/dist/commands/memory-service-container.d.ts +44 -0
- package/dist/commands/memory-service-container.d.ts.map +1 -1
- package/dist/commands/memory-service-container.js +49 -0
- package/dist/commands/memory-service-container.js.map +1 -1
- package/dist/commands/ps.d.ts +32 -0
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +34 -0
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/runbooks.d.ts +32 -0
- package/dist/commands/runbooks.d.ts.map +1 -1
- package/dist/commands/runbooks.js +79 -22
- package/dist/commands/runbooks.js.map +1 -1
- package/dist/commands/skills-source.d.ts.map +1 -1
- package/dist/commands/skills-source.js +77 -2
- package/dist/commands/skills-source.js.map +1 -1
- package/dist/commands/upgrade-history.d.ts +0 -2
- package/dist/commands/upgrade-history.d.ts.map +1 -1
- package/dist/commands/upgrade-history.js +0 -6
- package/dist/commands/upgrade-history.js.map +1 -1
- package/dist/commands/upgrade-lock.d.ts +0 -9
- package/dist/commands/upgrade-lock.d.ts.map +1 -1
- package/dist/commands/upgrade-lock.js +1 -1
- package/dist/commands/upgrade-lock.js.map +1 -1
- package/dist/commands/world-snapshot.d.ts +13 -0
- package/dist/commands/world-snapshot.d.ts.map +1 -1
- package/dist/commands/world-snapshot.js +81 -1
- package/dist/commands/world-snapshot.js.map +1 -1
- package/dist/commands/yolo.d.ts +95 -0
- package/dist/commands/yolo.d.ts.map +1 -0
- package/dist/commands/yolo.js +377 -0
- package/dist/commands/yolo.js.map +1 -0
- package/dist/image-digests.json +8 -8
- package/dist/index.js +3990 -2445
- package/dist/index.js.map +1 -1
- package/dist/lib/anthropic-base-url-file.d.ts +37 -0
- package/dist/lib/anthropic-base-url-file.d.ts.map +1 -0
- package/dist/lib/anthropic-base-url-file.js +46 -0
- package/dist/lib/anthropic-base-url-file.js.map +1 -0
- package/dist/lib/auth-remote.d.ts +9 -17
- package/dist/lib/auth-remote.d.ts.map +1 -1
- package/dist/lib/auth-remote.js +25 -20
- package/dist/lib/auth-remote.js.map +1 -1
- package/dist/lib/cf-access-token.d.ts +32 -0
- package/dist/lib/cf-access-token.d.ts.map +1 -0
- package/dist/lib/cf-access-token.js +52 -0
- package/dist/lib/cf-access-token.js.map +1 -0
- package/dist/lib/config.d.ts +17 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +28 -4
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/kubectl-context.d.ts +49 -0
- package/dist/lib/kubectl-context.d.ts.map +1 -1
- package/dist/lib/kubectl-context.js +64 -2
- package/dist/lib/kubectl-context.js.map +1 -1
- package/dist/lib/upgrade-kubernetes.d.ts +7 -0
- package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
- package/dist/lib/upgrade-kubernetes.js +35 -8
- package/dist/lib/upgrade-kubernetes.js.map +1 -1
- package/dist/mcp-server.js +1470 -991
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/45-pvc.yaml +6 -2
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- 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/50-deployment.yaml +1 -1
- package/host-cp/observability/trace-summary.mjs +267 -0
- package/host-cp/src/bootstrap-selective.mjs +58 -0
- package/host-cp/src/host-stream.mjs +52 -0
- package/host-cp/src/plan-chat-service.mjs +51 -0
- package/host-cp/src/redirect.mjs +159 -0
- package/host-cp/src/resolver.mjs +121 -0
- package/host-cp/src/router.mjs +168 -0
- package/host-cp/src/serve-only-config.mjs +85 -0
- package/host-cp/src/server.mjs +375 -205
- package/host-cp/src/world-services.mjs +136 -0
- package/package.json +1 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Service enrichment (Phase F-2-D dogfood fix) — extracted from server.mjs.
|
|
2
|
+
//
|
|
3
|
+
// Fetch port bindings for a world's container via docker-socket-proxy
|
|
4
|
+
// inspect, map each to a clickable URL tagged with well-known internal
|
|
5
|
+
// ports, and probe each for actual reachability.
|
|
6
|
+
//
|
|
7
|
+
// Extracted as a standalone module so the probe + enrichment logic can be
|
|
8
|
+
// unit-tested in isolation (server.mjs has module-level side effects that
|
|
9
|
+
// make direct import impractical). The two host-specific values that the
|
|
10
|
+
// inline version read from server.mjs module constants — HOST_FOR_WORLD and
|
|
11
|
+
// DOCKER_HOST — are injected as a `deps` object so the functions stay pure
|
|
12
|
+
// and deterministically testable.
|
|
13
|
+
|
|
14
|
+
export const WELL_KNOWN_PORTS = {
|
|
15
|
+
3000: 'atlas-core (Rails)',
|
|
16
|
+
5175: 'diner-app (Vite)',
|
|
17
|
+
7681: 'Terminal (ttyd)',
|
|
18
|
+
7682: 'Terminal Shell (ttyd)',
|
|
19
|
+
8080: 'Per-world CP',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Quick liveness probe against a service URL. Returns true if the
|
|
24
|
+
* service responds with ANY HTTP response (1xx-5xx) — we don't care
|
|
25
|
+
* about status codes because each app has its own conventions (Vite
|
|
26
|
+
* 200s on /, ttyd may 401, Rails may 500 on /, the per-world CP 200s).
|
|
27
|
+
* What matters is that something is listening.
|
|
28
|
+
*
|
|
29
|
+
* Probed from inside the host-cp container so we use hostForWorld
|
|
30
|
+
* (host.docker.internal on macOS/Windows, 172.17.0.1 on Linux) — the
|
|
31
|
+
* SPA's own 127.0.0.1:<port> URL is unreachable from container-side.
|
|
32
|
+
*
|
|
33
|
+
* Tight 800ms timeout. Worst case: 4 services × 800ms in parallel ≤ 1s
|
|
34
|
+
* added to the /api/worlds response — acceptable for a 4s poll cycle.
|
|
35
|
+
*
|
|
36
|
+
* @param {number} hostPort
|
|
37
|
+
* @param {{ hostForWorld: string }} deps
|
|
38
|
+
* @returns {Promise<boolean>}
|
|
39
|
+
*/
|
|
40
|
+
export async function probeServiceLive(hostPort, { hostForWorld }) {
|
|
41
|
+
const probeUrl = `http://${hostForWorld}:${hostPort}/`;
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(probeUrl, {
|
|
44
|
+
method: 'HEAD',
|
|
45
|
+
signal: AbortSignal.timeout(800),
|
|
46
|
+
redirect: 'manual',
|
|
47
|
+
});
|
|
48
|
+
return res.status > 0;
|
|
49
|
+
} catch {
|
|
50
|
+
// ECONNREFUSED, timeout, DNS — anything counts as not-live. Try
|
|
51
|
+
// GET as a fallback because some servers (e.g. ttyd) close on HEAD
|
|
52
|
+
// and we don't want false negatives from picky upstream behavior.
|
|
53
|
+
try {
|
|
54
|
+
const res2 = await fetch(probeUrl, {
|
|
55
|
+
method: 'GET',
|
|
56
|
+
signal: AbortSignal.timeout(800),
|
|
57
|
+
redirect: 'manual',
|
|
58
|
+
});
|
|
59
|
+
return res2.status > 0;
|
|
60
|
+
} catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the running container's port bindings from socket-proxy + map
|
|
68
|
+
* each to a clickable URL. Each service is then probed in parallel
|
|
69
|
+
* for actual reachability — the docker port mapping just tells us
|
|
70
|
+
* what's CONFIGURED; the probe confirms what's actually LISTENING.
|
|
71
|
+
*
|
|
72
|
+
* Returns [] on any docker-inspect failure (container missing, socket-
|
|
73
|
+
* proxy down) so the API still returns a valid worlds list.
|
|
74
|
+
*
|
|
75
|
+
* @param {string} worldId
|
|
76
|
+
* @param {{ hostForWorld: string, dockerHost: string }} deps
|
|
77
|
+
* @returns {Promise<Array<{name: string, host_port: number, internal_port: number, url: string, live: boolean}>>}
|
|
78
|
+
*/
|
|
79
|
+
export async function fetchWorldServices(worldId, { hostForWorld, dockerHost }) {
|
|
80
|
+
const containerName = `olam-${worldId}-devbox`;
|
|
81
|
+
let data;
|
|
82
|
+
try {
|
|
83
|
+
if (dockerHost === 'docker-cli') {
|
|
84
|
+
// Bare-node mode: shell out to `docker inspect` instead of HTTP.
|
|
85
|
+
// Same fix pattern as fetchContainerSecret (PR #108). Without
|
|
86
|
+
// this, the services array is always empty in bare-node and the
|
|
87
|
+
// SPA can't find the ttyd host port → terminal renders blank.
|
|
88
|
+
const { spawnSync } = await import('node:child_process');
|
|
89
|
+
const result = spawnSync(
|
|
90
|
+
'docker',
|
|
91
|
+
['inspect', containerName],
|
|
92
|
+
{ encoding: 'utf-8', timeout: 2000 },
|
|
93
|
+
);
|
|
94
|
+
if (result.status !== 0) return [];
|
|
95
|
+
const arr = JSON.parse(result.stdout || '[]');
|
|
96
|
+
data = Array.isArray(arr) && arr.length > 0 ? arr[0] : null;
|
|
97
|
+
if (!data) return [];
|
|
98
|
+
} else {
|
|
99
|
+
const apiBase = dockerHost.replace(/^tcp:\/\//, 'http://');
|
|
100
|
+
const res = await fetch(`${apiBase}/containers/${encodeURIComponent(containerName)}/json`, {
|
|
101
|
+
signal: AbortSignal.timeout(2000),
|
|
102
|
+
});
|
|
103
|
+
if (!res.ok) return [];
|
|
104
|
+
data = await res.json();
|
|
105
|
+
}
|
|
106
|
+
const ports = data?.NetworkSettings?.Ports ?? {};
|
|
107
|
+
const draft = [];
|
|
108
|
+
for (const [internal, bindings] of Object.entries(ports)) {
|
|
109
|
+
if (!Array.isArray(bindings) || bindings.length === 0) continue;
|
|
110
|
+
const internalPort = parseInt(internal.split('/')[0], 10);
|
|
111
|
+
const hostPort = parseInt(bindings[0].HostPort, 10);
|
|
112
|
+
if (!Number.isFinite(internalPort) || !Number.isFinite(hostPort)) continue;
|
|
113
|
+
draft.push({
|
|
114
|
+
name: WELL_KNOWN_PORTS[internalPort] ?? `App (port ${internalPort})`,
|
|
115
|
+
host_port: hostPort,
|
|
116
|
+
internal_port: internalPort,
|
|
117
|
+
url: `http://127.0.0.1:${hostPort}`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Probe each service in parallel for actual reachability. Adds a
|
|
122
|
+
// `live: boolean` field. The UI dims chips for non-live services
|
|
123
|
+
// so operators can see what's configured-but-down vs configured-
|
|
124
|
+
// and-up at a glance.
|
|
125
|
+
const liveResults = await Promise.all(
|
|
126
|
+
draft.map((s) => probeServiceLive(s.host_port, { hostForWorld })),
|
|
127
|
+
);
|
|
128
|
+
const services = draft.map((s, i) => ({ ...s, live: liveResults[i] }));
|
|
129
|
+
|
|
130
|
+
// Stable order: well-known ports first (CP, then Rails/Vite, then terminal).
|
|
131
|
+
services.sort((a, b) => a.internal_port - b.internal_port);
|
|
132
|
+
return services;
|
|
133
|
+
} catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|