@yagni-app/code-staging 1.0.5-staging.1233.1 → 1.0.5-staging.1234.1
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/dist/upgrade.d.ts +11 -2
- package/dist/upgrade.js +48 -8
- package/package.json +2 -2
package/dist/upgrade.d.ts
CHANGED
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export declare const PACKAGE_NAME: string;
|
|
18
18
|
export declare const UPDATE_CHECK_DISABLE_ENV = "YAGNI_DISABLE_UPDATE_CHECK";
|
|
19
|
-
export type InstallMethod = "npm" | "pnpm" | "bun";
|
|
19
|
+
export type InstallMethod = "npm" | "pnpm" | "bun" | "brew";
|
|
20
|
+
/** Fully qualified so `brew upgrade` can never resolve someone else's `yagni`. */
|
|
21
|
+
export declare const BREW_FORMULA = "yagni-app/tap/yagni";
|
|
20
22
|
/**
|
|
21
23
|
* The CLI's own version, read from this package's package.json. Resolved
|
|
22
24
|
* relative to the module (src/ and dist/ both sit one level below the package
|
|
@@ -70,8 +72,15 @@ export declare function maybeNudgeAndRefresh(deps: NudgeDeps): Promise<{
|
|
|
70
72
|
}>;
|
|
71
73
|
/**
|
|
72
74
|
* Which global installer owns the running bin, from its (real) path. The
|
|
73
|
-
* heuristic covers the
|
|
75
|
+
* heuristic covers the four installers the package supports; `--method` is
|
|
74
76
|
* the escape hatch when a layout defeats it.
|
|
77
|
+
*
|
|
78
|
+
* The path is realpath'd first because Homebrew is invisible in argv[1]:
|
|
79
|
+
* `/opt/homebrew/bin/yagni` is a symlink chain into the Cellar, and only the
|
|
80
|
+
* resolved path contains the `/Cellar/` segment (macOS, Intel /usr/local,
|
|
81
|
+
* and Linuxbrew all share it). Detecting brew matters: running `npm install
|
|
82
|
+
* -g` over a brew install creates a shadowing parallel copy — or the exact
|
|
83
|
+
* managed-Mac EACCES the brew channel exists to avoid.
|
|
75
84
|
*/
|
|
76
85
|
export declare function detectInstallMethod(binPath: string): InstallMethod;
|
|
77
86
|
export type ParsedUpgradeArgs = {
|
package/dist/upgrade.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* `yagni upgrade` still works there.
|
|
16
16
|
*/
|
|
17
17
|
import { spawn } from "node:child_process";
|
|
18
|
-
import { readFileSync } from "node:fs";
|
|
18
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
19
19
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
20
20
|
import { dirname, join } from "node:path";
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
@@ -26,7 +26,9 @@ export const UPDATE_CHECK_DISABLE_ENV = "YAGNI_DISABLE_UPDATE_CHECK";
|
|
|
26
26
|
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
27
27
|
const FETCH_TIMEOUT_MS = 5_000;
|
|
28
28
|
const SEMVER_RE = /^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
|
|
29
|
-
const INSTALL_METHODS = ["npm", "pnpm", "bun"];
|
|
29
|
+
const INSTALL_METHODS = ["npm", "pnpm", "bun", "brew"];
|
|
30
|
+
/** Fully qualified so `brew upgrade` can never resolve someone else's `yagni`. */
|
|
31
|
+
export const BREW_FORMULA = "yagni-app/tap/yagni";
|
|
30
32
|
/**
|
|
31
33
|
* The CLI's own version, read from this package's package.json. Resolved
|
|
32
34
|
* relative to the module (src/ and dist/ both sit one level below the package
|
|
@@ -188,18 +190,34 @@ export async function maybeNudgeAndRefresh(deps) {
|
|
|
188
190
|
// ── `yagni upgrade` ─────────────────────────────────────────────────────────
|
|
189
191
|
/**
|
|
190
192
|
* Which global installer owns the running bin, from its (real) path. The
|
|
191
|
-
* heuristic covers the
|
|
193
|
+
* heuristic covers the four installers the package supports; `--method` is
|
|
192
194
|
* the escape hatch when a layout defeats it.
|
|
195
|
+
*
|
|
196
|
+
* The path is realpath'd first because Homebrew is invisible in argv[1]:
|
|
197
|
+
* `/opt/homebrew/bin/yagni` is a symlink chain into the Cellar, and only the
|
|
198
|
+
* resolved path contains the `/Cellar/` segment (macOS, Intel /usr/local,
|
|
199
|
+
* and Linuxbrew all share it). Detecting brew matters: running `npm install
|
|
200
|
+
* -g` over a brew install creates a shadowing parallel copy — or the exact
|
|
201
|
+
* managed-Mac EACCES the brew channel exists to avoid.
|
|
193
202
|
*/
|
|
194
203
|
export function detectInstallMethod(binPath) {
|
|
195
|
-
|
|
204
|
+
let resolved = binPath;
|
|
205
|
+
try {
|
|
206
|
+
resolved = realpathSync(binPath);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Nonexistent or unreadable (tests, exotic layouts): judge the raw path.
|
|
210
|
+
}
|
|
211
|
+
const normalized = resolved.replaceAll("\\", "/").toLowerCase();
|
|
212
|
+
if (normalized.includes("/cellar/"))
|
|
213
|
+
return "brew";
|
|
196
214
|
if (normalized.includes("/.bun/"))
|
|
197
215
|
return "bun";
|
|
198
216
|
if (normalized.includes("pnpm"))
|
|
199
217
|
return "pnpm";
|
|
200
218
|
return "npm";
|
|
201
219
|
}
|
|
202
|
-
const UPGRADE_USAGE = `Usage: ${DISTRIBUTION.commandName} upgrade [version] [--method npm|pnpm|bun]`;
|
|
220
|
+
const UPGRADE_USAGE = `Usage: ${DISTRIBUTION.commandName} upgrade [version] [--method npm|pnpm|bun|brew]`;
|
|
203
221
|
export function parseUpgradeArgs(args) {
|
|
204
222
|
let target;
|
|
205
223
|
let method;
|
|
@@ -232,9 +250,22 @@ export function parseUpgradeArgs(args) {
|
|
|
232
250
|
return { ok: true, target, method };
|
|
233
251
|
}
|
|
234
252
|
function installArgv(method, target) {
|
|
253
|
+
// brew upgrades to whatever the tap formula publishes; it cannot pin a
|
|
254
|
+
// version, so `target` only tells us an upgrade is worthwhile.
|
|
255
|
+
if (method === "brew")
|
|
256
|
+
return ["upgrade", BREW_FORMULA];
|
|
235
257
|
const spec = `${PACKAGE_NAME}@${target}`;
|
|
236
258
|
return method === "npm" ? ["install", "-g", spec] : ["add", "-g", spec];
|
|
237
259
|
}
|
|
260
|
+
function failureHint(method) {
|
|
261
|
+
if (method === "brew") {
|
|
262
|
+
return `Try \`brew update\` and \`brew reinstall ${BREW_FORMULA}\`, or \`brew doctor\` if that fails too.`;
|
|
263
|
+
}
|
|
264
|
+
// Never suggest sudo: on managed machines the fix is a user-writable
|
|
265
|
+
// prefix, which the installer sets up automatically.
|
|
266
|
+
return ("If it was a permissions error, the installer repairs the global prefix without sudo: " +
|
|
267
|
+
"curl -fsSL https://yagni.app/install.sh | sh");
|
|
268
|
+
}
|
|
238
269
|
function defaultRunInstall(command, args) {
|
|
239
270
|
return new Promise((resolve) => {
|
|
240
271
|
// npm/pnpm/bun are .cmd shims on Windows; a shell is required to run them.
|
|
@@ -256,6 +287,11 @@ export async function upgradeCommand(args, deps) {
|
|
|
256
287
|
}
|
|
257
288
|
const env = deps.env ?? process.env;
|
|
258
289
|
const method = parsed.method ?? detectInstallMethod(deps.binPath ?? process.argv[1] ?? "");
|
|
290
|
+
if (method === "brew" && parsed.target !== undefined) {
|
|
291
|
+
logError("Homebrew installs track the tap formula and cannot pin a version. " +
|
|
292
|
+
`Run \`${DISTRIBUTION.commandName} upgrade\` for the newest release.`);
|
|
293
|
+
return 1;
|
|
294
|
+
}
|
|
259
295
|
const fetchLatest = deps.fetchLatest ?? (() => fetchLatestVersion({ env }));
|
|
260
296
|
const target = parsed.target ?? (await fetchLatest());
|
|
261
297
|
if (!target) {
|
|
@@ -272,13 +308,17 @@ export async function upgradeCommand(args, deps) {
|
|
|
272
308
|
const runInstall = deps.runInstall ?? defaultRunInstall;
|
|
273
309
|
const code = await runInstall(method, installArgv(method, target));
|
|
274
310
|
if (code !== 0) {
|
|
275
|
-
logError(`Upgrade failed (${method} exited ${code}). `
|
|
276
|
-
`If it was a permissions error, fix your ${method} global prefix or retry with elevated permissions.`);
|
|
311
|
+
logError(`Upgrade failed (${method} exited ${code}). ${failureHint(method)}`);
|
|
277
312
|
return 1;
|
|
278
313
|
}
|
|
279
314
|
// Keep the nudge honest: the freshly installed version is the known latest.
|
|
280
315
|
await writeUpdateCache(target).catch(() => undefined);
|
|
281
|
-
|
|
316
|
+
// brew lands on whatever the formula publishes, which can trail the
|
|
317
|
+
// registry briefly, so only the package managers that pin get the
|
|
318
|
+
// version-specific claim.
|
|
319
|
+
log(method === "brew"
|
|
320
|
+
? `${DISTRIBUTION.displayName} upgraded via Homebrew. Run \`${DISTRIBUTION.commandName} version\` to confirm.`
|
|
321
|
+
: `${DISTRIBUTION.displayName} ${target} installed. Run \`${DISTRIBUTION.commandName} version\` to confirm.`);
|
|
282
322
|
return 0;
|
|
283
323
|
}
|
|
284
324
|
//# sourceMappingURL=upgrade.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagni-app/code-staging",
|
|
3
|
-
"version": "1.0.5-staging.
|
|
3
|
+
"version": "1.0.5-staging.1234.1",
|
|
4
4
|
"description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"turndown": "^7.2.4",
|
|
42
42
|
"typebox": "^1.3.15"
|
|
43
43
|
},
|
|
44
|
-
"yagniSourceSha": "
|
|
44
|
+
"yagniSourceSha": "8e2d5ff11858a49f92fc3d4a1e938723d5f9dc91"
|
|
45
45
|
}
|