@oalo-ai/cli 0.0.0-stage → 0.1.0
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 +21 -0
- package/README.md +392 -2
- package/man/oalo.1 +1530 -0
- package/package.json +44 -4
- package/plugin/.claude-plugin/plugin.json +12 -0
- package/plugin/skills/oalo/SKILL.md +414 -0
- package/src/api.js +132 -0
- package/src/app-ref.js +11 -0
- package/src/args.js +67 -0
- package/src/bot-settings.json +468 -0
- package/src/channel.js +162 -0
- package/src/commands/apps.js +64 -0
- package/src/commands/bots.js +278 -0
- package/src/commands/call.js +179 -0
- package/src/commands/channels.js +110 -0
- package/src/commands/data.js +446 -0
- package/src/commands/db.js +58 -0
- package/src/commands/deploy.js +431 -0
- package/src/commands/dockerfile.js +81 -0
- package/src/commands/docs.js +70 -0
- package/src/commands/emit.js +124 -0
- package/src/commands/env.js +223 -0
- package/src/commands/graphs.js +570 -0
- package/src/commands/incidents.js +44 -0
- package/src/commands/link.js +150 -0
- package/src/commands/login.js +180 -0
- package/src/commands/logs.js +69 -0
- package/src/commands/mcp.js +125 -0
- package/src/commands/metrics.js +168 -0
- package/src/commands/products.js +169 -0
- package/src/commands/qa.js +98 -0
- package/src/commands/rehearse.js +100 -0
- package/src/commands/run.js +152 -0
- package/src/commands/secrets.js +68 -0
- package/src/commands/setup.js +96 -0
- package/src/commands/skill.js +142 -0
- package/src/commands/sources.js +377 -0
- package/src/commands/switches.js +156 -0
- package/src/commands/tail.js +84 -0
- package/src/commands/tokens.js +85 -0
- package/src/commands/typegen.js +505 -0
- package/src/commands/whoami.js +112 -0
- package/src/config.js +157 -0
- package/src/data.js +392 -0
- package/src/envfile.js +71 -0
- package/src/events.js +63 -0
- package/src/graphfiles.js +273 -0
- package/src/help.js +920 -0
- package/src/index.js +216 -0
- package/src/mcp/tools.js +773 -0
- package/src/server.js +73 -0
- package/src/workspace.js +44 -0
package/src/server.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Version handshake with the workspace (GET /api/cli/version).
|
|
5
|
+
*
|
|
6
|
+
* A CLI and a box are updated separately, so either can be ahead. A command
|
|
7
|
+
* that needs new server code checks for its feature first and says which side
|
|
8
|
+
* is behind, instead of failing halfway with an error that reads like a bug.
|
|
9
|
+
* A box from before this endpoint answers 404: it supports none of the
|
|
10
|
+
* features listed here, and so does one whose catch-all route answers with
|
|
11
|
+
* the dashboard page.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const CLI_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
15
|
+
|
|
16
|
+
const NO_FEATURES = { api: 1, min_cli: null, features: [] };
|
|
17
|
+
|
|
18
|
+
/** `{api, min_cli, features}`, NO_FEATURES for a box that predates the endpoint, or null if unreachable. */
|
|
19
|
+
export async function serverInfo(url) {
|
|
20
|
+
let res;
|
|
21
|
+
try {
|
|
22
|
+
res = await fetch(`${url.replace(/\/$/, "")}/api/cli/version`);
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (res.status === 404) return NO_FEATURES;
|
|
27
|
+
if (!res.ok) return null;
|
|
28
|
+
// An older box can answer 200 with the dashboard's HTML (its catch-all
|
|
29
|
+
// route), so only a JSON reply with a feature list counts.
|
|
30
|
+
try {
|
|
31
|
+
const info = await res.json();
|
|
32
|
+
return Array.isArray(info?.features) ? info : NO_FEATURES;
|
|
33
|
+
} catch {
|
|
34
|
+
return NO_FEATURES;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** -1, 0 or 1, comparing dotted versions numerically ("0.10.0" > "0.9.1"). */
|
|
39
|
+
export function compareVersions(a, b) {
|
|
40
|
+
const pa = String(a).split(".").map(Number);
|
|
41
|
+
const pb = String(b).split(".").map(Number);
|
|
42
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
43
|
+
const d = (pa[i] || 0) - (pb[i] || 0);
|
|
44
|
+
if (d) return d > 0 ? 1 : -1;
|
|
45
|
+
}
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Why this CLI can't talk to the server, or null when it can. */
|
|
50
|
+
export function cliTooOld(info) {
|
|
51
|
+
if (info?.min_cli && compareVersions(CLI_VERSION, info.min_cli) < 0) {
|
|
52
|
+
return `This workspace needs @oalo-ai/cli ${info.min_cli} or newer (you have ${CLI_VERSION}). Update with: npm i -g @oalo-ai/cli`;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Throw a readable error unless the workspace supports `feature`. `what` names
|
|
59
|
+
* the command for the message, e.g. "oalo emit". An unreachable server passes:
|
|
60
|
+
* the command's own connect error says that better.
|
|
61
|
+
*/
|
|
62
|
+
export async function requireFeature(url, feature, what) {
|
|
63
|
+
const info = await serverInfo(url);
|
|
64
|
+
if (!info) return null;
|
|
65
|
+
const old = cliTooOld(info);
|
|
66
|
+
if (old) throw new Error(old);
|
|
67
|
+
if (!info.features.includes(feature)) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`${url} runs an older OALO than this CLI, so \`${what}\` isn't available there yet. It will be once the workspace is updated.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return info;
|
|
73
|
+
}
|
package/src/workspace.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OaloChannel } from "./channel.js";
|
|
2
|
+
import { resolve as resolveConfig, controlPlane, HOW_TO_CONNECT } from "./config.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Open the build-surface channel with the linked CLI token (control plane).
|
|
6
|
+
* Falls back to the most recently linked workspace when this project has none,
|
|
7
|
+
* like `oalo run`. Returns null after printing how to link when there is no
|
|
8
|
+
* token, so commands can exit 2 without a stack trace.
|
|
9
|
+
*/
|
|
10
|
+
export async function openWorkspace(flags, command) {
|
|
11
|
+
const cfg = resolveConfig(flags);
|
|
12
|
+
const { url, token } = controlPlane(cfg);
|
|
13
|
+
|
|
14
|
+
if (!url || !token) {
|
|
15
|
+
console.error(
|
|
16
|
+
`oalo ${command} needs a CLI token.\n\n${HOW_TO_CONNECT}`,
|
|
17
|
+
);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ch = new OaloChannel({ url, token });
|
|
22
|
+
await ch.connect();
|
|
23
|
+
return { ch, url, env: cfg.env };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Print lint findings, most severe first. Returns {errors, warnings, infos}. */
|
|
27
|
+
export function printFindings(findings, { label = "", verbose = false } = {}) {
|
|
28
|
+
const counts = { errors: 0, warnings: 0, infos: 0 };
|
|
29
|
+
const mark = { error: "error ", warning: "warning", info: "info " };
|
|
30
|
+
|
|
31
|
+
for (const f of findings || []) {
|
|
32
|
+
if (f.severity === "error") counts.errors++;
|
|
33
|
+
else if (f.severity === "warning") counts.warnings++;
|
|
34
|
+
else counts.infos++;
|
|
35
|
+
|
|
36
|
+
if (f.severity === "info" && !verbose) continue;
|
|
37
|
+
const where = f.node_id ? `${f.node_id}: ` : f.edge_index != null ? `edge #${f.edge_index}: ` : "";
|
|
38
|
+
console.log(` ${mark[f.severity] || f.severity} ${label}${where}${f.detail}`);
|
|
39
|
+
if (f.suggestion) console.log(` fix: ${f.suggestion}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (counts.infos && !verbose) console.log(` (${counts.infos} info finding(s) hidden; --verbose shows them)`);
|
|
43
|
+
return counts;
|
|
44
|
+
}
|