@orchagent/cli 0.3.38 → 0.3.40
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/commands/init.js
CHANGED
|
@@ -84,10 +84,10 @@ if __name__ == "__main__":
|
|
|
84
84
|
function readmeTemplate(agentName, type) {
|
|
85
85
|
const callExample = type === 'code'
|
|
86
86
|
? `orchagent call ${agentName} input-file.txt`
|
|
87
|
-
: `orchagent call ${agentName} --data '{"input": "Hello world"}'`;
|
|
87
|
+
: `orchagent call ${agentName} --data '{"${type === 'agentic' ? 'task' : 'input'}": "Hello world"}'`;
|
|
88
88
|
const runExample = type === 'code'
|
|
89
89
|
? `orchagent run ${agentName} --input '{"file_path": "src/app.py"}'`
|
|
90
|
-
: `orchagent run ${agentName} --input '{"input": "Hello world"}'`;
|
|
90
|
+
: `orchagent run ${agentName} --input '{"${type === 'agentic' ? 'task' : 'input'}": "Hello world"}'`;
|
|
91
91
|
return `# ${agentName}
|
|
92
92
|
|
|
93
93
|
A brief description of what this agent does.
|
|
@@ -119,6 +119,61 @@ ${runExample}
|
|
|
119
119
|
| \`result\` | string | The agent's response |
|
|
120
120
|
`;
|
|
121
121
|
}
|
|
122
|
+
const AGENTIC_MANIFEST_TEMPLATE = `{
|
|
123
|
+
"name": "my-agent",
|
|
124
|
+
"description": "An agentic AI agent with tool use",
|
|
125
|
+
"type": "agentic",
|
|
126
|
+
"supported_providers": ["anthropic"],
|
|
127
|
+
"max_turns": 25,
|
|
128
|
+
"timeout_seconds": 300,
|
|
129
|
+
"custom_tools": [
|
|
130
|
+
{
|
|
131
|
+
"name": "run_tests",
|
|
132
|
+
"description": "Run the test suite",
|
|
133
|
+
"command": "pytest"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
`;
|
|
138
|
+
const AGENTIC_PROMPT_TEMPLATE = `You are a helpful AI agent with access to a sandboxed environment.
|
|
139
|
+
|
|
140
|
+
Given the input, complete the task using the available tools:
|
|
141
|
+
- Use bash to run commands
|
|
142
|
+
- Use read_file and write_file to work with files
|
|
143
|
+
- Use custom tools defined by the agent author
|
|
144
|
+
- Call submit_result when you're done
|
|
145
|
+
|
|
146
|
+
Input: The caller's input will be provided as JSON.
|
|
147
|
+
|
|
148
|
+
Work step by step, verify your results, and submit the final output.
|
|
149
|
+
`;
|
|
150
|
+
const AGENTIC_SCHEMA_TEMPLATE = `{
|
|
151
|
+
"input": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"task": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"description": "The task to complete"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"required": ["task"]
|
|
160
|
+
},
|
|
161
|
+
"output": {
|
|
162
|
+
"type": "object",
|
|
163
|
+
"properties": {
|
|
164
|
+
"result": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"description": "The result of the task"
|
|
167
|
+
},
|
|
168
|
+
"success": {
|
|
169
|
+
"type": "boolean",
|
|
170
|
+
"description": "Whether the task completed successfully"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"required": ["result", "success"]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
122
177
|
const SKILL_TEMPLATE = `---
|
|
123
178
|
name: my-skill
|
|
124
179
|
description: When to use this skill
|
|
@@ -134,7 +189,7 @@ function registerInitCommand(program) {
|
|
|
134
189
|
.command('init')
|
|
135
190
|
.description('Initialize a new agent project')
|
|
136
191
|
.argument('[name]', 'Agent name (default: current directory name)')
|
|
137
|
-
.option('--type <type>', 'Type: prompt, code, or skill (default: prompt)', 'prompt')
|
|
192
|
+
.option('--type <type>', 'Type: prompt, code, agentic, or skill (default: prompt)', 'prompt')
|
|
138
193
|
.action(async (name, options) => {
|
|
139
194
|
const cwd = process.cwd();
|
|
140
195
|
// When a name is provided, create a subdirectory for the project
|
|
@@ -187,21 +242,30 @@ function registerInitCommand(program) {
|
|
|
187
242
|
throw err;
|
|
188
243
|
}
|
|
189
244
|
}
|
|
190
|
-
// Create manifest
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const entrypointPath = path_1.default.join(targetDir, 'main.py');
|
|
198
|
-
await promises_1.default.writeFile(entrypointPath, CODE_TEMPLATE_PY);
|
|
245
|
+
// Create manifest and type-specific files
|
|
246
|
+
if (options.type === 'agentic') {
|
|
247
|
+
const manifest = JSON.parse(AGENTIC_MANIFEST_TEMPLATE);
|
|
248
|
+
manifest.name = agentName;
|
|
249
|
+
await promises_1.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
250
|
+
await promises_1.default.writeFile(promptPath, AGENTIC_PROMPT_TEMPLATE);
|
|
251
|
+
await promises_1.default.writeFile(schemaPath, AGENTIC_SCHEMA_TEMPLATE);
|
|
199
252
|
}
|
|
200
253
|
else {
|
|
201
|
-
|
|
254
|
+
const manifest = JSON.parse(MANIFEST_TEMPLATE);
|
|
255
|
+
manifest.name = agentName;
|
|
256
|
+
manifest.type = ['code', 'skill'].includes(options.type) ? options.type : 'prompt';
|
|
257
|
+
await promises_1.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
258
|
+
// Create prompt template (for prompt-based agents) or entrypoint (for code agents)
|
|
259
|
+
if (options.type === 'code') {
|
|
260
|
+
const entrypointPath = path_1.default.join(targetDir, 'main.py');
|
|
261
|
+
await promises_1.default.writeFile(entrypointPath, CODE_TEMPLATE_PY);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
await promises_1.default.writeFile(promptPath, PROMPT_TEMPLATE);
|
|
265
|
+
}
|
|
266
|
+
// Create schema template
|
|
267
|
+
await promises_1.default.writeFile(schemaPath, SCHEMA_TEMPLATE);
|
|
202
268
|
}
|
|
203
|
-
// Create schema template
|
|
204
|
-
await promises_1.default.writeFile(schemaPath, SCHEMA_TEMPLATE);
|
|
205
269
|
// Create README
|
|
206
270
|
const readmePath = path_1.default.join(targetDir, 'README.md');
|
|
207
271
|
await promises_1.default.writeFile(readmePath, readmeTemplate(agentName, options.type));
|
|
@@ -218,7 +282,17 @@ function registerInitCommand(program) {
|
|
|
218
282
|
process.stdout.write(` ${prefix}schema.json - Input/output schemas\n`);
|
|
219
283
|
process.stdout.write(` ${prefix}README.md - Agent documentation\n`);
|
|
220
284
|
process.stdout.write(`\nNext steps:\n`);
|
|
221
|
-
if (options.type
|
|
285
|
+
if (options.type === 'agentic') {
|
|
286
|
+
const stepNum = name ? 2 : 1;
|
|
287
|
+
if (name) {
|
|
288
|
+
process.stdout.write(` 1. cd ${name}\n`);
|
|
289
|
+
}
|
|
290
|
+
process.stdout.write(` ${stepNum}. Edit prompt.md with your agent instructions\n`);
|
|
291
|
+
process.stdout.write(` ${stepNum + 1}. Edit custom_tools in orchagent.json for your environment\n`);
|
|
292
|
+
process.stdout.write(` ${stepNum + 2}. Edit schema.json with your input/output schemas\n`);
|
|
293
|
+
process.stdout.write(` ${stepNum + 3}. Run: orchagent publish\n`);
|
|
294
|
+
}
|
|
295
|
+
else if (options.type !== 'code') {
|
|
222
296
|
const stepNum = name ? 2 : 1;
|
|
223
297
|
if (name) {
|
|
224
298
|
process.stdout.write(` 1. cd ${name}\n`);
|
package/dist/commands/publish.js
CHANGED
|
@@ -328,16 +328,16 @@ function registerPublishCommand(program) {
|
|
|
328
328
|
` }\n\n` +
|
|
329
329
|
`See docs/manifest.md for details.`);
|
|
330
330
|
}
|
|
331
|
-
// Read prompt (for prompt-based
|
|
331
|
+
// Read prompt (for prompt-based, agentic, and skill agents)
|
|
332
332
|
let prompt;
|
|
333
|
-
if (manifest.type === 'prompt' || manifest.type === 'skill') {
|
|
333
|
+
if (manifest.type === 'prompt' || manifest.type === 'skill' || manifest.type === 'agentic') {
|
|
334
334
|
const promptPath = path_1.default.join(cwd, 'prompt.md');
|
|
335
335
|
try {
|
|
336
336
|
prompt = await promises_1.default.readFile(promptPath, 'utf-8');
|
|
337
337
|
}
|
|
338
338
|
catch (err) {
|
|
339
339
|
if (err.code === 'ENOENT') {
|
|
340
|
-
const agentTypeName = manifest.type === 'skill' ? 'skill' : 'prompt-based agent';
|
|
340
|
+
const agentTypeName = manifest.type === 'skill' ? 'skill' : manifest.type === 'agentic' ? 'agentic agent' : 'prompt-based agent';
|
|
341
341
|
throw new errors_1.CliError(`No prompt.md found for ${agentTypeName}.\n\n` +
|
|
342
342
|
'Create a prompt.md file in the current directory with your prompt template.\n' +
|
|
343
343
|
'See: https://orchagent.io/docs/publishing');
|
|
@@ -345,6 +345,39 @@ function registerPublishCommand(program) {
|
|
|
345
345
|
throw err;
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
|
+
// For agentic agents, validate custom_tools and build manifest
|
|
349
|
+
if (manifest.type === 'agentic') {
|
|
350
|
+
// Validate custom_tools format
|
|
351
|
+
if (manifest.custom_tools) {
|
|
352
|
+
for (const tool of manifest.custom_tools) {
|
|
353
|
+
if (!tool.name || !tool.command) {
|
|
354
|
+
throw new errors_1.CliError(`Invalid custom_tool: each tool must have 'name' and 'command' fields.\n` +
|
|
355
|
+
`Found: ${JSON.stringify(tool)}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// Validate max_turns
|
|
360
|
+
if (manifest.max_turns !== undefined) {
|
|
361
|
+
if (typeof manifest.max_turns !== 'number' || manifest.max_turns < 1 || manifest.max_turns > 50) {
|
|
362
|
+
throw new errors_1.CliError('max_turns must be a number between 1 and 50');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Store agentic config in manifest field
|
|
366
|
+
const agenticManifest = {
|
|
367
|
+
...(manifest.manifest || {}),
|
|
368
|
+
};
|
|
369
|
+
if (manifest.custom_tools) {
|
|
370
|
+
agenticManifest.custom_tools = manifest.custom_tools;
|
|
371
|
+
}
|
|
372
|
+
if (manifest.max_turns) {
|
|
373
|
+
agenticManifest.max_turns = manifest.max_turns;
|
|
374
|
+
}
|
|
375
|
+
manifest.manifest = agenticManifest;
|
|
376
|
+
// Agentic agents default to anthropic provider
|
|
377
|
+
if (!manifest.supported_providers) {
|
|
378
|
+
manifest.supported_providers = ['anthropic'];
|
|
379
|
+
}
|
|
380
|
+
}
|
|
348
381
|
// Read schemas
|
|
349
382
|
let inputSchema;
|
|
350
383
|
let outputSchema;
|
|
@@ -363,7 +396,8 @@ function registerPublishCommand(program) {
|
|
|
363
396
|
throw new errors_1.CliError(`Failed to read schema.json: ${err}`);
|
|
364
397
|
}
|
|
365
398
|
}
|
|
366
|
-
// For prompt agents, derive input schema from template variables if needed
|
|
399
|
+
// For prompt/skill agents, derive input schema from template variables if needed
|
|
400
|
+
// (Agentic agents use schema.json directly — no template variable derivation)
|
|
367
401
|
if (prompt && (manifest.type === 'prompt' || manifest.type === 'skill')) {
|
|
368
402
|
const templateVars = extractTemplateVariables(prompt);
|
|
369
403
|
if (templateVars.length > 0) {
|
|
@@ -391,9 +425,26 @@ function registerPublishCommand(program) {
|
|
|
391
425
|
}
|
|
392
426
|
}
|
|
393
427
|
// For code-based agents, either --url is required OR we bundle the code
|
|
428
|
+
// For agentic agents, use internal placeholder (no user code, platform handles execution)
|
|
394
429
|
let agentUrl = options.url;
|
|
395
430
|
let shouldUploadBundle = false;
|
|
396
|
-
if (manifest.type === '
|
|
431
|
+
if (manifest.type === 'agentic') {
|
|
432
|
+
// Agentic agents don't need a URL or code bundle
|
|
433
|
+
agentUrl = agentUrl || 'https://agentic-agent.internal';
|
|
434
|
+
// But they can include a Dockerfile for custom environments
|
|
435
|
+
if (options.docker) {
|
|
436
|
+
const dockerfilePath = path_1.default.join(cwd, 'Dockerfile');
|
|
437
|
+
try {
|
|
438
|
+
await promises_1.default.access(dockerfilePath);
|
|
439
|
+
shouldUploadBundle = true;
|
|
440
|
+
process.stdout.write(`Including Dockerfile for custom environment\n`);
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
throw new errors_1.CliError('--docker flag specified but no Dockerfile found in project directory');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
else if (manifest.type === 'code' && !options.url) {
|
|
397
448
|
// Check if this looks like a Python or JS project that can be bundled
|
|
398
449
|
const entrypoint = manifest.entrypoint || await (0, bundle_1.detectEntrypoint)(cwd);
|
|
399
450
|
if (entrypoint) {
|
|
@@ -441,6 +492,18 @@ function registerPublishCommand(program) {
|
|
|
441
492
|
process.stderr.write(` ✓ Input schema derived from template variables: ${vars.join(', ')}\n`);
|
|
442
493
|
}
|
|
443
494
|
}
|
|
495
|
+
else if (manifest.type === 'agentic') {
|
|
496
|
+
// Agentic agent validations
|
|
497
|
+
const promptBytes = prompt ? Buffer.byteLength(prompt, 'utf-8') : 0;
|
|
498
|
+
process.stderr.write(` ✓ prompt.md found (${promptBytes.toLocaleString()} bytes)\n`);
|
|
499
|
+
if (schemaFromFile) {
|
|
500
|
+
const schemaTypes = [inputSchema ? 'input' : null, outputSchema ? 'output' : null].filter(Boolean).join(' + ');
|
|
501
|
+
process.stderr.write(` ✓ schema.json found (${schemaTypes} schemas)\n`);
|
|
502
|
+
}
|
|
503
|
+
const customToolCount = manifest.custom_tools?.length || 0;
|
|
504
|
+
process.stderr.write(` ✓ Custom tools: ${customToolCount}\n`);
|
|
505
|
+
process.stderr.write(` ✓ Max turns: ${manifest.max_turns || 25}\n`);
|
|
506
|
+
}
|
|
444
507
|
else if (manifest.type === 'code') {
|
|
445
508
|
// Code agent validations
|
|
446
509
|
const entrypoint = manifest.entrypoint || await (0, bundle_1.detectEntrypoint)(cwd);
|
|
@@ -522,7 +585,7 @@ function registerPublishCommand(program) {
|
|
|
522
585
|
}
|
|
523
586
|
const assignedVersion = result.agent?.version || 'v1';
|
|
524
587
|
const agentId = result.agent?.id;
|
|
525
|
-
// Upload code bundle if this is a hosted code agent
|
|
588
|
+
// Upload code bundle if this is a hosted code agent or agentic agent with --docker
|
|
526
589
|
if (shouldUploadBundle && agentId) {
|
|
527
590
|
process.stdout.write(`\nBundling code...\n`);
|
|
528
591
|
const tempDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'orchagent-bundle-'));
|
|
@@ -541,8 +604,20 @@ function registerPublishCommand(program) {
|
|
|
541
604
|
throw new errors_1.CliError('--docker flag specified but no Dockerfile found in project directory');
|
|
542
605
|
}
|
|
543
606
|
}
|
|
607
|
+
// For agentic agents, also include requirements.txt if present
|
|
608
|
+
if (manifest.type === 'agentic') {
|
|
609
|
+
const reqPath = path_1.default.join(cwd, 'requirements.txt');
|
|
610
|
+
try {
|
|
611
|
+
await promises_1.default.access(reqPath);
|
|
612
|
+
includePatterns.push('requirements.txt');
|
|
613
|
+
process.stdout.write(` Including requirements.txt for sandbox dependencies\n`);
|
|
614
|
+
}
|
|
615
|
+
catch {
|
|
616
|
+
// Optional
|
|
617
|
+
}
|
|
618
|
+
}
|
|
544
619
|
const bundleResult = await (0, bundle_1.createCodeBundle)(cwd, bundlePath, {
|
|
545
|
-
entrypoint: manifest.entrypoint,
|
|
620
|
+
entrypoint: manifest.type === 'agentic' ? undefined : manifest.entrypoint,
|
|
546
621
|
exclude: manifest.bundle?.exclude,
|
|
547
622
|
include: includePatterns.length > 0 ? includePatterns : undefined,
|
|
548
623
|
});
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.extractCount = extractCount;
|
|
7
7
|
exports.registerSecurityCommand = registerSecurityCommand;
|
|
8
|
+
exports.generateMarkdownReport = generateMarkdownReport;
|
|
8
9
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
10
11
|
const config_1 = require("../lib/config");
|
|
@@ -82,26 +83,28 @@ function formatSummaryOutput(result) {
|
|
|
82
83
|
// Summary stats
|
|
83
84
|
process.stdout.write(`${chalk_1.default.bold('Attacks Tested:')} ${result.total_attacks}\n`);
|
|
84
85
|
process.stdout.write(`${chalk_1.default.bold('Vulnerabilities Found:')} ${result.vulnerabilities_found}\n\n`);
|
|
85
|
-
// Breakdown by severity
|
|
86
|
+
// Breakdown by severity — show all tested levels, not just those with leaks
|
|
86
87
|
if (Object.keys(result.summary.by_severity).length > 0) {
|
|
87
88
|
process.stdout.write(chalk_1.default.bold('By Severity:\n'));
|
|
88
89
|
const severityOrder = ['critical', 'high', 'medium', 'low'];
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
const entries = Object.entries(result.summary.by_severity)
|
|
91
|
+
.sort(([a], [b]) => {
|
|
92
|
+
const ai = severityOrder.indexOf(a);
|
|
93
|
+
const bi = severityOrder.indexOf(b);
|
|
94
|
+
return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
|
|
95
|
+
});
|
|
96
|
+
for (const [sev, rawCount] of entries) {
|
|
97
|
+
const count = extractCount(rawCount);
|
|
98
|
+
process.stdout.write(` ${severityColor(sev)}: ${count}\n`);
|
|
94
99
|
}
|
|
95
100
|
process.stdout.write('\n');
|
|
96
101
|
}
|
|
97
|
-
// Breakdown by category
|
|
102
|
+
// Breakdown by category — show all tested categories
|
|
98
103
|
if (Object.keys(result.summary.by_category).length > 0) {
|
|
99
104
|
process.stdout.write(chalk_1.default.bold('By Category:\n'));
|
|
100
105
|
for (const [cat, rawCount] of Object.entries(result.summary.by_category)) {
|
|
101
106
|
const count = extractCount(rawCount);
|
|
102
|
-
|
|
103
|
-
process.stdout.write(` ${cat}: ${count}\n`);
|
|
104
|
-
}
|
|
107
|
+
process.stdout.write(` ${cat}: ${count}\n`);
|
|
105
108
|
}
|
|
106
109
|
process.stdout.write('\n');
|
|
107
110
|
}
|
|
@@ -305,9 +308,7 @@ function generateMarkdownReport(result) {
|
|
|
305
308
|
lines.push('');
|
|
306
309
|
for (const [sev, rawCount] of Object.entries(result.summary.by_severity)) {
|
|
307
310
|
const count = extractCount(rawCount);
|
|
308
|
-
|
|
309
|
-
lines.push(`- ${sev.toUpperCase()}: ${count}`);
|
|
310
|
-
}
|
|
311
|
+
lines.push(`- ${sev.toUpperCase()}: ${count}`);
|
|
311
312
|
}
|
|
312
313
|
lines.push('');
|
|
313
314
|
}
|
|
@@ -316,9 +317,7 @@ function generateMarkdownReport(result) {
|
|
|
316
317
|
lines.push('');
|
|
317
318
|
for (const [cat, rawCount] of Object.entries(result.summary.by_category)) {
|
|
318
319
|
const count = extractCount(rawCount);
|
|
319
|
-
|
|
320
|
-
lines.push(`- ${cat}: ${count}`);
|
|
321
|
-
}
|
|
320
|
+
lines.push(`- ${cat}: ${count}`);
|
|
322
321
|
}
|
|
323
322
|
lines.push('');
|
|
324
323
|
}
|
|
@@ -9,6 +9,7 @@ exports.checkGitAvailable = checkGitAvailable;
|
|
|
9
9
|
exports.runEnvironmentChecks = runEnvironmentChecks;
|
|
10
10
|
const child_process_1 = require("child_process");
|
|
11
11
|
const package_json_1 = __importDefault(require("../../../../package.json"));
|
|
12
|
+
const update_notifier_1 = require("../../update-notifier");
|
|
12
13
|
const REQUIRED_NODE_MAJOR = 18;
|
|
13
14
|
/**
|
|
14
15
|
* Check if Node.js version is 18+.
|
|
@@ -40,8 +41,9 @@ async function checkNodeVersion() {
|
|
|
40
41
|
async function checkCliVersion() {
|
|
41
42
|
const installedVersion = package_json_1.default.version;
|
|
42
43
|
try {
|
|
43
|
-
// Fetch latest version from
|
|
44
|
-
|
|
44
|
+
// Fetch latest version from the same dist-tags endpoint the update banner uses,
|
|
45
|
+
// so both always agree on the latest version (fixes D-1 inconsistency).
|
|
46
|
+
const response = await fetch(update_notifier_1.DIST_TAGS_URL, { signal: AbortSignal.timeout(5000) });
|
|
45
47
|
if (!response.ok) {
|
|
46
48
|
return {
|
|
47
49
|
category: 'environment',
|
|
@@ -52,7 +54,9 @@ async function checkCliVersion() {
|
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
56
|
const data = (await response.json());
|
|
55
|
-
const latestVersion = data.
|
|
57
|
+
const latestVersion = data.latest;
|
|
58
|
+
// Sync the update-notifier cache so the banner shows the same version
|
|
59
|
+
(0, update_notifier_1.writeCache)(latestVersion);
|
|
56
60
|
if (installedVersion === latestVersion) {
|
|
57
61
|
return {
|
|
58
62
|
category: 'environment',
|
|
@@ -18,6 +18,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.DIST_TAGS_URL = void 0;
|
|
22
|
+
exports.writeCache = writeCache;
|
|
21
23
|
exports.checkForUpdates = checkForUpdates;
|
|
22
24
|
exports.printUpdateNotification = printUpdateNotification;
|
|
23
25
|
const https_1 = __importDefault(require("https"));
|
|
@@ -30,6 +32,8 @@ const CACHE_DIR = path_1.default.join(os_1.default.homedir(), '.orchagent');
|
|
|
30
32
|
const CACHE_PATH = path_1.default.join(CACHE_DIR, 'update-check.json');
|
|
31
33
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
32
34
|
const REQUEST_TIMEOUT_MS = 5000;
|
|
35
|
+
/** npm dist-tags endpoint — single source of truth for latest version. */
|
|
36
|
+
exports.DIST_TAGS_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
|
|
33
37
|
// ── Cache I/O ──────────────────────────────────────────────────────────
|
|
34
38
|
function readCache() {
|
|
35
39
|
try {
|