@onklave/agent-cli 0.1.42 → 0.1.43

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.
Files changed (2) hide show
  1. package/main.js +199 -40
  2. package/package.json +1 -1
package/main.js CHANGED
@@ -735,8 +735,8 @@ var PlatformClient = class {
735
735
  /*
736
736
  * Make an authenticated HTTP request to the platform.
737
737
  */
738
- async request(method, path8, body, extraHeaders) {
739
- const url = `${this.baseUrl}${GATEWAY_SERVICE_PREFIX}${path8}`;
738
+ async request(method, path10, body, extraHeaders) {
739
+ const url = `${this.baseUrl}${GATEWAY_SERVICE_PREFIX}${path10}`;
740
740
  const headers = {
741
741
  Authorization: `Bearer ${this.token}`,
742
742
  "Content-Type": "application/json",
@@ -3009,7 +3009,7 @@ async function logsCommand(args) {
3009
3009
  }
3010
3010
 
3011
3011
  // _apps/@onklave/agent-cli/src/commands/daemon.command.ts
3012
- import * as fs7 from "fs";
3012
+ import * as fs8 from "fs";
3013
3013
 
3014
3014
  // _apps/@onklave/agent-cli/src/services/daemon-comms.service.ts
3015
3015
  var DaemonCommsService = class {
@@ -3436,8 +3436,8 @@ var PlatformBrokerClient = class {
3436
3436
  params
3437
3437
  );
3438
3438
  }
3439
- async request(method, path8, body) {
3440
- const url = `${this.baseUrl}/agent-orchestration${path8}`;
3439
+ async request(method, path10, body) {
3440
+ const url = `${this.baseUrl}/agent-orchestration${path10}`;
3441
3441
  const response = await fetch(url, {
3442
3442
  method,
3443
3443
  headers: {
@@ -3969,9 +3969,37 @@ function parseSemverNumeric(v) {
3969
3969
  ];
3970
3970
  }
3971
3971
 
3972
+ // _apps/@onklave/agent-cli/src/services/cli-version.ts
3973
+ import * as fs6 from "node:fs";
3974
+ import * as path7 from "node:path";
3975
+ import { fileURLToPath } from "node:url";
3976
+ function readPackageVersion() {
3977
+ try {
3978
+ const moduleDir = path7.dirname(fileURLToPath(import.meta.url));
3979
+ const candidates = [
3980
+ path7.join(moduleDir, "package.json"),
3981
+ // bundled: dist root
3982
+ path7.join(moduleDir, "..", "package.json"),
3983
+ path7.join(moduleDir, "..", "..", "package.json"),
3984
+ // dev: src/services -> root
3985
+ path7.join(moduleDir, "..", "..", "..", "package.json")
3986
+ ];
3987
+ for (const p of candidates) {
3988
+ if (!fs6.existsSync(p)) continue;
3989
+ const pkg = JSON.parse(fs6.readFileSync(p, "utf8"));
3990
+ if (pkg.name === PACKAGE_NAME && pkg.version) return pkg.version;
3991
+ }
3992
+ } catch {
3993
+ }
3994
+ return null;
3995
+ }
3996
+ function getCurrentVersion() {
3997
+ return readPackageVersion() ?? "0.0.0";
3998
+ }
3999
+
3972
4000
  // _apps/@onklave/agent-cli/src/services/daemon-state.service.ts
3973
- import * as fs6 from "fs";
3974
- import * as path7 from "path";
4001
+ import * as fs7 from "fs";
4002
+ import * as path8 from "path";
3975
4003
  import * as os6 from "os";
3976
4004
  var VALID_TRANSITIONS = {
3977
4005
  installing: ["registered"],
@@ -3983,10 +4011,10 @@ var VALID_TRANSITIONS = {
3983
4011
  stopped: ["starting"]
3984
4012
  };
3985
4013
  function defaultStateFilePath() {
3986
- return path7.join(os6.homedir(), ".config", "onklave", "daemon.state.json");
4014
+ return path8.join(os6.homedir(), ".config", "onklave", "daemon.state.json");
3987
4015
  }
3988
4016
  function defaultPidFilePath() {
3989
- return path7.join(os6.homedir(), ".config", "onklave", "daemon.pid");
4017
+ return path8.join(os6.homedir(), ".config", "onklave", "daemon.pid");
3990
4018
  }
3991
4019
  var DaemonStateError = class extends Error {
3992
4020
  constructor(message) {
@@ -4010,8 +4038,8 @@ var DaemonStateService = class {
4010
4038
  */
4011
4039
  static readPersisted(stateFile = defaultStateFilePath()) {
4012
4040
  try {
4013
- if (!fs6.existsSync(stateFile)) return null;
4014
- const raw = fs6.readFileSync(stateFile, "utf8");
4041
+ if (!fs7.existsSync(stateFile)) return null;
4042
+ const raw = fs7.readFileSync(stateFile, "utf8");
4015
4043
  const parsed = JSON.parse(raw);
4016
4044
  if (!parsed.state || !parsed.enteredAt) return null;
4017
4045
  return parsed;
@@ -4061,8 +4089,8 @@ var DaemonStateService = class {
4061
4089
  }
4062
4090
  }
4063
4091
  persist(reason) {
4064
- const dir = path7.dirname(this.stateFile);
4065
- fs6.mkdirSync(dir, { recursive: true });
4092
+ const dir = path8.dirname(this.stateFile);
4093
+ fs7.mkdirSync(dir, { recursive: true });
4066
4094
  const payload = {
4067
4095
  state: this.current,
4068
4096
  enteredAt: this.enteredAt.toISOString(),
@@ -4072,8 +4100,8 @@ var DaemonStateService = class {
4072
4100
  ...this.latestRuntime ? { runtime: this.latestRuntime } : {}
4073
4101
  };
4074
4102
  const tmp = `${this.stateFile}.tmp`;
4075
- fs6.writeFileSync(tmp, JSON.stringify(payload, null, 2));
4076
- fs6.renameSync(tmp, this.stateFile);
4103
+ fs7.writeFileSync(tmp, JSON.stringify(payload, null, 2));
4104
+ fs7.renameSync(tmp, this.stateFile);
4077
4105
  }
4078
4106
  /**
4079
4107
  * Publish the latest runtime snapshot. Persists to the state file
@@ -4091,7 +4119,7 @@ var DaemonStateService = class {
4091
4119
  */
4092
4120
  clearPersisted() {
4093
4121
  try {
4094
- fs6.unlinkSync(this.stateFile);
4122
+ fs7.unlinkSync(this.stateFile);
4095
4123
  } catch {
4096
4124
  }
4097
4125
  }
@@ -4547,7 +4575,7 @@ function transitionToAction(next) {
4547
4575
  }
4548
4576
  function readPid(pidFile) {
4549
4577
  try {
4550
- const raw = fs7.readFileSync(pidFile, "utf8").trim();
4578
+ const raw = fs8.readFileSync(pidFile, "utf8").trim();
4551
4579
  const parsed = Number.parseInt(raw, 10);
4552
4580
  return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
4553
4581
  } catch {
@@ -4556,12 +4584,12 @@ function readPid(pidFile) {
4556
4584
  }
4557
4585
  function writePid(pidFile) {
4558
4586
  const dir = pidFile.replace(/\/[^/]+$/, "");
4559
- fs7.mkdirSync(dir, { recursive: true });
4560
- fs7.writeFileSync(pidFile, String(process.pid), { mode: 384 });
4587
+ fs8.mkdirSync(dir, { recursive: true });
4588
+ fs8.writeFileSync(pidFile, String(process.pid), { mode: 384 });
4561
4589
  }
4562
4590
  function removePid(pidFile) {
4563
4591
  try {
4564
- fs7.unlinkSync(pidFile);
4592
+ fs8.unlinkSync(pidFile);
4565
4593
  } catch {
4566
4594
  }
4567
4595
  }
@@ -4570,25 +4598,6 @@ function isPidAlive(pidFile) {
4570
4598
  if (pid == null) return false;
4571
4599
  return isProcessAlive(pid);
4572
4600
  }
4573
- function readPackageVersion() {
4574
- try {
4575
- const candidates = [
4576
- // dist layout (bin/onklave.js → ../package.json)
4577
- `${__dirname}/../../package.json`,
4578
- // src layout during dev
4579
- `${__dirname}/../../../package.json`
4580
- ];
4581
- for (const p of candidates) {
4582
- if (fs7.existsSync(p)) {
4583
- const pkg = JSON.parse(fs7.readFileSync(p, "utf8"));
4584
- if (pkg.name === "@onklave/agent-cli" && pkg.version)
4585
- return pkg.version;
4586
- }
4587
- }
4588
- } catch {
4589
- }
4590
- return null;
4591
- }
4592
4601
  function isProcessAlive(pid) {
4593
4602
  try {
4594
4603
  process.kill(pid, 0);
@@ -4623,8 +4632,157 @@ var COMMANDS = {
4623
4632
  daemon: daemonCommand
4624
4633
  };
4625
4634
 
4635
+ // _apps/@onklave/agent-cli/src/services/update-notifier.service.ts
4636
+ import * as fs9 from "node:fs";
4637
+ import * as path9 from "node:path";
4638
+ import * as os7 from "node:os";
4639
+ import { createInterface } from "node:readline/promises";
4640
+ import { spawnSync } from "node:child_process";
4641
+ var CHECK_TTL_MS = 24 * 60 * 60 * 1e3;
4642
+ var FETCH_DEADLINE_MS = 1500;
4643
+ var CACHE_PATH = path9.join(
4644
+ os7.homedir(),
4645
+ ".config",
4646
+ "onklave",
4647
+ "update-check.json"
4648
+ );
4649
+ function shouldPromptForUpdate(current, latest, dismissedVersion) {
4650
+ if (!latest) return false;
4651
+ if (!isNewerVersion(latest, current)) return false;
4652
+ if (dismissedVersion && dismissedVersion === latest) return false;
4653
+ return true;
4654
+ }
4655
+ async function maybeNotifyUpdate(deps = {}) {
4656
+ const log = deps.log ?? ((m) => console.error(m));
4657
+ try {
4658
+ const isInteractive = deps.isInteractive ?? defaultIsInteractive;
4659
+ if (!isInteractive()) return;
4660
+ const now = deps.now ?? Date.now;
4661
+ const read = deps.readCache ?? readCache;
4662
+ const write = deps.writeCache ?? writeCache;
4663
+ const current = deps.currentVersion ?? "0.0.0";
4664
+ let cache = read();
4665
+ if (!isCacheFresh(cache, now())) {
4666
+ const fetchLatest = deps.fetchLatest ?? (() => defaultRegistryFetcher(PACKAGE_NAME));
4667
+ try {
4668
+ const latestVersion = await withTimeout(
4669
+ fetchLatest(),
4670
+ FETCH_DEADLINE_MS
4671
+ );
4672
+ cache = {
4673
+ ...cache,
4674
+ latestVersion,
4675
+ lastCheckedAt: new Date(now()).toISOString()
4676
+ };
4677
+ write(cache);
4678
+ } catch {
4679
+ write({ ...cache, lastCheckedAt: new Date(now()).toISOString() });
4680
+ return;
4681
+ }
4682
+ }
4683
+ if (!shouldPromptForUpdate(
4684
+ current,
4685
+ cache.latestVersion,
4686
+ cache.dismissedVersion
4687
+ )) {
4688
+ return;
4689
+ }
4690
+ const latest = cache.latestVersion;
4691
+ log(
4692
+ `
4693
+ \u2B06 A new version of the Onklave CLI is available: ${current} \u2192 ${latest}`
4694
+ );
4695
+ const promptYesNo = deps.promptYesNo ?? defaultPromptYesNo;
4696
+ const accepted = await promptYesNo(
4697
+ ` Update now (npm i -g ${PACKAGE_NAME}@latest)? [y/N] `
4698
+ );
4699
+ if (!accepted) {
4700
+ write({ ...cache, dismissedVersion: latest });
4701
+ log(
4702
+ ` Skipped. Run \`npm i -g ${PACKAGE_NAME}@latest\` whenever you're ready.`
4703
+ );
4704
+ return;
4705
+ }
4706
+ const runUpdate = deps.runUpdate ?? defaultRunUpdate;
4707
+ const ok = runUpdate();
4708
+ if (ok) {
4709
+ write({ ...cache, dismissedVersion: latest });
4710
+ log(
4711
+ `
4712
+ \u2705 Updated to ${latest}. Re-run your command to use the new version.`
4713
+ );
4714
+ (deps.exit ?? ((code) => process.exit(code)))(0);
4715
+ return;
4716
+ }
4717
+ log(`
4718
+ \u26A0 Update failed. Try manually: npm i -g ${PACKAGE_NAME}@latest`);
4719
+ } catch {
4720
+ }
4721
+ }
4722
+ function withTimeout(promise, ms) {
4723
+ return new Promise((resolve3, reject) => {
4724
+ const timer = setTimeout(
4725
+ () => reject(new Error("update check timed out")),
4726
+ ms
4727
+ );
4728
+ if (typeof timer.unref === "function") timer.unref();
4729
+ promise.then(
4730
+ (value) => {
4731
+ clearTimeout(timer);
4732
+ resolve3(value);
4733
+ },
4734
+ (err) => {
4735
+ clearTimeout(timer);
4736
+ reject(err);
4737
+ }
4738
+ );
4739
+ });
4740
+ }
4741
+ function defaultIsInteractive() {
4742
+ if (process.env.NO_UPDATE_NOTIFIER) return false;
4743
+ if (process.env.CI) return false;
4744
+ return Boolean(process.stdout.isTTY && process.stdin.isTTY);
4745
+ }
4746
+ function isCacheFresh(cache, nowMs) {
4747
+ if (!cache.lastCheckedAt) return false;
4748
+ const last = new Date(cache.lastCheckedAt).getTime();
4749
+ if (Number.isNaN(last)) return false;
4750
+ return nowMs - last < CHECK_TTL_MS;
4751
+ }
4752
+ function readCache() {
4753
+ try {
4754
+ if (!fs9.existsSync(CACHE_PATH)) return {};
4755
+ return JSON.parse(fs9.readFileSync(CACHE_PATH, "utf8"));
4756
+ } catch {
4757
+ return {};
4758
+ }
4759
+ }
4760
+ function writeCache(cache) {
4761
+ try {
4762
+ fs9.mkdirSync(path9.dirname(CACHE_PATH), { recursive: true, mode: 448 });
4763
+ fs9.writeFileSync(CACHE_PATH, JSON.stringify(cache, null, 2), "utf8");
4764
+ } catch {
4765
+ }
4766
+ }
4767
+ async function defaultPromptYesNo(question) {
4768
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
4769
+ try {
4770
+ const answer = (await rl.question(question)).trim().toLowerCase();
4771
+ return answer === "y" || answer === "yes";
4772
+ } finally {
4773
+ rl.close();
4774
+ }
4775
+ }
4776
+ function defaultRunUpdate() {
4777
+ const result = spawnSync("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], {
4778
+ stdio: "inherit",
4779
+ shell: process.platform === "win32"
4780
+ });
4781
+ return result.status === 0;
4782
+ }
4783
+
4626
4784
  // _apps/@onklave/agent-cli/src/main.ts
4627
- var VERSION = "0.1.0";
4785
+ var VERSION = getCurrentVersion();
4628
4786
  function showHelp() {
4629
4787
  console.log(
4630
4788
  `
@@ -4681,6 +4839,7 @@ async function main() {
4681
4839
  process.exitCode = 1;
4682
4840
  return;
4683
4841
  }
4842
+ await maybeNotifyUpdate({ currentVersion: VERSION });
4684
4843
  const commandArgs = args.slice(1);
4685
4844
  if (commandArgs.includes("--help") || commandArgs.includes("-h")) {
4686
4845
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onklave/agent-cli",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "description": "Onklave Agent CLI — local agent runner with cloud orchestration",
5
5
  "bin": {
6
6
  "onklave": "./main.js"