@odla-ai/cli 0.26.2 → 0.27.1
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/bin.cjs +291 -135
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-MBZXWPZP.js → chunk-4JWDJN3P.js} +175 -14
- package/dist/chunk-4JWDJN3P.js.map +1 -0
- package/dist/index.cjs +291 -135
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-MBZXWPZP.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -138,7 +138,7 @@ import process2 from "process";
|
|
|
138
138
|
async function openUrl(url, options = {}) {
|
|
139
139
|
const command = openerFor(options.platform ?? process2.platform);
|
|
140
140
|
const doSpawn = options.spawnImpl ?? spawn;
|
|
141
|
-
await new Promise((
|
|
141
|
+
await new Promise((resolve13, reject) => {
|
|
142
142
|
const child = doSpawn(command.cmd, [...command.args, url], {
|
|
143
143
|
stdio: "ignore",
|
|
144
144
|
detached: true
|
|
@@ -146,7 +146,7 @@ async function openUrl(url, options = {}) {
|
|
|
146
146
|
child.once("error", reject);
|
|
147
147
|
child.once("spawn", () => {
|
|
148
148
|
child.unref();
|
|
149
|
-
|
|
149
|
+
resolve13();
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
}
|
|
@@ -312,6 +312,7 @@ async function freshHandshake(ctx, waitMs) {
|
|
|
312
312
|
endpoint: ctx.cfg.platformUrl,
|
|
313
313
|
email: ctx.email,
|
|
314
314
|
label: `${ctx.cfg.app.id} provisioner`,
|
|
315
|
+
projectIds: [ctx.cfg.app.id],
|
|
315
316
|
fetch: ctx.doFetch,
|
|
316
317
|
waitMs,
|
|
317
318
|
onCode: async ({ userCode, deviceCode, expiresIn, interval, verificationUriComplete }) => {
|
|
@@ -1444,8 +1445,8 @@ function credential(value2) {
|
|
|
1444
1445
|
// src/calendar-poll.ts
|
|
1445
1446
|
async function waitForCalendarPoll(milliseconds, signal) {
|
|
1446
1447
|
if (signal?.aborted) throw signal.reason ?? new Error("calendar connection aborted");
|
|
1447
|
-
await new Promise((
|
|
1448
|
-
const timer = setTimeout(
|
|
1448
|
+
await new Promise((resolve13, reject) => {
|
|
1449
|
+
const timer = setTimeout(resolve13, milliseconds);
|
|
1449
1450
|
signal?.addEventListener("abort", () => {
|
|
1450
1451
|
clearTimeout(timer);
|
|
1451
1452
|
reject(signal.reason ?? new Error("calendar connection aborted"));
|
|
@@ -2083,7 +2084,7 @@ async function configOperationWait(options) {
|
|
|
2083
2084
|
assertOperationId(options.operationId);
|
|
2084
2085
|
const cfg = await loadProjectConfig(options.configPath);
|
|
2085
2086
|
const client = await operationClient(cfg, options, "wait");
|
|
2086
|
-
const wait2 = options.pollWait ?? ((ms) => new Promise((
|
|
2087
|
+
const wait2 = options.pollWait ?? ((ms) => new Promise((resolve13) => setTimeout(resolve13, ms)));
|
|
2087
2088
|
const now = () => (options.now?.() ?? /* @__PURE__ */ new Date()).getTime();
|
|
2088
2089
|
const deadline = now() + (options.timeoutSeconds ?? DEFAULT_WAIT_SECONDS) * 1e3;
|
|
2089
2090
|
const interval = (options.intervalSeconds ?? DEFAULT_INTERVAL_SECONDS) * 1e3;
|
|
@@ -3766,8 +3767,8 @@ function hostedPollTimeout(value2 = 10 * 6e4) {
|
|
|
3766
3767
|
}
|
|
3767
3768
|
async function waitForHostedPoll(milliseconds, signal) {
|
|
3768
3769
|
if (signal?.aborted) throw signal.reason ?? new DOMException("aborted", "AbortError");
|
|
3769
|
-
await new Promise((
|
|
3770
|
-
const timer = setTimeout(
|
|
3770
|
+
await new Promise((resolve13, reject) => {
|
|
3771
|
+
const timer = setTimeout(resolve13, milliseconds);
|
|
3771
3772
|
signal?.addEventListener("abort", () => {
|
|
3772
3773
|
clearTimeout(timer);
|
|
3773
3774
|
reject(signal.reason ?? new DOMException("aborted", "AbortError"));
|
|
@@ -7513,6 +7514,7 @@ var COMMAND_SURFACE = {
|
|
|
7513
7514
|
promote: {},
|
|
7514
7515
|
owners: { list: {}, add: {}, remove: {} }
|
|
7515
7516
|
},
|
|
7517
|
+
brand: { design: { unpack: {} } },
|
|
7516
7518
|
calendar: { status: {}, calendars: {}, connect: {}, disconnect: {} },
|
|
7517
7519
|
capabilities: {},
|
|
7518
7520
|
code: { connect: {} },
|
|
@@ -8879,6 +8881,158 @@ async function appCommand(parsed, dependencies = {}) {
|
|
|
8879
8881
|
else await appRestore(options);
|
|
8880
8882
|
}
|
|
8881
8883
|
|
|
8884
|
+
// src/brand-command.ts
|
|
8885
|
+
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
8886
|
+
import { dirname as dirname8, resolve as resolve12 } from "path";
|
|
8887
|
+
|
|
8888
|
+
// src/brand-design-unpack.ts
|
|
8889
|
+
import { gunzipSync } from "zlib";
|
|
8890
|
+
import {
|
|
8891
|
+
digestDesignBundle,
|
|
8892
|
+
parseDesignBundle,
|
|
8893
|
+
readDesignManifest,
|
|
8894
|
+
renderTokensCss
|
|
8895
|
+
} from "@odla-ai/brand";
|
|
8896
|
+
var EXTENSIONS = {
|
|
8897
|
+
"image/png": "png",
|
|
8898
|
+
"image/jpeg": "jpg",
|
|
8899
|
+
"image/gif": "gif",
|
|
8900
|
+
"image/webp": "webp",
|
|
8901
|
+
"image/svg+xml": "svg",
|
|
8902
|
+
"image/avif": "avif",
|
|
8903
|
+
"font/woff2": "woff2",
|
|
8904
|
+
"font/woff": "woff",
|
|
8905
|
+
"font/ttf": "ttf",
|
|
8906
|
+
"font/otf": "otf",
|
|
8907
|
+
"text/javascript": "js",
|
|
8908
|
+
"application/javascript": "js",
|
|
8909
|
+
"text/css": "css",
|
|
8910
|
+
"text/html": "html",
|
|
8911
|
+
"application/json": "json"
|
|
8912
|
+
};
|
|
8913
|
+
var encode = (text2) => new TextEncoder().encode(text2);
|
|
8914
|
+
function assetFileName(uuid, mime) {
|
|
8915
|
+
const ext = EXTENSIONS[mime.split(";")[0].trim().toLowerCase()] ?? "bin";
|
|
8916
|
+
return `${uuid.replace(/[^a-zA-Z0-9._-]/g, "_")}.${ext}`;
|
|
8917
|
+
}
|
|
8918
|
+
function decodePayload(data, compressed) {
|
|
8919
|
+
const raw = Buffer.from(data, "base64");
|
|
8920
|
+
return new Uint8Array(compressed ? gunzipSync(raw) : raw);
|
|
8921
|
+
}
|
|
8922
|
+
function rewriteReferences(template, assetPaths, pagePaths) {
|
|
8923
|
+
let out = template;
|
|
8924
|
+
for (const [uuid, path] of pagePaths) {
|
|
8925
|
+
out = out.split(`about:blank#${uuid}`).join(path);
|
|
8926
|
+
}
|
|
8927
|
+
for (const [uuid, path] of assetPaths) {
|
|
8928
|
+
out = out.split(uuid).join(path);
|
|
8929
|
+
}
|
|
8930
|
+
return out;
|
|
8931
|
+
}
|
|
8932
|
+
function tokensCss(digest) {
|
|
8933
|
+
if (Object.keys(digest.tokens.light).length === 0) return null;
|
|
8934
|
+
return renderTokensCss(digest.tokens.light, { dark: digest.tokens.dark });
|
|
8935
|
+
}
|
|
8936
|
+
function unpackDesign(html) {
|
|
8937
|
+
const bundle = parseDesignBundle(html);
|
|
8938
|
+
const manifest = readDesignManifest(html);
|
|
8939
|
+
const digest = digestDesignBundle(bundle);
|
|
8940
|
+
const pageUuids = new Set(bundle.pageOrder);
|
|
8941
|
+
const files = [];
|
|
8942
|
+
const failed = [];
|
|
8943
|
+
const assetPaths = /* @__PURE__ */ new Map();
|
|
8944
|
+
const pagePaths = /* @__PURE__ */ new Map();
|
|
8945
|
+
for (const [uuid, entry] of Object.entries(manifest)) {
|
|
8946
|
+
let bytes;
|
|
8947
|
+
try {
|
|
8948
|
+
bytes = decodePayload(entry.data, entry.compressed);
|
|
8949
|
+
} catch {
|
|
8950
|
+
failed.push(uuid);
|
|
8951
|
+
continue;
|
|
8952
|
+
}
|
|
8953
|
+
if (pageUuids.has(uuid)) {
|
|
8954
|
+
const path2 = `pages/${assetFileName(uuid, "text/html")}`;
|
|
8955
|
+
pagePaths.set(uuid, `./${path2}`);
|
|
8956
|
+
files.push({ path: path2, bytes });
|
|
8957
|
+
continue;
|
|
8958
|
+
}
|
|
8959
|
+
const path = `assets/${assetFileName(uuid, entry.mime)}`;
|
|
8960
|
+
assetPaths.set(uuid, `./${path}`);
|
|
8961
|
+
files.push({ path, bytes });
|
|
8962
|
+
}
|
|
8963
|
+
files.push({
|
|
8964
|
+
path: "index.html",
|
|
8965
|
+
bytes: encode(rewriteReferences(bundle.template, assetPaths, pagePaths))
|
|
8966
|
+
});
|
|
8967
|
+
files.push({ path: "digest.json", bytes: encode(`${JSON.stringify(digest, null, 2)}
|
|
8968
|
+
`) });
|
|
8969
|
+
const css = tokensCss(digest);
|
|
8970
|
+
if (css !== null) files.push({ path: "tokens.css", bytes: encode(css) });
|
|
8971
|
+
if (bundle.thumbnailSvg) files.push({ path: "thumbnail.svg", bytes: encode(bundle.thumbnailSvg) });
|
|
8972
|
+
return { files, digest, failed };
|
|
8973
|
+
}
|
|
8974
|
+
function describeUnpack(result, outDir) {
|
|
8975
|
+
const { digest } = result;
|
|
8976
|
+
const lines = [
|
|
8977
|
+
`Unpacked ${digest.title ? `"${digest.title}"` : "design"} into ${outDir}`,
|
|
8978
|
+
` index.html the design, offline-runnable (${digest.templateBytes} bytes)`,
|
|
8979
|
+
` assets/ ${digest.assetCount} embedded files (${digest.assetBytes} bytes)`,
|
|
8980
|
+
` digest.json ${Object.keys(digest.tokens.light).length} --ui-* tokens, ${digest.props.length} props, ${digest.outline.length} headings`
|
|
8981
|
+
];
|
|
8982
|
+
if (result.files.some((f) => f.path === "tokens.css"))
|
|
8983
|
+
lines.push(" tokens.css the design's tokens as an @odla-ai/ui theme sheet");
|
|
8984
|
+
if (digest.fonts.length > 0) lines.push(`Typefaces: ${digest.fonts.join(", ")}`);
|
|
8985
|
+
if (result.failed.length > 0)
|
|
8986
|
+
lines.push(`WARNING: ${result.failed.length} embedded asset(s) could not be decoded.`);
|
|
8987
|
+
return lines;
|
|
8988
|
+
}
|
|
8989
|
+
|
|
8990
|
+
// src/brand-command.ts
|
|
8991
|
+
var USAGE = "usage: odla-ai brand design unpack <bundle.html|-> [--out <dir>] [--json]";
|
|
8992
|
+
async function readBundle(source, deps) {
|
|
8993
|
+
if (source !== "-") return readFile3(resolve12(source), "utf8");
|
|
8994
|
+
const readStdin = deps.readStdin;
|
|
8995
|
+
if (!readStdin) throw new Error("reading a bundle from stdin is not supported here");
|
|
8996
|
+
return readStdin();
|
|
8997
|
+
}
|
|
8998
|
+
async function writeAll(result, outDir) {
|
|
8999
|
+
for (const file of result.files) {
|
|
9000
|
+
const target = resolve12(outDir, file.path);
|
|
9001
|
+
await mkdir4(dirname8(target), { recursive: true });
|
|
9002
|
+
await writeFile4(target, file.bytes);
|
|
9003
|
+
}
|
|
9004
|
+
}
|
|
9005
|
+
async function designUnpack(parsed, deps) {
|
|
9006
|
+
assertArgs(parsed, ["out", "json"], 4);
|
|
9007
|
+
const source = parsed.positionals[3];
|
|
9008
|
+
if (!source) throw new Error(USAGE);
|
|
9009
|
+
const outDir = resolve12(stringOpt(parsed.options.out) ?? "design");
|
|
9010
|
+
const result = unpackDesign(await readBundle(source, deps));
|
|
9011
|
+
await writeAll(result, outDir);
|
|
9012
|
+
const out = deps.stdout ?? console;
|
|
9013
|
+
if (parsed.options.json === true) {
|
|
9014
|
+
out.log(
|
|
9015
|
+
JSON.stringify({
|
|
9016
|
+
outDir,
|
|
9017
|
+
files: result.files.map((f) => f.path),
|
|
9018
|
+
failed: result.failed,
|
|
9019
|
+
digest: result.digest
|
|
9020
|
+
})
|
|
9021
|
+
);
|
|
9022
|
+
return;
|
|
9023
|
+
}
|
|
9024
|
+
for (const line of describeUnpack(result, outDir)) out.log(line);
|
|
9025
|
+
}
|
|
9026
|
+
async function brandCommand(parsed, deps) {
|
|
9027
|
+
const subject = parsed.positionals[1];
|
|
9028
|
+
const action2 = parsed.positionals[2];
|
|
9029
|
+
if (subject === "design" && action2 === "unpack") {
|
|
9030
|
+
await designUnpack(parsed, deps);
|
|
9031
|
+
return;
|
|
9032
|
+
}
|
|
9033
|
+
throw new Error(USAGE);
|
|
9034
|
+
}
|
|
9035
|
+
|
|
8882
9036
|
// src/harness-options.ts
|
|
8883
9037
|
function harnessList(parsed) {
|
|
8884
9038
|
const selected = [
|
|
@@ -9255,10 +9409,8 @@ function requireName(parsed) {
|
|
|
9255
9409
|
return name;
|
|
9256
9410
|
}
|
|
9257
9411
|
|
|
9258
|
-
// src/help.ts
|
|
9259
|
-
|
|
9260
|
-
output.log(`odla-ai
|
|
9261
|
-
|
|
9412
|
+
// src/help-usage.ts
|
|
9413
|
+
var USAGE_SECTION = `
|
|
9262
9414
|
Start here:
|
|
9263
9415
|
odla-ai runbook ask "<question>" The current procedure, from odla's own
|
|
9264
9416
|
runbooks. Ask BEFORE searching the web or
|
|
@@ -9292,6 +9444,7 @@ Usage:
|
|
|
9292
9444
|
odla-ai app owners list [--config odla.config.mjs] [--email <odla-account>] [--json]
|
|
9293
9445
|
odla-ai app owners add <email> [--email <odla-account>] [--json]
|
|
9294
9446
|
odla-ai app owners remove <email> [--email <odla-account>] [--json]
|
|
9447
|
+
odla-ai brand design unpack <bundle.html|-> [--out <dir>] [--json]
|
|
9295
9448
|
odla-ai pm goal list [--app <id>] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
|
|
9296
9449
|
odla-ai pm task list [--app <id>] [--column <c>] [--goal <id>] [--assignee <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
|
|
9297
9450
|
odla-ai pm decision list [--app <id>] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
|
|
@@ -9371,8 +9524,12 @@ Usage:
|
|
|
9371
9524
|
odla-ai secrets push --env <env> [--config odla.config.mjs] [--dry-run] [--yes]
|
|
9372
9525
|
odla-ai secrets set <name> --env <env> (--from-env <NAME>|--stdin) [--email <odla-account>] [--config odla.config.mjs] [--yes]
|
|
9373
9526
|
odla-ai secrets set-clerk-key --env <env> (--from-env <NAME>|--stdin) [--email <odla-account>] [--config odla.config.mjs] [--yes]
|
|
9374
|
-
odla-ai version
|
|
9527
|
+
odla-ai version`;
|
|
9375
9528
|
|
|
9529
|
+
// src/help.ts
|
|
9530
|
+
function printHelp(output = console) {
|
|
9531
|
+
output.log(`odla-ai
|
|
9532
|
+
${USAGE_SECTION}
|
|
9376
9533
|
Commands:
|
|
9377
9534
|
agent Inspect durable agent wakeups and explicitly requeue a
|
|
9378
9535
|
dead-lettered job; JSON output is stable for remote operators.
|
|
@@ -9821,7 +9978,7 @@ function jsonl(ctx, parsed, value2) {
|
|
|
9821
9978
|
}
|
|
9822
9979
|
async function discussWatch(ctx, topicId, parsed) {
|
|
9823
9980
|
if (ctx.json && parsed.options.jsonl === true) throw new Error("--json and --jsonl cannot be combined");
|
|
9824
|
-
const sleep = ctx.sleep ?? ((ms) => new Promise((
|
|
9981
|
+
const sleep = ctx.sleep ?? ((ms) => new Promise((resolve13) => setTimeout(resolve13, ms)));
|
|
9825
9982
|
const now = ctx.now ?? Date.now;
|
|
9826
9983
|
const intervalMs = (numberOpt2(parsed, "interval", DEFAULT_INTERVAL_MS / 1e3) ?? DEFAULT_INTERVAL_MS / 1e3) * 1e3;
|
|
9827
9984
|
const timeoutSeconds = numberOpt2(parsed, "timeout");
|
|
@@ -12433,6 +12590,10 @@ async function runCli(argv = process.argv.slice(2), dependencies = {}) {
|
|
|
12433
12590
|
await securityCommand(parsed, runtime);
|
|
12434
12591
|
return;
|
|
12435
12592
|
}
|
|
12593
|
+
if (command === "brand") {
|
|
12594
|
+
await brandCommand(parsed, runtime);
|
|
12595
|
+
return;
|
|
12596
|
+
}
|
|
12436
12597
|
if (command === "pm") {
|
|
12437
12598
|
await pmCommand(parsed, runtime);
|
|
12438
12599
|
return;
|
|
@@ -12576,4 +12737,4 @@ export {
|
|
|
12576
12737
|
exitCodeFor,
|
|
12577
12738
|
runCli
|
|
12578
12739
|
};
|
|
12579
|
-
//# sourceMappingURL=chunk-
|
|
12740
|
+
//# sourceMappingURL=chunk-4JWDJN3P.js.map
|