@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.
- package/main.js +199 -40
- 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,
|
|
739
|
-
const url = `${this.baseUrl}${GATEWAY_SERVICE_PREFIX}${
|
|
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
|
|
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,
|
|
3440
|
-
const url = `${this.baseUrl}/agent-orchestration${
|
|
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
|
|
3974
|
-
import * as
|
|
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
|
|
4014
|
+
return path8.join(os6.homedir(), ".config", "onklave", "daemon.state.json");
|
|
3987
4015
|
}
|
|
3988
4016
|
function defaultPidFilePath() {
|
|
3989
|
-
return
|
|
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 (!
|
|
4014
|
-
const raw =
|
|
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 =
|
|
4065
|
-
|
|
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
|
-
|
|
4076
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
4560
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
}
|