@aragon-agent/cli 0.5.9 → 0.5.11
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/CHANGELOG.md +1157 -1026
- package/README.md +123 -0
- package/dist/boot/guard.d.ts +135 -0
- package/dist/boot/guard.js +218 -0
- package/dist/boot/rollback.d.ts +86 -0
- package/dist/boot/rollback.js +185 -0
- package/dist/cli.js +376 -2
- package/dist/commands/builtins.js +118 -0
- package/dist/commands/perf.d.ts +5 -1
- package/dist/commands/perf.js +43 -1
- package/dist/commands/registry.d.ts +17 -0
- package/dist/config/app-paths.d.ts +31 -0
- package/dist/config/app-paths.js +37 -0
- package/dist/config/cli-commands.d.ts +27 -1
- package/dist/config/cli-commands.js +51 -2
- package/dist/config/env.d.ts +11 -1
- package/dist/config/env.js +58 -1
- package/dist/config/load.d.ts +30 -0
- package/dist/config/load.js +56 -1
- package/dist/config/schema.d.ts +91 -0
- package/dist/config/schema.js +107 -0
- package/dist/config/store.js +13 -1
- package/dist/launcher.d.ts +14 -0
- package/dist/launcher.js +43 -0
- package/dist/logging/logger.d.ts +1 -1
- package/dist/ui/App.d.ts +11 -1
- package/dist/ui/App.js +88 -2
- package/dist/ui/BottomStatusRow.d.ts +25 -3
- package/dist/ui/BottomStatusRow.js +10 -7
- package/dist/ui/PromptInput.d.ts +10 -0
- package/dist/ui/PromptInput.js +41 -48
- package/dist/ui/UpdateLine.d.ts +44 -0
- package/dist/ui/UpdateLine.js +129 -0
- package/dist/ui/editor-reducer.d.ts +62 -0
- package/dist/ui/editor-reducer.js +90 -0
- package/dist/ui/frame-differ.d.ts +95 -0
- package/dist/ui/frame-differ.js +230 -0
- package/dist/ui/stdout-frame-writer.d.ts +41 -0
- package/dist/ui/stdout-frame-writer.js +102 -0
- package/dist/update/classify-failure.d.ts +32 -0
- package/dist/update/classify-failure.js +60 -0
- package/dist/update/install-lock.d.ts +55 -0
- package/dist/update/install-lock.js +184 -0
- package/dist/update/install-source.d.ts +97 -0
- package/dist/update/install-source.js +218 -0
- package/dist/update/installer.d.ts +108 -0
- package/dist/update/installer.js +242 -0
- package/dist/update/limits.d.ts +111 -0
- package/dist/update/limits.js +111 -0
- package/dist/update/npm-view.d.ts +62 -0
- package/dist/update/npm-view.js +133 -0
- package/dist/update/registry.d.ts +52 -0
- package/dist/update/registry.js +161 -0
- package/dist/update/semver.d.ts +89 -0
- package/dist/update/semver.js +295 -0
- package/dist/update/service.d.ts +193 -0
- package/dist/update/service.js +636 -0
- package/dist/update/state.d.ts +103 -0
- package/dist/update/state.js +142 -0
- package/dist/update/types.d.ts +169 -0
- package/dist/update/types.js +68 -0
- package/package.json +3 -3
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `UpdateService` - the state machine, the scheduler and the event stream
|
|
3
|
+
* (cli-auto-update section 3.6).
|
|
4
|
+
*
|
|
5
|
+
* ASCII ONLY - this tree is inside the glyph scanner's scope (C-2 / C-3).
|
|
6
|
+
*
|
|
7
|
+
* idle --check()--> checking --none--> idle
|
|
8
|
+
* |
|
|
9
|
+
* |-notify--> available (terminal for the session)
|
|
10
|
+
* `-install-> installing --ok--> ready (terminal)
|
|
11
|
+
* `-err--> failed --backoff--> idle
|
|
12
|
+
*
|
|
13
|
+
* EVERY FAILURE IS SILENT (D-7). A background updater that cannot reach the
|
|
14
|
+
* registry behind a corporate proxy, or cannot write to `/usr/lib/node_modules`
|
|
15
|
+
* without sudo, must not turn into a recurring interruption: it logs, backs off
|
|
16
|
+
* exponentially, and stays quiet. The single exception is a failure the user can
|
|
17
|
+
* actually fix, after `UPDATE_LIMITS.failuresBeforeNotice` consecutive
|
|
18
|
+
* occurrences.
|
|
19
|
+
*
|
|
20
|
+
* THIS MODULE IS REACHED ONLY THROUGH A DYNAMIC `import()` (section 3.8 / D-25).
|
|
21
|
+
* `runOneShot` and `runInteractive` live in the same `cli.tsx` module and there
|
|
22
|
+
* is no bundler (C-16), so a static import here would put the whole subsystem in
|
|
23
|
+
* `dist/cli.js`'s graph and `aragon -p` would evaluate every module under
|
|
24
|
+
* `update/`.
|
|
25
|
+
*/
|
|
26
|
+
import type { ScopedLogger } from '../logging/logger.js';
|
|
27
|
+
import type { UpdateConfig } from '../config/schema.js';
|
|
28
|
+
import { type NpmViewDeps } from './npm-view.js';
|
|
29
|
+
import { type InstallDeps, type SpawnImpl } from './installer.js';
|
|
30
|
+
import type { InstallSource, UpdateCommandPort, UpdateSnapshot } from './types.js';
|
|
31
|
+
/** A timer handle we only ever cancel and `unref`. */
|
|
32
|
+
interface TimerHandle {
|
|
33
|
+
unref?: () => void;
|
|
34
|
+
}
|
|
35
|
+
export interface UpdateServiceDeps {
|
|
36
|
+
config: UpdateConfig;
|
|
37
|
+
/** The running version - `cli.tsx`'s `VERSION`. */
|
|
38
|
+
currentVersion: string;
|
|
39
|
+
now?: () => number;
|
|
40
|
+
fetchImpl?: typeof fetch;
|
|
41
|
+
spawnImpl?: SpawnImpl;
|
|
42
|
+
logger?: ScopedLogger;
|
|
43
|
+
env?: NodeJS.ProcessEnv;
|
|
44
|
+
/** `process.versions.node`, injected so every engine test is offline. */
|
|
45
|
+
nodeVersion?: string;
|
|
46
|
+
/** Overrides `selfPackageRoot()`; tests point it at a synthetic tree. */
|
|
47
|
+
packageRoot?: string | null;
|
|
48
|
+
/** Overrides the name read from `<root>/package.json`. */
|
|
49
|
+
packageName?: string;
|
|
50
|
+
/** Pre-resolved classification, so a test need not build a real tree. */
|
|
51
|
+
source?: InstallSource;
|
|
52
|
+
setTimeoutImpl?: (fn: () => void, ms: number) => TimerHandle;
|
|
53
|
+
clearTimeoutImpl?: (handle: TimerHandle) => void;
|
|
54
|
+
/** Deterministic jitter for tests. */
|
|
55
|
+
random?: () => number;
|
|
56
|
+
/** Forwarded to `runNpmInstall` and `tryAcquireInstallLock`. */
|
|
57
|
+
install?: InstallDeps;
|
|
58
|
+
/** Forwarded to `fetchLatestViaNpm`, so no test spawns npm (H3). */
|
|
59
|
+
npmView?: NpmViewDeps;
|
|
60
|
+
lockPath?: string;
|
|
61
|
+
isProcessAlive?: (pid: number) => boolean;
|
|
62
|
+
}
|
|
63
|
+
type Listener = (snapshot: UpdateSnapshot) => void;
|
|
64
|
+
export declare class UpdateService implements UpdateCommandPort {
|
|
65
|
+
private readonly deps;
|
|
66
|
+
private readonly now;
|
|
67
|
+
private readonly log;
|
|
68
|
+
private readonly listeners;
|
|
69
|
+
private phase;
|
|
70
|
+
private latestVersion;
|
|
71
|
+
private reason;
|
|
72
|
+
private advice;
|
|
73
|
+
/** Set only on the `node-too-old` path; both, or neither (section 6.2). */
|
|
74
|
+
private requiredNode;
|
|
75
|
+
private runningNode;
|
|
76
|
+
private nextAt;
|
|
77
|
+
private failures;
|
|
78
|
+
/**
|
|
79
|
+
* The rollback notice, held for THIS SESSION and cleared from the file the
|
|
80
|
+
* first time it is read (section 5.2a / D-38). Both, or neither.
|
|
81
|
+
*/
|
|
82
|
+
private rolledBackFrom;
|
|
83
|
+
private rolledBackTo;
|
|
84
|
+
/** What `aragon update --rollback` would reinstall, for `/update status`. */
|
|
85
|
+
private lastGoodVersion;
|
|
86
|
+
/** Which probe answered the last successful check (H3). */
|
|
87
|
+
private probe;
|
|
88
|
+
private timer;
|
|
89
|
+
private started;
|
|
90
|
+
private disposed;
|
|
91
|
+
private inFlight;
|
|
92
|
+
private resolved;
|
|
93
|
+
constructor(deps: UpdateServiceDeps);
|
|
94
|
+
/**
|
|
95
|
+
* Schedule the first check. Idempotent.
|
|
96
|
+
*
|
|
97
|
+
* The first check fires `UPDATE_LIMITS.startupDelayMs` after this call so it
|
|
98
|
+
* can never contend with first paint, and every timer is `unref()`ed so a
|
|
99
|
+
* pending check never keeps `aragon` from exiting.
|
|
100
|
+
*/
|
|
101
|
+
start(): void;
|
|
102
|
+
snapshot(): UpdateSnapshot;
|
|
103
|
+
subscribe(fn: Listener): () => void;
|
|
104
|
+
nextCheckAt(): number | null;
|
|
105
|
+
/**
|
|
106
|
+
* Run a check now, subject to the machine-wide throttle unless forced.
|
|
107
|
+
*
|
|
108
|
+
* SINGLE-FLIGHT. Two `/update now` in a row, or a slash command landing on top
|
|
109
|
+
* of the scheduled tick, must produce one registry request and one install -
|
|
110
|
+
* the in-process half of what `lastCheckAt` does across processes.
|
|
111
|
+
*/
|
|
112
|
+
checkNow(opts?: {
|
|
113
|
+
force?: boolean;
|
|
114
|
+
}): Promise<UpdateSnapshot>;
|
|
115
|
+
/**
|
|
116
|
+
* Install a specific version now, bypassing the decision gates.
|
|
117
|
+
*
|
|
118
|
+
* The explicit escape hatch behind `aragon update --to <version>` (non-goal 4:
|
|
119
|
+
* there is no AUTOMATIC downgrade, but a deliberate one is exactly what a user
|
|
120
|
+
* needs when a release misbehaves).
|
|
121
|
+
*/
|
|
122
|
+
installNow(version?: string): Promise<UpdateSnapshot>;
|
|
123
|
+
/** Persist `skippedVersion`; the line disappears until a newer one appears. */
|
|
124
|
+
skip(version: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Clear timers and drop listeners. NEVER KILLS THE INSTALLER CHILD (U-3).
|
|
127
|
+
*
|
|
128
|
+
* Killing a running `npm install -g` is the one action in this feature that
|
|
129
|
+
* can leave the user's global installation broken, and `dispose()` is called
|
|
130
|
+
* by the most ordinary event there is - the user pressing Ctrl+C. The child is
|
|
131
|
+
* detached and `unref()`ed precisely so it can finish without us.
|
|
132
|
+
*
|
|
133
|
+
* Idempotent, and called on BOTH of `runInteractive`'s teardown branches.
|
|
134
|
+
*/
|
|
135
|
+
dispose(): void;
|
|
136
|
+
private cancelTimer;
|
|
137
|
+
/**
|
|
138
|
+
* Arm the next check.
|
|
139
|
+
*
|
|
140
|
+
* The jitter is not decoration (D-12 / R-6): machine fleets started by the
|
|
141
|
+
* same automation otherwise arrive at the registry together, and the throttle
|
|
142
|
+
* in `update-state.json` only de-duplicates within ONE machine.
|
|
143
|
+
*/
|
|
144
|
+
private schedule;
|
|
145
|
+
/** `backoffBaseMs * 2^(n-1)`, capped. `n` is the consecutive-failure count. */
|
|
146
|
+
private backoffMs;
|
|
147
|
+
private scheduleNext;
|
|
148
|
+
private setPhase;
|
|
149
|
+
/**
|
|
150
|
+
* Step 11 of the happy path: the new version is now the running one, so the
|
|
151
|
+
* pending marker has served its purpose.
|
|
152
|
+
*
|
|
153
|
+
* Silent by design - the user restarted, which is the acknowledgement. The log
|
|
154
|
+
* record is what makes "when did this machine actually pick up 0.6.0"
|
|
155
|
+
* answerable after the fact.
|
|
156
|
+
*/
|
|
157
|
+
private reconcilePendingRestart;
|
|
158
|
+
/**
|
|
159
|
+
* Read the rollback notice, hold it for this session, and clear the file
|
|
160
|
+
* (cli-auto-update-hardening section 5.2a / D-38 / D-40).
|
|
161
|
+
*
|
|
162
|
+
* CONSUMING ON READ IS WHAT MAKES "ONE SESSION" TRUE WITHOUT A SECOND
|
|
163
|
+
* TIMESTAMP. It also means a launch that never constructs a service -
|
|
164
|
+
* `update.mode: 'off'`, a non-TTY, CI - does NOT burn the notice, so it
|
|
165
|
+
* survives to the first session that could actually have shown it.
|
|
166
|
+
*
|
|
167
|
+
* `rolledBackTo` is the running version and is therefore DERIVED, not stored:
|
|
168
|
+
* we are, by definition, the target of the rollback that wrote this field. The
|
|
169
|
+
* "both or neither" rule the pair inherits from `requiredNode` / `runningNode`
|
|
170
|
+
* is satisfied by construction rather than by discipline.
|
|
171
|
+
*
|
|
172
|
+
* `lastGoodVersion` is picked up in the same read - it is what
|
|
173
|
+
* `aragon update --rollback` would reinstall, and `/update status` is the only
|
|
174
|
+
* place a user can find that out before running the command.
|
|
175
|
+
*/
|
|
176
|
+
private consumeRollbackNotice;
|
|
177
|
+
/** Classify this installation once. Cheap, but it stats the filesystem. */
|
|
178
|
+
private resolve;
|
|
179
|
+
private runCheck;
|
|
180
|
+
/**
|
|
181
|
+
* Report an available version without installing it.
|
|
182
|
+
*
|
|
183
|
+
* `dev-monorepo` and `npx` are SILENT even here (AC-6 / AC-7): a developer's
|
|
184
|
+
* clone is not out of date, it is checked out, and `npx` resolved `latest`
|
|
185
|
+
* seconds ago. Both fall back to `idle`, which `shouldRenderUpdateLine`
|
|
186
|
+
* answers `false` for.
|
|
187
|
+
*/
|
|
188
|
+
private offer;
|
|
189
|
+
private performInstall;
|
|
190
|
+
private recordFailure;
|
|
191
|
+
private clearFailures;
|
|
192
|
+
}
|
|
193
|
+
export {};
|