@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.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runCli
4
+ } from "./chunk-JHB6352A.js";
5
+ import {
6
+ exitCodeFor
7
+ } from "./chunk-5MEO3BVF.js";
8
+ export {
9
+ exitCodeFor,
10
+ runCli
11
+ };
12
+ //# sourceMappingURL=cli-2FTL245Y.js.map
package/dist/index.cjs CHANGED
@@ -11430,9 +11430,17 @@ Safety:
11430
11430
  grant, run it once with --request-grant. That flag ignores ODLA_DEV_TOKEN and
11431
11431
  the local cache, prints and opens a fresh exact-project owner-review URL, then
11432
11432
  continues provisioning with the approved replacement credential.
11433
- Before a non-dry-run provision, the executable checks npm's current CLI
11434
- release. A confirmed stale client stops with a safe npx rerun command; a
11435
- workspace-linked client also identifies the worktree that must be updated.
11433
+ Every command says so on STDERR when this CLI is older than the one npm
11434
+ serves, naming the repair for how this executable was launched \u2014 rebuild the
11435
+ worktree, npm i the dependency, or npx the scoped package. The answer is read
11436
+ from a cache under ~/.odla refreshed in the background at most every three
11437
+ hours, so no invocation waits on the registry and stdout is never touched.
11438
+ Set ODLA_CLI_UPDATE_CHECK=0 to switch it off.
11439
+ Before a non-dry-run provision, the executable additionally checks npm LIVE
11440
+ rather than trusting that cache: a security-sensitive grant shape must not
11441
+ ride on a three-hour-old answer. A confirmed stale client stops with a safe
11442
+ npx rerun command; a workspace-linked client also identifies the worktree
11443
+ that must be updated.
11436
11444
  Run Code from a GitHub checkout already connected to an app in Studio; an
11437
11445
  odla.config.mjs may select the app explicitly but is not required. With an
11438
11446
  enrolled code.session device, the Studio repository selection authorizes the
@@ -16108,6 +16116,87 @@ async function securityStatus(parsed, dependencies) {
16108
16116
  }
16109
16117
  }
16110
16118
 
16119
+ // src/update-notice.ts
16120
+ var import_node_child_process8 = require("child_process");
16121
+ var import_node_fs24 = require("fs");
16122
+ var import_node_path23 = require("path");
16123
+ var import_node_process21 = __toESM(require("process"), 1);
16124
+ var REGISTRY_URL = "https://registry.npmjs.org/@odla-ai%2fcli/latest";
16125
+ var INTERVAL_MS = 3 * 60 * 60 * 1e3;
16126
+ var VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
16127
+ var refreshScheduled = false;
16128
+ function updateCacheFile(env) {
16129
+ return odlaHomePath(["cli-update.json"], env);
16130
+ }
16131
+ function readUpdateCache(path) {
16132
+ try {
16133
+ const parsed = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
16134
+ if (typeof parsed.latest !== "string" || !VERSION.test(parsed.latest)) return null;
16135
+ if (typeof parsed.checkedAt !== "number") return null;
16136
+ return { latest: parsed.latest, checkedAt: parsed.checkedAt };
16137
+ } catch {
16138
+ return null;
16139
+ }
16140
+ }
16141
+ function updateNotice(options = {}) {
16142
+ const env = options.env ?? import_node_process21.default.env;
16143
+ if (env.ODLA_CLI_UPDATE_CHECK === "0") return null;
16144
+ const current = options.currentVersion ?? cliVersion();
16145
+ if (!VERSION.test(current)) return null;
16146
+ const path = updateCacheFile(env);
16147
+ const cache2 = readUpdateCache(path);
16148
+ const now = options.now ?? Date.now();
16149
+ if ((!cache2 || now - cache2.checkedAt > INTERVAL_MS) && !refreshScheduled) {
16150
+ refreshScheduled = true;
16151
+ (options.refresh ?? spawnRefresh)(path, env.ODLA_CLI_REGISTRY_URL ?? REGISTRY_URL);
16152
+ }
16153
+ if (!cache2 || compareVersions(current, cache2.latest) >= 0) return null;
16154
+ return renderNotice(current, cache2.latest, options.entryPath ?? import_node_process21.default.argv[1]);
16155
+ }
16156
+ function renderNotice(current, latest, entryPath) {
16157
+ const resolved = resolvedEntryPath(entryPath);
16158
+ const behindMajor = Number(latest.split(".")[0]) > Number(current.split(".")[0]);
16159
+ 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}`;
16160
+ const severity = behindMajor ? "a MAJOR version behind, so commands and flags this version has may no longer exist" : "behind";
16161
+ return `odla-ai: ${current} is ${severity}; npm serves ${latest}. To update, ${repair}.`;
16162
+ }
16163
+ function spawnRefresh(cachePath, registryUrl) {
16164
+ const script = `
16165
+ const {mkdirSync,writeFileSync}=require("node:fs");
16166
+ const {dirname}=require("node:path");
16167
+ const [path,url]=process.argv.slice(1);
16168
+ const done=setTimeout(()=>process.exit(0),5000); done.unref();
16169
+ fetch(url,{headers:{accept:"application/vnd.npm.install-v1+json"}})
16170
+ .then(r=>r.ok?r.json():null)
16171
+ .then(b=>{
16172
+ const v=b&&b.version;
16173
+ if (typeof v!=="string"||!/^\\d+\\.\\d+\\.\\d+/.test(v)) return;
16174
+ mkdirSync(dirname(path),{recursive:true});
16175
+ writeFileSync(path,JSON.stringify({latest:v,checkedAt:Date.now()}));
16176
+ })
16177
+ .catch(()=>{});
16178
+ `;
16179
+ try {
16180
+ (0, import_node_child_process8.spawn)(import_node_process21.default.execPath, ["-e", script, cachePath, registryUrl], {
16181
+ detached: true,
16182
+ stdio: "ignore"
16183
+ }).unref();
16184
+ } catch {
16185
+ }
16186
+ }
16187
+ function resolvedEntryPath(entryPath) {
16188
+ if (!entryPath) return "unknown executable";
16189
+ try {
16190
+ return (0, import_node_fs24.realpathSync)(entryPath);
16191
+ } catch {
16192
+ return entryPath;
16193
+ }
16194
+ }
16195
+ function isWorkspaceCli(entryPath) {
16196
+ const normalized = entryPath.replaceAll("\\", "/");
16197
+ return /\/packages\/cli\/(dist|bin)\//.test(normalized) && !normalized.includes("/node_modules/");
16198
+ }
16199
+
16111
16200
  // src/exit-code.ts
16112
16201
  function exitCodeFor(err) {
16113
16202
  const code = err?.code;
@@ -16135,6 +16224,11 @@ async function runCli(argv = process.argv.slice(2), dependencies = {}) {
16135
16224
  throw error;
16136
16225
  } finally {
16137
16226
  renderAdvisories(out, advisories);
16227
+ try {
16228
+ const behind = updateNotice();
16229
+ if (behind) out.error(behind);
16230
+ } catch {
16231
+ }
16138
16232
  }
16139
16233
  }
16140
16234
  async function dispatchCli(argv, dependencies) {