@aui.io/apollo 0.1.60 → 0.1.66
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/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js +236 -93
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js +4 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/runtime-version.js +22 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/runtime-version.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/status.js +19 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/status.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.d.ts +12 -0
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.js +21 -0
- package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/index.d.ts +11 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/index.js +95 -8
- package/node_modules/@aui.io/apollo-cli/dist/src/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-cli/dist/src/update-refresh.d.ts +1 -0
- package/node_modules/@aui.io/apollo-cli/dist/src/update-refresh.js +21 -0
- package/node_modules/@aui.io/apollo-cli/dist/src/update-refresh.js.map +1 -0
- package/node_modules/@aui.io/apollo-cli/package.json +3 -3
- package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.d.ts +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.d.ts +117 -41
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.js +26 -25
- package/node_modules/@aui.io/apollo-core/dist/src/api/builder-api.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.d.ts +0 -18
- package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.js +0 -8
- package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/config/store.d.ts +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/config/store.js +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/config/store.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/config/types.d.ts +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.d.ts +30 -0
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js +47 -0
- package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/index.d.ts +6 -4
- package/node_modules/@aui.io/apollo-core/dist/src/index.js +4 -2
- package/node_modules/@aui.io/apollo-core/dist/src/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.d.ts +31 -5
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.js +36 -5
- package/node_modules/@aui.io/apollo-core/dist/src/output/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/availability.d.ts +81 -0
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/availability.js +260 -0
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/availability.js.map +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/index.d.ts +7 -0
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/index.js +2 -1
- package/node_modules/@aui.io/apollo-core/dist/src/runtime-version/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/builds.d.ts +5 -8
- package/node_modules/@aui.io/apollo-core/dist/src/services/builds.js +5 -7
- package/node_modules/@aui.io/apollo-core/dist/src/services/builds.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.d.ts +7 -11
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js +22 -18
- package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/clients.d.ts +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/doctor.js +64 -2
- package/node_modules/@aui.io/apollo-core/dist/src/services/doctor.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/runs.d.ts +84 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/runs.js +186 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/runs.js.map +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.d.ts +8 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.js +15 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/dist/src/services/update-check.d.ts +105 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/update-check.js +265 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/update-check.js.map +1 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.d.ts +11 -0
- package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.js +6 -2
- package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.js.map +1 -1
- package/node_modules/@aui.io/apollo-core/package.json +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/index.d.ts +2 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/index.js +2 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/index.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.d.ts +10 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.js +58 -12
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/actions.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.d.ts +3 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js +2 -2
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/update.d.ts +16 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/update.js +21 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/lib/update.js.map +1 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js +37 -19
- package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/shell/FooterHints.d.ts +24 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/shell/FooterHints.js +41 -4
- package/node_modules/@aui.io/apollo-tui/dist/src/shell/FooterHints.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/dist/src/theme/glyphs.d.ts +2 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/theme/glyphs.js +2 -0
- package/node_modules/@aui.io/apollo-tui/dist/src/theme/glyphs.js.map +1 -1
- package/node_modules/@aui.io/apollo-tui/package.json +2 -2
- package/package.json +4 -4
- package/node_modules/@aui.io/apollo-core/dist/src/services/evaluations.d.ts +0 -42
- package/node_modules/@aui.io/apollo-core/dist/src/services/evaluations.js +0 -106
- package/node_modules/@aui.io/apollo-core/dist/src/services/evaluations.js.map +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readBuildFiles } from "../bundle/build-area.js";
|
|
4
|
+
import { CliError, ConfigError } from "../errors/index.js";
|
|
5
|
+
import { agentRoot, readCheckoutTree, requireAgent } from "./bundles.js";
|
|
6
|
+
/**
|
|
7
|
+
* The two proving lanes' console half
|
|
8
|
+
* (builder/flow/regressions-and-evaluations-plan.md phase 5): ship the
|
|
9
|
+
* checkout's current tree — the program under `src/**`, the records under
|
|
10
|
+
* `build/**` — and the server runs it against the shipped snapshot. A
|
|
11
|
+
* REGRESSION drives `build/scenarios.yaml` through the simulator, nobody
|
|
12
|
+
* improvising; an EVALUATION plans improvising callers from guidelines and
|
|
13
|
+
* ends on a macro verdict. No session exists; polling IS the progress
|
|
14
|
+
* surface. The last run's id per lane is a LOCAL fact in the checkout's
|
|
15
|
+
* `.apollo/<kind>.json`, so `--status`, `--cancel`, `--pull` and
|
|
16
|
+
* `--annotate` name nothing and still find their run.
|
|
17
|
+
*/
|
|
18
|
+
/** Run statuses that are still moving — everything else is the verdict. */
|
|
19
|
+
const RUN_LIVE = new Set(["queued", "running", "cancelling"]);
|
|
20
|
+
/** A run is real conversations plus judge calls — hours-scale like a
|
|
21
|
+
* build, so the poll loop's own deadline is generous; each poll request
|
|
22
|
+
* stays cheap. */
|
|
23
|
+
export const RUN_DEADLINE_MS = 2 * 3600_000;
|
|
24
|
+
const RUN_POLL_MS = 5_000;
|
|
25
|
+
function runStateFile(root, kind) {
|
|
26
|
+
return path.join(root, ".apollo", `${kind}.json`);
|
|
27
|
+
}
|
|
28
|
+
/** The saved run handle, or nothing — a missing or corrupt file simply
|
|
29
|
+
* means there is no run to name. The pre-phase-5 evaluation file carried
|
|
30
|
+
* `evaluation_id`; it still reads. */
|
|
31
|
+
export async function readRunState(root, kind) {
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(await readFile(runStateFile(root, kind), "utf8"));
|
|
34
|
+
const id = typeof parsed.run_id === "string" ? parsed.run_id : parsed.evaluation_id;
|
|
35
|
+
return typeof id === "string" ? { run_id: id, kind } : undefined;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export async function writeRunState(root, state) {
|
|
42
|
+
const file = runStateFile(root, state.kind);
|
|
43
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
44
|
+
await writeFile(file, `${JSON.stringify(state, null, 2)}\n`, "utf8");
|
|
45
|
+
}
|
|
46
|
+
/** The id a receipt carries — an evaluation's `evaluation_id`, a
|
|
47
|
+
* regression's `regression_id`. */
|
|
48
|
+
export function receiptId(receipt) {
|
|
49
|
+
const id = receipt.regression_id ?? receipt.evaluation_id;
|
|
50
|
+
if (!id)
|
|
51
|
+
throw new CliError("The server's receipt named no run.");
|
|
52
|
+
return id;
|
|
53
|
+
}
|
|
54
|
+
/** Every file under `<root>/bundle/build/**` as `build/**` wire paths.
|
|
55
|
+
* Absent directory reads as an empty map: the server names the missing
|
|
56
|
+
* file (422), which teaches more than a local guess. */
|
|
57
|
+
async function readBuildTree(buildDir) {
|
|
58
|
+
const { files } = await readBuildFiles(buildDir);
|
|
59
|
+
return Object.fromEntries(Object.entries(files).map(([relativePath, content]) => [
|
|
60
|
+
`build/${relativePath}`,
|
|
61
|
+
content.toString("utf8"),
|
|
62
|
+
]));
|
|
63
|
+
}
|
|
64
|
+
async function checkoutTree(root) {
|
|
65
|
+
return {
|
|
66
|
+
...(await readCheckoutTree(path.join(root, "bundle", "src"))),
|
|
67
|
+
...(await readBuildTree(path.join(root, "bundle", "build"))),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Start one detached evaluation over this checkout and save its id. The
|
|
72
|
+
* tree is frozen at accept — keep editing, the run's bytes do not move.
|
|
73
|
+
*/
|
|
74
|
+
export async function startEvaluation(context, builder, options) {
|
|
75
|
+
const root = options.root ?? agentRoot(context);
|
|
76
|
+
const guidelines = options.guidelines.trim();
|
|
77
|
+
if (!guidelines) {
|
|
78
|
+
throw new ConfigError("An evaluation needs guidelines — what to evaluate, in plain words.", 'Example: apollo evaluate "the refund refusal path after this change".');
|
|
79
|
+
}
|
|
80
|
+
const versionTag = options.versionTag ?? context.versionTag;
|
|
81
|
+
const receipt = await builder.startEvaluation({
|
|
82
|
+
agent_id: requireAgent(context),
|
|
83
|
+
files: await checkoutTree(root),
|
|
84
|
+
guidelines,
|
|
85
|
+
...(options.config && Object.keys(options.config).length ? { config: options.config } : {}),
|
|
86
|
+
...(options.message ? { message: options.message } : {}),
|
|
87
|
+
...(versionTag ? { version_tag: versionTag } : {}),
|
|
88
|
+
});
|
|
89
|
+
await writeRunState(root, { run_id: receiptId(receipt), kind: "evaluation" });
|
|
90
|
+
return receipt;
|
|
91
|
+
}
|
|
92
|
+
/** Start one detached regression over this checkout and save its id. */
|
|
93
|
+
export async function startRegression(context, builder, options = {}) {
|
|
94
|
+
const root = options.root ?? agentRoot(context);
|
|
95
|
+
const versionTag = options.versionTag ?? context.versionTag;
|
|
96
|
+
const receipt = await builder.startRegression({
|
|
97
|
+
agent_id: requireAgent(context),
|
|
98
|
+
files: await checkoutTree(root),
|
|
99
|
+
...(options.scenarios?.length ? { scenarios: options.scenarios } : {}),
|
|
100
|
+
...(options.judge ? { judge: true } : {}),
|
|
101
|
+
...(options.message ? { message: options.message } : {}),
|
|
102
|
+
...(versionTag ? { version_tag: versionTag } : {}),
|
|
103
|
+
});
|
|
104
|
+
await writeRunState(root, { run_id: receiptId(receipt), kind: "regression" });
|
|
105
|
+
return receipt;
|
|
106
|
+
}
|
|
107
|
+
/** Poll one run to its terminal view (completed, failed or cancelled). */
|
|
108
|
+
export async function awaitRun(builder, kind, runId, options = {}) {
|
|
109
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
110
|
+
const interval = options.pollIntervalMs ?? RUN_POLL_MS;
|
|
111
|
+
const deadline = Date.now() + (options.deadlineMs ?? RUN_DEADLINE_MS);
|
|
112
|
+
for (;;) {
|
|
113
|
+
const view = await builder.runView(kind, runId);
|
|
114
|
+
if (!RUN_LIVE.has(view.status))
|
|
115
|
+
return view;
|
|
116
|
+
if (Date.now() >= deadline) {
|
|
117
|
+
// The run keeps executing server-side; the saved id still names it.
|
|
118
|
+
throw new CliError(`The ${kind} is still running (${runId}).`, {
|
|
119
|
+
suggestion: `\`apollo ${verb(kind)} --status\` picks the report up later.`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
await sleep(interval);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** The CLI verb per lane. */
|
|
126
|
+
export function verb(kind) {
|
|
127
|
+
return kind === "regression" ? "regress" : "evaluate";
|
|
128
|
+
}
|
|
129
|
+
/** The run the caller means: the explicit id, else the checkout's saved
|
|
130
|
+
* last run of that lane — no run at all is a config story, not a 404. */
|
|
131
|
+
export async function resolveRunId(context, kind, explicit, root) {
|
|
132
|
+
if (explicit)
|
|
133
|
+
return explicit;
|
|
134
|
+
const saved = await readRunState(root ?? agentRoot(context), kind);
|
|
135
|
+
if (!saved) {
|
|
136
|
+
throw new ConfigError(`No ${kind} to name — this checkout has not started one.`, `Run \`apollo ${verb(kind)}\` first, or pass --id.`);
|
|
137
|
+
}
|
|
138
|
+
return saved.run_id;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Fetch a settled run's evidence and write it under the checkout —
|
|
142
|
+
* `tmp/regressions/<id>/` or `tmp/evaluations/<id>/`, the layout the
|
|
143
|
+
* builder writes in a session, so a CLI author and a builder session read
|
|
144
|
+
* the same files. `tmp/**` never ships; a re-pull overwrites.
|
|
145
|
+
*/
|
|
146
|
+
export async function pullRun(context, builder, kind, runId, options = {}) {
|
|
147
|
+
const root = path.resolve(options.root ?? agentRoot(context));
|
|
148
|
+
const artifacts = await builder.runArtifacts(kind, runId, options.all ?? true);
|
|
149
|
+
const written = [];
|
|
150
|
+
for (const [relativePath, content] of Object.entries(artifacts.files)) {
|
|
151
|
+
const target = insideTmp(root, relativePath);
|
|
152
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
153
|
+
await writeFile(target, content, "utf8");
|
|
154
|
+
written.push(relativePath);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
directory: insideTmp(root, artifacts.root),
|
|
158
|
+
files: written.sort(),
|
|
159
|
+
note: artifacts.note,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/** A server-named artifact path must live under `tmp/` inside the
|
|
163
|
+
* checkout — anything else is refused before a byte is written. */
|
|
164
|
+
function insideTmp(root, relativePath) {
|
|
165
|
+
const normalized = relativePath.split("\\").join("/");
|
|
166
|
+
if (!normalized.startsWith("tmp/") || normalized.split("/").includes("..")) {
|
|
167
|
+
throw new CliError(`Refusing to write outside tmp/: ${relativePath}`);
|
|
168
|
+
}
|
|
169
|
+
const target = path.resolve(root, normalized);
|
|
170
|
+
if (!target.startsWith(`${path.join(root, "tmp")}${path.sep}`)) {
|
|
171
|
+
throw new CliError(`Refusing to write outside tmp/: ${relativePath}`);
|
|
172
|
+
}
|
|
173
|
+
return target;
|
|
174
|
+
}
|
|
175
|
+
/** Append one reading to a settled run; the server answers the run as it
|
|
176
|
+
* now reads. */
|
|
177
|
+
export function annotateRun(builder, kind, runId, annotation) {
|
|
178
|
+
const text = annotation.text.trim();
|
|
179
|
+
if (!text)
|
|
180
|
+
throw new ConfigError("An annotation needs some text.");
|
|
181
|
+
return builder.annotateRun(kind, runId, {
|
|
182
|
+
text,
|
|
183
|
+
...(annotation.verdict ? { verdict: annotation.verdict } : {}),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../../src/services/runs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Context } from "../config/index.js";
|
|
2
|
+
import { type RuntimePinCheck } from "../runtime-version/availability.js";
|
|
2
3
|
export interface ServiceCheck {
|
|
3
4
|
service: "identity" | "management" | "runtime";
|
|
4
5
|
reachable: boolean;
|
|
@@ -20,8 +21,15 @@ export interface StatusResult {
|
|
|
20
21
|
bindingPath: string | null;
|
|
21
22
|
agentRoot: string | null;
|
|
22
23
|
checks?: ServiceCheck[];
|
|
24
|
+
/**
|
|
25
|
+
* With `--check` on a pinned checkout: whether the pinned runtime is still
|
|
26
|
+
* served (the family may be retired, or the gateway may route the pin to
|
|
27
|
+
* a different engine). Absent when unpinned or without `--check`.
|
|
28
|
+
*/
|
|
29
|
+
runtimePinned?: RuntimePinCheck;
|
|
23
30
|
}
|
|
24
31
|
export declare function getStatus(context: Context, options?: {
|
|
25
32
|
check?: boolean;
|
|
26
33
|
fetch?: typeof globalThis.fetch;
|
|
34
|
+
homeDir?: string;
|
|
27
35
|
}): Promise<StatusResult>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Transport } from "../api/transport.js";
|
|
2
2
|
import { ApiError, AuthError } from "../errors/index.js";
|
|
3
|
+
import { checkRuntimeAvailability, } from "../runtime-version/availability.js";
|
|
3
4
|
import { RUNTIME_VERSION_HEADER } from "../runtime-version/index.js";
|
|
5
|
+
import { createClients } from "./clients.js";
|
|
4
6
|
export async function getStatus(context, options = {}) {
|
|
5
7
|
const result = {
|
|
6
8
|
environment: context.environment,
|
|
@@ -22,6 +24,19 @@ export async function getStatus(context, options = {}) {
|
|
|
22
24
|
checkManagement(context, options.fetch),
|
|
23
25
|
checkRuntime(context, options.fetch),
|
|
24
26
|
]);
|
|
27
|
+
if (context.runtimeVersion) {
|
|
28
|
+
const clients = createClients(context, {
|
|
29
|
+
...(options.homeDir ? { homeDir: options.homeDir } : {}),
|
|
30
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
31
|
+
});
|
|
32
|
+
const pinned = await checkRuntimeAvailability(context, clients, {
|
|
33
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
34
|
+
...(options.homeDir ? { homeDir: options.homeDir } : {}),
|
|
35
|
+
withoutCatalog: "probe",
|
|
36
|
+
});
|
|
37
|
+
if (pinned)
|
|
38
|
+
result.runtimePinned = pinned;
|
|
39
|
+
}
|
|
25
40
|
}
|
|
26
41
|
return result;
|
|
27
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.service.js","sourceRoot":"","sources":["../../../src/services/status.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"status.service.js","sourceRoot":"","sources":["../../../src/services/status.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { type NpmRunner } from "./upgrade.js";
|
|
2
|
+
/**
|
|
3
|
+
* Which package the running console upgrades from, and the bin whose
|
|
4
|
+
* `upgrade` verb does it. The public build is the default; a distribution
|
|
5
|
+
* (apollo-internal) retargets both at startup, the same way it registers
|
|
6
|
+
* its environments — before any command or the TUI resolves a context.
|
|
7
|
+
*/
|
|
8
|
+
export interface UpdateTarget {
|
|
9
|
+
/** The npm package the notifier tracks (`npm view <package>@latest`). */
|
|
10
|
+
packageName: string;
|
|
11
|
+
/** The bin name the user runs — `<bin> upgrade` is the advertised fix. */
|
|
12
|
+
bin: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const PUBLIC_UPDATE_TARGET: Readonly<UpdateTarget>;
|
|
15
|
+
export declare function setUpdateTarget(next: UpdateTarget): void;
|
|
16
|
+
export declare function updateTarget(): Readonly<UpdateTarget>;
|
|
17
|
+
/** The exact command a notice tells the reader to run. */
|
|
18
|
+
export declare function upgradeCommand(which?: Readonly<UpdateTarget>): string;
|
|
19
|
+
/** One npm lookup satisfies the cache for an hour before the next command
|
|
20
|
+
* triggers another. Releases land several times a day here, so a shorter
|
|
21
|
+
* window than the usual daily check is worth it; the lookup runs detached,
|
|
22
|
+
* so the cadence costs no command any latency. */
|
|
23
|
+
export declare const UPDATE_CHECK_TTL_MS: number;
|
|
24
|
+
export declare const UPDATE_CHECK_FILE = "update-check.json";
|
|
25
|
+
export interface UpdateCheckEntry {
|
|
26
|
+
/** The last lookup ATTEMPT (success or failure), ISO-8601. Drives the TTL,
|
|
27
|
+
* so an offline machine retries once per window, not on every command. */
|
|
28
|
+
checkedAt: string;
|
|
29
|
+
/** The `latest` dist-tag from the last successful lookup. */
|
|
30
|
+
latest?: string;
|
|
31
|
+
/** When `latest` was resolved, ISO-8601. */
|
|
32
|
+
resolvedAt?: string;
|
|
33
|
+
}
|
|
34
|
+
/** `~/.apollo/update-check.json`: one entry per tracked package. */
|
|
35
|
+
export type UpdateCheckFile = Record<string, UpdateCheckEntry>;
|
|
36
|
+
/** `APOLLO_UPDATE_CHECK=0` opts out entirely (same shape as `APOLLO_TUI=0`). */
|
|
37
|
+
export declare function updateCheckDisabled(env?: NodeJS.ProcessEnv): boolean;
|
|
38
|
+
export declare function updateCheckPath(homeDir?: string): string;
|
|
39
|
+
/** The whole file; anything that is not a map of well-formed entries reads
|
|
40
|
+
* as empty (that covers a corrupt file and any older flat layout). */
|
|
41
|
+
export declare function readUpdateCache(homeDir?: string): Promise<UpdateCheckFile>;
|
|
42
|
+
export declare function readUpdateEntry(packageName: string, homeDir?: string): Promise<UpdateCheckEntry | undefined>;
|
|
43
|
+
/** Merge one package's entry into the file, keeping the other packages'. */
|
|
44
|
+
export declare function writeUpdateEntry(packageName: string, entry: UpdateCheckEntry, homeDir?: string): Promise<void>;
|
|
45
|
+
export declare function isUpdateEntryStale(entry: UpdateCheckEntry | undefined, now?: number): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Compare two `x.y.z[-prerelease]` versions; > 0 when `a` is newer than
|
|
48
|
+
* `b`. Enough for what this project publishes — a real semver range parser
|
|
49
|
+
* would be a dependency for a single comparison.
|
|
50
|
+
*/
|
|
51
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
52
|
+
/**
|
|
53
|
+
* What every surface hands the reader. The fields are for programs
|
|
54
|
+
* (`run` is the command to execute verbatim); `message` is the same fact
|
|
55
|
+
* as one sentence, so a coding agent that has never seen this schema still
|
|
56
|
+
* knows what to do.
|
|
57
|
+
*/
|
|
58
|
+
export interface UpdateNotice {
|
|
59
|
+
package: string;
|
|
60
|
+
current: string;
|
|
61
|
+
latest: string;
|
|
62
|
+
/** The command that installs `latest` — run it as written. */
|
|
63
|
+
run: string;
|
|
64
|
+
message: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The one line plain runs print to stderr. Starts with "Update available"
|
|
68
|
+
* so it can never be mistaken for the command failing, and quotes the
|
|
69
|
+
* command so an agent can copy it without guessing.
|
|
70
|
+
*/
|
|
71
|
+
export declare function formatUpdateNotice(notice: Pick<UpdateNotice, "current" | "latest" | "run">, bin?: string): string;
|
|
72
|
+
/** The notice for a cache entry, or undefined unless it names a strictly
|
|
73
|
+
* newer version than the one running. */
|
|
74
|
+
export declare function updateNoticeFrom(entry: UpdateCheckEntry | undefined, currentVersion: string, which?: Readonly<UpdateTarget>): UpdateNotice | undefined;
|
|
75
|
+
export interface RefreshUpdateCacheOptions {
|
|
76
|
+
packageName: string;
|
|
77
|
+
homeDir?: string;
|
|
78
|
+
npm?: NpmRunner;
|
|
79
|
+
now?: () => Date;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Ask npm for `latest` and persist the answer. Never throws: offline or a
|
|
83
|
+
* registry outage keeps the previous `latest` (a stale truth beats none)
|
|
84
|
+
* and only moves `checkedAt`, so the next window's command retries once
|
|
85
|
+
* rather than every command hammering the registry.
|
|
86
|
+
*/
|
|
87
|
+
export declare function refreshUpdateCache(options: RefreshUpdateCacheOptions): Promise<UpdateCheckEntry>;
|
|
88
|
+
/**
|
|
89
|
+
* Record a `latest` we just learned first-hand (`apollo upgrade`, its
|
|
90
|
+
* `--check`, the TUI's /upgrade) so the notice clears — or appears —
|
|
91
|
+
* immediately instead of after the next window.
|
|
92
|
+
*/
|
|
93
|
+
export declare function recordLatestVersion(packageName: string, latest: string, homeDir?: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* The whole check for a long-lived surface (the TUI): cached verdict when
|
|
96
|
+
* fresh, an inline refresh when stale, and the notice — if any — for the
|
|
97
|
+
* version that is running. Never throws.
|
|
98
|
+
*/
|
|
99
|
+
export declare function checkForUpdate(currentVersion: string, options?: {
|
|
100
|
+
homeDir?: string;
|
|
101
|
+
npm?: NpmRunner;
|
|
102
|
+
now?: () => Date;
|
|
103
|
+
env?: NodeJS.ProcessEnv;
|
|
104
|
+
which?: Readonly<UpdateTarget>;
|
|
105
|
+
}): Promise<UpdateNotice | undefined>;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The update notifier — "a newer apollo is on npm, run `apollo upgrade`".
|
|
3
|
+
*
|
|
4
|
+
* The contract every surface follows:
|
|
5
|
+
*
|
|
6
|
+
* 1. A command never waits on npm. It reads `~/.apollo/update-check.json`
|
|
7
|
+
* (microseconds) and, when the entry is older than the TTL, hands the
|
|
8
|
+
* lookup to a detached child that refreshes the file for the NEXT run.
|
|
9
|
+
* The long-lived TUI refreshes inline instead and re-checks on a timer.
|
|
10
|
+
* 2. The notice reaches humans and coding agents alike: one stderr line
|
|
11
|
+
* on plain runs (stdout stays the pipeable result), an additive top-level
|
|
12
|
+
* `update` field in every `--json` envelope (success or failure), and a
|
|
13
|
+
* toast + footer marker in the TUI. The text names the exact command.
|
|
14
|
+
* 3. The cache is disposable. A missing, corrupt, foreign-shaped or
|
|
15
|
+
* unwritable file degrades to "no notice" — never to a failed command.
|
|
16
|
+
* 4. `APOLLO_UPDATE_CHECK=0` disables everything; `CI` mutes the banner
|
|
17
|
+
* and the background refresh (the envelope still reports what the
|
|
18
|
+
* cache already knows).
|
|
19
|
+
*
|
|
20
|
+
* The file is keyed by package name because two distributions coexist on a
|
|
21
|
+
* staff machine (`@aui.io/apollo` and `@aui.io/apollo-internal`, separate
|
|
22
|
+
* bins); a flat file would have each build overwrite the other's verdict
|
|
23
|
+
* and re-spawn the lookup on every alternate run.
|
|
24
|
+
*/
|
|
25
|
+
import { readFile } from "node:fs/promises";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { apolloDir, writeJsonAtomic } from "../config/store.js";
|
|
29
|
+
import { resolvePublishedVersion } from "./upgrade.js";
|
|
30
|
+
export const PUBLIC_UPDATE_TARGET = Object.freeze({
|
|
31
|
+
packageName: "@aui.io/apollo",
|
|
32
|
+
bin: "apollo",
|
|
33
|
+
});
|
|
34
|
+
let target = PUBLIC_UPDATE_TARGET;
|
|
35
|
+
export function setUpdateTarget(next) {
|
|
36
|
+
target = Object.freeze({ ...next });
|
|
37
|
+
}
|
|
38
|
+
export function updateTarget() {
|
|
39
|
+
return target;
|
|
40
|
+
}
|
|
41
|
+
/** The exact command a notice tells the reader to run. */
|
|
42
|
+
export function upgradeCommand(which = target) {
|
|
43
|
+
return `${which.bin} upgrade`;
|
|
44
|
+
}
|
|
45
|
+
// ------------------------------------------------------------------ cache
|
|
46
|
+
/** One npm lookup satisfies the cache for an hour before the next command
|
|
47
|
+
* triggers another. Releases land several times a day here, so a shorter
|
|
48
|
+
* window than the usual daily check is worth it; the lookup runs detached,
|
|
49
|
+
* so the cadence costs no command any latency. */
|
|
50
|
+
export const UPDATE_CHECK_TTL_MS = 60 * 60 * 1000;
|
|
51
|
+
export const UPDATE_CHECK_FILE = "update-check.json";
|
|
52
|
+
/** `APOLLO_UPDATE_CHECK=0` opts out entirely (same shape as `APOLLO_TUI=0`). */
|
|
53
|
+
export function updateCheckDisabled(env = process.env) {
|
|
54
|
+
return env.APOLLO_UPDATE_CHECK === "0";
|
|
55
|
+
}
|
|
56
|
+
export function updateCheckPath(homeDir = homedir()) {
|
|
57
|
+
return join(apolloDir(homeDir), UPDATE_CHECK_FILE);
|
|
58
|
+
}
|
|
59
|
+
function isEntry(value) {
|
|
60
|
+
return (typeof value === "object" &&
|
|
61
|
+
value !== null &&
|
|
62
|
+
typeof value.checkedAt === "string" &&
|
|
63
|
+
(value.latest === undefined ||
|
|
64
|
+
typeof value.latest === "string"));
|
|
65
|
+
}
|
|
66
|
+
/** The whole file; anything that is not a map of well-formed entries reads
|
|
67
|
+
* as empty (that covers a corrupt file and any older flat layout). */
|
|
68
|
+
export async function readUpdateCache(homeDir = homedir()) {
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(await readFile(updateCheckPath(homeDir), "utf8"));
|
|
71
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
const file = {};
|
|
75
|
+
for (const [name, entry] of Object.entries(parsed)) {
|
|
76
|
+
if (isEntry(entry))
|
|
77
|
+
file[name] = entry;
|
|
78
|
+
}
|
|
79
|
+
return file;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Missing or unreadable — never checked, as far as the notifier knows.
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function readUpdateEntry(packageName, homeDir = homedir()) {
|
|
87
|
+
return (await readUpdateCache(homeDir))[packageName];
|
|
88
|
+
}
|
|
89
|
+
/** Merge one package's entry into the file, keeping the other packages'. */
|
|
90
|
+
export async function writeUpdateEntry(packageName, entry, homeDir = homedir()) {
|
|
91
|
+
const file = await readUpdateCache(homeDir);
|
|
92
|
+
file[packageName] = entry;
|
|
93
|
+
await writeJsonAtomic(updateCheckPath(homeDir), file, 0o644);
|
|
94
|
+
}
|
|
95
|
+
export function isUpdateEntryStale(entry, now = Date.now()) {
|
|
96
|
+
if (entry === undefined)
|
|
97
|
+
return true;
|
|
98
|
+
const checked = Date.parse(entry.checkedAt);
|
|
99
|
+
if (Number.isNaN(checked))
|
|
100
|
+
return true;
|
|
101
|
+
return now - checked >= UPDATE_CHECK_TTL_MS;
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------- versions
|
|
104
|
+
/**
|
|
105
|
+
* Compare two `x.y.z[-prerelease]` versions; > 0 when `a` is newer than
|
|
106
|
+
* `b`. Enough for what this project publishes — a real semver range parser
|
|
107
|
+
* would be a dependency for a single comparison.
|
|
108
|
+
*/
|
|
109
|
+
export function compareVersions(a, b) {
|
|
110
|
+
const [coreA, preA] = splitPrerelease(a);
|
|
111
|
+
const [coreB, preB] = splitPrerelease(b);
|
|
112
|
+
const partsA = coreA.split(".").map(numericPart);
|
|
113
|
+
const partsB = coreB.split(".").map(numericPart);
|
|
114
|
+
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
115
|
+
const valueA = partsA[i] ?? 0;
|
|
116
|
+
const valueB = partsB[i] ?? 0;
|
|
117
|
+
if (valueA !== valueB)
|
|
118
|
+
return valueA - valueB;
|
|
119
|
+
}
|
|
120
|
+
// Equal cores: a release outranks any prerelease of it.
|
|
121
|
+
if (preA === undefined && preB === undefined)
|
|
122
|
+
return 0;
|
|
123
|
+
if (preA === undefined)
|
|
124
|
+
return 1;
|
|
125
|
+
if (preB === undefined)
|
|
126
|
+
return -1;
|
|
127
|
+
return comparePrerelease(preA, preB);
|
|
128
|
+
}
|
|
129
|
+
function numericPart(part) {
|
|
130
|
+
const value = Number.parseInt(part, 10);
|
|
131
|
+
return Number.isNaN(value) ? 0 : value;
|
|
132
|
+
}
|
|
133
|
+
function splitPrerelease(version) {
|
|
134
|
+
const cleaned = version.trim().replace(/^v/, "");
|
|
135
|
+
const dash = cleaned.indexOf("-");
|
|
136
|
+
if (dash === -1)
|
|
137
|
+
return [cleaned, undefined];
|
|
138
|
+
return [cleaned.slice(0, dash), cleaned.slice(dash + 1)];
|
|
139
|
+
}
|
|
140
|
+
/** Dot-separated identifiers, numeric ones numerically (`beta.2 < beta.10`). */
|
|
141
|
+
function comparePrerelease(a, b) {
|
|
142
|
+
const partsA = a.split(".");
|
|
143
|
+
const partsB = b.split(".");
|
|
144
|
+
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
145
|
+
const valueA = partsA[i];
|
|
146
|
+
const valueB = partsB[i];
|
|
147
|
+
if (valueA === undefined)
|
|
148
|
+
return -1;
|
|
149
|
+
if (valueB === undefined)
|
|
150
|
+
return 1;
|
|
151
|
+
const numA = /^\d+$/.test(valueA) ? Number.parseInt(valueA, 10) : undefined;
|
|
152
|
+
const numB = /^\d+$/.test(valueB) ? Number.parseInt(valueB, 10) : undefined;
|
|
153
|
+
if (numA !== undefined && numB !== undefined) {
|
|
154
|
+
if (numA !== numB)
|
|
155
|
+
return numA - numB;
|
|
156
|
+
}
|
|
157
|
+
else if (numA !== undefined) {
|
|
158
|
+
return -1;
|
|
159
|
+
}
|
|
160
|
+
else if (numB !== undefined) {
|
|
161
|
+
return 1;
|
|
162
|
+
}
|
|
163
|
+
else if (valueA !== valueB) {
|
|
164
|
+
return valueA < valueB ? -1 : 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The one line plain runs print to stderr. Starts with "Update available"
|
|
171
|
+
* so it can never be mistaken for the command failing, and quotes the
|
|
172
|
+
* command so an agent can copy it without guessing.
|
|
173
|
+
*/
|
|
174
|
+
export function formatUpdateNotice(notice, bin = target.bin) {
|
|
175
|
+
return `Update available: ${bin} ${notice.current} → ${notice.latest} — run "${notice.run}" to install it.`;
|
|
176
|
+
}
|
|
177
|
+
/** The notice for a cache entry, or undefined unless it names a strictly
|
|
178
|
+
* newer version than the one running. */
|
|
179
|
+
export function updateNoticeFrom(entry, currentVersion, which = target) {
|
|
180
|
+
if (entry?.latest === undefined)
|
|
181
|
+
return undefined;
|
|
182
|
+
if (compareVersions(entry.latest, currentVersion) <= 0)
|
|
183
|
+
return undefined;
|
|
184
|
+
const run = upgradeCommand(which);
|
|
185
|
+
const partial = { current: currentVersion, latest: entry.latest, run };
|
|
186
|
+
return {
|
|
187
|
+
package: which.packageName,
|
|
188
|
+
...partial,
|
|
189
|
+
message: formatUpdateNotice(partial, which.bin),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Ask npm for `latest` and persist the answer. Never throws: offline or a
|
|
194
|
+
* registry outage keeps the previous `latest` (a stale truth beats none)
|
|
195
|
+
* and only moves `checkedAt`, so the next window's command retries once
|
|
196
|
+
* rather than every command hammering the registry.
|
|
197
|
+
*/
|
|
198
|
+
export async function refreshUpdateCache(options) {
|
|
199
|
+
const homeDir = options.homeDir ?? homedir();
|
|
200
|
+
const checkedAt = (options.now?.() ?? new Date()).toISOString();
|
|
201
|
+
const previous = await readUpdateEntry(options.packageName, homeDir);
|
|
202
|
+
let entry;
|
|
203
|
+
try {
|
|
204
|
+
const latest = await resolvePublishedVersion(options.packageName, "latest", options.npm);
|
|
205
|
+
entry = { checkedAt, latest, resolvedAt: checkedAt };
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
entry = {
|
|
209
|
+
checkedAt,
|
|
210
|
+
...(previous?.latest === undefined ? {} : { latest: previous.latest }),
|
|
211
|
+
...(previous?.resolvedAt === undefined
|
|
212
|
+
? {}
|
|
213
|
+
: { resolvedAt: previous.resolvedAt }),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
await writeUpdateEntry(options.packageName, entry, homeDir);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// Read-only home: the notifier stands down silently.
|
|
221
|
+
}
|
|
222
|
+
return entry;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Record a `latest` we just learned first-hand (`apollo upgrade`, its
|
|
226
|
+
* `--check`, the TUI's /upgrade) so the notice clears — or appears —
|
|
227
|
+
* immediately instead of after the next window.
|
|
228
|
+
*/
|
|
229
|
+
export async function recordLatestVersion(packageName, latest, homeDir = homedir()) {
|
|
230
|
+
const now = new Date().toISOString();
|
|
231
|
+
try {
|
|
232
|
+
await writeUpdateEntry(packageName, { checkedAt: now, latest, resolvedAt: now }, homeDir);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
// Best effort only.
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The whole check for a long-lived surface (the TUI): cached verdict when
|
|
240
|
+
* fresh, an inline refresh when stale, and the notice — if any — for the
|
|
241
|
+
* version that is running. Never throws.
|
|
242
|
+
*/
|
|
243
|
+
export async function checkForUpdate(currentVersion, options = {}) {
|
|
244
|
+
if (updateCheckDisabled(options.env))
|
|
245
|
+
return undefined;
|
|
246
|
+
const which = options.which ?? target;
|
|
247
|
+
try {
|
|
248
|
+
const homeDir = options.homeDir ?? homedir();
|
|
249
|
+
let entry = await readUpdateEntry(which.packageName, homeDir);
|
|
250
|
+
const now = options.now?.() ?? new Date();
|
|
251
|
+
if (isUpdateEntryStale(entry, now.getTime())) {
|
|
252
|
+
entry = await refreshUpdateCache({
|
|
253
|
+
packageName: which.packageName,
|
|
254
|
+
homeDir,
|
|
255
|
+
...(options.npm === undefined ? {} : { npm: options.npm }),
|
|
256
|
+
now: () => now,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return updateNoticeFrom(entry, currentVersion, which);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=update-check.js.map
|