@withone/cli 1.44.0 → 1.44.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/index.js +59 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -548,6 +548,20 @@ Settings propagate automatically to all installed agent configs.
|
|
|
548
548
|
|
|
549
549
|
Auto-sync refuses to resurrect skills if you opted out of skill installation during `one init` — the canonical dir has to already exist.
|
|
550
550
|
|
|
551
|
+
### `one update`
|
|
552
|
+
|
|
553
|
+
Updates the CLI to the latest version (`npm install -g @withone/cli@latest`).
|
|
554
|
+
|
|
555
|
+
The CLI also **auto-updates in the background**: when a newer version has been published for more than 30 minutes, the next `one` command silently kicks off a global install. This is hardened against concurrent runs — a lock file in `~/.one/` ensures at most one install runs at a time (so parallel agent invocations can't collide and wedge npm), and the lock self-heals after 10 minutes if an install ever crashes or hangs.
|
|
556
|
+
|
|
557
|
+
To disable background auto-updates entirely (e.g. on CI or a shared agent host), set:
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
export ONE_NO_AUTO_UPDATE=1
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Run `one update` manually whenever you want to upgrade.
|
|
564
|
+
|
|
551
565
|
### Project config (`.onerc`)
|
|
552
566
|
|
|
553
567
|
Drop a `.onerc` file in your project root to override global settings per-project. Simple `KEY=VALUE` format; `#` for comments. Read from the current working directory (no parent lookup).
|
package/dist/index.js
CHANGED
|
@@ -621,14 +621,17 @@ import { fileURLToPath } from "url";
|
|
|
621
621
|
// src/commands/update.ts
|
|
622
622
|
import { createRequire } from "module";
|
|
623
623
|
import { spawn } from "child_process";
|
|
624
|
-
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
624
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
|
625
625
|
import { homedir } from "os";
|
|
626
626
|
import { join } from "path";
|
|
627
627
|
var require2 = createRequire(import.meta.url);
|
|
628
628
|
var { version: currentVersion } = require2("../package.json");
|
|
629
|
-
var
|
|
629
|
+
var ONE_DIR = join(homedir(), ".one");
|
|
630
|
+
var CACHE_PATH = join(ONE_DIR, "update-check.json");
|
|
631
|
+
var LOCK_PATH = join(ONE_DIR, "auto-update.lock");
|
|
630
632
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
631
633
|
var AGE_GATE_MS = 30 * 60 * 1e3;
|
|
634
|
+
var LOCK_TTL_MS = 10 * 60 * 1e3;
|
|
632
635
|
async function fetchLatestVersionInfo() {
|
|
633
636
|
try {
|
|
634
637
|
const res = await fetch("https://registry.npmjs.org/@withone/cli");
|
|
@@ -725,16 +728,52 @@ function isNewerVersion(latest, current) {
|
|
|
725
728
|
if (lMin !== cMin) return lMin > cMin;
|
|
726
729
|
return lPat > cPat;
|
|
727
730
|
}
|
|
731
|
+
function isAutoUpdateDisabled() {
|
|
732
|
+
const v = process.env.ONE_NO_AUTO_UPDATE ?? process.env.ONE_DISABLE_AUTO_UPDATE;
|
|
733
|
+
return v === "1" || v === "true";
|
|
734
|
+
}
|
|
735
|
+
function acquireUpdateLock(targetVersion) {
|
|
736
|
+
try {
|
|
737
|
+
mkdirSync(ONE_DIR, { recursive: true });
|
|
738
|
+
} catch {
|
|
739
|
+
}
|
|
740
|
+
try {
|
|
741
|
+
const lock = JSON.parse(readFileSync(LOCK_PATH, "utf8"));
|
|
742
|
+
const startedAt = typeof lock.startedAt === "number" ? lock.startedAt : 0;
|
|
743
|
+
if (Date.now() - startedAt < LOCK_TTL_MS) return false;
|
|
744
|
+
rmSync(LOCK_PATH, { force: true });
|
|
745
|
+
} catch {
|
|
746
|
+
}
|
|
747
|
+
try {
|
|
748
|
+
writeFileSync(
|
|
749
|
+
LOCK_PATH,
|
|
750
|
+
JSON.stringify({ pid: process.pid, startedAt: Date.now(), targetVersion }),
|
|
751
|
+
{ flag: "wx" }
|
|
752
|
+
// fail if another invocation created it first
|
|
753
|
+
);
|
|
754
|
+
return true;
|
|
755
|
+
} catch {
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
728
759
|
function autoUpdate(targetVersion, publishedAt) {
|
|
760
|
+
if (isAutoUpdateDisabled()) return;
|
|
729
761
|
if (publishedAt) {
|
|
730
762
|
const age = Date.now() - new Date(publishedAt).getTime();
|
|
731
763
|
if (age < AGE_GATE_MS) return;
|
|
732
764
|
}
|
|
765
|
+
if (!acquireUpdateLock(targetVersion)) return;
|
|
733
766
|
const child = spawn("npm", ["install", "-g", `@withone/cli@${targetVersion}`], {
|
|
734
767
|
detached: true,
|
|
735
768
|
stdio: "ignore",
|
|
736
769
|
shell: true
|
|
737
770
|
});
|
|
771
|
+
child.on("error", () => {
|
|
772
|
+
try {
|
|
773
|
+
rmSync(LOCK_PATH, { force: true });
|
|
774
|
+
} catch {
|
|
775
|
+
}
|
|
776
|
+
});
|
|
738
777
|
child.unref();
|
|
739
778
|
}
|
|
740
779
|
|
|
@@ -6273,17 +6312,23 @@ async function syncModel(api, profile, options) {
|
|
|
6273
6312
|
if (lock) lock.release();
|
|
6274
6313
|
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
6275
6314
|
const shortMsg = truncate(rawMsg, 500);
|
|
6315
|
+
const httpStatus = err instanceof ApiError ? err.status : void 0;
|
|
6316
|
+
const retryAfter = err instanceof ApiError ? err.retryAfterSeconds : void 0;
|
|
6276
6317
|
if (pagesProcessed > 0) {
|
|
6277
6318
|
const resumeErr = new Error(
|
|
6278
6319
|
`Sync interrupted after page ${pagesProcessed} (${totalRecords} records). Run again to resume. Error: ${shortMsg}`
|
|
6279
6320
|
);
|
|
6280
6321
|
resumeErr._recordsSynced = totalRecords;
|
|
6281
6322
|
resumeErr._pagesProcessed = pagesProcessed;
|
|
6323
|
+
resumeErr._httpStatus = httpStatus;
|
|
6324
|
+
resumeErr._retryAfter = retryAfter;
|
|
6282
6325
|
throw resumeErr;
|
|
6283
6326
|
}
|
|
6284
6327
|
const wrapped = new Error(shortMsg);
|
|
6285
6328
|
wrapped._recordsSynced = totalRecords;
|
|
6286
6329
|
wrapped._pagesProcessed = pagesProcessed;
|
|
6330
|
+
wrapped._httpStatus = httpStatus;
|
|
6331
|
+
wrapped._retryAfter = retryAfter;
|
|
6287
6332
|
throw wrapped;
|
|
6288
6333
|
} finally {
|
|
6289
6334
|
process.off("SIGINT", onSigint);
|
|
@@ -7762,13 +7807,18 @@ async function syncRunCommand(platform, options) {
|
|
|
7762
7807
|
results.push(result);
|
|
7763
7808
|
} catch (err) {
|
|
7764
7809
|
const errObj = err;
|
|
7810
|
+
const errorContext = {
|
|
7811
|
+
message: err instanceof Error ? err.message : String(err),
|
|
7812
|
+
...errObj?._httpStatus !== void 0 ? { httpStatus: errObj._httpStatus } : {},
|
|
7813
|
+
...errObj?._retryAfter !== void 0 ? { retryAfter: errObj._retryAfter } : {}
|
|
7814
|
+
};
|
|
7765
7815
|
results.push({
|
|
7766
7816
|
model: profile.model,
|
|
7767
7817
|
recordsSynced: errObj?._recordsSynced ?? 0,
|
|
7768
7818
|
pagesProcessed: errObj?._pagesProcessed ?? 0,
|
|
7769
7819
|
duration: "0s",
|
|
7770
7820
|
status: "failed",
|
|
7771
|
-
error:
|
|
7821
|
+
error: errorContext
|
|
7772
7822
|
});
|
|
7773
7823
|
}
|
|
7774
7824
|
}
|
|
@@ -7787,8 +7837,11 @@ async function syncRunCommand(platform, options) {
|
|
|
7787
7837
|
const archivedColor = sc.archived > sc.active ? pc9.red : pc9.dim;
|
|
7788
7838
|
console.log(` memory: ${pc9.green(String(sc.active))} active, ${archivedColor(String(sc.archived))} archived`);
|
|
7789
7839
|
}
|
|
7790
|
-
if (
|
|
7791
|
-
|
|
7840
|
+
if (r.error) {
|
|
7841
|
+
const errParts = [r.error.message];
|
|
7842
|
+
if (r.error.httpStatus) errParts.push(`HTTP ${r.error.httpStatus}`);
|
|
7843
|
+
if (r.error.retryAfter) errParts.push(`retry after ${r.error.retryAfter}s`);
|
|
7844
|
+
console.log(` ${pc9.red(errParts.join(" \u2014 "))}`);
|
|
7792
7845
|
}
|
|
7793
7846
|
}
|
|
7794
7847
|
}
|
|
@@ -11121,7 +11174,7 @@ program.command("guide [topic]").description("Full CLI usage guide for agents (t
|
|
|
11121
11174
|
program.command("onboard").description("Agent onboarding \u2014 teaches your agent what the One CLI can do").option("--step <number>", "Run a specific onboarding step (1, 2, or 3)").action(async (options) => {
|
|
11122
11175
|
await onboardCommand(options.step ? parseInt(options.step, 10) : void 0);
|
|
11123
11176
|
});
|
|
11124
|
-
program.command("update").description("Update the One CLI to the latest version").action(async () => {
|
|
11177
|
+
program.command("update").description("Update the One CLI to the latest version (background auto-update can be disabled with ONE_NO_AUTO_UPDATE=1)").action(async () => {
|
|
11125
11178
|
await updateCommand();
|
|
11126
11179
|
});
|
|
11127
11180
|
program.command("whoami").description("Show the user, organization, and project for the current API key").action(async () => {
|