@indy2kro/agentenv 1.0.1 → 1.1.0
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/adapters/agent-dirs.d.ts +29 -0
- package/dist/adapters/agent-dirs.d.ts.map +1 -0
- package/dist/adapters/agent-dirs.js +46 -0
- package/dist/adapters/agent-dirs.js.map +1 -0
- package/dist/adapters/base.d.ts +7 -1
- package/dist/adapters/base.d.ts.map +1 -1
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +18 -10
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/cline.d.ts.map +1 -1
- package/dist/adapters/cline.js +2 -2
- package/dist/adapters/cline.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +3 -2
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot.d.ts.map +1 -1
- package/dist/adapters/copilot.js +3 -4
- package/dist/adapters/copilot.js.map +1 -1
- package/dist/adapters/cursor.d.ts.map +1 -1
- package/dist/adapters/cursor.js +7 -6
- package/dist/adapters/cursor.js.map +1 -1
- package/dist/adapters/detect.d.ts.map +1 -1
- package/dist/adapters/detect.js +1 -0
- package/dist/adapters/detect.js.map +1 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +2 -2
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/opencode.d.ts.map +1 -1
- package/dist/adapters/opencode.js +2 -2
- package/dist/adapters/opencode.js.map +1 -1
- package/dist/adapters/rtk-delegation.d.ts.map +1 -1
- package/dist/adapters/rtk-delegation.js +16 -1
- package/dist/adapters/rtk-delegation.js.map +1 -1
- package/dist/adapters/vibe.d.ts.map +1 -1
- package/dist/adapters/vibe.js +2 -2
- package/dist/adapters/vibe.js.map +1 -1
- package/dist/adapters/windsurf.d.ts.map +1 -1
- package/dist/adapters/windsurf.js +2 -2
- package/dist/adapters/windsurf.js.map +1 -1
- package/dist/cli/exit.d.ts +17 -6
- package/dist/cli/exit.d.ts.map +1 -1
- package/dist/cli/exit.js +17 -7
- package/dist/cli/exit.js.map +1 -1
- package/dist/commands/apply.d.ts +77 -0
- package/dist/commands/apply.d.ts.map +1 -1
- package/dist/commands/apply.js +202 -27
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/config-edit.d.ts +33 -0
- package/dist/commands/config-edit.d.ts.map +1 -0
- package/dist/commands/config-edit.js +216 -0
- package/dist/commands/config-edit.js.map +1 -0
- package/dist/commands/doctor.d.ts +57 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +233 -59
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/setup.d.ts +4 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +58 -5
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +40 -16
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/uninstall.d.ts +78 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +329 -31
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts +51 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +172 -71
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/wizard.d.ts +27 -1
- package/dist/commands/wizard.d.ts.map +1 -1
- package/dist/commands/wizard.js +48 -31
- package/dist/commands/wizard.js.map +1 -1
- package/dist/config/schema.d.ts +28 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +206 -54
- package/dist/config/schema.js.map +1 -1
- package/dist/config/scopes.d.ts +4 -2
- package/dist/config/scopes.d.ts.map +1 -1
- package/dist/config/scopes.js +23 -4
- package/dist/config/scopes.js.map +1 -1
- package/dist/generate/agentsmd.d.ts +54 -0
- package/dist/generate/agentsmd.d.ts.map +1 -1
- package/dist/generate/agentsmd.js +222 -143
- package/dist/generate/agentsmd.js.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/render.d.ts.map +1 -1
- package/dist/integrations/render.js +25 -10
- package/dist/integrations/render.js.map +1 -1
- package/dist/integrations/superpowers.d.ts.map +1 -1
- package/dist/integrations/superpowers.js +2 -0
- package/dist/integrations/superpowers.js.map +1 -1
- package/dist/shell/detector.d.ts +63 -5
- package/dist/shell/detector.d.ts.map +1 -1
- package/dist/shell/detector.js +253 -65
- package/dist/shell/detector.js.map +1 -1
- package/dist/toolchain/gh.d.ts.map +1 -1
- package/dist/toolchain/gh.js +1 -0
- package/dist/toolchain/gh.js.map +1 -1
- package/dist/toolchain/mise.d.ts +7 -0
- package/dist/toolchain/mise.d.ts.map +1 -1
- package/dist/toolchain/mise.js +20 -3
- package/dist/toolchain/mise.js.map +1 -1
- package/dist/toolchain/rtk.d.ts +71 -3
- package/dist/toolchain/rtk.d.ts.map +1 -1
- package/dist/toolchain/rtk.js +115 -7
- package/dist/toolchain/rtk.js.map +1 -1
- package/dist/ui/output.d.ts.map +1 -1
- package/dist/ui/output.js +10 -2
- package/dist/ui/output.js.map +1 -1
- package/dist/ui/spinner.d.ts +15 -3
- package/dist/ui/spinner.d.ts.map +1 -1
- package/dist/ui/spinner.js +52 -4
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/theme.d.ts +27 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +73 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/utils/fs-retry.d.ts +16 -0
- package/dist/utils/fs-retry.d.ts.map +1 -1
- package/dist/utils/fs-retry.js +28 -0
- package/dist/utils/fs-retry.js.map +1 -1
- package/package.json +6 -5
package/dist/toolchain/rtk.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as child_process from 'child_process';
|
|
7
7
|
import { resolveBinary } from '../adapters/detect.js';
|
|
8
|
+
import { runMiseCaptured } from './mise.js';
|
|
8
9
|
/** rtk init args per agent, verified against real `rtk init` in smoke:real. */
|
|
9
10
|
export const RTK_INIT_FLAGS = {
|
|
10
11
|
claude_code: ['--claude'],
|
|
@@ -21,16 +22,37 @@ export const RTK_INIT_FLAGS = {
|
|
|
21
22
|
cline: ['--agent', 'cline'],
|
|
22
23
|
vibe: ['-g', '--agent', 'vibe'],
|
|
23
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the rtk binary to run: prefer the mise-managed rtk pinned in this
|
|
27
|
+
* scope's mise.toml (`mise which rtk`, run in `cwd`) over a bare PATH lookup.
|
|
28
|
+
* This matters two ways: a bare `where`/`which` can resolve to a
|
|
29
|
+
* stale rtk, or to an unrelated same-named binary earlier on PATH (the
|
|
30
|
+
* "Rust Type Kit" name collision RTK.md warns about); and right after
|
|
31
|
+
* `mise install` puts a new rtk in the mise shims dir, that dir is not
|
|
32
|
+
* necessarily on PATH yet in the current terminal ("needs-new-terminal") even
|
|
33
|
+
* though `mise which`/`mise exec` can already resolve it.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveRtkBinary(cwd, deps = {}) {
|
|
36
|
+
const miseCapture = deps.runMiseCaptured ?? runMiseCaptured;
|
|
37
|
+
const pathLookup = deps.resolveBinary ?? resolveBinary;
|
|
38
|
+
const mise = miseCapture(['which', 'rtk'], { cwd });
|
|
39
|
+
if (mise.status === 0) {
|
|
40
|
+
const resolved = mise.stdout.trim();
|
|
41
|
+
if (resolved)
|
|
42
|
+
return resolved;
|
|
43
|
+
}
|
|
44
|
+
return pathLookup('rtk');
|
|
45
|
+
}
|
|
24
46
|
const defaultRtkInit = (args, cwd) => {
|
|
25
47
|
// Testing escape hatch: point at a stub `rtk` program (run via node) that
|
|
26
48
|
// writes the files a real `rtk init` would, so the full CLI pipeline can be
|
|
27
49
|
// exercised in CI without installing rtk.
|
|
28
50
|
const stub = process.env.AGENTENV_RTK_BIN;
|
|
29
|
-
const rtkPath = stub ? process.execPath :
|
|
51
|
+
const rtkPath = stub ? process.execPath : resolveRtkBinary(cwd);
|
|
30
52
|
if (!stub && !rtkPath) {
|
|
31
53
|
return {
|
|
32
54
|
success: false,
|
|
33
|
-
message: 'rtk binary not found on PATH — is rtk in mise.toml (Tier 1) and did `mise install` run?',
|
|
55
|
+
message: 'rtk binary not found via `mise which rtk` or on PATH — is rtk in mise.toml (Tier 1) and did `mise install` run?',
|
|
34
56
|
stdout: '',
|
|
35
57
|
stderr: '',
|
|
36
58
|
};
|
|
@@ -42,6 +64,7 @@ const defaultRtkInit = (args, cwd) => {
|
|
|
42
64
|
cwd,
|
|
43
65
|
encoding: 'utf-8',
|
|
44
66
|
stdio: 'pipe',
|
|
67
|
+
timeout: 30000,
|
|
45
68
|
});
|
|
46
69
|
const ok = result.status === 0;
|
|
47
70
|
return {
|
|
@@ -66,17 +89,64 @@ const defaultRtkInit = (args, cwd) => {
|
|
|
66
89
|
export function resolveRtkInit(rtkInit) {
|
|
67
90
|
return rtkInit ?? defaultRtkInit;
|
|
68
91
|
}
|
|
92
|
+
/** Parse a leading `X.Y.Z` out of rtk's `--version` output (e.g. "rtk 0.42.4"); null if unparseable. */
|
|
93
|
+
export function parseRtkVersion(version) {
|
|
94
|
+
if (!version)
|
|
95
|
+
return null;
|
|
96
|
+
const match = version.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
97
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
98
|
+
}
|
|
99
|
+
/** -1/0/1, like a standard Array.sort comparator. */
|
|
100
|
+
export function compareRtkVersions(a, b) {
|
|
101
|
+
for (let i = 0; i < 3; i++) {
|
|
102
|
+
if (a[i] !== b[i])
|
|
103
|
+
return a[i] < b[i] ? -1 : 1;
|
|
104
|
+
}
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Minimum rtk version known — and independently verified — to support each
|
|
109
|
+
* agent as an `rtk init --agent <value>`. An agent absent from this map has
|
|
110
|
+
* no confirmed minimum: isRtkAgentSupportedByVersion() then returns null
|
|
111
|
+
* (unknown) instead of guessing a threshold nobody has verified, and callers
|
|
112
|
+
* fall back to attempting the delegation and reading rtk's own rejection
|
|
113
|
+
* (isUnsupportedRtkAgentError's clap-style text match, below).
|
|
114
|
+
*
|
|
115
|
+
* vibe: confirmed NOT supported as of rtk 0.42.4 — `rtk init --agent`'s enum
|
|
116
|
+
* lists claude/cursor/windsurf/cline/kilocode/antigravity/pi/hermes, no
|
|
117
|
+
* "vibe" — checked live against a real rtk binary (2026-09-23). No verified
|
|
118
|
+
* release adds it yet, so it's left out rather than guessing a version.
|
|
119
|
+
*/
|
|
120
|
+
export const RTK_AGENT_MIN_VERSIONS = {};
|
|
121
|
+
/**
|
|
122
|
+
* Whether `agent` is supported by a resolved rtk `version`, per
|
|
123
|
+
* RTK_AGENT_MIN_VERSIONS: true/false when a verified threshold exists and
|
|
124
|
+
* `version` parses, null when either is unknown — callers treat null as
|
|
125
|
+
* "don't know yet, attempt delegation normally" rather than as a denial.
|
|
126
|
+
*/
|
|
127
|
+
export function isRtkAgentSupportedByVersion(agent, version) {
|
|
128
|
+
const minVersion = RTK_AGENT_MIN_VERSIONS[agent];
|
|
129
|
+
if (!minVersion)
|
|
130
|
+
return null;
|
|
131
|
+
const parsed = parseRtkVersion(version);
|
|
132
|
+
if (!parsed)
|
|
133
|
+
return null;
|
|
134
|
+
return compareRtkVersions(parsed, minVersion) >= 0;
|
|
135
|
+
}
|
|
69
136
|
/**
|
|
70
137
|
* True when an `rtk init` failure is rtk's own `--agent` enum rejecting a
|
|
71
138
|
* value agentenv passes it (e.g. the pinned rtk build not yet knowing
|
|
72
139
|
* "vibe"), rather than an environment problem (missing binary, permissions,
|
|
73
|
-
* ...).
|
|
74
|
-
*
|
|
75
|
-
*
|
|
140
|
+
* ...). Recognizes both rtk's clap-style usage error text (keeps working as
|
|
141
|
+
* rtk's supported agent list changes upstream, without agentenv having to
|
|
142
|
+
* hardcode rtk's enum) and the synthetic message RtkDelegationAdapter
|
|
143
|
+
* produces when a version-verified threshold (RTK_AGENT_MIN_VERSIONS) rules
|
|
144
|
+
* an agent out before even attempting delegation.
|
|
76
145
|
*/
|
|
77
146
|
export function isUnsupportedRtkAgentError(errors, agentValue) {
|
|
78
|
-
const
|
|
79
|
-
|
|
147
|
+
const clapPattern = new RegExp(`invalid value ['"]?${agentValue}['"]?`, 'i');
|
|
148
|
+
const versionPattern = new RegExp(`does not yet support ['"]?${agentValue}['"]? as an --agent value`, 'i');
|
|
149
|
+
return errors.some((error) => clapPattern.test(error) || versionPattern.test(error));
|
|
80
150
|
}
|
|
81
151
|
/**
|
|
82
152
|
* Surfaces what rtk actually rewrote as part of the per-agent message, so its
|
|
@@ -95,4 +165,42 @@ export function rtkMessage(run) {
|
|
|
95
165
|
// This is a side effect that users should be aware of
|
|
96
166
|
return message;
|
|
97
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Checks rtk is actually usable: resolvable, reports a version, and responds
|
|
170
|
+
* to `rtk gain` (ruling out the Rust Type Kit name-collision case). Used by
|
|
171
|
+
* `doctor` — everything here is read-only.
|
|
172
|
+
*/
|
|
173
|
+
export function checkRtkInstallation(cwd, deps = {}) {
|
|
174
|
+
const resolve = deps.resolveRtkBinary ?? resolveRtkBinary;
|
|
175
|
+
const spawn = deps.spawnSync ?? child_process.spawnSync;
|
|
176
|
+
const resolvedPath = resolve(cwd);
|
|
177
|
+
if (!resolvedPath) {
|
|
178
|
+
return { resolvedPath: null, version: null, gainOk: null };
|
|
179
|
+
}
|
|
180
|
+
let version = null;
|
|
181
|
+
try {
|
|
182
|
+
const result = spawn(resolvedPath, ['--version'], {
|
|
183
|
+
encoding: 'utf-8',
|
|
184
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
185
|
+
});
|
|
186
|
+
const output = (result.stdout || result.stderr || '').trim();
|
|
187
|
+
if (result.status === 0 && output)
|
|
188
|
+
version = output;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// version stays null
|
|
192
|
+
}
|
|
193
|
+
let gainOk;
|
|
194
|
+
try {
|
|
195
|
+
const result = spawn(resolvedPath, ['gain'], {
|
|
196
|
+
encoding: 'utf-8',
|
|
197
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
198
|
+
});
|
|
199
|
+
gainOk = result.status === 0;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
gainOk = false;
|
|
203
|
+
}
|
|
204
|
+
return { resolvedPath, version, gainOk };
|
|
205
|
+
}
|
|
98
206
|
//# sourceMappingURL=rtk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtk.js","sourceRoot":"","sources":["../../src/toolchain/rtk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"rtk.js","sourceRoot":"","sources":["../../src/toolchain/rtk.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/ui/output.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEtD;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAE7E;AAYD,6EAA6E;AAC7E,eAAO,MAAM,IAAI,QAAwB,CAAC;AAE1C,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/ui/output.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEtD;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAE7E;AAYD,6EAA6E;AAC7E,eAAO,MAAM,IAAI,QAAwB,CAAC;AAE1C,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyCD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAUhE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,EACxB,KAAK,GAAE,OAAuC,EAC9C,SAAS,GAAE,OAAe,GACzB,MAAM,CAER"}
|
package/dist/ui/output.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { theme } from './theme.js';
|
|
1
|
+
import { asciiGlyphsEnabled, theme } from './theme.js';
|
|
2
2
|
let quiet = false;
|
|
3
3
|
/** Global quiet state, wired to `-q/--quiet` in index.ts. */
|
|
4
4
|
export function setQuietEnabled(enabled) {
|
|
@@ -33,6 +33,14 @@ const RESULT_GLYPHS = {
|
|
|
33
33
|
warn: '⚠️',
|
|
34
34
|
fail: '❌',
|
|
35
35
|
};
|
|
36
|
+
const RESULT_GLYPHS_ASCII = {
|
|
37
|
+
ok: '[ok]',
|
|
38
|
+
warn: '[warn]',
|
|
39
|
+
fail: '[FAIL]',
|
|
40
|
+
};
|
|
41
|
+
function resultGlyph(severity) {
|
|
42
|
+
return asciiGlyphsEnabled() ? RESULT_GLYPHS_ASCII[severity] : RESULT_GLYPHS[severity];
|
|
43
|
+
}
|
|
36
44
|
function severityColor(text, severity) {
|
|
37
45
|
if (severity === 'ok')
|
|
38
46
|
return theme.ok(text);
|
|
@@ -80,7 +88,7 @@ export function displayWidth(text) {
|
|
|
80
88
|
* and words survive `--no-color`, so the outcome is never color-only.
|
|
81
89
|
*/
|
|
82
90
|
export function formatResultBox(result) {
|
|
83
|
-
const bodyLines = [`${
|
|
91
|
+
const bodyLines = [`${resultGlyph(result.severity)} ${result.headline}`];
|
|
84
92
|
if (result.summary !== undefined)
|
|
85
93
|
bodyLines.push(result.summary);
|
|
86
94
|
const widths = bodyLines.map(displayWidth);
|
package/dist/ui/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/ui/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/ui/output.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/spinner.d.ts
CHANGED
|
@@ -14,12 +14,24 @@ export interface Spinner {
|
|
|
14
14
|
stop(): Spinner;
|
|
15
15
|
}
|
|
16
16
|
export type SpinnerFactory = (text: string) => Spinner;
|
|
17
|
+
/** Force the animated spinner on/off; pass undefined to restore auto-detection. Wired to --no-spinner. */
|
|
18
|
+
export declare function setSpinnerEnabled(enabled: boolean | undefined): void;
|
|
19
|
+
/**
|
|
20
|
+
* Whether to animate: off under TERM=dumb or CI (most CI systems set
|
|
21
|
+
* CI=true; the animation floods a non-interactive log with redraw frames),
|
|
22
|
+
* unless --no-spinner/setSpinnerEnabled() overrides either way.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isSpinnerEnabled(): boolean;
|
|
17
25
|
/**
|
|
18
26
|
* Run fn() under a spinner labeled `label`, resolving succeed/fail from the
|
|
19
27
|
* result's `success` field. `-q/--quiet` swaps in a no-op spinner so quiet
|
|
20
|
-
* output is actually silent even on a TTY
|
|
21
|
-
*
|
|
22
|
-
*
|
|
28
|
+
* output is actually silent even on a TTY; `--no-spinner`/TERM=dumb/CI swap
|
|
29
|
+
* the *real* (ora) spinner for a static, non-animated one that still prints
|
|
30
|
+
* the label and succeed/fail lines — an explicitly injected `spinnerFactory`
|
|
31
|
+
* (as every test passes) is never second-guessed by that auto-detection,
|
|
32
|
+
* since a test double has no animation to disable in the first place. `fn`
|
|
33
|
+
* receives the spinner itself so a long inner step can `stop()` it before
|
|
34
|
+
* printing raw output and `start()` it again afterwards.
|
|
23
35
|
*/
|
|
24
36
|
export declare function withSpinner<T extends {
|
|
25
37
|
success: boolean;
|
package/dist/ui/spinner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,OAAO;IACtB,KAAK,IAAI,OAAO,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,kNAAkN;IAClN,IAAI,IAAI,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAiCvD,0GAA0G;AAC1G,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAG1C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EAC9D,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,EACpC,cAAc,GAAE,cAAsC,GACrD,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
|
package/dist/ui/spinner.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import ora from 'ora';
|
|
10
10
|
import { isQuiet } from './output.js';
|
|
11
|
+
import { colorizeLine, failGlyph, successGlyph } from './theme.js';
|
|
11
12
|
const defaultSpinnerFactory = (text) => ora(text);
|
|
12
13
|
const quietSpinner = {
|
|
13
14
|
start: () => quietSpinner,
|
|
@@ -15,15 +16,62 @@ const quietSpinner = {
|
|
|
15
16
|
fail: () => quietSpinner,
|
|
16
17
|
stop: () => quietSpinner,
|
|
17
18
|
};
|
|
19
|
+
/** A non-animated stand-in: prints the label once, then a plain succeed/fail line — no redrawing. */
|
|
20
|
+
function staticSpinner(label) {
|
|
21
|
+
const spinner = {
|
|
22
|
+
start: () => {
|
|
23
|
+
console.log(label);
|
|
24
|
+
return spinner;
|
|
25
|
+
},
|
|
26
|
+
succeed: (text) => {
|
|
27
|
+
console.log(colorizeLine(`${successGlyph()} ${text ?? label}`));
|
|
28
|
+
return spinner;
|
|
29
|
+
},
|
|
30
|
+
fail: (text) => {
|
|
31
|
+
console.log(colorizeLine(`${failGlyph()} ${text ?? label}`));
|
|
32
|
+
return spinner;
|
|
33
|
+
},
|
|
34
|
+
stop: () => spinner,
|
|
35
|
+
};
|
|
36
|
+
return spinner;
|
|
37
|
+
}
|
|
38
|
+
let spinnerOverride;
|
|
39
|
+
/** Force the animated spinner on/off; pass undefined to restore auto-detection. Wired to --no-spinner. */
|
|
40
|
+
export function setSpinnerEnabled(enabled) {
|
|
41
|
+
spinnerOverride = enabled;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether to animate: off under TERM=dumb or CI (most CI systems set
|
|
45
|
+
* CI=true; the animation floods a non-interactive log with redraw frames),
|
|
46
|
+
* unless --no-spinner/setSpinnerEnabled() overrides either way.
|
|
47
|
+
*/
|
|
48
|
+
export function isSpinnerEnabled() {
|
|
49
|
+
if (spinnerOverride !== undefined)
|
|
50
|
+
return spinnerOverride;
|
|
51
|
+
return process.env.TERM !== 'dumb' && !process.env.CI;
|
|
52
|
+
}
|
|
18
53
|
/**
|
|
19
54
|
* Run fn() under a spinner labeled `label`, resolving succeed/fail from the
|
|
20
55
|
* result's `success` field. `-q/--quiet` swaps in a no-op spinner so quiet
|
|
21
|
-
* output is actually silent even on a TTY
|
|
22
|
-
*
|
|
23
|
-
*
|
|
56
|
+
* output is actually silent even on a TTY; `--no-spinner`/TERM=dumb/CI swap
|
|
57
|
+
* the *real* (ora) spinner for a static, non-animated one that still prints
|
|
58
|
+
* the label and succeed/fail lines — an explicitly injected `spinnerFactory`
|
|
59
|
+
* (as every test passes) is never second-guessed by that auto-detection,
|
|
60
|
+
* since a test double has no animation to disable in the first place. `fn`
|
|
61
|
+
* receives the spinner itself so a long inner step can `stop()` it before
|
|
62
|
+
* printing raw output and `start()` it again afterwards.
|
|
24
63
|
*/
|
|
25
64
|
export async function withSpinner(label, fn, spinnerFactory = defaultSpinnerFactory) {
|
|
26
|
-
|
|
65
|
+
let factory;
|
|
66
|
+
if (isQuiet()) {
|
|
67
|
+
factory = () => quietSpinner;
|
|
68
|
+
}
|
|
69
|
+
else if (spinnerFactory === defaultSpinnerFactory && !isSpinnerEnabled()) {
|
|
70
|
+
factory = staticSpinner;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
factory = spinnerFactory;
|
|
74
|
+
}
|
|
27
75
|
const spinner = factory(label).start();
|
|
28
76
|
try {
|
|
29
77
|
const result = await fn(spinner);
|
package/dist/ui/spinner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAYnE,MAAM,qBAAqB,GAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAuB,CAAC;AAExF,MAAM,YAAY,GAAY;IAC5B,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY;IACzB,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY;IAC3B,IAAI,EAAE,GAAG,EAAE,CAAC,YAAY;IACxB,IAAI,EAAE,GAAG,EAAE,CAAC,YAAY;CACzB,CAAC;AAEF,qGAAqG;AACrG,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,GAAG,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,YAAY,EAAE,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;YAChE,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACb,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;YAC7D,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO;KACpB,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,IAAI,eAAoC,CAAC;AAEzC,0GAA0G;AAC1G,MAAM,UAAU,iBAAiB,CAAC,OAA4B;IAC5D,eAAe,GAAG,OAAO,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,EAAoC,EACpC,iBAAiC,qBAAqB;IAEtD,IAAI,OAAuB,CAAC;IAC5B,IAAI,OAAO,EAAE,EAAE,CAAC;QACd,OAAO,GAAG,GAAY,EAAE,CAAC,YAAY,CAAC;IACxC,CAAC;SAAM,IAAI,cAAc,KAAK,qBAAqB,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAC3E,OAAO,GAAG,aAAa,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,cAAc,CAAC;IAC3B,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;;YACtC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/ui/theme.d.ts
CHANGED
|
@@ -12,11 +12,37 @@ export declare const theme: {
|
|
|
12
12
|
fail: (text: string) => string;
|
|
13
13
|
warn: (text: string) => string;
|
|
14
14
|
};
|
|
15
|
+
export interface AsciiDetectionEnv {
|
|
16
|
+
/** Overrides process.env.AGENTENV_ASCII ("1"/"true" forces ASCII, "0"/"false" forces Unicode). */
|
|
17
|
+
forceAscii?: string;
|
|
18
|
+
term?: string;
|
|
19
|
+
platform?: NodeJS.Platform;
|
|
20
|
+
getWindowsCodePage?: () => number | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* True when the console likely can't render ✓/✗/✅/⚠️/❌ reliably: an explicit
|
|
24
|
+
* AGENTENV_ASCII override, TERM=dumb, or (on Windows) an active code page
|
|
25
|
+
* other than 65001 (UTF-8) — legacy `conhost` defaults to the OS locale's
|
|
26
|
+
* code page (437 on a US system), which renders these as mojibake.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useAsciiGlyphs(env?: AsciiDetectionEnv): boolean;
|
|
29
|
+
/** useAsciiGlyphs() for the real process environment, probed once per process and cached. */
|
|
30
|
+
export declare function asciiGlyphsEnabled(): boolean;
|
|
31
|
+
/** Test-only: clear the cached ascii-mode detection so a new environment can be probed. */
|
|
32
|
+
export declare function resetAsciiGlyphsCache(): void;
|
|
33
|
+
/** The glyph agentenv prints for a passing/configured check. */
|
|
34
|
+
export declare function successGlyph(): string;
|
|
35
|
+
/** The glyph agentenv prints for a failing/missing check. */
|
|
36
|
+
export declare function failGlyph(): string;
|
|
37
|
+
/** The glyph agentenv prints for a tool/agent this platform doesn't support. */
|
|
38
|
+
export declare function unsupportedGlyph(): string;
|
|
39
|
+
export declare const DRIFT_GLYPH = "!";
|
|
15
40
|
/**
|
|
16
41
|
* Colorize a pre-formatted message line by its leading status glyph (or a
|
|
17
42
|
* "warning:" substring), so command output built elsewhere in the pipeline
|
|
18
43
|
* (mise, adapters, integrations) gets consistent coloring without every
|
|
19
|
-
* producer needing to know about chalk.
|
|
44
|
+
* producer needing to know about chalk. Recognizes both the Unicode and
|
|
45
|
+
* ASCII-fallback glyph forms, regardless of which mode produced the line.
|
|
20
46
|
*/
|
|
21
47
|
export declare function colorizeLine(line: string): string;
|
|
22
48
|
//# sourceMappingURL=theme.d.ts.map
|
package/dist/ui/theme.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEtD;AAED,eAAO,MAAM,KAAK;oBACA,MAAM;iBACT,MAAM;gBACP,MAAM;eACP,MAAM;iBACJ,MAAM;iBACN,MAAM;CACpB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CAC/C;AAiBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,iBAAsB,GAAG,OAAO,CAanE;AAID,6FAA6F;AAC7F,wBAAgB,kBAAkB,IAAI,OAAO,CAG5C;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,gEAAgE;AAChE,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,6DAA6D;AAC7D,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAGD,eAAO,MAAM,WAAW,MAAM,CAAC;AAK/B;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBjD"}
|
package/dist/ui/theme.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* is the only override this CLI needs (wired to --no-color in index.ts).
|
|
5
5
|
*/
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
+
import { execFileSync } from 'child_process';
|
|
7
8
|
export function setColorEnabled(enabled) {
|
|
8
9
|
if (!enabled)
|
|
9
10
|
chalk.level = 0;
|
|
@@ -16,27 +17,91 @@ export const theme = {
|
|
|
16
17
|
fail: (text) => chalk.red(text),
|
|
17
18
|
warn: (text) => chalk.yellow(text),
|
|
18
19
|
};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
20
|
+
/** The active Windows console code page (e.g. 437, 65001), or undefined if `chcp` can't be read. */
|
|
21
|
+
function detectWindowsCodePage() {
|
|
22
|
+
try {
|
|
23
|
+
const output = execFileSync('chcp.com', [], {
|
|
24
|
+
encoding: 'utf8',
|
|
25
|
+
timeout: 1000,
|
|
26
|
+
windowsHide: true,
|
|
27
|
+
});
|
|
28
|
+
const match = /(\d+)/.exec(output);
|
|
29
|
+
return match ? Number(match[1]) : undefined;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* True when the console likely can't render ✓/✗/✅/⚠️/❌ reliably: an explicit
|
|
37
|
+
* AGENTENV_ASCII override, TERM=dumb, or (on Windows) an active code page
|
|
38
|
+
* other than 65001 (UTF-8) — legacy `conhost` defaults to the OS locale's
|
|
39
|
+
* code page (437 on a US system), which renders these as mojibake.
|
|
40
|
+
*/
|
|
41
|
+
export function useAsciiGlyphs(env = {}) {
|
|
42
|
+
const forceAscii = env.forceAscii ?? process.env.AGENTENV_ASCII;
|
|
43
|
+
if (forceAscii === '1' || forceAscii === 'true')
|
|
44
|
+
return true;
|
|
45
|
+
if (forceAscii === '0' || forceAscii === 'false')
|
|
46
|
+
return false;
|
|
47
|
+
if ((env.term ?? process.env.TERM) === 'dumb')
|
|
48
|
+
return true;
|
|
49
|
+
if ((env.platform ?? process.platform) === 'win32') {
|
|
50
|
+
const codePage = (env.getWindowsCodePage ?? detectWindowsCodePage)();
|
|
51
|
+
if (codePage !== undefined && codePage !== 65001)
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
let cachedAsciiGlyphs;
|
|
57
|
+
/** useAsciiGlyphs() for the real process environment, probed once per process and cached. */
|
|
58
|
+
export function asciiGlyphsEnabled() {
|
|
59
|
+
if (cachedAsciiGlyphs === undefined)
|
|
60
|
+
cachedAsciiGlyphs = useAsciiGlyphs();
|
|
61
|
+
return cachedAsciiGlyphs;
|
|
62
|
+
}
|
|
63
|
+
/** Test-only: clear the cached ascii-mode detection so a new environment can be probed. */
|
|
64
|
+
export function resetAsciiGlyphsCache() {
|
|
65
|
+
cachedAsciiGlyphs = undefined;
|
|
66
|
+
}
|
|
67
|
+
/** The glyph agentenv prints for a passing/configured check. */
|
|
68
|
+
export function successGlyph() {
|
|
69
|
+
return asciiGlyphsEnabled() ? '[ok]' : '✓';
|
|
70
|
+
}
|
|
71
|
+
/** The glyph agentenv prints for a failing/missing check. */
|
|
72
|
+
export function failGlyph() {
|
|
73
|
+
return asciiGlyphsEnabled() ? '[FAIL]' : '✗';
|
|
74
|
+
}
|
|
75
|
+
/** The glyph agentenv prints for a tool/agent this platform doesn't support. */
|
|
76
|
+
export function unsupportedGlyph() {
|
|
77
|
+
return asciiGlyphsEnabled() ? '[-]' : '·';
|
|
78
|
+
}
|
|
79
|
+
// Already ASCII-safe; kept as a named export so callers don't hardcode '!'.
|
|
80
|
+
export const DRIFT_GLYPH = '!';
|
|
81
|
+
const UNICODE_GLYPHS = { success: '✓', fail: '✗', unsupported: '·' };
|
|
82
|
+
const ASCII_GLYPHS = { success: '[ok]', fail: '[FAIL]', unsupported: '[-]' };
|
|
23
83
|
/**
|
|
24
84
|
* Colorize a pre-formatted message line by its leading status glyph (or a
|
|
25
85
|
* "warning:" substring), so command output built elsewhere in the pipeline
|
|
26
86
|
* (mise, adapters, integrations) gets consistent coloring without every
|
|
27
|
-
* producer needing to know about chalk.
|
|
87
|
+
* producer needing to know about chalk. Recognizes both the Unicode and
|
|
88
|
+
* ASCII-fallback glyph forms, regardless of which mode produced the line.
|
|
28
89
|
*/
|
|
29
90
|
export function colorizeLine(line) {
|
|
30
91
|
const trimmed = line.trimStart();
|
|
31
|
-
if (trimmed.startsWith(
|
|
92
|
+
if (trimmed.startsWith(UNICODE_GLYPHS.success) || trimmed.startsWith(ASCII_GLYPHS.success)) {
|
|
32
93
|
return theme.ok(line);
|
|
33
|
-
|
|
94
|
+
}
|
|
95
|
+
if (trimmed.startsWith(UNICODE_GLYPHS.fail) || trimmed.startsWith(ASCII_GLYPHS.fail)) {
|
|
34
96
|
return theme.fail(line);
|
|
97
|
+
}
|
|
35
98
|
if (trimmed.startsWith(DRIFT_GLYPH) || line.toLowerCase().includes('warning:')) {
|
|
36
99
|
return theme.warn(line);
|
|
37
100
|
}
|
|
38
|
-
if (trimmed.startsWith(
|
|
101
|
+
if (trimmed.startsWith(UNICODE_GLYPHS.unsupported) ||
|
|
102
|
+
trimmed.startsWith(ASCII_GLYPHS.unsupported)) {
|
|
39
103
|
return theme.dim(line);
|
|
104
|
+
}
|
|
40
105
|
return line;
|
|
41
106
|
}
|
|
42
107
|
//# sourceMappingURL=theme.js.map
|
package/dist/ui/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/fs-retry.d.ts
CHANGED
|
@@ -33,6 +33,22 @@ export declare function isRetryableWriteError(err: unknown): boolean;
|
|
|
33
33
|
* (EBUSY/EPERM). Throws when the write ultimately cannot succeed.
|
|
34
34
|
*/
|
|
35
35
|
export declare function writeFileWithRetry(filePath: string, content: string, opts?: WriteRetryOptions, fsImpl?: RetryFs): void;
|
|
36
|
+
/**
|
|
37
|
+
* Back up `filePath`'s current content to `<filePath>.agentenv-backup` the
|
|
38
|
+
* first time agentenv is about to modify a file it did not create — a
|
|
39
|
+
* user-global file like ~/.claude/settings.json or a pre-existing user-scope
|
|
40
|
+
* CLAUDE.md/AGENTS.md. Tier 0's shell-fix writes to these same kinds of
|
|
41
|
+
* files already have an undo path (shell-fix-state.json); the adapters'
|
|
42
|
+
* writes did not.
|
|
43
|
+
*
|
|
44
|
+
* Never overwrites an existing backup — once one exists it holds the user's
|
|
45
|
+
* true pre-agentenv content, and a later call (a second `apply`) must not
|
|
46
|
+
* clobber it with agentenv's own already-modified content. A no-op when
|
|
47
|
+
* `filePath` doesn't exist yet (nothing to back up: this is a fresh file
|
|
48
|
+
* agentenv is creating, not modifying). Backing up is advisory: a failure
|
|
49
|
+
* here (e.g. a locked filesystem) must never block the real write.
|
|
50
|
+
*/
|
|
51
|
+
export declare function backupBeforeFirstEdit(filePath: string): void;
|
|
36
52
|
export interface WriteVerifyResult {
|
|
37
53
|
success: boolean;
|
|
38
54
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-retry.d.ts","sourceRoot":"","sources":["../../src/utils/fs-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,cAAc,EAAE,OAS5B,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAKD,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK3D;AAOD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,EAC5B,MAAM,GAAE,OAAwB,GAC/B,IAAI,CAcN;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,EAC5B,MAAM,GAAE,OAAwB,GAC/B,iBAAiB,CAwBnB"}
|
|
1
|
+
{"version":3,"file":"fs-retry.d.ts","sourceRoot":"","sources":["../../src/utils/fs-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,cAAc,EAAE,OAS5B,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAKD,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK3D;AAOD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,EAC5B,MAAM,GAAE,OAAwB,GAC/B,IAAI,CAcN;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAS5D;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,EAC5B,MAAM,GAAE,OAAwB,GAC/B,iBAAiB,CAwBnB"}
|
package/dist/utils/fs-retry.js
CHANGED
|
@@ -61,6 +61,34 @@ export function writeFileWithRetry(filePath, content, opts = {}, fsImpl = defaul
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Back up `filePath`'s current content to `<filePath>.agentenv-backup` the
|
|
66
|
+
* first time agentenv is about to modify a file it did not create — a
|
|
67
|
+
* user-global file like ~/.claude/settings.json or a pre-existing user-scope
|
|
68
|
+
* CLAUDE.md/AGENTS.md. Tier 0's shell-fix writes to these same kinds of
|
|
69
|
+
* files already have an undo path (shell-fix-state.json); the adapters'
|
|
70
|
+
* writes did not.
|
|
71
|
+
*
|
|
72
|
+
* Never overwrites an existing backup — once one exists it holds the user's
|
|
73
|
+
* true pre-agentenv content, and a later call (a second `apply`) must not
|
|
74
|
+
* clobber it with agentenv's own already-modified content. A no-op when
|
|
75
|
+
* `filePath` doesn't exist yet (nothing to back up: this is a fresh file
|
|
76
|
+
* agentenv is creating, not modifying). Backing up is advisory: a failure
|
|
77
|
+
* here (e.g. a locked filesystem) must never block the real write.
|
|
78
|
+
*/
|
|
79
|
+
export function backupBeforeFirstEdit(filePath) {
|
|
80
|
+
try {
|
|
81
|
+
if (!fs.existsSync(filePath))
|
|
82
|
+
return;
|
|
83
|
+
const backupPath = `${filePath}.agentenv-backup`;
|
|
84
|
+
if (fs.existsSync(backupPath))
|
|
85
|
+
return;
|
|
86
|
+
fs.copyFileSync(filePath, backupPath);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Advisory only — never block the real write on a failed backup.
|
|
90
|
+
}
|
|
91
|
+
}
|
|
64
92
|
/**
|
|
65
93
|
* Write `content` and confirm it persisted: the file must exist after the
|
|
66
94
|
* write, and, for non-empty content, be non-empty. Any mismatch is reported as
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-retry.js","sourceRoot":"","sources":["../../src/utils/fs-retry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fs-retry.js","sourceRoot":"","sources":["../../src/utils/fs-retry.ts"],"names":[],"mappings":"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"}
|