@odla-ai/cli 0.44.0 → 0.45.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/dist/bin.cjs +408 -303
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +12 -14
- package/dist/bin.js.map +1 -1
- package/dist/chunk-5MEO3BVF.js +282 -0
- package/dist/chunk-5MEO3BVF.js.map +1 -0
- package/dist/{chunk-7MUWCSGP.js → chunk-JHB6352A.js} +179 -212
- package/dist/chunk-JHB6352A.js.map +1 -0
- package/dist/cli-2FTL245Y.js +12 -0
- package/dist/index.cjs +97 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-7MUWCSGP.js.map +0 -1
- package/dist/chunk-UKLSRQ5J.js +0 -129
- package/dist/chunk-UKLSRQ5J.js.map +0 -1
- package/dist/cli-ZQBZT6YF.js +0 -12
- /package/dist/{cli-ZQBZT6YF.js.map → cli-2FTL245Y.js.map} +0 -0
package/dist/bin.cjs
CHANGED
|
@@ -99,17 +99,173 @@ var init_runbook_requires = __esm({
|
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
// src/odla-home.ts
|
|
103
|
+
function odlaHome(env = import_node_process.default.env) {
|
|
104
|
+
if (env.VITEST && !env.ODLA_HOME) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"ODLA_HOME must be set under test \u2014 resolving the real ~/.odla would write to the developer's machine"
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return env.ODLA_HOME ?? (0, import_node_path.join)(env.HOME ?? (0, import_node_os.homedir)(), ".odla");
|
|
110
|
+
}
|
|
111
|
+
function odlaHomePath(segments, env = import_node_process.default.env) {
|
|
112
|
+
return (0, import_node_path.join)(odlaHome(env), ...segments);
|
|
113
|
+
}
|
|
114
|
+
function identityFile(env) {
|
|
115
|
+
return odlaHomePath(["identity.json"], env);
|
|
116
|
+
}
|
|
117
|
+
function deviceSessionFile(env) {
|
|
118
|
+
return odlaHomePath(["session.json"], env);
|
|
119
|
+
}
|
|
120
|
+
function appTokenFile(appId, env) {
|
|
121
|
+
return odlaHomePath(["apps", safeSegment(appId), "dev-token.json"], env);
|
|
122
|
+
}
|
|
123
|
+
function appCredentialsFile(appId, env) {
|
|
124
|
+
return odlaHomePath(["apps", safeSegment(appId), "credentials.json"], env);
|
|
125
|
+
}
|
|
126
|
+
function scopedTokenFile(env) {
|
|
127
|
+
return odlaHomePath(["admin-token.local.json"], env);
|
|
128
|
+
}
|
|
129
|
+
function pmContextFile(env) {
|
|
130
|
+
return odlaHomePath(["pm-context.json"], env);
|
|
131
|
+
}
|
|
132
|
+
function adoptRepoLocalCache(legacyPath, machinePath, out) {
|
|
133
|
+
if (!(0, import_node_fs.existsSync)(legacyPath) || legacyPath === machinePath) return false;
|
|
134
|
+
const superseded2 = (0, import_node_fs.existsSync)(machinePath);
|
|
135
|
+
if (!superseded2) {
|
|
136
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(machinePath), { recursive: true });
|
|
137
|
+
(0, import_node_fs.copyFileSync)(legacyPath, machinePath);
|
|
138
|
+
(0, import_node_fs.chmodSync)(machinePath, 384);
|
|
139
|
+
}
|
|
140
|
+
(0, import_node_fs.rmSync)(legacyPath, { force: true });
|
|
141
|
+
out?.error(
|
|
142
|
+
superseded2 ? `auth: removed superseded ${legacyPath}; this machine's credentials live in ${odlaHome()}` : `auth: moved ${legacyPath} into ${machinePath}; credentials are per machine now, not per worktree`
|
|
143
|
+
);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
function safeSegment(value2) {
|
|
147
|
+
const clean4 = value2.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "");
|
|
148
|
+
if (!clean4) throw new Error(`"${value2}" is not a usable app id`);
|
|
149
|
+
return clean4;
|
|
150
|
+
}
|
|
151
|
+
var import_node_fs, import_node_os, import_node_path, import_node_process;
|
|
152
|
+
var init_odla_home = __esm({
|
|
153
|
+
"src/odla-home.ts"() {
|
|
154
|
+
"use strict";
|
|
155
|
+
init_cjs_shims();
|
|
156
|
+
import_node_fs = require("fs");
|
|
157
|
+
import_node_os = require("os");
|
|
158
|
+
import_node_path = require("path");
|
|
159
|
+
import_node_process = __toESM(require("process"), 1);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
102
163
|
// src/version.ts
|
|
103
164
|
function cliVersion() {
|
|
104
|
-
const pkg = JSON.parse((0,
|
|
165
|
+
const pkg = JSON.parse((0, import_node_fs2.readFileSync)(new URL("../package.json", importMetaUrl), "utf8"));
|
|
105
166
|
return pkg.version ?? "unknown";
|
|
106
167
|
}
|
|
107
|
-
var
|
|
168
|
+
var import_node_fs2;
|
|
108
169
|
var init_version = __esm({
|
|
109
170
|
"src/version.ts"() {
|
|
110
171
|
"use strict";
|
|
111
172
|
init_cjs_shims();
|
|
112
|
-
|
|
173
|
+
import_node_fs2 = require("fs");
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// src/update-notice.ts
|
|
178
|
+
function updateCacheFile(env) {
|
|
179
|
+
return odlaHomePath(["cli-update.json"], env);
|
|
180
|
+
}
|
|
181
|
+
function readUpdateCache(path) {
|
|
182
|
+
try {
|
|
183
|
+
const parsed = JSON.parse((0, import_node_fs3.readFileSync)(path, "utf8"));
|
|
184
|
+
if (typeof parsed.latest !== "string" || !VERSION.test(parsed.latest)) return null;
|
|
185
|
+
if (typeof parsed.checkedAt !== "number") return null;
|
|
186
|
+
return { latest: parsed.latest, checkedAt: parsed.checkedAt };
|
|
187
|
+
} catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function writeUpdateCache(path, cache2) {
|
|
192
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path2.dirname)(path), { recursive: true });
|
|
193
|
+
(0, import_node_fs3.writeFileSync)(path, JSON.stringify(cache2));
|
|
194
|
+
}
|
|
195
|
+
function updateNotice(options = {}) {
|
|
196
|
+
const env = options.env ?? import_node_process2.default.env;
|
|
197
|
+
if (env.ODLA_CLI_UPDATE_CHECK === "0") return null;
|
|
198
|
+
const current = options.currentVersion ?? cliVersion();
|
|
199
|
+
if (!VERSION.test(current)) return null;
|
|
200
|
+
const path = updateCacheFile(env);
|
|
201
|
+
const cache2 = readUpdateCache(path);
|
|
202
|
+
const now = options.now ?? Date.now();
|
|
203
|
+
if ((!cache2 || now - cache2.checkedAt > INTERVAL_MS) && !refreshScheduled) {
|
|
204
|
+
refreshScheduled = true;
|
|
205
|
+
(options.refresh ?? spawnRefresh)(path, env.ODLA_CLI_REGISTRY_URL ?? REGISTRY_URL);
|
|
206
|
+
}
|
|
207
|
+
if (!cache2 || compareVersions(current, cache2.latest) >= 0) return null;
|
|
208
|
+
return renderNotice(current, cache2.latest, options.entryPath ?? import_node_process2.default.argv[1]);
|
|
209
|
+
}
|
|
210
|
+
function renderNotice(current, latest, entryPath) {
|
|
211
|
+
const resolved = resolvedEntryPath(entryPath);
|
|
212
|
+
const behindMajor = Number(latest.split(".")[0]) > Number(current.split(".")[0]);
|
|
213
|
+
const repair = isWorkspaceCli(resolved) ? `this is the workspace build at ${resolved} \u2014 rebase that worktree and rebuild it` : resolved.includes("/_npx/") ? `run npx --yes @odla-ai/cli@${latest} <command>` : `run npm i @odla-ai/cli@${latest}`;
|
|
214
|
+
const severity = behindMajor ? "a MAJOR version behind, so commands and flags this version has may no longer exist" : "behind";
|
|
215
|
+
return `odla-ai: ${current} is ${severity}; npm serves ${latest}. To update, ${repair}.`;
|
|
216
|
+
}
|
|
217
|
+
function spawnRefresh(cachePath, registryUrl) {
|
|
218
|
+
const script = `
|
|
219
|
+
const {mkdirSync,writeFileSync}=require("node:fs");
|
|
220
|
+
const {dirname}=require("node:path");
|
|
221
|
+
const [path,url]=process.argv.slice(1);
|
|
222
|
+
const done=setTimeout(()=>process.exit(0),5000); done.unref();
|
|
223
|
+
fetch(url,{headers:{accept:"application/vnd.npm.install-v1+json"}})
|
|
224
|
+
.then(r=>r.ok?r.json():null)
|
|
225
|
+
.then(b=>{
|
|
226
|
+
const v=b&&b.version;
|
|
227
|
+
if (typeof v!=="string"||!/^\\d+\\.\\d+\\.\\d+/.test(v)) return;
|
|
228
|
+
mkdirSync(dirname(path),{recursive:true});
|
|
229
|
+
writeFileSync(path,JSON.stringify({latest:v,checkedAt:Date.now()}));
|
|
230
|
+
})
|
|
231
|
+
.catch(()=>{});
|
|
232
|
+
`;
|
|
233
|
+
try {
|
|
234
|
+
(0, import_node_child_process.spawn)(import_node_process2.default.execPath, ["-e", script, cachePath, registryUrl], {
|
|
235
|
+
detached: true,
|
|
236
|
+
stdio: "ignore"
|
|
237
|
+
}).unref();
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function resolvedEntryPath(entryPath) {
|
|
242
|
+
if (!entryPath) return "unknown executable";
|
|
243
|
+
try {
|
|
244
|
+
return (0, import_node_fs3.realpathSync)(entryPath);
|
|
245
|
+
} catch {
|
|
246
|
+
return entryPath;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function isWorkspaceCli(entryPath) {
|
|
250
|
+
const normalized = entryPath.replaceAll("\\", "/");
|
|
251
|
+
return /\/packages\/cli\/(dist|bin)\//.test(normalized) && !normalized.includes("/node_modules/");
|
|
252
|
+
}
|
|
253
|
+
var import_node_child_process, import_node_fs3, import_node_path2, import_node_process2, REGISTRY_URL, INTERVAL_MS, VERSION, refreshScheduled;
|
|
254
|
+
var init_update_notice = __esm({
|
|
255
|
+
"src/update-notice.ts"() {
|
|
256
|
+
"use strict";
|
|
257
|
+
init_cjs_shims();
|
|
258
|
+
import_node_child_process = require("child_process");
|
|
259
|
+
import_node_fs3 = require("fs");
|
|
260
|
+
import_node_path2 = require("path");
|
|
261
|
+
import_node_process2 = __toESM(require("process"), 1);
|
|
262
|
+
init_odla_home();
|
|
263
|
+
init_runbook_requires();
|
|
264
|
+
init_version();
|
|
265
|
+
REGISTRY_URL = "https://registry.npmjs.org/@odla-ai%2fcli/latest";
|
|
266
|
+
INTERVAL_MS = 3 * 60 * 60 * 1e3;
|
|
267
|
+
VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
268
|
+
refreshScheduled = false;
|
|
113
269
|
}
|
|
114
270
|
});
|
|
115
271
|
|
|
@@ -232,8 +388,8 @@ var init_approval_prompt = __esm({
|
|
|
232
388
|
|
|
233
389
|
// src/open.ts
|
|
234
390
|
async function openUrl(url, options = {}) {
|
|
235
|
-
const command = openerFor(options.platform ??
|
|
236
|
-
const doSpawn = options.spawnImpl ??
|
|
391
|
+
const command = openerFor(options.platform ?? import_node_process3.default.platform);
|
|
392
|
+
const doSpawn = options.spawnImpl ?? import_node_child_process2.spawn;
|
|
237
393
|
await new Promise((resolve15, reject) => {
|
|
238
394
|
const child = doSpawn(command.cmd, [...command.args, url], {
|
|
239
395
|
stdio: "ignore",
|
|
@@ -251,13 +407,13 @@ function openerFor(platform) {
|
|
|
251
407
|
if (platform === "win32") return { cmd: "cmd", args: ["/c", "start", ""] };
|
|
252
408
|
return { cmd: "xdg-open", args: [] };
|
|
253
409
|
}
|
|
254
|
-
var
|
|
410
|
+
var import_node_child_process2, import_node_process3;
|
|
255
411
|
var init_open = __esm({
|
|
256
412
|
"src/open.ts"() {
|
|
257
413
|
"use strict";
|
|
258
414
|
init_cjs_shims();
|
|
259
|
-
|
|
260
|
-
|
|
415
|
+
import_node_child_process2 = require("child_process");
|
|
416
|
+
import_node_process3 = __toESM(require("process"), 1);
|
|
261
417
|
}
|
|
262
418
|
});
|
|
263
419
|
|
|
@@ -265,7 +421,7 @@ var init_open = __esm({
|
|
|
265
421
|
function approvalBrowser(options, host = {}) {
|
|
266
422
|
if (options.open === false) return { open: false, reason: "disabled by --no-open" };
|
|
267
423
|
if (options.open === true) return { open: true, mode: "forced" };
|
|
268
|
-
const env = host.env ??
|
|
424
|
+
const env = host.env ?? import_node_process4.default.env;
|
|
269
425
|
if (env.VITEST || env.NODE_ENV === "test") {
|
|
270
426
|
return { open: false, reason: "test environment" };
|
|
271
427
|
}
|
|
@@ -295,12 +451,12 @@ function handshakeUrl(platformUrl, userCode) {
|
|
|
295
451
|
url.searchParams.set("code", userCode);
|
|
296
452
|
return url.toString();
|
|
297
453
|
}
|
|
298
|
-
var
|
|
454
|
+
var import_node_process4;
|
|
299
455
|
var init_handshake_approval = __esm({
|
|
300
456
|
"src/handshake-approval.ts"() {
|
|
301
457
|
"use strict";
|
|
302
458
|
init_cjs_shims();
|
|
303
|
-
|
|
459
|
+
import_node_process4 = __toESM(require("process"), 1);
|
|
304
460
|
init_approval_prompt();
|
|
305
461
|
init_open();
|
|
306
462
|
}
|
|
@@ -308,10 +464,10 @@ var init_handshake_approval = __esm({
|
|
|
308
464
|
|
|
309
465
|
// src/handshake-state.ts
|
|
310
466
|
function handshakeFile(cfg) {
|
|
311
|
-
return (0,
|
|
467
|
+
return (0, import_node_path4.join)((0, import_node_path4.dirname)(cfg.local.tokenFile), "handshake.local.json");
|
|
312
468
|
}
|
|
313
469
|
function clearPendingHandshake(path) {
|
|
314
|
-
(0,
|
|
470
|
+
(0, import_node_fs5.rmSync)(path, { force: true });
|
|
315
471
|
}
|
|
316
472
|
function minutesLeft(expiresAt) {
|
|
317
473
|
return Math.max(1, Math.round((expiresAt - Date.now()) / 6e4));
|
|
@@ -331,31 +487,31 @@ function approvalReminder(out, pending, periodMs = 3e4) {
|
|
|
331
487
|
timer.unref?.();
|
|
332
488
|
return () => clearInterval(timer);
|
|
333
489
|
}
|
|
334
|
-
function handshakeWaitMs(waitSeconds, interactive =
|
|
490
|
+
function handshakeWaitMs(waitSeconds, interactive = import_node_process5.default.stdout.isTTY === true) {
|
|
335
491
|
if (waitSeconds !== void 0) return waitSeconds * 1e3;
|
|
336
492
|
return interactive ? void 0 : 9e4;
|
|
337
493
|
}
|
|
338
|
-
var
|
|
494
|
+
var import_node_fs5, import_node_path4, import_node_process5;
|
|
339
495
|
var init_handshake_state = __esm({
|
|
340
496
|
"src/handshake-state.ts"() {
|
|
341
497
|
"use strict";
|
|
342
498
|
init_cjs_shims();
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
499
|
+
import_node_fs5 = require("fs");
|
|
500
|
+
import_node_path4 = require("path");
|
|
501
|
+
import_node_process5 = __toESM(require("process"), 1);
|
|
346
502
|
init_approval_prompt();
|
|
347
503
|
}
|
|
348
504
|
});
|
|
349
505
|
|
|
350
506
|
// src/device-session.ts
|
|
351
|
-
function deviceCredentialPath(env =
|
|
352
|
-
return env.ODLA_DEVICE_CREDENTIAL ?? (0,
|
|
507
|
+
function deviceCredentialPath(env = import_node_process6.default.env) {
|
|
508
|
+
return env.ODLA_DEVICE_CREDENTIAL ?? (0, import_node_path5.join)(env.HOME ?? (0, import_node_os2.homedir)(), ".odla", "device.json");
|
|
353
509
|
}
|
|
354
|
-
function readDeviceCredential(platform, env =
|
|
510
|
+
function readDeviceCredential(platform, env = import_node_process6.default.env) {
|
|
355
511
|
const path = deviceCredentialPath(env);
|
|
356
|
-
if (!(0,
|
|
512
|
+
if (!(0, import_node_fs6.existsSync)(path)) return null;
|
|
357
513
|
try {
|
|
358
|
-
const parsed = JSON.parse((0,
|
|
514
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
|
|
359
515
|
if (typeof parsed.token !== "string" || !parsed.token.startsWith("odla_device_")) return null;
|
|
360
516
|
if (parsed.platform !== platform) return null;
|
|
361
517
|
return { ...parsed, token: parsed.token, platform: parsed.platform };
|
|
@@ -389,76 +545,15 @@ async function mintDeviceSession(platformUrl, credential2, doFetch) {
|
|
|
389
545
|
...Array.isArray(body.scopes) ? { scopes: body.scopes } : {}
|
|
390
546
|
};
|
|
391
547
|
}
|
|
392
|
-
var
|
|
548
|
+
var import_node_fs6, import_node_os2, import_node_path5, import_node_process6;
|
|
393
549
|
var init_device_session = __esm({
|
|
394
550
|
"src/device-session.ts"() {
|
|
395
|
-
"use strict";
|
|
396
|
-
init_cjs_shims();
|
|
397
|
-
import_node_fs5 = require("fs");
|
|
398
|
-
import_node_os = require("os");
|
|
399
|
-
import_node_path3 = require("path");
|
|
400
|
-
import_node_process4 = __toESM(require("process"), 1);
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
// src/odla-home.ts
|
|
405
|
-
function odlaHome(env = import_node_process5.default.env) {
|
|
406
|
-
if (env.VITEST && !env.ODLA_HOME) {
|
|
407
|
-
throw new Error(
|
|
408
|
-
"ODLA_HOME must be set under test \u2014 resolving the real ~/.odla would write to the developer's machine"
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
return env.ODLA_HOME ?? (0, import_node_path4.join)(env.HOME ?? (0, import_node_os2.homedir)(), ".odla");
|
|
412
|
-
}
|
|
413
|
-
function odlaHomePath(segments, env = import_node_process5.default.env) {
|
|
414
|
-
return (0, import_node_path4.join)(odlaHome(env), ...segments);
|
|
415
|
-
}
|
|
416
|
-
function identityFile(env) {
|
|
417
|
-
return odlaHomePath(["identity.json"], env);
|
|
418
|
-
}
|
|
419
|
-
function deviceSessionFile(env) {
|
|
420
|
-
return odlaHomePath(["session.json"], env);
|
|
421
|
-
}
|
|
422
|
-
function appTokenFile(appId, env) {
|
|
423
|
-
return odlaHomePath(["apps", safeSegment(appId), "dev-token.json"], env);
|
|
424
|
-
}
|
|
425
|
-
function appCredentialsFile(appId, env) {
|
|
426
|
-
return odlaHomePath(["apps", safeSegment(appId), "credentials.json"], env);
|
|
427
|
-
}
|
|
428
|
-
function scopedTokenFile(env) {
|
|
429
|
-
return odlaHomePath(["admin-token.local.json"], env);
|
|
430
|
-
}
|
|
431
|
-
function pmContextFile(env) {
|
|
432
|
-
return odlaHomePath(["pm-context.json"], env);
|
|
433
|
-
}
|
|
434
|
-
function adoptRepoLocalCache(legacyPath, machinePath, out) {
|
|
435
|
-
if (!(0, import_node_fs6.existsSync)(legacyPath) || legacyPath === machinePath) return false;
|
|
436
|
-
const superseded2 = (0, import_node_fs6.existsSync)(machinePath);
|
|
437
|
-
if (!superseded2) {
|
|
438
|
-
(0, import_node_fs6.mkdirSync)((0, import_node_path4.dirname)(machinePath), { recursive: true });
|
|
439
|
-
(0, import_node_fs6.copyFileSync)(legacyPath, machinePath);
|
|
440
|
-
(0, import_node_fs6.chmodSync)(machinePath, 384);
|
|
441
|
-
}
|
|
442
|
-
(0, import_node_fs6.rmSync)(legacyPath, { force: true });
|
|
443
|
-
out?.error(
|
|
444
|
-
superseded2 ? `auth: removed superseded ${legacyPath}; this machine's credentials live in ${odlaHome()}` : `auth: moved ${legacyPath} into ${machinePath}; credentials are per machine now, not per worktree`
|
|
445
|
-
);
|
|
446
|
-
return true;
|
|
447
|
-
}
|
|
448
|
-
function safeSegment(value2) {
|
|
449
|
-
const clean4 = value2.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "");
|
|
450
|
-
if (!clean4) throw new Error(`"${value2}" is not a usable app id`);
|
|
451
|
-
return clean4;
|
|
452
|
-
}
|
|
453
|
-
var import_node_fs6, import_node_os2, import_node_path4, import_node_process5;
|
|
454
|
-
var init_odla_home = __esm({
|
|
455
|
-
"src/odla-home.ts"() {
|
|
456
551
|
"use strict";
|
|
457
552
|
init_cjs_shims();
|
|
458
553
|
import_node_fs6 = require("fs");
|
|
459
554
|
import_node_os2 = require("os");
|
|
460
|
-
|
|
461
|
-
|
|
555
|
+
import_node_path5 = require("path");
|
|
556
|
+
import_node_process6 = __toESM(require("process"), 1);
|
|
462
557
|
}
|
|
463
558
|
});
|
|
464
559
|
|
|
@@ -508,7 +603,7 @@ function mergeCredential(current, update) {
|
|
|
508
603
|
return next;
|
|
509
604
|
}
|
|
510
605
|
function ensureGitignore(rootDir, localPaths = []) {
|
|
511
|
-
const path = (0,
|
|
606
|
+
const path = (0, import_node_path6.resolve)(rootDir, ".gitignore");
|
|
512
607
|
const existing = (0, import_node_fs7.existsSync)(path) ? (0, import_node_fs7.readFileSync)(path, "utf8") : "";
|
|
513
608
|
const configured = localPaths.map((localPath) => gitignoreEntry(rootDir, localPath)).filter((line2) => !!line2);
|
|
514
609
|
const wanted = [.../* @__PURE__ */ new Set([...GITIGNORE_LINES, ...configured])];
|
|
@@ -529,7 +624,7 @@ function o11yDevVars(cfg) {
|
|
|
529
624
|
function resolveWriteDevVarsTarget(cfg, requested) {
|
|
530
625
|
if (!requested) return null;
|
|
531
626
|
if (requested === true) return cfg.local.devVarsFile;
|
|
532
|
-
return (0,
|
|
627
|
+
return (0, import_node_path6.resolve)((0, import_node_path6.dirname)(cfg.configPath), requested);
|
|
533
628
|
}
|
|
534
629
|
function writeDevVars(path, credentials, env, o11y) {
|
|
535
630
|
const entry = credentials.envs[env];
|
|
@@ -557,28 +652,28 @@ function isManagedDevVar(line2) {
|
|
|
557
652
|
return !!match?.[1] && MANAGED_DEV_VARS.has(match[1]);
|
|
558
653
|
}
|
|
559
654
|
function writePrivateText(path, text4) {
|
|
560
|
-
(0, import_node_fs7.mkdirSync)((0,
|
|
655
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path6.dirname)(path), { recursive: true });
|
|
561
656
|
const temporary = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
562
657
|
(0, import_node_fs7.writeFileSync)(temporary, text4, { mode: 384 });
|
|
563
658
|
(0, import_node_fs7.chmodSync)(temporary, 384);
|
|
564
659
|
(0, import_node_fs7.renameSync)(temporary, path);
|
|
565
660
|
}
|
|
566
661
|
function gitignoreEntry(rootDir, path) {
|
|
567
|
-
const rel = (0,
|
|
568
|
-
if (!rel || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || (0,
|
|
662
|
+
const rel = (0, import_node_path6.relative)((0, import_node_path6.resolve)(rootDir), (0, import_node_path6.resolve)(path));
|
|
663
|
+
if (!rel || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || (0, import_node_path6.isAbsolute)(rel)) return null;
|
|
569
664
|
return rel.replaceAll("\\", "/");
|
|
570
665
|
}
|
|
571
666
|
function displayPath(path, rootDir = process.cwd()) {
|
|
572
|
-
const rel = (0,
|
|
667
|
+
const rel = (0, import_node_path6.relative)(rootDir, path);
|
|
573
668
|
return rel && !rel.startsWith("..") ? rel : path;
|
|
574
669
|
}
|
|
575
|
-
var import_node_fs7,
|
|
670
|
+
var import_node_fs7, import_node_path6, GITIGNORE_LINES, MANAGED_DEV_VARS;
|
|
576
671
|
var init_local = __esm({
|
|
577
672
|
"src/local.ts"() {
|
|
578
673
|
"use strict";
|
|
579
674
|
init_cjs_shims();
|
|
580
675
|
import_node_fs7 = require("fs");
|
|
581
|
-
|
|
676
|
+
import_node_path6 = require("path");
|
|
582
677
|
GITIGNORE_LINES = [".odla/*.local.json", ".odla/dev-token.json", ".dev.vars"];
|
|
583
678
|
MANAGED_DEV_VARS = /* @__PURE__ */ new Set([
|
|
584
679
|
"ODLA_PLATFORM",
|
|
@@ -596,7 +691,7 @@ var init_local = __esm({
|
|
|
596
691
|
});
|
|
597
692
|
|
|
598
693
|
// src/auth-guidance.ts
|
|
599
|
-
function machineAuthState(audience, env =
|
|
694
|
+
function machineAuthState(audience, env = import_node_process7.default.env) {
|
|
600
695
|
const device = readDeviceCredential(audience, env);
|
|
601
696
|
if (!device) return { enrolled: false };
|
|
602
697
|
const session = readJsonFile(deviceSessionFile(env));
|
|
@@ -640,12 +735,12 @@ function lapseNotice(state2, now = Date.now()) {
|
|
|
640
735
|
if (days < 0) return "this machine's enrollment has lapsed; the next command will ask for approval";
|
|
641
736
|
return `idle for ${days} more day${days === 1 ? "" : "s"} before this machine needs approving again (using it resets the clock)`;
|
|
642
737
|
}
|
|
643
|
-
var
|
|
738
|
+
var import_node_process7, ENROL_EVERYTHING, ENROL_PLATFORM_WIDE;
|
|
644
739
|
var init_auth_guidance = __esm({
|
|
645
740
|
"src/auth-guidance.ts"() {
|
|
646
741
|
"use strict";
|
|
647
742
|
init_cjs_shims();
|
|
648
|
-
|
|
743
|
+
import_node_process7 = __toESM(require("process"), 1);
|
|
649
744
|
init_device_session();
|
|
650
745
|
init_odla_home();
|
|
651
746
|
init_local();
|
|
@@ -687,7 +782,7 @@ var init_cached_credential = __esm({
|
|
|
687
782
|
});
|
|
688
783
|
|
|
689
784
|
// src/device-session-cache.ts
|
|
690
|
-
async function deviceSessionToken(platformUrl, audience, credential2, doFetch, env =
|
|
785
|
+
async function deviceSessionToken(platformUrl, audience, credential2, doFetch, env = import_node_process8.default.env) {
|
|
691
786
|
const path = deviceSessionFile(env);
|
|
692
787
|
const cached = readJsonFile(path);
|
|
693
788
|
if (cached?.token && cached.platform === audience && cached.deviceId === credential2.deviceId && (cached.expiresAt ?? 0) > Date.now() + SKEW_MS) return cached;
|
|
@@ -700,12 +795,12 @@ async function deviceSessionToken(platformUrl, audience, credential2, doFetch, e
|
|
|
700
795
|
writePrivateJson(path, session);
|
|
701
796
|
return session;
|
|
702
797
|
}
|
|
703
|
-
var
|
|
798
|
+
var import_node_process8, SKEW_MS;
|
|
704
799
|
var init_device_session_cache = __esm({
|
|
705
800
|
"src/device-session-cache.ts"() {
|
|
706
801
|
"use strict";
|
|
707
802
|
init_cjs_shims();
|
|
708
|
-
|
|
803
|
+
import_node_process8 = __toESM(require("process"), 1);
|
|
709
804
|
init_odla_home();
|
|
710
805
|
init_local();
|
|
711
806
|
init_device_session();
|
|
@@ -714,23 +809,23 @@ var init_device_session_cache = __esm({
|
|
|
714
809
|
});
|
|
715
810
|
|
|
716
811
|
// src/machine-identity.ts
|
|
717
|
-
function readMachineIdentity(audience, env =
|
|
812
|
+
function readMachineIdentity(audience, env = import_node_process9.default.env) {
|
|
718
813
|
const stored = readJsonFile(identityFile(env));
|
|
719
814
|
if (!stored || typeof stored.email !== "string" || !stored.email) return null;
|
|
720
815
|
return stored.platform === audience ? { platform: audience, email: stored.email } : null;
|
|
721
816
|
}
|
|
722
|
-
function rememberMachineIdentity(audience, email, env =
|
|
817
|
+
function rememberMachineIdentity(audience, email, env = import_node_process9.default.env) {
|
|
723
818
|
if (!email) return;
|
|
724
819
|
const existing = readMachineIdentity(audience, env);
|
|
725
820
|
if (existing?.email === email) return;
|
|
726
821
|
writePrivateJson(identityFile(env), { platform: audience, email });
|
|
727
822
|
}
|
|
728
|
-
var
|
|
823
|
+
var import_node_process9;
|
|
729
824
|
var init_machine_identity = __esm({
|
|
730
825
|
"src/machine-identity.ts"() {
|
|
731
826
|
"use strict";
|
|
732
827
|
init_cjs_shims();
|
|
733
|
-
|
|
828
|
+
import_node_process9 = __toESM(require("process"), 1);
|
|
734
829
|
init_odla_home();
|
|
735
830
|
init_local();
|
|
736
831
|
}
|
|
@@ -744,14 +839,14 @@ async function getDeveloperToken(cfg, options, doFetch, out, grantRequest = {})
|
|
|
744
839
|
const cached = readJsonFile(cfg.local.tokenFile);
|
|
745
840
|
if (!grantRequest.forceReview && !grantRequest.freshLogin) {
|
|
746
841
|
if (options.token) return options.token;
|
|
747
|
-
if (
|
|
748
|
-
const declared =
|
|
842
|
+
if (import_node_process10.default.env.ODLA_DEV_TOKEN) {
|
|
843
|
+
const declared = import_node_process10.default.env.ODLA_DEV_TOKEN_AUDIENCE;
|
|
749
844
|
if (declared) {
|
|
750
845
|
if (platformAudience(declared) !== audience) throw new Error("ODLA_DEV_TOKEN_AUDIENCE does not match the configured platform");
|
|
751
846
|
} else if (audience !== "https://odla.ai") {
|
|
752
847
|
throw new Error("ODLA_DEV_TOKEN_AUDIENCE is required for a non-default platform");
|
|
753
848
|
}
|
|
754
|
-
return
|
|
849
|
+
return import_node_process10.default.env.ODLA_DEV_TOKEN;
|
|
755
850
|
}
|
|
756
851
|
const device = readDeviceCredential(audience);
|
|
757
852
|
if (device) {
|
|
@@ -866,7 +961,7 @@ function stillPending(pending, email) {
|
|
|
866
961
|
);
|
|
867
962
|
}
|
|
868
963
|
function handshakeEmail(value2, cached) {
|
|
869
|
-
const email = (value2 ??
|
|
964
|
+
const email = (value2 ?? import_node_process10.default.env.ODLA_USER_EMAIL ?? cached ?? "").trim().toLowerCase();
|
|
870
965
|
if (/@users\.noreply\.github\.com$/i.test(email)) {
|
|
871
966
|
throw new Error(
|
|
872
967
|
`"${email}" is a GitHub commit identity, not an odla account email; use --email <signed-in-odla-account> or ODLA_USER_EMAIL`
|
|
@@ -895,14 +990,14 @@ function platformAudience(value2) {
|
|
|
895
990
|
}
|
|
896
991
|
return url.origin;
|
|
897
992
|
}
|
|
898
|
-
var import_db, import_node_crypto,
|
|
993
|
+
var import_db, import_node_crypto, import_node_process10;
|
|
899
994
|
var init_token = __esm({
|
|
900
995
|
"src/token.ts"() {
|
|
901
996
|
"use strict";
|
|
902
997
|
init_cjs_shims();
|
|
903
998
|
import_db = require("@odla-ai/db");
|
|
904
999
|
import_node_crypto = require("crypto");
|
|
905
|
-
|
|
1000
|
+
import_node_process10 = __toESM(require("process"), 1);
|
|
906
1001
|
init_handshake_approval();
|
|
907
1002
|
init_handshake_state();
|
|
908
1003
|
init_cached_credential();
|
|
@@ -917,7 +1012,7 @@ var init_token = __esm({
|
|
|
917
1012
|
async function secretInputValue(options, kind = "credential") {
|
|
918
1013
|
if (options.fromEnv && options.stdin) throw new Error("choose exactly one of --from-env or --stdin");
|
|
919
1014
|
let value2;
|
|
920
|
-
if (options.fromEnv) value2 =
|
|
1015
|
+
if (options.fromEnv) value2 = import_node_process11.default.env[options.fromEnv];
|
|
921
1016
|
else if (options.stdin) value2 = await (options.readStdin ?? (() => readSecretStream(kind)))();
|
|
922
1017
|
else throw new Error(`${kind} input required: use --from-env <NAME> or --stdin; values are never accepted as arguments`);
|
|
923
1018
|
value2 = value2?.replace(/[\r\n]+$/, "");
|
|
@@ -925,7 +1020,7 @@ async function secretInputValue(options, kind = "credential") {
|
|
|
925
1020
|
if (new TextEncoder().encode(value2).byteLength > MAX_BYTES) throw new Error(`${kind} exceeds 64 KiB`);
|
|
926
1021
|
return value2;
|
|
927
1022
|
}
|
|
928
|
-
async function readSecretStream(kind, stream =
|
|
1023
|
+
async function readSecretStream(kind, stream = import_node_process11.default.stdin) {
|
|
929
1024
|
let value2 = "";
|
|
930
1025
|
for await (const chunk of stream) {
|
|
931
1026
|
value2 += String(chunk);
|
|
@@ -933,12 +1028,12 @@ async function readSecretStream(kind, stream = import_node_process10.default.std
|
|
|
933
1028
|
}
|
|
934
1029
|
return value2;
|
|
935
1030
|
}
|
|
936
|
-
var
|
|
1031
|
+
var import_node_process11, MAX_BYTES;
|
|
937
1032
|
var init_secret_input = __esm({
|
|
938
1033
|
"src/secret-input.ts"() {
|
|
939
1034
|
"use strict";
|
|
940
1035
|
init_cjs_shims();
|
|
941
|
-
|
|
1036
|
+
import_node_process11 = __toESM(require("process"), 1);
|
|
942
1037
|
MAX_BYTES = 64 * 1024;
|
|
943
1038
|
}
|
|
944
1039
|
});
|
|
@@ -950,7 +1045,7 @@ async function getScopedPlatformToken(options) {
|
|
|
950
1045
|
async function resolveAdminPlatformToken(options) {
|
|
951
1046
|
const audience = platformAudience(options.platform);
|
|
952
1047
|
if (options.token) return options.token;
|
|
953
|
-
const fromEnv =
|
|
1048
|
+
const fromEnv = import_node_process12.default.env.ODLA_ADMIN_TOKEN;
|
|
954
1049
|
if (fromEnv) return audienceBoundEnvToken(fromEnv, audience);
|
|
955
1050
|
return scopedToken(
|
|
956
1051
|
audience,
|
|
@@ -962,7 +1057,7 @@ async function resolveAdminPlatformToken(options) {
|
|
|
962
1057
|
}
|
|
963
1058
|
function audienceBoundEnvToken(token, platform) {
|
|
964
1059
|
const audience = platformAudience(platform);
|
|
965
|
-
const declared =
|
|
1060
|
+
const declared = import_node_process12.default.env.ODLA_ADMIN_TOKEN_AUDIENCE;
|
|
966
1061
|
if (declared) {
|
|
967
1062
|
if (platformAudience(declared) !== audience) throw new Error("ODLA_ADMIN_TOKEN_AUDIENCE does not match the configured platform");
|
|
968
1063
|
} else if (audience !== "https://odla.ai") {
|
|
@@ -972,9 +1067,9 @@ function audienceBoundEnvToken(token, platform) {
|
|
|
972
1067
|
}
|
|
973
1068
|
async function scopedToken(platform, scope, options, doFetch, out) {
|
|
974
1069
|
const audience = platformAudience(platform);
|
|
975
|
-
const rootDir = options.rootDir ??
|
|
1070
|
+
const rootDir = options.rootDir ?? import_node_process12.default.cwd();
|
|
976
1071
|
const tokenFile = options.tokenFile ?? scopedTokenFile();
|
|
977
|
-
adoptRepoLocalCache((0,
|
|
1072
|
+
adoptRepoLocalCache((0, import_node_path7.join)(rootDir, ".odla/admin-token.local.json"), tokenFile, out);
|
|
978
1073
|
const device = readDeviceCredential(audience);
|
|
979
1074
|
if (device && options.cache !== false) {
|
|
980
1075
|
const session = await deviceSessionToken(platform, audience, device, doFetch);
|
|
@@ -1021,13 +1116,13 @@ async function scopedToken(platform, scope, options, doFetch, out) {
|
|
|
1021
1116
|
}
|
|
1022
1117
|
return token;
|
|
1023
1118
|
}
|
|
1024
|
-
var
|
|
1119
|
+
var import_node_path7, import_node_process12, import_db2, SCOPE_PURPOSE;
|
|
1025
1120
|
var init_admin_ai_auth = __esm({
|
|
1026
1121
|
"src/admin-ai-auth.ts"() {
|
|
1027
1122
|
"use strict";
|
|
1028
1123
|
init_cjs_shims();
|
|
1029
|
-
|
|
1030
|
-
|
|
1124
|
+
import_node_path7 = require("path");
|
|
1125
|
+
import_node_process12 = __toESM(require("process"), 1);
|
|
1031
1126
|
import_db2 = require("@odla-ai/db");
|
|
1032
1127
|
init_local();
|
|
1033
1128
|
init_handshake_approval();
|
|
@@ -1252,7 +1347,7 @@ var init_admin_ai_usage = __esm({
|
|
|
1252
1347
|
|
|
1253
1348
|
// src/admin-ai.ts
|
|
1254
1349
|
async function adminAi(options) {
|
|
1255
|
-
const platform = platformAudience(options.platform ??
|
|
1350
|
+
const platform = platformAudience(options.platform ?? import_node_process13.default.env.ODLA_PLATFORM ?? "https://odla.ai");
|
|
1256
1351
|
const doFetch = options.fetch ?? fetch;
|
|
1257
1352
|
const out = options.stdout ?? console;
|
|
1258
1353
|
const usageQuery = options.action === "usage" ? adminAiUsageQuery(options) : void 0;
|
|
@@ -1430,12 +1525,12 @@ function apiError3(action2, status, body) {
|
|
|
1430
1525
|
function isRecord3(value2) {
|
|
1431
1526
|
return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
|
|
1432
1527
|
}
|
|
1433
|
-
var
|
|
1528
|
+
var import_node_process13;
|
|
1434
1529
|
var init_admin_ai = __esm({
|
|
1435
1530
|
"src/admin-ai.ts"() {
|
|
1436
1531
|
"use strict";
|
|
1437
1532
|
init_cjs_shims();
|
|
1438
|
-
|
|
1533
|
+
import_node_process13 = __toESM(require("process"), 1);
|
|
1439
1534
|
init_token();
|
|
1440
1535
|
init_secret_input();
|
|
1441
1536
|
init_admin_ai_auth();
|
|
@@ -2213,12 +2308,12 @@ var init_monitoring_validation = __esm({
|
|
|
2213
2308
|
|
|
2214
2309
|
// src/config.ts
|
|
2215
2310
|
async function loadProjectConfig(configPath = "odla.config.mjs", options = {}) {
|
|
2216
|
-
const resolved = (0,
|
|
2311
|
+
const resolved = (0, import_node_path8.resolve)(configPath);
|
|
2217
2312
|
if (!(0, import_node_fs9.existsSync)(resolved)) {
|
|
2218
2313
|
throw new Error(`config not found: ${configPath}. Run "odla-ai init" first or pass --config.`);
|
|
2219
2314
|
}
|
|
2220
2315
|
const raw = await loadConfigModule(resolved);
|
|
2221
|
-
const rootDir = (0,
|
|
2316
|
+
const rootDir = (0, import_node_path8.dirname)(resolved);
|
|
2222
2317
|
validateRawConfig(raw, resolved);
|
|
2223
2318
|
const platformUrl = trimSlash(process.env.ODLA_PLATFORM_URL || raw.platformUrl || DEFAULT_PLATFORM);
|
|
2224
2319
|
const dbEndpoint = trimSlash(process.env.ODLA_DB_ENDPOINT || raw.dbEndpoint || platformUrl);
|
|
@@ -2228,14 +2323,14 @@ async function loadProjectConfig(configPath = "odla.config.mjs", options = {}) {
|
|
|
2228
2323
|
validateCalendarConfig(raw, unique3([...envs, ...options.additionalEnvs ?? []]), services, resolved);
|
|
2229
2324
|
validateMonitoringConfig(raw, unique3([...envs, ...options.additionalEnvs ?? []]), services, resolved);
|
|
2230
2325
|
const local = {
|
|
2231
|
-
tokenFile: raw.local?.tokenFile ? (0,
|
|
2232
|
-
credentialsFile: raw.local?.credentialsFile ? (0,
|
|
2233
|
-
devVarsFile: (0,
|
|
2326
|
+
tokenFile: raw.local?.tokenFile ? (0, import_node_path8.resolve)(rootDir, raw.local.tokenFile) : appTokenFile(raw.app.id),
|
|
2327
|
+
credentialsFile: raw.local?.credentialsFile ? (0, import_node_path8.resolve)(rootDir, raw.local.credentialsFile) : appCredentialsFile(raw.app.id),
|
|
2328
|
+
devVarsFile: (0, import_node_path8.resolve)(rootDir, raw.local?.devVarsFile ?? ".dev.vars"),
|
|
2234
2329
|
gitignore: raw.local?.gitignore ?? true
|
|
2235
2330
|
};
|
|
2236
|
-
adoptRepoLocalCache((0,
|
|
2237
|
-
adoptRepoLocalCache((0,
|
|
2238
|
-
(0, import_node_fs9.rmSync)((0,
|
|
2331
|
+
adoptRepoLocalCache((0, import_node_path8.resolve)(rootDir, ".odla/dev-token.json"), local.tokenFile, stderr);
|
|
2332
|
+
adoptRepoLocalCache((0, import_node_path8.resolve)(rootDir, ".odla/credentials.local.json"), local.credentialsFile, stderr);
|
|
2333
|
+
(0, import_node_fs9.rmSync)((0, import_node_path8.resolve)(rootDir, ".odla/handshake.local.json"), { force: true });
|
|
2239
2334
|
return {
|
|
2240
2335
|
...raw,
|
|
2241
2336
|
configPath: resolved,
|
|
@@ -2250,7 +2345,7 @@ async function loadProjectConfig(configPath = "odla.config.mjs", options = {}) {
|
|
|
2250
2345
|
async function resolveDataExport(cfg, value2, names) {
|
|
2251
2346
|
if (value2 === void 0 || value2 === null || value2 === false) return void 0;
|
|
2252
2347
|
if (typeof value2 !== "string") return value2;
|
|
2253
|
-
const target = (0,
|
|
2348
|
+
const target = (0, import_node_path8.isAbsolute)(value2) ? value2 : (0, import_node_path8.resolve)(cfg.rootDir, value2);
|
|
2254
2349
|
if (target.endsWith(".json")) {
|
|
2255
2350
|
return JSON.parse((0, import_node_fs9.readFileSync)(target, "utf8"));
|
|
2256
2351
|
}
|
|
@@ -2341,13 +2436,13 @@ function trimSlash(value2) {
|
|
|
2341
2436
|
function unique3(values) {
|
|
2342
2437
|
return [...new Set(values.filter(Boolean))];
|
|
2343
2438
|
}
|
|
2344
|
-
var import_node_fs9,
|
|
2439
|
+
var import_node_fs9, import_node_path8, import_node_url, import_apps, DEFAULT_PLATFORM, DEFAULT_ENVS, DEFAULT_SERVICES, configImportSerial, GOOGLE_CALENDAR_EVENTS_SCOPE, stderr;
|
|
2345
2440
|
var init_config = __esm({
|
|
2346
2441
|
"src/config.ts"() {
|
|
2347
2442
|
"use strict";
|
|
2348
2443
|
init_cjs_shims();
|
|
2349
2444
|
import_node_fs9 = require("fs");
|
|
2350
|
-
|
|
2445
|
+
import_node_path8 = require("path");
|
|
2351
2446
|
import_node_url = require("url");
|
|
2352
2447
|
import_apps = require("@odla-ai/apps");
|
|
2353
2448
|
init_ai_config_validation();
|
|
@@ -2370,13 +2465,13 @@ var init_config = __esm({
|
|
|
2370
2465
|
|
|
2371
2466
|
// src/operator-profiles.ts
|
|
2372
2467
|
function operatorProfileFile() {
|
|
2373
|
-
return (0,
|
|
2374
|
-
clean(
|
|
2468
|
+
return (0, import_node_path9.resolve)(
|
|
2469
|
+
clean(import_node_process14.default.env.ODLA_CONTEXT_FILE) ?? (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".odla", "contexts.json")
|
|
2375
2470
|
);
|
|
2376
2471
|
}
|
|
2377
2472
|
function resolveOperatorProfile(parsed) {
|
|
2378
2473
|
const fromFlag = clean(stringOpt(parsed.options.context));
|
|
2379
|
-
const fromEnvironment = clean(
|
|
2474
|
+
const fromEnvironment = clean(import_node_process14.default.env.ODLA_CONTEXT);
|
|
2380
2475
|
const name = fromFlag ?? fromEnvironment ?? null;
|
|
2381
2476
|
const file = operatorProfileFile();
|
|
2382
2477
|
if (!name) {
|
|
@@ -2416,10 +2511,10 @@ function removeOperatorProfile(name, file = operatorProfileFile()) {
|
|
|
2416
2511
|
return true;
|
|
2417
2512
|
}
|
|
2418
2513
|
function operatorCredentialFiles(selection) {
|
|
2419
|
-
const base = selection.name ? (0,
|
|
2514
|
+
const base = selection.name ? (0, import_node_path9.join)((0, import_node_path9.dirname)(selection.file), "profiles", selection.name) : (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".odla");
|
|
2420
2515
|
return {
|
|
2421
|
-
developer: (0,
|
|
2422
|
-
scoped: (0,
|
|
2516
|
+
developer: (0, import_node_path9.join)(base, "dev-token.json"),
|
|
2517
|
+
scoped: (0, import_node_path9.join)(base, "admin-token.local.json")
|
|
2423
2518
|
};
|
|
2424
2519
|
}
|
|
2425
2520
|
function assertOperatorName(value2, label) {
|
|
@@ -2491,15 +2586,15 @@ function clean(value2) {
|
|
|
2491
2586
|
const normalized = value2?.trim();
|
|
2492
2587
|
return normalized || void 0;
|
|
2493
2588
|
}
|
|
2494
|
-
var import_node_fs10, import_node_os3,
|
|
2589
|
+
var import_node_fs10, import_node_os3, import_node_path9, import_node_process14;
|
|
2495
2590
|
var init_operator_profiles = __esm({
|
|
2496
2591
|
"src/operator-profiles.ts"() {
|
|
2497
2592
|
"use strict";
|
|
2498
2593
|
init_cjs_shims();
|
|
2499
2594
|
import_node_fs10 = require("fs");
|
|
2500
2595
|
import_node_os3 = require("os");
|
|
2501
|
-
|
|
2502
|
-
|
|
2596
|
+
import_node_path9 = require("path");
|
|
2597
|
+
import_node_process14 = __toESM(require("process"), 1);
|
|
2503
2598
|
init_argv();
|
|
2504
2599
|
init_local();
|
|
2505
2600
|
init_token();
|
|
@@ -2510,7 +2605,7 @@ var init_operator_profiles = __esm({
|
|
|
2510
2605
|
async function resolveOperatorContext(parsed, options = {}) {
|
|
2511
2606
|
const profile = resolveOperatorProfile(parsed);
|
|
2512
2607
|
const configArgument = stringOpt(parsed.options.config) ?? "odla.config.mjs";
|
|
2513
|
-
const configPath = (0,
|
|
2608
|
+
const configPath = (0, import_node_path10.resolve)(configArgument);
|
|
2514
2609
|
const explicitConfig = parsed.options.config !== void 0;
|
|
2515
2610
|
const hasConfig = (0, import_node_fs11.existsSync)(configPath);
|
|
2516
2611
|
if (!hasConfig && (!options.allowMissingConfig || explicitConfig)) {
|
|
@@ -2518,13 +2613,13 @@ async function resolveOperatorContext(parsed, options = {}) {
|
|
|
2518
2613
|
}
|
|
2519
2614
|
const loaded = hasConfig ? await loadProjectConfig(configArgument) : void 0;
|
|
2520
2615
|
const platformFlag = clean2(stringOpt(parsed.options.platform));
|
|
2521
|
-
const platformEnvironment = clean2(
|
|
2616
|
+
const platformEnvironment = clean2(import_node_process15.default.env.ODLA_PLATFORM_URL);
|
|
2522
2617
|
const platformValue = platformAudience(
|
|
2523
2618
|
platformFlag ?? platformEnvironment ?? profile.value?.platform ?? loaded?.platformUrl ?? DEFAULT_PLATFORM2
|
|
2524
2619
|
);
|
|
2525
2620
|
const platformSource = platformFlag ? "flag" : platformEnvironment ? "environment" : profile.value ? "profile" : loaded ? "config" : "default";
|
|
2526
2621
|
const appFlag = clean2(stringOpt(parsed.options.app));
|
|
2527
|
-
const appEnvironment = clean2(
|
|
2622
|
+
const appEnvironment = clean2(import_node_process15.default.env.ODLA_APP_ID);
|
|
2528
2623
|
const appValue = appFlag ?? appEnvironment ?? profile.value?.app ?? loaded?.app.id ?? null;
|
|
2529
2624
|
const appSource = appFlag ? "flag" : appEnvironment ? "environment" : profile.value?.app ? "profile" : loaded ? "config" : "unresolved";
|
|
2530
2625
|
if (appValue) {
|
|
@@ -2538,16 +2633,16 @@ async function resolveOperatorContext(parsed, options = {}) {
|
|
|
2538
2633
|
);
|
|
2539
2634
|
}
|
|
2540
2635
|
const envFlag = clean2(stringOpt(parsed.options.env));
|
|
2541
|
-
const envEnvironment = clean2(
|
|
2636
|
+
const envEnvironment = clean2(import_node_process15.default.env.ODLA_ENV);
|
|
2542
2637
|
const environmentValue = envFlag ?? envEnvironment ?? profile.value?.environment ?? options.defaultEnvironment ?? null;
|
|
2543
2638
|
const environmentSource = envFlag ? "flag" : envEnvironment ? "environment" : profile.value?.environment ? "profile" : options.defaultEnvironment ? "default" : "unresolved";
|
|
2544
2639
|
if (environmentValue) {
|
|
2545
2640
|
assertOperatorName(environmentValue, "environment");
|
|
2546
2641
|
}
|
|
2547
|
-
const rootDir = loaded?.rootDir ??
|
|
2642
|
+
const rootDir = loaded?.rootDir ?? import_node_process15.default.cwd();
|
|
2548
2643
|
const profileCredentials = operatorCredentialFiles(profile);
|
|
2549
|
-
const tokenFile = clean2(
|
|
2550
|
-
const scopedTokenFile2 = clean2(
|
|
2644
|
+
const tokenFile = clean2(import_node_process15.default.env.ODLA_DEV_TOKEN_FILE) ? (0, import_node_path10.resolve)(import_node_process15.default.env.ODLA_DEV_TOKEN_FILE) : profile.name ? profileCredentials.developer : loaded?.local.tokenFile ?? profileCredentials.developer;
|
|
2645
|
+
const scopedTokenFile2 = clean2(import_node_process15.default.env.ODLA_ADMIN_TOKEN_FILE) ? (0, import_node_path10.resolve)(import_node_process15.default.env.ODLA_ADMIN_TOKEN_FILE) : profile.name ? profileCredentials.scoped : loaded ? (0, import_node_path10.join)(loaded.rootDir, ".odla", "admin-token.local.json") : profileCredentials.scoped;
|
|
2551
2646
|
const cfg = loaded ? {
|
|
2552
2647
|
...loaded,
|
|
2553
2648
|
platformUrl: platformValue,
|
|
@@ -2569,8 +2664,8 @@ async function resolveOperatorContext(parsed, options = {}) {
|
|
|
2569
2664
|
services: [],
|
|
2570
2665
|
local: {
|
|
2571
2666
|
tokenFile,
|
|
2572
|
-
credentialsFile: (0,
|
|
2573
|
-
devVarsFile: (0,
|
|
2667
|
+
credentialsFile: (0, import_node_path10.join)(rootDir, ".odla", "credentials.local.json"),
|
|
2668
|
+
devVarsFile: (0, import_node_path10.join)(rootDir, ".dev.vars"),
|
|
2574
2669
|
gitignore: true
|
|
2575
2670
|
}
|
|
2576
2671
|
};
|
|
@@ -2602,14 +2697,14 @@ function clean2(value2) {
|
|
|
2602
2697
|
const normalized = value2?.trim();
|
|
2603
2698
|
return normalized || void 0;
|
|
2604
2699
|
}
|
|
2605
|
-
var import_node_fs11,
|
|
2700
|
+
var import_node_fs11, import_node_path10, import_node_process15, DEFAULT_PLATFORM2;
|
|
2606
2701
|
var init_operator_context = __esm({
|
|
2607
2702
|
"src/operator-context.ts"() {
|
|
2608
2703
|
"use strict";
|
|
2609
2704
|
init_cjs_shims();
|
|
2610
2705
|
import_node_fs11 = require("fs");
|
|
2611
|
-
|
|
2612
|
-
|
|
2706
|
+
import_node_path10 = require("path");
|
|
2707
|
+
import_node_process15 = __toESM(require("process"), 1);
|
|
2613
2708
|
init_argv();
|
|
2614
2709
|
init_config();
|
|
2615
2710
|
init_operator_profiles();
|
|
@@ -2915,7 +3010,7 @@ async function authCommand(parsed, deps = {}) {
|
|
|
2915
3010
|
const { cfg } = context;
|
|
2916
3011
|
const out = deps.stdout ?? console;
|
|
2917
3012
|
const doFetch = deps.fetch ?? fetch;
|
|
2918
|
-
const email = stringOpt(parsed.options.email) ??
|
|
3013
|
+
const email = stringOpt(parsed.options.email) ?? import_node_process16.default.env.ODLA_USER_EMAIL?.trim();
|
|
2919
3014
|
if (!email) {
|
|
2920
3015
|
throw new Error(
|
|
2921
3016
|
"auth login requires --email <odla-account> or ODLA_USER_EMAIL; confirm the signed-in odla email instead of using git or GitHub identity"
|
|
@@ -2954,12 +3049,12 @@ async function authCommand(parsed, deps = {}) {
|
|
|
2954
3049
|
out.log(`Authorized ${identity.displayName}${handle} for ${cfg.app.id}.`);
|
|
2955
3050
|
out.log(`odla account: ${identity.email ?? "not returned"}`);
|
|
2956
3051
|
}
|
|
2957
|
-
var
|
|
3052
|
+
var import_node_process16;
|
|
2958
3053
|
var init_auth_command = __esm({
|
|
2959
3054
|
"src/auth-command.ts"() {
|
|
2960
3055
|
"use strict";
|
|
2961
3056
|
init_cjs_shims();
|
|
2962
|
-
|
|
3057
|
+
import_node_process16 = __toESM(require("process"), 1);
|
|
2963
3058
|
init_argv();
|
|
2964
3059
|
init_operator_context();
|
|
2965
3060
|
init_token();
|
|
@@ -3479,15 +3574,15 @@ var init_brand_design_unpack = __esm({
|
|
|
3479
3574
|
|
|
3480
3575
|
// src/brand-command.ts
|
|
3481
3576
|
async function readBundle(source, deps) {
|
|
3482
|
-
if (source !== "-") return (0, import_promises.readFile)((0,
|
|
3577
|
+
if (source !== "-") return (0, import_promises.readFile)((0, import_node_path11.resolve)(source), "utf8");
|
|
3483
3578
|
const readStdin = deps.readStdin;
|
|
3484
3579
|
if (!readStdin) throw new Error("reading a bundle from stdin is not supported here");
|
|
3485
3580
|
return readStdin();
|
|
3486
3581
|
}
|
|
3487
3582
|
async function writeAll(result, outDir) {
|
|
3488
3583
|
for (const file of result.files) {
|
|
3489
|
-
const target = (0,
|
|
3490
|
-
await (0, import_promises.mkdir)((0,
|
|
3584
|
+
const target = (0, import_node_path11.resolve)(outDir, file.path);
|
|
3585
|
+
await (0, import_promises.mkdir)((0, import_node_path11.dirname)(target), { recursive: true });
|
|
3491
3586
|
await (0, import_promises.writeFile)(target, file.bytes);
|
|
3492
3587
|
}
|
|
3493
3588
|
}
|
|
@@ -3495,7 +3590,7 @@ async function designUnpack(parsed, deps) {
|
|
|
3495
3590
|
assertArgs(parsed, ["out", "json"], 4);
|
|
3496
3591
|
const source = parsed.positionals[3];
|
|
3497
3592
|
if (!source) throw new Error(USAGE);
|
|
3498
|
-
const outDir = (0,
|
|
3593
|
+
const outDir = (0, import_node_path11.resolve)(stringOpt(parsed.options.out) ?? "design");
|
|
3499
3594
|
const result = unpackDesign(await readBundle(source, deps));
|
|
3500
3595
|
await writeAll(result, outDir);
|
|
3501
3596
|
const out = deps.stdout ?? console;
|
|
@@ -3522,13 +3617,13 @@ async function brandCommand(parsed, deps) {
|
|
|
3522
3617
|
if (subject !== "design") rejectWord(["brand"], subject);
|
|
3523
3618
|
rejectWord(["brand", "design"], action2, USAGE);
|
|
3524
3619
|
}
|
|
3525
|
-
var import_promises,
|
|
3620
|
+
var import_promises, import_node_path11, USAGE;
|
|
3526
3621
|
var init_brand_command = __esm({
|
|
3527
3622
|
"src/brand-command.ts"() {
|
|
3528
3623
|
"use strict";
|
|
3529
3624
|
init_cjs_shims();
|
|
3530
3625
|
import_promises = require("fs/promises");
|
|
3531
|
-
|
|
3626
|
+
import_node_path11 = require("path");
|
|
3532
3627
|
init_argv();
|
|
3533
3628
|
init_brand_design_unpack();
|
|
3534
3629
|
init_surface();
|
|
@@ -4577,7 +4672,7 @@ async function operationClient(cfg, options, purpose) {
|
|
|
4577
4672
|
platform: cfg.platformUrl,
|
|
4578
4673
|
scope: "app:config:write",
|
|
4579
4674
|
token: options.token,
|
|
4580
|
-
tokenFile: (0,
|
|
4675
|
+
tokenFile: (0, import_node_path12.join)(cfg.rootDir, ".odla", "admin-token.local.json"),
|
|
4581
4676
|
rootDir: cfg.rootDir,
|
|
4582
4677
|
email: options.email,
|
|
4583
4678
|
open: options.open,
|
|
@@ -4629,13 +4724,13 @@ function normalizeRequestError(error) {
|
|
|
4629
4724
|
function record4(value2) {
|
|
4630
4725
|
return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
|
|
4631
4726
|
}
|
|
4632
|
-
var import_apps6,
|
|
4727
|
+
var import_apps6, import_node_path12, IDEMPOTENCY_KEY, DEFAULT_WAIT_SECONDS, DEFAULT_INTERVAL_SECONDS;
|
|
4633
4728
|
var init_config_operation_command = __esm({
|
|
4634
4729
|
"src/config-operation-command.ts"() {
|
|
4635
4730
|
"use strict";
|
|
4636
4731
|
init_cjs_shims();
|
|
4637
4732
|
import_apps6 = require("@odla-ai/apps");
|
|
4638
|
-
|
|
4733
|
+
import_node_path12 = require("path");
|
|
4639
4734
|
init_admin_ai_auth();
|
|
4640
4735
|
init_version();
|
|
4641
4736
|
init_config();
|
|
@@ -4958,7 +5053,7 @@ async function inspectConfig(options) {
|
|
|
4958
5053
|
platform: cfg.platformUrl,
|
|
4959
5054
|
scope: "app:config:read",
|
|
4960
5055
|
token: options.token,
|
|
4961
|
-
tokenFile: (0,
|
|
5056
|
+
tokenFile: (0, import_node_path13.join)(cfg.rootDir, ".odla", "admin-token.local.json"),
|
|
4962
5057
|
rootDir: cfg.rootDir,
|
|
4963
5058
|
email: options.email,
|
|
4964
5059
|
open: options.open,
|
|
@@ -5087,13 +5182,13 @@ function studioSettingsUrl(reconciliation) {
|
|
|
5087
5182
|
function quoteArg2(value2) {
|
|
5088
5183
|
return `'${value2.replace(/'/g, `'\\''`)}'`;
|
|
5089
5184
|
}
|
|
5090
|
-
var import_apps8,
|
|
5185
|
+
var import_apps8, import_node_path13;
|
|
5091
5186
|
var init_config_reconcile_command = __esm({
|
|
5092
5187
|
"src/config-reconcile-command.ts"() {
|
|
5093
5188
|
"use strict";
|
|
5094
5189
|
init_cjs_shims();
|
|
5095
5190
|
import_apps8 = require("@odla-ai/apps");
|
|
5096
|
-
|
|
5191
|
+
import_node_path13 = require("path");
|
|
5097
5192
|
init_admin_ai_auth();
|
|
5098
5193
|
init_config();
|
|
5099
5194
|
init_config_reconcile_digest();
|
|
@@ -5106,7 +5201,7 @@ var init_config_reconcile_command = __esm({
|
|
|
5106
5201
|
// src/wrangler.ts
|
|
5107
5202
|
function findWranglerConfig(rootDir) {
|
|
5108
5203
|
for (const name of WRANGLER_CONFIG_FILES) {
|
|
5109
|
-
const path = (0,
|
|
5204
|
+
const path = (0, import_node_path14.join)(rootDir, name);
|
|
5110
5205
|
if ((0, import_node_fs14.existsSync)(path)) return path;
|
|
5111
5206
|
}
|
|
5112
5207
|
return null;
|
|
@@ -5218,16 +5313,16 @@ function wranglerBulkSecrets(run, opts) {
|
|
|
5218
5313
|
];
|
|
5219
5314
|
return run("npx", args, { input: JSON.stringify(opts.secrets), cwd: opts.cwd });
|
|
5220
5315
|
}
|
|
5221
|
-
var
|
|
5316
|
+
var import_node_child_process3, import_node_fs14, import_node_path14, defaultRunner, WRANGLER_CONFIG_FILES;
|
|
5222
5317
|
var init_wrangler = __esm({
|
|
5223
5318
|
"src/wrangler.ts"() {
|
|
5224
5319
|
"use strict";
|
|
5225
5320
|
init_cjs_shims();
|
|
5226
|
-
|
|
5321
|
+
import_node_child_process3 = require("child_process");
|
|
5227
5322
|
import_node_fs14 = require("fs");
|
|
5228
|
-
|
|
5323
|
+
import_node_path14 = require("path");
|
|
5229
5324
|
defaultRunner = (cmd, args, opts) => new Promise((resolvePromise, reject) => {
|
|
5230
|
-
const child = (0,
|
|
5325
|
+
const child = (0, import_node_child_process3.spawn)(cmd, args, { cwd: opts?.cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
5231
5326
|
let stdout = "";
|
|
5232
5327
|
let stderr2 = "";
|
|
5233
5328
|
child.stdout.on("data", (chunk) => stdout += chunk.toString());
|
|
@@ -5284,10 +5379,10 @@ function wranglerWarnings(rootDir) {
|
|
|
5284
5379
|
for (const { label, block: block2 } of blocks) {
|
|
5285
5380
|
const assets = block2.assets;
|
|
5286
5381
|
if (assets?.directory) {
|
|
5287
|
-
const dir = (0,
|
|
5288
|
-
if (dir === (0,
|
|
5382
|
+
const dir = (0, import_node_path15.resolve)(rootDir, assets.directory);
|
|
5383
|
+
if (dir === (0, import_node_path15.resolve)(rootDir)) {
|
|
5289
5384
|
warnings.push(`${label}assets.directory is the project root \u2014 point it at a dedicated build dir (wrangler dev fails with "spawn EBADF")`);
|
|
5290
|
-
} else if ((0, import_node_fs15.existsSync)((0,
|
|
5385
|
+
} else if ((0, import_node_fs15.existsSync)((0, import_node_path15.join)(dir, "node_modules"))) {
|
|
5291
5386
|
warnings.push(`${label}assets.directory contains node_modules \u2014 wrangler dev's watcher will exhaust file descriptors`);
|
|
5292
5387
|
}
|
|
5293
5388
|
}
|
|
@@ -5322,7 +5417,7 @@ function o11yProjectWarnings(rootDir) {
|
|
|
5322
5417
|
warnings.push("cannot verify o11y Worker instrumentation \u2014 add a parseable wrangler.jsonc/json config");
|
|
5323
5418
|
return warnings;
|
|
5324
5419
|
}
|
|
5325
|
-
const main = typeof config.main === "string" ? (0,
|
|
5420
|
+
const main = typeof config.main === "string" ? (0, import_node_path15.resolve)(rootDir, config.main) : null;
|
|
5326
5421
|
if (!main || !(0, import_node_fs15.existsSync)(main)) {
|
|
5327
5422
|
warnings.push("cannot verify o11y Worker instrumentation \u2014 wrangler main is missing or unreadable");
|
|
5328
5423
|
} else {
|
|
@@ -5352,23 +5447,23 @@ function calendarProjectWarnings(rootDir) {
|
|
|
5352
5447
|
}
|
|
5353
5448
|
function readPackageJson(rootDir) {
|
|
5354
5449
|
try {
|
|
5355
|
-
return JSON.parse((0, import_node_fs15.readFileSync)((0,
|
|
5450
|
+
return JSON.parse((0, import_node_fs15.readFileSync)((0, import_node_path15.join)(rootDir, "package.json"), "utf8"));
|
|
5356
5451
|
} catch {
|
|
5357
5452
|
return null;
|
|
5358
5453
|
}
|
|
5359
5454
|
}
|
|
5360
|
-
var
|
|
5455
|
+
var import_node_child_process4, import_node_fs15, import_node_path15, defaultExec;
|
|
5361
5456
|
var init_doctor_checks = __esm({
|
|
5362
5457
|
"src/doctor-checks.ts"() {
|
|
5363
5458
|
"use strict";
|
|
5364
5459
|
init_cjs_shims();
|
|
5365
|
-
|
|
5460
|
+
import_node_child_process4 = require("child_process");
|
|
5366
5461
|
import_node_fs15 = require("fs");
|
|
5367
|
-
|
|
5462
|
+
import_node_path15 = require("path");
|
|
5368
5463
|
init_redact();
|
|
5369
5464
|
init_local();
|
|
5370
5465
|
init_wrangler();
|
|
5371
|
-
defaultExec = (cmd, args, cwd) => (0,
|
|
5466
|
+
defaultExec = (cmd, args, cwd) => (0, import_node_child_process4.execFileSync)(cmd, args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
5372
5467
|
}
|
|
5373
5468
|
});
|
|
5374
5469
|
|
|
@@ -5701,8 +5796,8 @@ var init_harness_options = __esm({
|
|
|
5701
5796
|
// src/init.ts
|
|
5702
5797
|
function initProject(options) {
|
|
5703
5798
|
const out = options.stdout ?? console;
|
|
5704
|
-
const rootDir = (0,
|
|
5705
|
-
const configPath = (0,
|
|
5799
|
+
const rootDir = (0, import_node_path16.resolve)(options.rootDir ?? process.cwd());
|
|
5800
|
+
const configPath = (0, import_node_path16.resolve)(rootDir, options.configPath ?? "odla.config.mjs");
|
|
5706
5801
|
if ((0, import_node_fs16.existsSync)(configPath) && !options.force) {
|
|
5707
5802
|
throw new Error(`${configPath} already exists. Pass --force to overwrite.`);
|
|
5708
5803
|
}
|
|
@@ -5719,12 +5814,12 @@ function initProject(options) {
|
|
|
5719
5814
|
}
|
|
5720
5815
|
}
|
|
5721
5816
|
const aiProvider = options.aiProvider;
|
|
5722
|
-
(0, import_node_fs16.mkdirSync)((0,
|
|
5723
|
-
(0, import_node_fs16.mkdirSync)((0,
|
|
5724
|
-
(0, import_node_fs16.mkdirSync)((0,
|
|
5817
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path16.dirname)(configPath), { recursive: true });
|
|
5818
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path16.resolve)(rootDir, "src/odla"), { recursive: true });
|
|
5819
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path16.resolve)(rootDir, ".odla"), { recursive: true });
|
|
5725
5820
|
(0, import_node_fs16.writeFileSync)(configPath, configTemplate({ appId: options.appId, name: options.name, envs, services, aiProvider }));
|
|
5726
|
-
writeIfMissing((0,
|
|
5727
|
-
writeIfMissing((0,
|
|
5821
|
+
writeIfMissing((0, import_node_path16.resolve)(rootDir, "src/odla/schema.mjs"), schemaTemplate());
|
|
5822
|
+
writeIfMissing((0, import_node_path16.resolve)(rootDir, "src/odla/rules.mjs"), rulesTemplate());
|
|
5728
5823
|
ensureGitignore(rootDir);
|
|
5729
5824
|
out.log(`created ${relativeDisplay(configPath, rootDir)}`);
|
|
5730
5825
|
out.log("created src/odla/schema.mjs and src/odla/rules.mjs");
|
|
@@ -5837,13 +5932,13 @@ function defaultKeyEnv(provider) {
|
|
|
5837
5932
|
function relativeDisplay(path, rootDir) {
|
|
5838
5933
|
return path.startsWith(rootDir) ? path.slice(rootDir.length + 1) : path;
|
|
5839
5934
|
}
|
|
5840
|
-
var import_node_fs16,
|
|
5935
|
+
var import_node_fs16, import_node_path16, import_apps9;
|
|
5841
5936
|
var init_init = __esm({
|
|
5842
5937
|
"src/init.ts"() {
|
|
5843
5938
|
"use strict";
|
|
5844
5939
|
init_cjs_shims();
|
|
5845
5940
|
import_node_fs16 = require("fs");
|
|
5846
|
-
|
|
5941
|
+
import_node_path16 = require("path");
|
|
5847
5942
|
import_apps9 = require("@odla-ai/apps");
|
|
5848
5943
|
init_local();
|
|
5849
5944
|
}
|
|
@@ -6176,8 +6271,8 @@ function installSkill(options = {}) {
|
|
|
6176
6271
|
const files = listFiles(sourceDir);
|
|
6177
6272
|
if (files.length === 0) throw new Error(`no bundled skills found at ${sourceDir}`);
|
|
6178
6273
|
const harnesses = normalizeHarnesses(options.harnesses, options.global === true);
|
|
6179
|
-
const root = (0,
|
|
6180
|
-
const home = (0,
|
|
6274
|
+
const root = (0, import_node_path17.resolve)(options.dir ?? process.cwd());
|
|
6275
|
+
const home = (0, import_node_path17.resolve)(options.homeDir ?? (0, import_node_os4.homedir)());
|
|
6181
6276
|
const plans = /* @__PURE__ */ new Map();
|
|
6182
6277
|
const targets = /* @__PURE__ */ new Map();
|
|
6183
6278
|
const rememberTarget = (harness, target) => {
|
|
@@ -6191,48 +6286,48 @@ function installSkill(options = {}) {
|
|
|
6191
6286
|
plans.set(target, { target, content: content2, boundary, managedMerge });
|
|
6192
6287
|
};
|
|
6193
6288
|
const planSkillTree = (targetDir2, boundary = root) => {
|
|
6194
|
-
for (const rel of files) plan((0,
|
|
6289
|
+
for (const rel of files) plan((0, import_node_path17.join)(targetDir2, rel), (0, import_node_fs17.readFileSync)((0, import_node_path17.join)(sourceDir, rel), "utf8"), false, boundary);
|
|
6195
6290
|
};
|
|
6196
6291
|
let targetDir;
|
|
6197
6292
|
if (options.global) {
|
|
6198
|
-
const claudeRoot = (0,
|
|
6199
|
-
const codexRoot = (0,
|
|
6293
|
+
const claudeRoot = (0, import_node_path17.join)(home, ".claude", "skills");
|
|
6294
|
+
const codexRoot = (0, import_node_path17.resolve)(options.codexHomeDir ?? process.env.CODEX_HOME ?? (0, import_node_path17.join)(home, ".codex"), "skills");
|
|
6200
6295
|
targetDir = harnesses[0] === "codex" ? codexRoot : claudeRoot;
|
|
6201
6296
|
for (const harness of harnesses) {
|
|
6202
6297
|
const skillRoot = harness === "claude" ? claudeRoot : codexRoot;
|
|
6203
|
-
planSkillTree(skillRoot, harness === "claude" ? home : (0,
|
|
6298
|
+
planSkillTree(skillRoot, harness === "claude" ? home : (0, import_node_path17.dirname)((0, import_node_path17.dirname)(codexRoot)));
|
|
6204
6299
|
rememberTarget(harness, skillRoot);
|
|
6205
6300
|
}
|
|
6206
6301
|
} else {
|
|
6207
|
-
const sharedRoot = (0,
|
|
6302
|
+
const sharedRoot = (0, import_node_path17.join)(root, ".agents", "skills");
|
|
6208
6303
|
planSkillTree(sharedRoot);
|
|
6209
|
-
const claudeRoot = (0,
|
|
6304
|
+
const claudeRoot = (0, import_node_path17.join)(root, ".claude", "skills");
|
|
6210
6305
|
targetDir = harnesses.includes("claude") ? claudeRoot : sharedRoot;
|
|
6211
6306
|
for (const harness of harnesses) rememberTarget(harness, sharedRoot);
|
|
6212
6307
|
if (harnesses.includes("claude")) {
|
|
6213
6308
|
for (const skill of skillNames(files)) {
|
|
6214
|
-
const canonical2 = (0, import_node_fs17.readFileSync)((0,
|
|
6215
|
-
plan((0,
|
|
6309
|
+
const canonical2 = (0, import_node_fs17.readFileSync)((0, import_node_path17.join)(sourceDir, skill, "SKILL.md"), "utf8");
|
|
6310
|
+
plan((0, import_node_path17.join)(claudeRoot, skill, "SKILL.md"), claudeAdapter(skill, canonical2));
|
|
6216
6311
|
}
|
|
6217
6312
|
rememberTarget("claude", claudeRoot);
|
|
6218
6313
|
}
|
|
6219
6314
|
if (harnesses.includes("cursor")) {
|
|
6220
|
-
const cursorRule = (0,
|
|
6315
|
+
const cursorRule = (0, import_node_path17.join)(root, ".cursor", "rules", "odla.mdc");
|
|
6221
6316
|
plan(cursorRule, CURSOR_RULE);
|
|
6222
6317
|
rememberTarget("cursor", cursorRule);
|
|
6223
6318
|
}
|
|
6224
6319
|
if (harnesses.includes("agents")) {
|
|
6225
|
-
const agentsFile = (0,
|
|
6320
|
+
const agentsFile = (0, import_node_path17.join)(root, "AGENTS.md");
|
|
6226
6321
|
plan(agentsFile, managedFileContent(agentsFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
|
|
6227
6322
|
rememberTarget("agents", agentsFile);
|
|
6228
6323
|
}
|
|
6229
6324
|
if (harnesses.includes("copilot")) {
|
|
6230
|
-
const copilotFile = (0,
|
|
6325
|
+
const copilotFile = (0, import_node_path17.join)(root, ".github", "copilot-instructions.md");
|
|
6231
6326
|
plan(copilotFile, managedFileContent(copilotFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
|
|
6232
6327
|
rememberTarget("copilot", copilotFile);
|
|
6233
6328
|
}
|
|
6234
6329
|
if (harnesses.includes("gemini")) {
|
|
6235
|
-
const geminiFile = (0,
|
|
6330
|
+
const geminiFile = (0, import_node_path17.join)(root, "GEMINI.md");
|
|
6236
6331
|
plan(geminiFile, managedFileContent(geminiFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
|
|
6237
6332
|
rememberTarget("gemini", geminiFile);
|
|
6238
6333
|
}
|
|
@@ -6268,7 +6363,7 @@ ${conflicts.map((f) => ` - ${f}`).join("\n")}`
|
|
|
6268
6363
|
}
|
|
6269
6364
|
for (const file of plans.values()) {
|
|
6270
6365
|
if (!(0, import_node_fs17.existsSync)(file.target) || (0, import_node_fs17.readFileSync)(file.target, "utf8") !== file.content) {
|
|
6271
|
-
(0, import_node_fs17.mkdirSync)((0,
|
|
6366
|
+
(0, import_node_fs17.mkdirSync)((0, import_node_path17.dirname)(file.target), { recursive: true });
|
|
6272
6367
|
(0, import_node_fs17.writeFileSync)(file.target, file.content);
|
|
6273
6368
|
}
|
|
6274
6369
|
}
|
|
@@ -6288,7 +6383,7 @@ ${conflicts.map((f) => ` - ${f}`).join("\n")}`
|
|
|
6288
6383
|
};
|
|
6289
6384
|
}
|
|
6290
6385
|
function pathsUnder(root, paths2) {
|
|
6291
|
-
return [...paths2].map((path) => (0,
|
|
6386
|
+
return [...paths2].map((path) => (0, import_node_path17.relative)(root, path)).filter((path) => path !== ".." && !path.startsWith(`..${import_node_path17.sep}`) && !(0, import_node_path17.isAbsolute)(path)).sort();
|
|
6292
6387
|
}
|
|
6293
6388
|
function normalizeHarnesses(values, global) {
|
|
6294
6389
|
const requested = values?.length ? values : ["claude"];
|
|
@@ -6333,13 +6428,13 @@ function managedFileContent(path, block2, force, boundary) {
|
|
|
6333
6428
|
return `${current.slice(0, startAt)}${block2}${current.slice(afterEnd)}`;
|
|
6334
6429
|
}
|
|
6335
6430
|
function symlinkedComponent(boundary, target) {
|
|
6336
|
-
const rel = (0,
|
|
6337
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
6431
|
+
const rel = (0, import_node_path17.relative)(boundary, target);
|
|
6432
|
+
if (rel === ".." || rel.startsWith(`..${import_node_path17.sep}`) || (0, import_node_path17.isAbsolute)(rel)) {
|
|
6338
6433
|
throw new Error(`agent setup target escapes its install root: ${target}`);
|
|
6339
6434
|
}
|
|
6340
6435
|
let current = boundary;
|
|
6341
|
-
for (const part of rel.split(
|
|
6342
|
-
current = (0,
|
|
6436
|
+
for (const part of rel.split(import_node_path17.sep).filter(Boolean)) {
|
|
6437
|
+
current = (0, import_node_path17.join)(current, part);
|
|
6343
6438
|
try {
|
|
6344
6439
|
if ((0, import_node_fs17.lstatSync)(current).isSymbolicLink()) return current;
|
|
6345
6440
|
} catch (error) {
|
|
@@ -6356,22 +6451,22 @@ function listFiles(dir) {
|
|
|
6356
6451
|
const results = [];
|
|
6357
6452
|
const walk = (current) => {
|
|
6358
6453
|
for (const entry of (0, import_node_fs17.readdirSync)(current, { withFileTypes: true })) {
|
|
6359
|
-
const path = (0,
|
|
6454
|
+
const path = (0, import_node_path17.join)(current, entry.name);
|
|
6360
6455
|
if (entry.isDirectory()) walk(path);
|
|
6361
|
-
else results.push((0,
|
|
6456
|
+
else results.push((0, import_node_path17.relative)(dir, path));
|
|
6362
6457
|
}
|
|
6363
6458
|
};
|
|
6364
6459
|
walk(dir);
|
|
6365
6460
|
return results.sort();
|
|
6366
6461
|
}
|
|
6367
|
-
var import_node_fs17, import_node_os4,
|
|
6462
|
+
var import_node_fs17, import_node_os4, import_node_path17, import_node_url2, AGENT_HARNESSES;
|
|
6368
6463
|
var init_skill = __esm({
|
|
6369
6464
|
"src/skill.ts"() {
|
|
6370
6465
|
"use strict";
|
|
6371
6466
|
init_cjs_shims();
|
|
6372
6467
|
import_node_fs17 = require("fs");
|
|
6373
6468
|
import_node_os4 = require("os");
|
|
6374
|
-
|
|
6469
|
+
import_node_path17 = require("path");
|
|
6375
6470
|
import_node_url2 = require("url");
|
|
6376
6471
|
init_skill_adapters();
|
|
6377
6472
|
AGENT_HARNESSES = ["claude", "codex", "cursor", "copilot", "gemini", "agents"];
|
|
@@ -7941,7 +8036,7 @@ var init_dist2 = __esm({
|
|
|
7941
8036
|
});
|
|
7942
8037
|
|
|
7943
8038
|
// ../graph/dist/code/index.js
|
|
7944
|
-
function
|
|
8039
|
+
function dirname11(path) {
|
|
7945
8040
|
const at = path.lastIndexOf("/");
|
|
7946
8041
|
return at <= 0 ? "." : path.slice(0, at);
|
|
7947
8042
|
}
|
|
@@ -7957,7 +8052,7 @@ function join14(base, specifier) {
|
|
|
7957
8052
|
}
|
|
7958
8053
|
function resolveImport(fromPath, specifier, known) {
|
|
7959
8054
|
if (!specifier.startsWith(".")) return null;
|
|
7960
|
-
const base = join14(
|
|
8055
|
+
const base = join14(dirname11(fromPath), specifier);
|
|
7961
8056
|
const candidates = [
|
|
7962
8057
|
base,
|
|
7963
8058
|
base.replace(/\.js$/, ".ts"),
|
|
@@ -11068,19 +11163,19 @@ async function inferGitHubRepository(cwd = process.cwd(), readOrigin = defaultRe
|
|
|
11068
11163
|
return repositoryFromGitRemote(remote);
|
|
11069
11164
|
}
|
|
11070
11165
|
async function defaultReadOrigin(cwd) {
|
|
11071
|
-
const result = await (0, import_node_util2.promisify)(
|
|
11166
|
+
const result = await (0, import_node_util2.promisify)(import_node_child_process5.execFile)(
|
|
11072
11167
|
"git",
|
|
11073
11168
|
["remote", "get-url", "origin"],
|
|
11074
11169
|
{ cwd, encoding: "utf8" }
|
|
11075
11170
|
);
|
|
11076
11171
|
return result.stdout;
|
|
11077
11172
|
}
|
|
11078
|
-
var
|
|
11173
|
+
var import_node_child_process5, import_node_util2;
|
|
11079
11174
|
var init_security_hosted_github = __esm({
|
|
11080
11175
|
"src/security-hosted-github.ts"() {
|
|
11081
11176
|
"use strict";
|
|
11082
11177
|
init_cjs_shims();
|
|
11083
|
-
|
|
11178
|
+
import_node_child_process5 = require("child_process");
|
|
11084
11179
|
import_node_util2 = require("util");
|
|
11085
11180
|
init_security_hosted_request();
|
|
11086
11181
|
}
|
|
@@ -11127,7 +11222,7 @@ async function prepareCodeLocalSource(cwd, repository, readHead = readGitHead) {
|
|
|
11127
11222
|
}
|
|
11128
11223
|
async function readGitHead(cwd) {
|
|
11129
11224
|
const value2 = await new Promise((accept, reject) => {
|
|
11130
|
-
(0,
|
|
11225
|
+
(0, import_node_child_process6.execFile)("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8", maxBuffer: 16384 }, (error, stdout) => {
|
|
11131
11226
|
if (error) reject(new Error("code connect requires a Git checkout with an initial commit"));
|
|
11132
11227
|
else accept(stdout.trim());
|
|
11133
11228
|
});
|
|
@@ -11138,12 +11233,12 @@ async function readGitHead(cwd) {
|
|
|
11138
11233
|
function digestText(value2) {
|
|
11139
11234
|
return `sha256:${(0, import_node_crypto3.createHash)("sha256").update(value2).digest("hex")}`;
|
|
11140
11235
|
}
|
|
11141
|
-
var
|
|
11236
|
+
var import_node_child_process6, import_node_crypto3, SOURCE_LIMITS2;
|
|
11142
11237
|
var init_code_local_source = __esm({
|
|
11143
11238
|
"src/code-local-source.ts"() {
|
|
11144
11239
|
"use strict";
|
|
11145
11240
|
init_cjs_shims();
|
|
11146
|
-
|
|
11241
|
+
import_node_child_process6 = require("child_process");
|
|
11147
11242
|
import_node_crypto3 = require("crypto");
|
|
11148
11243
|
init_node();
|
|
11149
11244
|
SOURCE_LIMITS2 = { maxFiles: 2e4, maxBytes: 512 * 1024 * 1024 };
|
|
@@ -11184,7 +11279,7 @@ var init_code_runtime_config = __esm({
|
|
|
11184
11279
|
// src/code-connect.ts
|
|
11185
11280
|
async function codeConnect(options) {
|
|
11186
11281
|
const cwd = options.cwd ?? process.cwd();
|
|
11187
|
-
const configPath = (0,
|
|
11282
|
+
const configPath = (0, import_node_path18.resolve)(cwd, options.configPath);
|
|
11188
11283
|
const cfg = (0, import_node_fs18.existsSync)(configPath) ? await loadProjectConfig(configPath) : null;
|
|
11189
11284
|
const requestedAppId = options.appId?.trim();
|
|
11190
11285
|
if (requestedAppId && !/^[a-z0-9][a-z0-9-]{1,62}$/.test(requestedAppId)) {
|
|
@@ -11350,14 +11445,14 @@ function apiFailure(action2, status, value2) {
|
|
|
11350
11445
|
function record6(value2) {
|
|
11351
11446
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
11352
11447
|
}
|
|
11353
|
-
var import_node_fs18, import_node_os5,
|
|
11448
|
+
var import_node_fs18, import_node_os5, import_node_path18;
|
|
11354
11449
|
var init_code_connect = __esm({
|
|
11355
11450
|
"src/code-connect.ts"() {
|
|
11356
11451
|
"use strict";
|
|
11357
11452
|
init_cjs_shims();
|
|
11358
11453
|
import_node_fs18 = require("fs");
|
|
11359
11454
|
import_node_os5 = require("os");
|
|
11360
|
-
|
|
11455
|
+
import_node_path18 = require("path");
|
|
11361
11456
|
init_node();
|
|
11362
11457
|
init_admin_ai_auth();
|
|
11363
11458
|
init_config();
|
|
@@ -11672,7 +11767,7 @@ function developerTokenStatus(context, parsed, now = Date.now()) {
|
|
|
11672
11767
|
const cacheStatus = !cached?.token ? "missing" : cached.platform !== context.platform.value ? "other-platform" : (cached.expiresAt ?? 0) <= now + 6e4 ? "expired" : "valid";
|
|
11673
11768
|
const source = clean3(
|
|
11674
11769
|
stringOpt(parsed.options.token)
|
|
11675
|
-
) ? "flag" : clean3(
|
|
11770
|
+
) ? "flag" : clean3(import_node_process17.default.env.ODLA_DEV_TOKEN) ? "environment" : cacheStatus === "valid" ? "cache" : "missing";
|
|
11676
11771
|
return {
|
|
11677
11772
|
source,
|
|
11678
11773
|
cacheFile: context.cfg.local.tokenFile,
|
|
@@ -11683,12 +11778,12 @@ function clean3(value2) {
|
|
|
11683
11778
|
const normalized = value2?.trim();
|
|
11684
11779
|
return normalized || void 0;
|
|
11685
11780
|
}
|
|
11686
|
-
var
|
|
11781
|
+
var import_node_process17;
|
|
11687
11782
|
var init_operator_credentials = __esm({
|
|
11688
11783
|
"src/operator-credentials.ts"() {
|
|
11689
11784
|
"use strict";
|
|
11690
11785
|
init_cjs_shims();
|
|
11691
|
-
|
|
11786
|
+
import_node_process17 = __toESM(require("process"), 1);
|
|
11692
11787
|
init_argv();
|
|
11693
11788
|
init_local();
|
|
11694
11789
|
}
|
|
@@ -12268,9 +12363,17 @@ Safety:
|
|
|
12268
12363
|
grant, run it once with --request-grant. That flag ignores ODLA_DEV_TOKEN and
|
|
12269
12364
|
the local cache, prints and opens a fresh exact-project owner-review URL, then
|
|
12270
12365
|
continues provisioning with the approved replacement credential.
|
|
12271
|
-
|
|
12272
|
-
|
|
12273
|
-
|
|
12366
|
+
Every command says so on STDERR when this CLI is older than the one npm
|
|
12367
|
+
serves, naming the repair for how this executable was launched \u2014 rebuild the
|
|
12368
|
+
worktree, npm i the dependency, or npx the scoped package. The answer is read
|
|
12369
|
+
from a cache under ~/.odla refreshed in the background at most every three
|
|
12370
|
+
hours, so no invocation waits on the registry and stdout is never touched.
|
|
12371
|
+
Set ODLA_CLI_UPDATE_CHECK=0 to switch it off.
|
|
12372
|
+
Before a non-dry-run provision, the executable additionally checks npm LIVE
|
|
12373
|
+
rather than trusting that cache: a security-sensitive grant shape must not
|
|
12374
|
+
ride on a three-hour-old answer. A confirmed stale client stops with a safe
|
|
12375
|
+
npx rerun command; a workspace-linked client also identifies the worktree
|
|
12376
|
+
that must be updated.
|
|
12274
12377
|
Run Code from a GitHub checkout already connected to an app in Studio; an
|
|
12275
12378
|
odla.config.mjs may select the app explicitly but is not required. With an
|
|
12276
12379
|
enrolled code.session device, the Studio repository selection authorizes the
|
|
@@ -13772,7 +13875,7 @@ function writePmProjectContext(rootDir, value2) {
|
|
|
13772
13875
|
});
|
|
13773
13876
|
}
|
|
13774
13877
|
function adoptLegacySelection(rootDir) {
|
|
13775
|
-
const legacy = (0,
|
|
13878
|
+
const legacy = (0, import_node_path19.resolve)(rootDir, ".odla", "pm-project.local.json");
|
|
13776
13879
|
if (!(0, import_node_fs19.existsSync)(legacy)) return;
|
|
13777
13880
|
const previous = readJsonFile(legacy);
|
|
13778
13881
|
(0, import_node_fs19.rmSync)(legacy, { force: true });
|
|
@@ -13787,13 +13890,13 @@ function readSelections() {
|
|
|
13787
13890
|
function isSelection(value2) {
|
|
13788
13891
|
return !!value2 && typeof value2.appId === "string" && typeof value2.projectId === "string" && typeof value2.selectedAt === "string";
|
|
13789
13892
|
}
|
|
13790
|
-
var import_node_fs19,
|
|
13893
|
+
var import_node_fs19, import_node_path19, pmProjectContextFile;
|
|
13791
13894
|
var init_pm_project_context = __esm({
|
|
13792
13895
|
"src/pm-project-context.ts"() {
|
|
13793
13896
|
"use strict";
|
|
13794
13897
|
init_cjs_shims();
|
|
13795
13898
|
import_node_fs19 = require("fs");
|
|
13796
|
-
|
|
13899
|
+
import_node_path19 = require("path");
|
|
13797
13900
|
init_local();
|
|
13798
13901
|
init_odla_home();
|
|
13799
13902
|
pmProjectContextFile = () => pmContextFile();
|
|
@@ -15371,7 +15474,7 @@ async function provision(options) {
|
|
|
15371
15474
|
await provisionIntegrationSeeds(doFetch, cfg.dbEndpoint, tenantId, dbKey, database.integrations, env, out);
|
|
15372
15475
|
}
|
|
15373
15476
|
if (cfg.services.includes("ai") && cfg.ai?.provider && cfg.ai.keyEnv) {
|
|
15374
|
-
const key =
|
|
15477
|
+
const key = import_node_process18.default.env[cfg.ai.keyEnv];
|
|
15375
15478
|
if (key) {
|
|
15376
15479
|
const secretName = cfg.ai.secretName ?? defaultSecretName(cfg.ai.provider);
|
|
15377
15480
|
await (0, import_ai6.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, secretName, key);
|
|
@@ -15410,14 +15513,14 @@ async function provision(options) {
|
|
|
15410
15513
|
}
|
|
15411
15514
|
}
|
|
15412
15515
|
}
|
|
15413
|
-
var import_apps13, import_ai6,
|
|
15516
|
+
var import_apps13, import_ai6, import_node_process18;
|
|
15414
15517
|
var init_provision = __esm({
|
|
15415
15518
|
"src/provision.ts"() {
|
|
15416
15519
|
"use strict";
|
|
15417
15520
|
init_cjs_shims();
|
|
15418
15521
|
import_apps13 = require("@odla-ai/apps");
|
|
15419
15522
|
import_ai6 = require("@odla-ai/ai");
|
|
15420
|
-
|
|
15523
|
+
import_node_process18 = __toESM(require("process"), 1);
|
|
15421
15524
|
init_config();
|
|
15422
15525
|
init_calendar();
|
|
15423
15526
|
init_calendar_errors();
|
|
@@ -15436,7 +15539,7 @@ var init_provision = __esm({
|
|
|
15436
15539
|
|
|
15437
15540
|
// src/record.ts
|
|
15438
15541
|
function recordInvocation(parsed) {
|
|
15439
|
-
const file =
|
|
15542
|
+
const file = import_node_process19.default.env.ODLA_CLI_RECORD;
|
|
15440
15543
|
if (!file) return;
|
|
15441
15544
|
try {
|
|
15442
15545
|
const entry = {
|
|
@@ -15449,13 +15552,13 @@ function recordInvocation(parsed) {
|
|
|
15449
15552
|
} catch {
|
|
15450
15553
|
}
|
|
15451
15554
|
}
|
|
15452
|
-
var import_node_fs20,
|
|
15555
|
+
var import_node_fs20, import_node_process19;
|
|
15453
15556
|
var init_record = __esm({
|
|
15454
15557
|
"src/record.ts"() {
|
|
15455
15558
|
"use strict";
|
|
15456
15559
|
init_cjs_shims();
|
|
15457
15560
|
import_node_fs20 = require("fs");
|
|
15458
|
-
|
|
15561
|
+
import_node_process19 = __toESM(require("process"), 1);
|
|
15459
15562
|
init_surface();
|
|
15460
15563
|
}
|
|
15461
15564
|
});
|
|
@@ -15580,7 +15683,7 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
15580
15683
|
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
15581
15684
|
body: JSON.stringify({
|
|
15582
15685
|
name,
|
|
15583
|
-
platform:
|
|
15686
|
+
platform: import_node_process20.default.platform,
|
|
15584
15687
|
appIds: apps,
|
|
15585
15688
|
...capabilities ? { capabilities } : {},
|
|
15586
15689
|
...scopes ? { scopes } : {},
|
|
@@ -15592,7 +15695,7 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
15592
15695
|
throw new Error(`device enroll failed: ${body.error?.message ?? `registry returned ${response2.status}`} (${response2.status})`);
|
|
15593
15696
|
}
|
|
15594
15697
|
const path = deviceCredentialPath();
|
|
15595
|
-
(0, import_node_fs21.mkdirSync)((0,
|
|
15698
|
+
(0, import_node_fs21.mkdirSync)((0, import_node_path20.dirname)(path), { recursive: true });
|
|
15596
15699
|
(0, import_node_fs21.writeFileSync)(path, JSON.stringify({
|
|
15597
15700
|
token: body.token,
|
|
15598
15701
|
platform: cfg.platformUrl.replace(/\/$/, ""),
|
|
@@ -15699,9 +15802,9 @@ async function scopedToken2(parsed, deps, cfg, doFetch, out, label, scope = "app
|
|
|
15699
15802
|
});
|
|
15700
15803
|
}
|
|
15701
15804
|
function defaultDeviceName() {
|
|
15702
|
-
return `${
|
|
15805
|
+
return `${import_node_process20.default.env.HOSTNAME ?? import_node_process20.default.env.HOST ?? "machine"}-${import_node_process20.default.platform}`;
|
|
15703
15806
|
}
|
|
15704
|
-
var import_db4, import_node_fs21,
|
|
15807
|
+
var import_db4, import_node_fs21, import_node_path20, import_node_process20;
|
|
15705
15808
|
var init_device_command = __esm({
|
|
15706
15809
|
"src/device-command.ts"() {
|
|
15707
15810
|
"use strict";
|
|
@@ -15712,8 +15815,8 @@ var init_device_command = __esm({
|
|
|
15712
15815
|
init_auth_guidance();
|
|
15713
15816
|
init_advisory_output();
|
|
15714
15817
|
import_node_fs21 = require("fs");
|
|
15715
|
-
|
|
15716
|
-
|
|
15818
|
+
import_node_path20 = require("path");
|
|
15819
|
+
import_node_process20 = __toESM(require("process"), 1);
|
|
15717
15820
|
init_argv();
|
|
15718
15821
|
init_admin_ai_auth();
|
|
15719
15822
|
init_device_session();
|
|
@@ -15900,8 +16003,8 @@ function readRunbookDir(dir) {
|
|
|
15900
16003
|
const files = (0, import_node_fs23.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
|
|
15901
16004
|
if (!files.length) throw new Error(`no .md files in ${dir}`);
|
|
15902
16005
|
return files.map((file) => {
|
|
15903
|
-
const slug = (0,
|
|
15904
|
-
const parsed = parseRunbook((0, import_node_fs23.readFileSync)((0,
|
|
16006
|
+
const slug = (0, import_node_path21.basename)(file, ".md");
|
|
16007
|
+
const parsed = parseRunbook((0, import_node_fs23.readFileSync)((0, import_node_path21.join)(dir, file), "utf8"), slug);
|
|
15905
16008
|
return { file, slug, ...parsed, words: parsed.body.split(/\s+/).filter(Boolean).length };
|
|
15906
16009
|
});
|
|
15907
16010
|
}
|
|
@@ -15966,13 +16069,13 @@ async function upsert(ctx, r, visibility) {
|
|
|
15966
16069
|
);
|
|
15967
16070
|
return "updated";
|
|
15968
16071
|
}
|
|
15969
|
-
var import_node_fs23,
|
|
16072
|
+
var import_node_fs23, import_node_path21;
|
|
15970
16073
|
var init_runbook_import = __esm({
|
|
15971
16074
|
"src/runbook-import.ts"() {
|
|
15972
16075
|
"use strict";
|
|
15973
16076
|
init_cjs_shims();
|
|
15974
16077
|
import_node_fs23 = require("fs");
|
|
15975
|
-
|
|
16078
|
+
import_node_path21 = require("path");
|
|
15976
16079
|
init_runbook_actions();
|
|
15977
16080
|
}
|
|
15978
16081
|
});
|
|
@@ -16105,7 +16208,7 @@ var init_runbook_impact_scan = __esm({
|
|
|
16105
16208
|
|
|
16106
16209
|
// src/runbook-impact.ts
|
|
16107
16210
|
function gitRunner(cwd) {
|
|
16108
|
-
return (args) => (0,
|
|
16211
|
+
return (args) => (0, import_node_child_process7.execFileSync)("git", args, { cwd, encoding: "utf8", maxBuffer: 64 * 1024 * 1024, stdio: ["ignore", "pipe", "pipe"] });
|
|
16109
16212
|
}
|
|
16110
16213
|
function collectDiff(runGit, base, read3) {
|
|
16111
16214
|
let merged = "";
|
|
@@ -16150,7 +16253,7 @@ ${body.split("\n").map((line2) => `+${line2}`).join("\n")}
|
|
|
16150
16253
|
}
|
|
16151
16254
|
function manifestLabeller(root) {
|
|
16152
16255
|
return (workspace) => {
|
|
16153
|
-
const manifest = (0,
|
|
16256
|
+
const manifest = (0, import_node_path22.join)(root, workspace, "package.json");
|
|
16154
16257
|
if (!(0, import_node_fs24.existsSync)(manifest)) return void 0;
|
|
16155
16258
|
try {
|
|
16156
16259
|
const name = JSON.parse((0, import_node_fs24.readFileSync)(manifest, "utf8")).name;
|
|
@@ -16219,7 +16322,7 @@ function report4(ctx, impacts) {
|
|
|
16219
16322
|
async function runbookImpact(ctx, options, deps = {}) {
|
|
16220
16323
|
const cwd = deps.cwd ?? process.cwd();
|
|
16221
16324
|
const runGit = deps.runGit ?? gitRunner(cwd);
|
|
16222
|
-
const read3 = deps.readRepoFile ?? ((path) => (0, import_node_fs24.readFileSync)((0,
|
|
16325
|
+
const read3 = deps.readRepoFile ?? ((path) => (0, import_node_fs24.readFileSync)((0, import_node_path22.join)(cwd, path), "utf8"));
|
|
16223
16326
|
const surfaces = changedSurfaces(collectDiff(runGit, options.base, read3), manifestLabeller(cwd));
|
|
16224
16327
|
if (!surfaces.length) {
|
|
16225
16328
|
return ctx.out.log(
|
|
@@ -16230,14 +16333,14 @@ async function runbookImpact(ctx, options, deps = {}) {
|
|
|
16230
16333
|
if (ctx.json) return ctx.out.log(JSON.stringify({ base: options.base, impacts }, null, 2));
|
|
16231
16334
|
report4(ctx, impacts);
|
|
16232
16335
|
}
|
|
16233
|
-
var
|
|
16336
|
+
var import_node_child_process7, import_node_fs24, import_node_path22, SOURCE3, editHint;
|
|
16234
16337
|
var init_runbook_impact = __esm({
|
|
16235
16338
|
"src/runbook-impact.ts"() {
|
|
16236
16339
|
"use strict";
|
|
16237
16340
|
init_cjs_shims();
|
|
16238
|
-
|
|
16341
|
+
import_node_child_process7 = require("child_process");
|
|
16239
16342
|
import_node_fs24 = require("fs");
|
|
16240
|
-
|
|
16343
|
+
import_node_path22 = require("path");
|
|
16241
16344
|
init_runbook_impact_scan();
|
|
16242
16345
|
init_runbook_actions();
|
|
16243
16346
|
SOURCE3 = /\.(ts|tsx|js|jsx|mts|cts)$/;
|
|
@@ -16377,7 +16480,7 @@ var init_runbook_search_command = __esm({
|
|
|
16377
16480
|
});
|
|
16378
16481
|
|
|
16379
16482
|
// src/runbook-editor.ts
|
|
16380
|
-
function resolveEditor(env =
|
|
16483
|
+
function resolveEditor(env = import_node_process21.default.env) {
|
|
16381
16484
|
for (const name of EDITOR_ENV) {
|
|
16382
16485
|
const value2 = env[name];
|
|
16383
16486
|
if (value2 && value2.trim()) return value2.trim();
|
|
@@ -16386,13 +16489,13 @@ function resolveEditor(env = import_node_process20.default.env) {
|
|
|
16386
16489
|
}
|
|
16387
16490
|
function defaultRun(command, path) {
|
|
16388
16491
|
const [bin, ...args] = command.split(/\s+/);
|
|
16389
|
-
const result = (0,
|
|
16492
|
+
const result = (0, import_node_child_process8.spawnSync)(bin, [...args, path], { stdio: "inherit" });
|
|
16390
16493
|
if (result.error) throw new Error(`could not start editor "${command}": ${result.error.message}`);
|
|
16391
16494
|
return result.status ?? 0;
|
|
16392
16495
|
}
|
|
16393
16496
|
function editText(initial, slug, deps = {}) {
|
|
16394
|
-
const env = deps.env ??
|
|
16395
|
-
const interactive = deps.interactive ?? (() => Boolean(
|
|
16497
|
+
const env = deps.env ?? import_node_process21.default.env;
|
|
16498
|
+
const interactive = deps.interactive ?? (() => Boolean(import_node_process21.default.stdin.isTTY));
|
|
16396
16499
|
const editor = resolveEditor(env);
|
|
16397
16500
|
if (!editor)
|
|
16398
16501
|
throw new Error(
|
|
@@ -16400,8 +16503,8 @@ function editText(initial, slug, deps = {}) {
|
|
|
16400
16503
|
);
|
|
16401
16504
|
if (!interactive())
|
|
16402
16505
|
throw new Error(`cannot open an editor without a terminal \u2014 pass --file <path> or --body "\u2026" instead`);
|
|
16403
|
-
const dir = (0, import_node_fs25.mkdtempSync)((0,
|
|
16404
|
-
const file = (0,
|
|
16506
|
+
const dir = (0, import_node_fs25.mkdtempSync)((0, import_node_path23.join)((0, import_node_os6.tmpdir)(), "odla-runbook-"));
|
|
16507
|
+
const file = (0, import_node_path23.join)(dir, `${slug}.md`);
|
|
16405
16508
|
try {
|
|
16406
16509
|
(0, import_node_fs25.writeFileSync)(file, initial, { mode: 384 });
|
|
16407
16510
|
const code = defaultRunOrInjected(deps)(editor, file);
|
|
@@ -16412,16 +16515,16 @@ function editText(initial, slug, deps = {}) {
|
|
|
16412
16515
|
(0, import_node_fs25.rmSync)(dir, { recursive: true, force: true });
|
|
16413
16516
|
}
|
|
16414
16517
|
}
|
|
16415
|
-
var
|
|
16518
|
+
var import_node_child_process8, import_node_fs25, import_node_os6, import_node_path23, import_node_process21, EDITOR_ENV, defaultRunOrInjected;
|
|
16416
16519
|
var init_runbook_editor = __esm({
|
|
16417
16520
|
"src/runbook-editor.ts"() {
|
|
16418
16521
|
"use strict";
|
|
16419
16522
|
init_cjs_shims();
|
|
16420
|
-
|
|
16523
|
+
import_node_child_process8 = require("child_process");
|
|
16421
16524
|
import_node_fs25 = require("fs");
|
|
16422
16525
|
import_node_os6 = require("os");
|
|
16423
|
-
|
|
16424
|
-
|
|
16526
|
+
import_node_path23 = require("path");
|
|
16527
|
+
import_node_process21 = __toESM(require("process"), 1);
|
|
16425
16528
|
EDITOR_ENV = ["ODLA_EDITOR", "VISUAL", "EDITOR"];
|
|
16426
16529
|
defaultRunOrInjected = (deps) => deps.run ?? defaultRun;
|
|
16427
16530
|
}
|
|
@@ -16811,9 +16914,9 @@ async function runHostedSecurity(options) {
|
|
|
16811
16914
|
const appId = selfAudit ? "odla-ai" : cfg.app.id;
|
|
16812
16915
|
const env = selfAudit ? "prod" : selectEnv(options.env, cfg.envs, cfg.configPath, cfg.rootDir);
|
|
16813
16916
|
const platform = options.platform ?? cfg?.platformUrl ?? "https://odla.ai";
|
|
16814
|
-
const target = (0,
|
|
16815
|
-
const output = (0,
|
|
16816
|
-
const outputRelative = (0,
|
|
16917
|
+
const target = (0, import_node_path24.resolve)(options.target ?? cfg?.rootDir ?? ".");
|
|
16918
|
+
const output = (0, import_node_path24.resolve)(options.out ?? (0, import_node_path24.resolve)(target, ".odla/security/hosted"));
|
|
16919
|
+
const outputRelative = (0, import_node_path24.relative)(target, output).split(import_node_path24.sep).join("/");
|
|
16817
16920
|
if (!outputRelative) throw new Error("Hosted security output cannot be the repository root");
|
|
16818
16921
|
const profile = profileFor(options.profile ?? "odla", options.maxHuntTasks ?? 12);
|
|
16819
16922
|
const tokenRequest = {
|
|
@@ -16825,7 +16928,7 @@ async function runHostedSecurity(options) {
|
|
|
16825
16928
|
};
|
|
16826
16929
|
const token = await injectedToken(options, tokenRequest);
|
|
16827
16930
|
const snapshot = await (0, import_node3.snapshotDirectory)(target, {
|
|
16828
|
-
exclude: !outputRelative.startsWith("../") && !(0,
|
|
16931
|
+
exclude: !outputRelative.startsWith("../") && !(0, import_node_path24.isAbsolute)(outputRelative) ? [outputRelative] : []
|
|
16829
16932
|
});
|
|
16830
16933
|
const hosted = await (0, import_security.createPlatformSecurityReasoners)({
|
|
16831
16934
|
platform,
|
|
@@ -16843,7 +16946,7 @@ async function runHostedSecurity(options) {
|
|
|
16843
16946
|
});
|
|
16844
16947
|
const harness = (0, import_security.createSecurityHarness)({
|
|
16845
16948
|
profile,
|
|
16846
|
-
store: new import_node3.FileRunStore((0,
|
|
16949
|
+
store: new import_node3.FileRunStore((0, import_node_path24.resolve)(output, "state")),
|
|
16847
16950
|
discoveryReasoner: hosted.discoveryReasoner,
|
|
16848
16951
|
validationReasoner: hosted.validationReasoner,
|
|
16849
16952
|
policy: {
|
|
@@ -16867,7 +16970,7 @@ async function runHostedSecurity(options) {
|
|
|
16867
16970
|
function selectEnv(requested, declared, configPath, rootDir) {
|
|
16868
16971
|
const env = requested ?? (declared.includes("dev") ? "dev" : declared[0]);
|
|
16869
16972
|
if (!env || !declared.includes(env)) {
|
|
16870
|
-
const shown = (0,
|
|
16973
|
+
const shown = (0, import_node_path24.relative)(rootDir, configPath) || configPath;
|
|
16871
16974
|
throw new Error(`env "${env ?? ""}" is not declared in ${shown}`);
|
|
16872
16975
|
}
|
|
16873
16976
|
return env;
|
|
@@ -16896,17 +16999,17 @@ function printSummary(out, appId, env, run, report5, output) {
|
|
|
16896
16999
|
out.log(` coverage: ${report5.coverageStatus} ${complete}/${report5.coverage.length} blocked=${report5.metrics.blockedCells} shallow=${report5.metrics.shallowCells} unscheduled=${report5.metrics.unscheduledCells} budget_exhausted=${report5.metrics.budgetExhaustedCells}`);
|
|
16897
17000
|
if (report5.callBudget) out.log(` calls: discovery=${formatBudget(report5.callBudget.discovery)} validation=${formatBudget(report5.callBudget.validation)}`);
|
|
16898
17001
|
out.log(` findings: confirmed=${report5.metrics.confirmed} needs_reproduction=${report5.metrics.needsReproduction} candidates=${report5.metrics.candidates}`);
|
|
16899
|
-
out.log(` report: ${(0,
|
|
17002
|
+
out.log(` report: ${(0, import_node_path24.resolve)(output, "REPORT.md")}`);
|
|
16900
17003
|
}
|
|
16901
17004
|
function formatBudget(usage) {
|
|
16902
17005
|
return usage ? `${usage.usedCalls}/${usage.maxCalls} skipped=${usage.skippedCalls}` : "caller-managed";
|
|
16903
17006
|
}
|
|
16904
|
-
var
|
|
17007
|
+
var import_node_path24, import_security, import_node3;
|
|
16905
17008
|
var init_security = __esm({
|
|
16906
17009
|
"src/security.ts"() {
|
|
16907
17010
|
"use strict";
|
|
16908
17011
|
init_cjs_shims();
|
|
16909
|
-
|
|
17012
|
+
import_node_path24 = require("path");
|
|
16910
17013
|
import_security = require("@odla-ai/security");
|
|
16911
17014
|
import_node3 = require("@odla-ai/security/node");
|
|
16912
17015
|
init_config();
|
|
@@ -17405,6 +17508,11 @@ async function runCli(argv2 = process.argv.slice(2), dependencies = {}) {
|
|
|
17405
17508
|
throw error;
|
|
17406
17509
|
} finally {
|
|
17407
17510
|
renderAdvisories(out, advisories);
|
|
17511
|
+
try {
|
|
17512
|
+
const behind = updateNotice();
|
|
17513
|
+
if (behind) out.error(behind);
|
|
17514
|
+
} catch {
|
|
17515
|
+
}
|
|
17408
17516
|
}
|
|
17409
17517
|
}
|
|
17410
17518
|
async function dispatchCli(argv2, dependencies) {
|
|
@@ -17613,6 +17721,7 @@ var init_cli = __esm({
|
|
|
17613
17721
|
init_security_command();
|
|
17614
17722
|
init_whoami_command();
|
|
17615
17723
|
init_surface();
|
|
17724
|
+
init_update_notice();
|
|
17616
17725
|
init_exit_code();
|
|
17617
17726
|
}
|
|
17618
17727
|
});
|
|
@@ -17622,16 +17731,17 @@ init_cjs_shims();
|
|
|
17622
17731
|
|
|
17623
17732
|
// src/cli-update.ts
|
|
17624
17733
|
init_cjs_shims();
|
|
17625
|
-
var import_node_fs2 = require("fs");
|
|
17626
17734
|
init_runbook_requires();
|
|
17735
|
+
init_update_notice();
|
|
17627
17736
|
init_version();
|
|
17628
17737
|
var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org/@odla-ai%2fcli/latest";
|
|
17629
|
-
var
|
|
17738
|
+
var VERSION2 = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
17630
17739
|
async function requireCurrentCliForProvision(argv2, options = {}) {
|
|
17631
17740
|
if (argv2[0] !== "provision" || argv2.includes("--dry-run")) return;
|
|
17632
17741
|
const current = options.currentVersion ?? cliVersion();
|
|
17633
|
-
if (!
|
|
17742
|
+
if (!VERSION2.test(current)) return;
|
|
17634
17743
|
const latest = await fetchLatestCliVersion(options);
|
|
17744
|
+
if (latest) rememberLatest(latest);
|
|
17635
17745
|
if (!latest || compareVersions(current, latest) >= 0) return;
|
|
17636
17746
|
const entryPath = resolvedEntryPath(options.entryPath ?? process.argv[1]);
|
|
17637
17747
|
const workspace = isWorkspaceCli(entryPath);
|
|
@@ -17660,25 +17770,19 @@ async function fetchLatestCliVersion(options) {
|
|
|
17660
17770
|
);
|
|
17661
17771
|
if (!response2.ok) return null;
|
|
17662
17772
|
const body = await response2.json();
|
|
17663
|
-
return typeof body.version === "string" &&
|
|
17773
|
+
return typeof body.version === "string" && VERSION2.test(body.version) ? body.version : null;
|
|
17664
17774
|
} catch {
|
|
17665
17775
|
return null;
|
|
17666
17776
|
} finally {
|
|
17667
17777
|
clearTimeout(timeout);
|
|
17668
17778
|
}
|
|
17669
17779
|
}
|
|
17670
|
-
function
|
|
17671
|
-
if (!entryPath) return "unknown executable";
|
|
17780
|
+
function rememberLatest(latest) {
|
|
17672
17781
|
try {
|
|
17673
|
-
|
|
17782
|
+
writeUpdateCache(updateCacheFile(), { latest, checkedAt: Date.now() });
|
|
17674
17783
|
} catch {
|
|
17675
|
-
return entryPath;
|
|
17676
17784
|
}
|
|
17677
17785
|
}
|
|
17678
|
-
function isWorkspaceCli(entryPath) {
|
|
17679
|
-
const normalized = entryPath.replaceAll("\\", "/");
|
|
17680
|
-
return normalized.includes("/packages/cli/dist/bin.") && !normalized.includes("/node_modules/");
|
|
17681
|
-
}
|
|
17682
17786
|
function renderReleasedProvisionCommand(latest, argv2) {
|
|
17683
17787
|
const safeArgs = [];
|
|
17684
17788
|
for (let index = 0; index < argv2.length; index++) {
|
|
@@ -17706,8 +17810,9 @@ function shellQuote(value2) {
|
|
|
17706
17810
|
// src/cli-runtime.ts
|
|
17707
17811
|
init_cjs_shims();
|
|
17708
17812
|
var import_node_module = require("module");
|
|
17709
|
-
var
|
|
17710
|
-
var
|
|
17813
|
+
var import_node_fs4 = require("fs");
|
|
17814
|
+
var import_node_path3 = require("path");
|
|
17815
|
+
init_update_notice();
|
|
17711
17816
|
init_version();
|
|
17712
17817
|
var EXACT_VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
17713
17818
|
var RUNTIME_MODULES = [
|
|
@@ -17766,26 +17871,26 @@ function installedRuntimeModules(entryPath) {
|
|
|
17766
17871
|
}));
|
|
17767
17872
|
}
|
|
17768
17873
|
function findPackageManifest(fromPath, expectedName) {
|
|
17769
|
-
let directory = (0,
|
|
17770
|
-
const root = (0,
|
|
17874
|
+
let directory = (0, import_node_path3.dirname)(resolvedEntryPath(fromPath));
|
|
17875
|
+
const root = (0, import_node_path3.parse)(directory).root;
|
|
17771
17876
|
while (true) {
|
|
17772
|
-
const path = (0,
|
|
17773
|
-
if ((0,
|
|
17877
|
+
const path = (0, import_node_path3.join)(directory, "package.json");
|
|
17878
|
+
if ((0, import_node_fs4.existsSync)(path)) {
|
|
17774
17879
|
try {
|
|
17775
|
-
const json = JSON.parse((0,
|
|
17880
|
+
const json = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
|
|
17776
17881
|
if (json?.name === expectedName && typeof json.version === "string") return { path, json };
|
|
17777
17882
|
} catch {
|
|
17778
17883
|
}
|
|
17779
17884
|
}
|
|
17780
17885
|
if (directory === root) return void 0;
|
|
17781
|
-
directory = (0,
|
|
17886
|
+
directory = (0, import_node_path3.dirname)(directory);
|
|
17782
17887
|
}
|
|
17783
17888
|
}
|
|
17784
17889
|
function absoluteEntryPath(entryPath) {
|
|
17785
|
-
const candidate = entryPath || (0,
|
|
17786
|
-
const absolute = (0,
|
|
17890
|
+
const candidate = entryPath || (0, import_node_path3.join)(process.cwd(), "odla-ai-cli.js");
|
|
17891
|
+
const absolute = (0, import_node_path3.isAbsolute)(candidate) ? candidate : (0, import_node_path3.resolve)(candidate);
|
|
17787
17892
|
try {
|
|
17788
|
-
return (0,
|
|
17893
|
+
return (0, import_node_fs4.realpathSync)(absolute);
|
|
17789
17894
|
} catch {
|
|
17790
17895
|
return absolute;
|
|
17791
17896
|
}
|