@duetso/agent 0.1.33 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/package.json +1 -1
- package/dist/src/cli/env.d.ts +18 -0
- package/dist/src/cli/env.d.ts.map +1 -0
- package/dist/src/cli/env.js +114 -0
- package/dist/src/cli/env.js.map +1 -0
- package/dist/src/cli/help.d.ts +8 -0
- package/dist/src/cli/help.d.ts.map +1 -0
- package/dist/src/cli/help.js +175 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/login.d.ts +13 -0
- package/dist/src/cli/login.d.ts.map +1 -0
- package/dist/src/cli/login.js +61 -0
- package/dist/src/cli/login.js.map +1 -0
- package/dist/src/cli/memories-db.d.ts +24 -0
- package/dist/src/cli/memories-db.d.ts.map +1 -0
- package/dist/src/cli/memories-db.js +74 -0
- package/dist/src/cli/memories-db.js.map +1 -0
- package/dist/src/cli/memories-tui.d.ts +11 -0
- package/dist/src/cli/memories-tui.d.ts.map +1 -0
- package/dist/src/cli/memories-tui.js +266 -0
- package/dist/src/cli/memories-tui.js.map +1 -0
- package/dist/src/cli/memories.d.ts +9 -0
- package/dist/src/cli/memories.d.ts.map +1 -0
- package/dist/src/cli/memories.js +38 -0
- package/dist/src/cli/memories.js.map +1 -0
- package/dist/src/cli/package-manager.d.ts +38 -0
- package/dist/src/cli/package-manager.d.ts.map +1 -0
- package/dist/src/cli/package-manager.js +78 -0
- package/dist/src/cli/package-manager.js.map +1 -0
- package/dist/src/cli/resume-hint.d.ts +22 -0
- package/dist/src/cli/resume-hint.d.ts.map +1 -0
- package/dist/src/cli/resume-hint.js +61 -0
- package/dist/src/cli/resume-hint.js.map +1 -0
- package/dist/src/cli/run.d.ts +43 -0
- package/dist/src/cli/run.d.ts.map +1 -0
- package/dist/src/cli/run.js +273 -0
- package/dist/src/cli/run.js.map +1 -0
- package/dist/src/cli/shared.d.ts +55 -0
- package/dist/src/cli/shared.d.ts.map +1 -0
- package/dist/src/cli/shared.js +125 -0
- package/dist/src/cli/shared.js.map +1 -0
- package/dist/src/cli/skills.d.ts +10 -0
- package/dist/src/cli/skills.d.ts.map +1 -0
- package/dist/src/cli/skills.js +42 -0
- package/dist/src/cli/skills.js.map +1 -0
- package/dist/src/cli/upgrade.d.ts +9 -0
- package/dist/src/cli/upgrade.d.ts.map +1 -0
- package/dist/src/cli/upgrade.js +52 -0
- package/dist/src/cli/upgrade.js.map +1 -0
- package/dist/src/cli/version-check.d.ts +22 -0
- package/dist/src/cli/version-check.d.ts.map +1 -0
- package/dist/src/cli/version-check.js +78 -0
- package/dist/src/cli/version-check.js.map +1 -0
- package/dist/src/cli.d.ts +20 -63
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +38 -887
- package/dist/src/cli.js.map +1 -1
- package/dist/src/memory/observational-prompts.d.ts.map +1 -1
- package/dist/src/memory/observational-prompts.js +11 -7
- package/dist/src/memory/observational-prompts.js.map +1 -1
- package/dist/src/tui/app.d.ts +7 -47
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +279 -396
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/autocomplete.d.ts +91 -0
- package/dist/src/tui/autocomplete.d.ts.map +1 -0
- package/dist/src/tui/autocomplete.js +177 -0
- package/dist/src/tui/autocomplete.js.map +1 -0
- package/dist/src/tui/file-index.d.ts +11 -0
- package/dist/src/tui/file-index.d.ts.map +1 -0
- package/dist/src/tui/file-index.js +75 -0
- package/dist/src/tui/file-index.js.map +1 -0
- package/dist/src/tui/history.d.ts +50 -0
- package/dist/src/tui/history.d.ts.map +1 -0
- package/dist/src/tui/history.js +132 -0
- package/dist/src/tui/history.js.map +1 -0
- package/dist/src/tui/sidebar.d.ts +20 -0
- package/dist/src/tui/sidebar.d.ts.map +1 -0
- package/dist/src/tui/sidebar.js +118 -0
- package/dist/src/tui/sidebar.js.map +1 -0
- package/dist/src/tui/theme.d.ts +15 -0
- package/dist/src/tui/theme.d.ts.map +1 -0
- package/dist/src/tui/theme.js +18 -0
- package/dist/src/tui/theme.js.map +1 -0
- package/dist/src/turn-runner/prompts.d.ts.map +1 -1
- package/dist/src/turn-runner/prompts.js +7 -0
- package/dist/src/turn-runner/prompts.js.map +1 -1
- package/dist/src/turn-runner/tools.d.ts +15 -1
- package/dist/src/turn-runner/tools.d.ts.map +1 -1
- package/dist/src/turn-runner/tools.js +42 -9
- package/dist/src/turn-runner/tools.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { shimDuetApiKeyToAiGateway } from "../model-resolution/duet-gateway.js";
|
|
3
|
+
import { maybeAutoSyncDefaultSkills } from "../lib/sync-skills.js";
|
|
4
|
+
import { describeModelResolution, resolveCliMemoryModel, resolveCliModel, } from "../model-resolution/resolver.js";
|
|
5
|
+
import { SessionManager } from "../session/session-manager.js";
|
|
6
|
+
import { runTui } from "../tui/app.js";
|
|
7
|
+
import { DEFAULT_RESUME_HISTORY_LINES, printRunHelp } from "./help.js";
|
|
8
|
+
import { resumeCommand } from "./resume-hint.js";
|
|
9
|
+
import { fail, isInteractive, loadCliEnvFiles, parseResumeHistoryLines } from "./shared.js";
|
|
10
|
+
import { getNewVersionNotice } from "./version-check.js";
|
|
11
|
+
/**
|
|
12
|
+
* Decide whether to render the interactive TUI vs JSONL events.
|
|
13
|
+
*
|
|
14
|
+
* Supplying a prompt argument selects JSONL so one-shot runs have a stable
|
|
15
|
+
* machine-readable contract by default; an explicit `--json` always wins.
|
|
16
|
+
*/
|
|
17
|
+
export function shouldUseTui(input) {
|
|
18
|
+
return input.interactive && !input.jsonOutput && !input.prompt;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the {@link TurnRunnerConfig} the CLI hands to the SessionManager,
|
|
22
|
+
* along with the resolutions used to render model provenance lines.
|
|
23
|
+
*/
|
|
24
|
+
export function buildCliTurnConfig(input, dotenvKeys) {
|
|
25
|
+
const modelResolution = resolveCliModel(input.modelName, dotenvKeys);
|
|
26
|
+
const memoryModelResolution = resolveCliMemoryModel(input.memoryModelName, dotenvKeys);
|
|
27
|
+
return {
|
|
28
|
+
config: {
|
|
29
|
+
model: modelResolution.modelName,
|
|
30
|
+
memoryModel: memoryModelResolution.modelName,
|
|
31
|
+
...(input.disableDurableMemory ? { memoryDbPath: false } : {}),
|
|
32
|
+
cwd: input.workDir,
|
|
33
|
+
...(input.systemInstructions ? { systemInstructions: input.systemInstructions } : {}),
|
|
34
|
+
...(input.systemPromptFiles ? { systemPromptFiles: input.systemPromptFiles } : {}),
|
|
35
|
+
},
|
|
36
|
+
modelResolution,
|
|
37
|
+
memoryModelResolution,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Default `duet` invocation: parse flags, load env files, build the config,
|
|
42
|
+
* decide TUI vs JSON output, then drive the SessionManager through one
|
|
43
|
+
* session. Prints a resume hint at the end whether the session terminated
|
|
44
|
+
* cleanly or not.
|
|
45
|
+
*/
|
|
46
|
+
export async function runRunCommand(args, pkg) {
|
|
47
|
+
let modelName;
|
|
48
|
+
let memoryModelName;
|
|
49
|
+
let workDir = process.cwd();
|
|
50
|
+
let resumeSessionId;
|
|
51
|
+
let systemInstructions;
|
|
52
|
+
let systemPromptFiles;
|
|
53
|
+
let resumeHistoryLines = DEFAULT_RESUME_HISTORY_LINES;
|
|
54
|
+
let resumeHistoryLinesExplicit = false;
|
|
55
|
+
let jsonOutput = false;
|
|
56
|
+
let envFilePath;
|
|
57
|
+
let disableDurableMemory = false;
|
|
58
|
+
const promptParts = [];
|
|
59
|
+
const interactive = isInteractive();
|
|
60
|
+
for (let i = 0; i < args.length; i++) {
|
|
61
|
+
switch (args[i]) {
|
|
62
|
+
case "--model":
|
|
63
|
+
case "-m":
|
|
64
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
65
|
+
fail(`Missing value for ${args[i]}`);
|
|
66
|
+
modelName = args[++i];
|
|
67
|
+
break;
|
|
68
|
+
case "--memory-model":
|
|
69
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
70
|
+
fail(`Missing value for ${args[i]}`);
|
|
71
|
+
memoryModelName = args[++i];
|
|
72
|
+
break;
|
|
73
|
+
case "--no-memory":
|
|
74
|
+
disableDurableMemory = true;
|
|
75
|
+
break;
|
|
76
|
+
case "--workdir":
|
|
77
|
+
case "-w":
|
|
78
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
79
|
+
fail(`Missing value for ${args[i]}`);
|
|
80
|
+
workDir = args[++i];
|
|
81
|
+
break;
|
|
82
|
+
case "--resume":
|
|
83
|
+
case "-r":
|
|
84
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
85
|
+
fail(`Missing value for ${args[i]}`);
|
|
86
|
+
resumeSessionId = args[++i];
|
|
87
|
+
break;
|
|
88
|
+
case "--resume-history-lines":
|
|
89
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
90
|
+
fail(`Missing value for ${args[i]}`);
|
|
91
|
+
try {
|
|
92
|
+
resumeHistoryLines = parseResumeHistoryLines(args[++i], args[i - 1]);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
96
|
+
}
|
|
97
|
+
resumeHistoryLinesExplicit = true;
|
|
98
|
+
break;
|
|
99
|
+
case "--system-prompt":
|
|
100
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
101
|
+
fail(`Missing value for ${args[i]}`);
|
|
102
|
+
systemInstructions = args[++i];
|
|
103
|
+
break;
|
|
104
|
+
case "--system-prompt-file":
|
|
105
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
106
|
+
fail(`Missing value for ${args[i]}`);
|
|
107
|
+
systemPromptFiles = [...(systemPromptFiles ?? []), args[++i]];
|
|
108
|
+
break;
|
|
109
|
+
case "--no-system-prompt-files":
|
|
110
|
+
systemPromptFiles = [];
|
|
111
|
+
break;
|
|
112
|
+
case "--json":
|
|
113
|
+
jsonOutput = true;
|
|
114
|
+
break;
|
|
115
|
+
case "--env-file":
|
|
116
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
117
|
+
fail(`Missing value for ${args[i]}`);
|
|
118
|
+
envFilePath = args[++i];
|
|
119
|
+
break;
|
|
120
|
+
case "--version":
|
|
121
|
+
case "-v":
|
|
122
|
+
console.log(pkg.version);
|
|
123
|
+
process.exit(0);
|
|
124
|
+
// eslint-disable-next-line no-fallthrough
|
|
125
|
+
case "--help":
|
|
126
|
+
case "-h":
|
|
127
|
+
printRunHelp(pkg.name);
|
|
128
|
+
process.exit(0);
|
|
129
|
+
// eslint-disable-next-line no-fallthrough
|
|
130
|
+
default:
|
|
131
|
+
if (args[i]?.startsWith("-")) {
|
|
132
|
+
fail(`Unknown option: ${args[i]}`);
|
|
133
|
+
}
|
|
134
|
+
promptParts.push(args[i]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let prompt = promptParts.join(" ");
|
|
138
|
+
// Read from stdin if no prompt is provided
|
|
139
|
+
if (!prompt && !interactive) {
|
|
140
|
+
const chunks = [];
|
|
141
|
+
for await (const chunk of process.stdin) {
|
|
142
|
+
chunks.push(chunk);
|
|
143
|
+
}
|
|
144
|
+
prompt = Buffer.concat(chunks).toString("utf-8").trim();
|
|
145
|
+
}
|
|
146
|
+
if (!prompt && jsonOutput && interactive) {
|
|
147
|
+
prompt = await readInteractivePrompt();
|
|
148
|
+
}
|
|
149
|
+
if (!prompt && !resumeSessionId && !interactive) {
|
|
150
|
+
console.error("Usage: duet <prompt>");
|
|
151
|
+
console.error(' e.g., duet "build a todo app"');
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
const dotenvKeys = loadCliEnvFiles(workDir, envFilePath);
|
|
155
|
+
shimDuetApiKeyToAiGateway();
|
|
156
|
+
// Refresh the gateway-managed default skills when the user has previously
|
|
157
|
+
// opted in via `duet login` (i.e. `~/.duet/.skills-hash` exists). Logging
|
|
158
|
+
// in with --skip-skill-sync leaves no hash, so this stays a no-op until
|
|
159
|
+
// the user explicitly syncs at least once. The conditional GET hits 304
|
|
160
|
+
// in steady state, so the cost is one cheap round-trip.
|
|
161
|
+
if (process.env.DUET_API_KEY) {
|
|
162
|
+
await maybeAutoSyncDefaultSkills({ apiKey: process.env.DUET_API_KEY });
|
|
163
|
+
}
|
|
164
|
+
const { config, modelResolution, memoryModelResolution } = buildCliTurnConfig({
|
|
165
|
+
...(modelName ? { modelName } : {}),
|
|
166
|
+
...(memoryModelName ? { memoryModelName } : {}),
|
|
167
|
+
disableDurableMemory,
|
|
168
|
+
workDir,
|
|
169
|
+
...(systemInstructions ? { systemInstructions } : {}),
|
|
170
|
+
...(systemPromptFiles ? { systemPromptFiles } : {}),
|
|
171
|
+
}, dotenvKeys);
|
|
172
|
+
modelName = modelResolution.modelName;
|
|
173
|
+
memoryModelName = memoryModelResolution.modelName;
|
|
174
|
+
const useTui = shouldUseTui({ interactive, jsonOutput, prompt });
|
|
175
|
+
const useJson = !useTui;
|
|
176
|
+
const newVersionNotice = await getNewVersionNotice(pkg.name, pkg.version);
|
|
177
|
+
if (useJson) {
|
|
178
|
+
if (newVersionNotice)
|
|
179
|
+
process.stderr.write(`${newVersionNotice}\n`);
|
|
180
|
+
process.stderr.write(`Model: ${modelName}\n`);
|
|
181
|
+
process.stderr.write(`Source: ${describeModelResolution(modelResolution)}\n`);
|
|
182
|
+
process.stderr.write(`Memory model: ${memoryModelName}\n`);
|
|
183
|
+
process.stderr.write(`Memory source: ${describeModelResolution(memoryModelResolution)}\n`);
|
|
184
|
+
}
|
|
185
|
+
const manager = new SessionManager(config);
|
|
186
|
+
manager.subscribe(({ event }) => {
|
|
187
|
+
if (useJson) {
|
|
188
|
+
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
try {
|
|
192
|
+
const session = resumeSessionId
|
|
193
|
+
? manager.resume(resumeSessionId)
|
|
194
|
+
: manager.create({
|
|
195
|
+
...(config.mode ? { mode: config.mode } : {}),
|
|
196
|
+
...(useTui || !prompt ? {} : { prompt }),
|
|
197
|
+
});
|
|
198
|
+
let resumedHistory;
|
|
199
|
+
if (resumeSessionId) {
|
|
200
|
+
// Force-load the persisted state.json so setup hands the resumed
|
|
201
|
+
// state to the runner and any TUI history replays before new turns.
|
|
202
|
+
await session.hydrate();
|
|
203
|
+
if (!session.getState()) {
|
|
204
|
+
throw new Error(`Unknown session: ${resumeSessionId}`);
|
|
205
|
+
}
|
|
206
|
+
// Setup runs against the hydrated state; manager.create() already
|
|
207
|
+
// dispatched setup for fresh sessions.
|
|
208
|
+
await session.start();
|
|
209
|
+
resumedHistory = session.getState()?.agent.messages;
|
|
210
|
+
}
|
|
211
|
+
if (prompt && resumeSessionId) {
|
|
212
|
+
await session.prompt({ message: prompt });
|
|
213
|
+
await session.waitForTerminal();
|
|
214
|
+
}
|
|
215
|
+
else if (prompt && !resumeSessionId) {
|
|
216
|
+
await session.waitForTerminal();
|
|
217
|
+
}
|
|
218
|
+
if (useTui) {
|
|
219
|
+
await runTui({
|
|
220
|
+
session,
|
|
221
|
+
...(resumedHistory ? { history: resumedHistory } : {}),
|
|
222
|
+
resumeHistoryLines,
|
|
223
|
+
modelName,
|
|
224
|
+
modelSource: describeModelResolution(modelResolution),
|
|
225
|
+
memoryModelName,
|
|
226
|
+
memoryModelSource: describeModelResolution(memoryModelResolution),
|
|
227
|
+
workDir,
|
|
228
|
+
sessionId: session.id,
|
|
229
|
+
packageVersion: pkg.version,
|
|
230
|
+
...(newVersionNotice ? { newVersionNotice } : {}),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
process.stderr.write(`To resume this session:\n${resumeCommand(session.id, {
|
|
234
|
+
...(modelName ? { modelName } : {}),
|
|
235
|
+
...(memoryModelName ? { memoryModelName } : {}),
|
|
236
|
+
workDir,
|
|
237
|
+
disableDurableMemory,
|
|
238
|
+
...(systemInstructions ? { systemInstructions } : {}),
|
|
239
|
+
...(systemPromptFiles ? { systemPromptFiles } : {}),
|
|
240
|
+
...(envFilePath ? { envFilePath } : {}),
|
|
241
|
+
...(resumeHistoryLinesExplicit ? { resumeHistoryLines } : {}),
|
|
242
|
+
})}\n`);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
console.error(`Fatal: ${err.message}`);
|
|
246
|
+
process.exitCode = 1;
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
await manager.dispose();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Read a single prompt from stdin when --json is set in an interactive
|
|
254
|
+
* terminal and no prompt was supplied via argv. Loops until the user
|
|
255
|
+
* provides non-empty input.
|
|
256
|
+
*/
|
|
257
|
+
async function readInteractivePrompt() {
|
|
258
|
+
const rl = createInterface({
|
|
259
|
+
input: process.stdin,
|
|
260
|
+
output: process.stderr,
|
|
261
|
+
});
|
|
262
|
+
try {
|
|
263
|
+
let prompt = "";
|
|
264
|
+
while (!prompt) {
|
|
265
|
+
prompt = (await rl.question("> ")).trim();
|
|
266
|
+
}
|
|
267
|
+
return prompt;
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
rl.close();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Default location of the shared duet env file shown in CLI help text. */
|
|
2
|
+
export declare const DEFAULT_DUET_ENV_FILE = "~/.duet/.env";
|
|
3
|
+
/**
|
|
4
|
+
* Provider API keys recognized by `duet env --keys`. Order is the order
|
|
5
|
+
* we prompt the user; first match wins for inferred-default model resolution.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUPPORTED_API_KEYS: readonly ["DUET_API_KEY", "ANTHROPIC_API_KEY", "AI_GATEWAY_API_KEY", "OPENROUTER_API_KEY", "OPENAI_API_KEY"];
|
|
8
|
+
/**
|
|
9
|
+
* Print a fatal error and exit with code 1. Used by every CLI subcommand for
|
|
10
|
+
* unrecoverable user-input errors so the message format stays consistent.
|
|
11
|
+
*/
|
|
12
|
+
export declare function fail(message: string): never;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a path that may use `~` for the home directory and may be relative
|
|
15
|
+
* to a base directory other than the cwd. Used everywhere the CLI accepts a
|
|
16
|
+
* filesystem path argument (env files, system-prompt files, workdir).
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveUserPath(path: string, baseDir?: string): string;
|
|
19
|
+
/** Resolved absolute path of the shared duet env file. */
|
|
20
|
+
export declare function defaultDuetEnvFilePath(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Ordered list of env files the CLI loads on startup. The cwd-local `.env`
|
|
23
|
+
* is loaded first so workspace-specific overrides win; the shared duet env
|
|
24
|
+
* file fills in the user-global defaults.
|
|
25
|
+
*/
|
|
26
|
+
export declare function cliEnvFilePaths(workDir: string, envFilePath?: string): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Load the env files from {@link cliEnvFilePaths} into `process.env` and
|
|
29
|
+
* return the set of keys that came from those files. The returned set lets
|
|
30
|
+
* model resolution distinguish keys we loaded from keys the user already
|
|
31
|
+
* exported in their shell.
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadCliEnvFiles(workDir: string, envFilePath?: string): Set<string>;
|
|
34
|
+
/** Reject negative or non-numeric values for `--resume-history-lines`. */
|
|
35
|
+
export declare function parseResumeHistoryLines(value: string, optionName?: string): number;
|
|
36
|
+
/** True when stdin or stdout is a TTY (heuristic for interactive sessions). */
|
|
37
|
+
export declare function isInteractive(): boolean;
|
|
38
|
+
/** True when an existing path resolves to a regular file. */
|
|
39
|
+
export declare function fileExists(path: string): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Merge the given key/value pairs into the env file at `target`, creating
|
|
42
|
+
* the directory tree if needed and preserving any keys that are not being
|
|
43
|
+
* updated. Values are quoted only when needed so the file remains diffable.
|
|
44
|
+
*/
|
|
45
|
+
export declare function mergeEnvEntries(target: string, entries: Map<string, string>): Promise<void>;
|
|
46
|
+
/** Serialize a key/value map as the text payload of a dotenv file. */
|
|
47
|
+
export declare function formatEnvEntries(entries: Map<string, string>): string;
|
|
48
|
+
/**
|
|
49
|
+
* Quote a string so it round-trips through a POSIX shell. Used to render
|
|
50
|
+
* resume hints and dry-run upgrade commands the user can copy verbatim.
|
|
51
|
+
*/
|
|
52
|
+
export declare function shellQuote(value: string): string;
|
|
53
|
+
/** Strip a leading `v` from a semver-ish string and return the bare numbers. */
|
|
54
|
+
export declare function normalizePackageVersion(version: string): string;
|
|
55
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAKA,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,8GAMrB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG3C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAgB,GAAG,MAAM,CAI7E;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CASlF;AAED,0EAA0E;AAC1E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,UAAU,SAA2B,GACpC,MAAM,CAKR;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,6DAA6D;AAC7D,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM/D;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjG;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAErE;AAOD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import dotenv from "dotenv";
|
|
5
|
+
/** Default location of the shared duet env file shown in CLI help text. */
|
|
6
|
+
export const DEFAULT_DUET_ENV_FILE = "~/.duet/.env";
|
|
7
|
+
/**
|
|
8
|
+
* Provider API keys recognized by `duet env --keys`. Order is the order
|
|
9
|
+
* we prompt the user; first match wins for inferred-default model resolution.
|
|
10
|
+
*/
|
|
11
|
+
export const SUPPORTED_API_KEYS = [
|
|
12
|
+
"DUET_API_KEY",
|
|
13
|
+
"ANTHROPIC_API_KEY",
|
|
14
|
+
"AI_GATEWAY_API_KEY",
|
|
15
|
+
"OPENROUTER_API_KEY",
|
|
16
|
+
"OPENAI_API_KEY",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Print a fatal error and exit with code 1. Used by every CLI subcommand for
|
|
20
|
+
* unrecoverable user-input errors so the message format stays consistent.
|
|
21
|
+
*/
|
|
22
|
+
export function fail(message) {
|
|
23
|
+
console.error(`Fatal: ${message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a path that may use `~` for the home directory and may be relative
|
|
28
|
+
* to a base directory other than the cwd. Used everywhere the CLI accepts a
|
|
29
|
+
* filesystem path argument (env files, system-prompt files, workdir).
|
|
30
|
+
*/
|
|
31
|
+
export function resolveUserPath(path, baseDir = process.cwd()) {
|
|
32
|
+
if (path === "~")
|
|
33
|
+
return homedir();
|
|
34
|
+
if (path.startsWith("~/"))
|
|
35
|
+
return join(homedir(), path.slice(2));
|
|
36
|
+
return isAbsolute(path) ? path : resolve(baseDir, path);
|
|
37
|
+
}
|
|
38
|
+
/** Resolved absolute path of the shared duet env file. */
|
|
39
|
+
export function defaultDuetEnvFilePath() {
|
|
40
|
+
return resolveUserPath(DEFAULT_DUET_ENV_FILE);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Ordered list of env files the CLI loads on startup. The cwd-local `.env`
|
|
44
|
+
* is loaded first so workspace-specific overrides win; the shared duet env
|
|
45
|
+
* file fills in the user-global defaults.
|
|
46
|
+
*/
|
|
47
|
+
export function cliEnvFilePaths(workDir, envFilePath) {
|
|
48
|
+
return [
|
|
49
|
+
join(workDir, ".env"),
|
|
50
|
+
envFilePath ? resolveUserPath(envFilePath, workDir) : defaultDuetEnvFilePath(),
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Load the env files from {@link cliEnvFilePaths} into `process.env` and
|
|
55
|
+
* return the set of keys that came from those files. The returned set lets
|
|
56
|
+
* model resolution distinguish keys we loaded from keys the user already
|
|
57
|
+
* exported in their shell.
|
|
58
|
+
*/
|
|
59
|
+
export function loadCliEnvFiles(workDir, envFilePath) {
|
|
60
|
+
const dotenvKeys = new Set();
|
|
61
|
+
for (const path of cliEnvFilePaths(workDir, envFilePath)) {
|
|
62
|
+
const result = dotenv.config({ path, quiet: true });
|
|
63
|
+
for (const key of Object.keys(result.parsed ?? {})) {
|
|
64
|
+
dotenvKeys.add(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return dotenvKeys;
|
|
68
|
+
}
|
|
69
|
+
/** Reject negative or non-numeric values for `--resume-history-lines`. */
|
|
70
|
+
export function parseResumeHistoryLines(value, optionName = "--resume-history-lines") {
|
|
71
|
+
if (!/^\d+$/.test(value)) {
|
|
72
|
+
throw new Error(`${optionName} must be a non-negative integer`);
|
|
73
|
+
}
|
|
74
|
+
return Number(value);
|
|
75
|
+
}
|
|
76
|
+
/** True when stdin or stdout is a TTY (heuristic for interactive sessions). */
|
|
77
|
+
export function isInteractive() {
|
|
78
|
+
return Boolean(process.stdin.isTTY ?? process.stdout.isTTY);
|
|
79
|
+
}
|
|
80
|
+
/** True when an existing path resolves to a regular file. */
|
|
81
|
+
export async function fileExists(path) {
|
|
82
|
+
try {
|
|
83
|
+
return (await stat(path)).isFile();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Merge the given key/value pairs into the env file at `target`, creating
|
|
91
|
+
* the directory tree if needed and preserving any keys that are not being
|
|
92
|
+
* updated. Values are quoted only when needed so the file remains diffable.
|
|
93
|
+
*/
|
|
94
|
+
export async function mergeEnvEntries(target, entries) {
|
|
95
|
+
await mkdir(dirname(target), { recursive: true });
|
|
96
|
+
const existingText = (await fileExists(target)) ? await readFile(target, "utf8") : "";
|
|
97
|
+
const merged = new Map(Object.entries(existingText ? dotenv.parse(existingText) : {}));
|
|
98
|
+
for (const [key, value] of entries) {
|
|
99
|
+
merged.set(key, value);
|
|
100
|
+
}
|
|
101
|
+
await writeFile(target, formatEnvEntries(merged));
|
|
102
|
+
}
|
|
103
|
+
/** Serialize a key/value map as the text payload of a dotenv file. */
|
|
104
|
+
export function formatEnvEntries(entries) {
|
|
105
|
+
return Array.from(entries, ([key, value]) => `${key}=${dotenvQuote(value)}`).join("\n") + "\n";
|
|
106
|
+
}
|
|
107
|
+
function dotenvQuote(value) {
|
|
108
|
+
if (/^[A-Za-z0-9_./:@+-]+$/.test(value))
|
|
109
|
+
return value;
|
|
110
|
+
return JSON.stringify(value);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Quote a string so it round-trips through a POSIX shell. Used to render
|
|
114
|
+
* resume hints and dry-run upgrade commands the user can copy verbatim.
|
|
115
|
+
*/
|
|
116
|
+
export function shellQuote(value) {
|
|
117
|
+
if (/^[A-Za-z0-9_./:=+-]+$/.test(value))
|
|
118
|
+
return value;
|
|
119
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
120
|
+
}
|
|
121
|
+
/** Strip a leading `v` from a semver-ish string and return the bare numbers. */
|
|
122
|
+
export function normalizePackageVersion(version) {
|
|
123
|
+
return version.replace(/^v/, "");
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run `duet skills` — print installed skills as JSON.
|
|
3
|
+
*
|
|
4
|
+
* Each entry includes name, description, absolute path, and resolved scope
|
|
5
|
+
* ("user" | "project" | "temporary"). Skill collisions are reported on
|
|
6
|
+
* stderr without changing exit status so scripts that rely on JSON output
|
|
7
|
+
* stay parseable.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runSkillsCommand(args: string[]): void;
|
|
10
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/cli/skills.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+BrD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { discoverInstalledSkills, resolveSkillScope } from "../turn-runner/skills.js";
|
|
2
|
+
import { printSkillsHelp } from "./help.js";
|
|
3
|
+
import { fail } from "./shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* Run `duet skills` — print installed skills as JSON.
|
|
6
|
+
*
|
|
7
|
+
* Each entry includes name, description, absolute path, and resolved scope
|
|
8
|
+
* ("user" | "project" | "temporary"). Skill collisions are reported on
|
|
9
|
+
* stderr without changing exit status so scripts that rely on JSON output
|
|
10
|
+
* stay parseable.
|
|
11
|
+
*/
|
|
12
|
+
export function runSkillsCommand(args) {
|
|
13
|
+
let workDir = process.cwd();
|
|
14
|
+
for (let i = 0; i < args.length; i++) {
|
|
15
|
+
switch (args[i]) {
|
|
16
|
+
case "--workdir":
|
|
17
|
+
case "-w":
|
|
18
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
19
|
+
fail(`Missing value for ${args[i]}`);
|
|
20
|
+
workDir = args[++i];
|
|
21
|
+
break;
|
|
22
|
+
case "--help":
|
|
23
|
+
case "-h":
|
|
24
|
+
printSkillsHelp();
|
|
25
|
+
return;
|
|
26
|
+
default:
|
|
27
|
+
fail(`Unknown skills option: ${args[i]}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const { skills, collisions } = discoverInstalledSkills(workDir);
|
|
31
|
+
const output = skills.map((skill) => ({
|
|
32
|
+
name: skill.name,
|
|
33
|
+
description: skill.description,
|
|
34
|
+
path: skill.baseDir,
|
|
35
|
+
scope: resolveSkillScope(skill, workDir),
|
|
36
|
+
}));
|
|
37
|
+
process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
|
|
38
|
+
for (const collision of collisions) {
|
|
39
|
+
process.stderr.write(`[skill collision] "${collision.name}": kept ${collision.winnerPath}, ignored ${collision.loserPath}\n`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/cli/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvF,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC;gBACrB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,eAAe,EAAE,CAAC;gBAClB,OAAO;YACT;gBACE,IAAI,CAAC,0BAA0B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,KAAK,EAAE,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC;KACzC,CAAC,CAAC,CAAC;IACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sBAAsB,SAAS,CAAC,IAAI,WAAW,SAAS,CAAC,UAAU,aAAa,SAAS,CAAC,SAAS,IAAI,CACxG,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run `duet upgrade`.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the target version (npm latest unless --version overrides),
|
|
5
|
+
* builds the right global-install command for the detected manager,
|
|
6
|
+
* prints it under --dry-run, and otherwise spawns it inheriting stdio.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runUpgradeCommand(args: string[], packageName: string): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=upgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../../src/cli/upgrade.ts"],"names":[],"mappings":"AAWA;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC1F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { detectPackageManager, globalUpgradeCommand, parsePackageManager, runCommand, } from "./package-manager.js";
|
|
2
|
+
import { fail, normalizePackageVersion, shellQuote } from "./shared.js";
|
|
3
|
+
import { fetchLatestPackageVersion } from "./version-check.js";
|
|
4
|
+
import { printUpgradeHelp } from "./help.js";
|
|
5
|
+
/**
|
|
6
|
+
* Run `duet upgrade`.
|
|
7
|
+
*
|
|
8
|
+
* Resolves the target version (npm latest unless --version overrides),
|
|
9
|
+
* builds the right global-install command for the detected manager,
|
|
10
|
+
* prints it under --dry-run, and otherwise spawns it inheriting stdio.
|
|
11
|
+
*/
|
|
12
|
+
export async function runUpgradeCommand(args, packageName) {
|
|
13
|
+
let packageManager = detectPackageManager();
|
|
14
|
+
let dryRun = false;
|
|
15
|
+
let targetVersion;
|
|
16
|
+
for (let i = 0; i < args.length; i++) {
|
|
17
|
+
switch (args[i]) {
|
|
18
|
+
case "--manager":
|
|
19
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
20
|
+
fail(`Missing value for ${args[i]}`);
|
|
21
|
+
packageManager = parsePackageManager(args[++i]);
|
|
22
|
+
break;
|
|
23
|
+
case "--dry-run":
|
|
24
|
+
dryRun = true;
|
|
25
|
+
break;
|
|
26
|
+
case "--version":
|
|
27
|
+
if (!args[i + 1] || args[i + 1]?.startsWith("-"))
|
|
28
|
+
fail(`Missing value for ${args[i]}`);
|
|
29
|
+
targetVersion = normalizePackageVersion(args[++i]);
|
|
30
|
+
break;
|
|
31
|
+
case "--help":
|
|
32
|
+
case "-h":
|
|
33
|
+
printUpgradeHelp(packageName);
|
|
34
|
+
return;
|
|
35
|
+
default:
|
|
36
|
+
fail(`Unknown upgrade option: ${args[i]}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
targetVersion ??= await fetchLatestPackageVersion(packageName);
|
|
40
|
+
if (!targetVersion) {
|
|
41
|
+
fail(`Could not resolve latest ${packageName} version from npm`);
|
|
42
|
+
}
|
|
43
|
+
const command = globalUpgradeCommand(packageManager, packageName, targetVersion);
|
|
44
|
+
const commandText = command.map(shellQuote).join(" ");
|
|
45
|
+
if (dryRun) {
|
|
46
|
+
console.log(commandText);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.error(`Upgrading ${packageName} to ${targetVersion} with ${packageManager}...`);
|
|
50
|
+
await runCommand(command[0], command.slice(1));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=upgrade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../../src/cli/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAEpB,mBAAmB,EACnB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAc,EAAE,WAAmB;IACzE,IAAI,cAAc,GAAmB,oBAAoB,EAAE,CAAC;IAC5D,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,aAAiC,CAAC;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,WAAW;gBACd,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvF,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC;gBACjD,MAAM;YACR,KAAK,WAAW;gBACd,MAAM,GAAG,IAAI,CAAC;gBACd,MAAM;YACR,KAAK,WAAW;gBACd,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvF,aAAa,GAAG,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC;gBACpD,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBAC9B,OAAO;YACT;gBACE,IAAI,CAAC,2BAA2B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,aAAa,KAAK,MAAM,yBAAyB,CAAC,WAAW,CAAC,CAAC;IAC/D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,CAAC,4BAA4B,WAAW,mBAAmB,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,OAAO,GAAG,oBAAoB,CAAC,cAAc,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACjF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,aAAa,WAAW,OAAO,aAAa,SAAS,cAAc,KAAK,CAAC,CAAC;IACxF,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two semver-ish strings. Returns -1, 0, or 1 like Array.sort.
|
|
3
|
+
*
|
|
4
|
+
* Pre-release ordering follows the simple rule "release wins over pre-release",
|
|
5
|
+
* which is enough for the upgrade-notice path; full SemVer 2.0 ordering is
|
|
6
|
+
* not required here because we only compare published npm versions.
|
|
7
|
+
*/
|
|
8
|
+
export declare function compareSemverVersions(left: string, right: string): number;
|
|
9
|
+
/**
|
|
10
|
+
* Fetch the `latest` dist-tag for a package from the npm registry.
|
|
11
|
+
* Returns undefined on any failure so callers can no-op silently.
|
|
12
|
+
*/
|
|
13
|
+
export declare function fetchLatestPackageVersion(packageName: string): Promise<string | undefined>;
|
|
14
|
+
/** Format the "Update available" notice we print at startup. */
|
|
15
|
+
export declare function formatNewVersionNotice(packageName: string, currentVersion: string, latestVersion: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the upgrade notice for `packageName@currentVersion`. Returns
|
|
18
|
+
* undefined when the user is already on the latest version or the registry
|
|
19
|
+
* lookup failed; callers print whatever string comes back.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getNewVersionNotice(packageName: string, currentVersion: string): Promise<string | undefined>;
|
|
22
|
+
//# sourceMappingURL=version-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-check.d.ts","sourceRoot":"","sources":["../../../src/cli/version-check.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWzE;AAcD;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAehG;AAED,gEAAgE;AAChE,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
|