@rackbops/ac-agent 2.0.0-alpha.56 → 2.0.0-alpha.57
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 +2 -2
- package/dist/ac-agent.mjs +19 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -907,7 +907,7 @@ kind's jobs, and one holding only `agent.exec.claude` never reads these):
|
|
|
907
907
|
| `already-current` | exit 0 and the version is unchanged; winget's `0x8A15002B` (no applicable update) also maps here, and means "no newer version this machine can install", which is not always the same as "current" | for the winget code |
|
|
908
908
|
| `needs-sudoers` | `apt`: `sudo -n` refused, in sudo 1.9's wording (`a password is required`, `is not in the sudoers file`, `is not allowed to execute`, `is not allowed to run sudo on`, `user <u> may not run sudo on <host>`) or sudo-rs's, the default `sudo` of recent Ubuntu (`interactive authentication is required`, `I'm afraid I can't do that`, `user <u> may not run <command> on <host>`) | the sudoers rule to add, with what it grants |
|
|
909
909
|
| `needs-elevation` | `winget`: its `0x8A150019` return code (command requires administrator privileges) | the command to paste into an elevated terminal |
|
|
910
|
-
| `failed` | any other non-zero exit (the last output line
|
|
910
|
+
| `failed` | any other non-zero exit (the last output line that is not closing advice such as `Or consider using native installation with: claude install`, printable and cut at 300 characters), winget's `0x8A150014` (no installed package with that id), the output cap, a version that cannot be read after an exit 0, a command that could not start | what failed |
|
|
911
911
|
| `timed-out` | the 15-minute limit | check the package before retrying: it may be half-installed |
|
|
912
912
|
|
|
913
913
|
The winget return codes are pinned by number from winget's own generated table
|
|
@@ -918,7 +918,7 @@ package, or an installer that elevates itself, when its caller is not elevated h
|
|
|
918
918
|
here**: it may relaunch the installer through UAC, which puts a consent prompt on the logon user's
|
|
919
919
|
desktop (the agent is a logon task in that session) that the agent cannot answer; the job then waits
|
|
920
920
|
until it is answered or the 15-minute limit fires (`timed-out`), and a limited `taskkill` cannot end an
|
|
921
|
-
elevated installer. Anything else an installer fails with is `failed`, with its last output line.
|
|
921
|
+
elevated installer. Anything else an installer fails with is `failed`, with its last output line that is not closing advice.
|
|
922
922
|
|
|
923
923
|
**Audit.** Two lines in the agent log per run: `toolchain upgrade started: "<tool>" via <manager>
|
|
924
924
|
<packageId> (version of <cmd>)` when the job starts (so a run the agent does not survive is on record),
|
package/dist/ac-agent.mjs
CHANGED
|
@@ -47,7 +47,7 @@ function _mergeNamespaces(n, m) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
var name = "@rackbops/ac-agent";
|
|
50
|
-
var version = "2.0.0-alpha.
|
|
50
|
+
var version = "2.0.0-alpha.57";
|
|
51
51
|
var type = "module";
|
|
52
52
|
var description = "The per-machine host agent (installed with npx @rackbops/ac-agent): an HTTPS health server plus install/status/uninstall for a Windows logon task or a systemd user unit.";
|
|
53
53
|
var bin = {
|
|
@@ -5210,7 +5210,12 @@ function createGrantState(initial, persist) {
|
|
|
5210
5210
|
let current = initial;
|
|
5211
5211
|
return {
|
|
5212
5212
|
revision: () => current?.revision ?? null,
|
|
5213
|
-
|
|
5213
|
+
// Own keys only (#722): `grants` is parsed from JSON, a plain object, and `constructor` passes
|
|
5214
|
+
// PLUGIN_ID, so a bare `grants[pluginId]` read the inherited `Object` (no `.includes`) and the
|
|
5215
|
+
// guard answered 500 instead of 403.
|
|
5216
|
+
allows: (pluginId, capability) => current !== null && Object.hasOwn(current.grants, pluginId)
|
|
5217
|
+
? (current.grants[pluginId] ?? []).includes(capability)
|
|
5218
|
+
: false,
|
|
5214
5219
|
replace: (set) => {
|
|
5215
5220
|
persist(set);
|
|
5216
5221
|
current = set;
|
|
@@ -66328,7 +66333,8 @@ const WINDOWS = {
|
|
|
66328
66333
|
};
|
|
66329
66334
|
const TIERS = [200_000, 1_000_000];
|
|
66330
66335
|
function windowFor(model, occupancy) {
|
|
66331
|
-
|
|
66336
|
+
// Own keys only (#722): `model` is text from a transcript, as in 1.x's dict lookup.
|
|
66337
|
+
const win = Object.hasOwn(WINDOWS, model) ? WINDOWS[model] : undefined;
|
|
66332
66338
|
if (win !== undefined)
|
|
66333
66339
|
return { window: win, mapped: true };
|
|
66334
66340
|
for (const tier of TIERS) {
|
|
@@ -66738,7 +66744,8 @@ function isPlainObject(v) {
|
|
|
66738
66744
|
/** USD-equivalent for one assistant turn, at list API rates. `0` for an unpriced model -- the
|
|
66739
66745
|
* caller counts its tokens and surfaces the id instead of guessing. */
|
|
66740
66746
|
function recordCost(model, usage) {
|
|
66741
|
-
|
|
66747
|
+
// Own keys only (#722): `model` is text from a transcript, as in 1.x's dict lookup.
|
|
66748
|
+
const rate = Object.hasOwn(PRICES, model) ? PRICES[model] : undefined;
|
|
66742
66749
|
if (!rate)
|
|
66743
66750
|
return 0;
|
|
66744
66751
|
const creation = isPlainObject(usage.cache_creation) ? usage.cache_creation : {};
|
|
@@ -66827,7 +66834,7 @@ function scanFile(fileBuffer, mtime, size, stem, parentName, fullPathComponents)
|
|
|
66827
66834
|
turns++;
|
|
66828
66835
|
if (model) {
|
|
66829
66836
|
models.add(model);
|
|
66830
|
-
if (!(model
|
|
66837
|
+
if (!Object.hasOwn(PRICES, model))
|
|
66831
66838
|
unpriced.add(model);
|
|
66832
66839
|
}
|
|
66833
66840
|
cost += recordCost(model, usage);
|
|
@@ -75850,12 +75857,18 @@ function sudoersRule(username) {
|
|
|
75850
75857
|
function printable(text, max) {
|
|
75851
75858
|
return text.replace(/[^\x20-\x7e]/g, "?").slice(0, max);
|
|
75852
75859
|
}
|
|
75860
|
+
/** A closing line that advises rather than reports, e.g. the Claude CLI's "Or consider using native
|
|
75861
|
+
* installation with: claude install" printed after the error that actually failed the run. */
|
|
75862
|
+
const ADVICE_LINE = /^(?:or\s+)?(?:consider|try|hint|tip|see|for more)(?=\s|:|$)/i;
|
|
75863
|
+
/** The command's last line that reports something: trailing advice lines are skipped, so the reason
|
|
75864
|
+
* is the failure and not the hint printed after it. All-advice output falls back to its last line. */
|
|
75853
75865
|
function lastNonEmptyLine(text) {
|
|
75854
75866
|
const lines = text
|
|
75855
75867
|
.split(/\r?\n/)
|
|
75856
75868
|
.map((line) => line.trim())
|
|
75857
75869
|
.filter((line) => line !== "");
|
|
75858
|
-
|
|
75870
|
+
const reported = lines.findLast((line) => !ADVICE_LINE.test(line));
|
|
75871
|
+
return printable(reported ?? lines.at(-1) ?? "", MAX_REASON_CHARS);
|
|
75859
75872
|
}
|
|
75860
75873
|
function classifyOutcome(input) {
|
|
75861
75874
|
if (input.limit === "timeout") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rackbops/ac-agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.57",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The per-machine host agent (installed with npx @rackbops/ac-agent): an HTTPS health server plus install/status/uninstall for a Windows logon task or a systemd user unit.",
|