@empirical-gauzza/cli 1.0.35 → 1.0.37
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/bin/empirical.js +7 -1
- package/lib/auth.js +30 -2
- package/lib/blueprintCommands.js +23 -3
- package/lib/constants.js +672 -657
- package/lib/empiricalTokensFormat.js +66 -0
- package/lib/help.js +15 -3
- package/lib/http.js +11 -3
- package/lib/installWizard.js +3 -1
- package/lib/installers/coreMemoryBlock.js +2 -1
- package/lib/installers/nativePlugin.js +1 -1
- package/lib/installers/promptBlocks.js +9 -0
- package/lib/memoryCommands.js +74 -2
- package/lib/pluginCommands.js +3 -2
- package/lib/setupCommands.js +574 -31
- package/lib/usageCommands.js +52 -0
- package/lib/workspaceCommands.js +59 -7
- package/lib/workspaceContext.js +176 -76
- package/package.json +33 -33
package/bin/empirical.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
@@ -25,6 +25,7 @@ const { showVersion } = require('../lib/help');
|
|
|
25
25
|
const { isPluginCommand, runPluginCommand } = require('../lib/pluginCommands');
|
|
26
26
|
const { runPolicyCommand } = require('../lib/policyCommands');
|
|
27
27
|
const { runSetupCommand } = require('../lib/setupCommands');
|
|
28
|
+
const { runUsageCommand } = require('../lib/usageCommands');
|
|
28
29
|
const { runBlueprintCommand } = require('../lib/blueprintCommands');
|
|
29
30
|
const { checkNativePluginUpdates } = require('../lib/pluginUpdateCheck');
|
|
30
31
|
|
|
@@ -112,6 +113,11 @@ async function main() {
|
|
|
112
113
|
return;
|
|
113
114
|
}
|
|
114
115
|
|
|
116
|
+
if (args[0] === 'usage') {
|
|
117
|
+
await runUsageCommand(args.slice(1));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
115
121
|
if (args[0] === 'setup') {
|
|
116
122
|
await runSetupCommand(args.slice(1));
|
|
117
123
|
return;
|
package/lib/auth.js
CHANGED
|
@@ -361,7 +361,7 @@ function inspectToken(token) {
|
|
|
361
361
|
// Gathers the same identity/workspace facts `doctor` reports (token presence/type/expiry, plus
|
|
362
362
|
// user + workspace from /api/v1/users/me), formatted for `auth status` / `whoami` as a single
|
|
363
363
|
// JSON object instead of doctor's multi-check report.
|
|
364
|
-
async function gatherAuthStatus() {
|
|
364
|
+
async function gatherAuthStatus({ includeEmpiricalTokens = false } = {}) {
|
|
365
365
|
const token = resolveAccessToken();
|
|
366
366
|
const tokenInfo = inspectToken(token);
|
|
367
367
|
|
|
@@ -385,6 +385,31 @@ async function gatherAuthStatus() {
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
+
// What the CLI itself will scope the next memory command to (env, project binding, or the
|
|
389
|
+
// global selection), beside the server-reported account workspace above. The two can differ,
|
|
390
|
+
// and when they do this is the field that explains a "[]" recall. Lazy require: workspaceContext
|
|
391
|
+
// depends on this module.
|
|
392
|
+
let cliWorkspace = null;
|
|
393
|
+
try {
|
|
394
|
+
const { resolveLocalWorkspaceSelection } = require('./workspaceContext');
|
|
395
|
+
const local = resolveLocalWorkspaceSelection();
|
|
396
|
+
if (local) cliWorkspace = { workspaceId: local.workspaceId, label: local.label || null, source: local.source, path: local.path };
|
|
397
|
+
} catch (_error) {
|
|
398
|
+
cliWorkspace = null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// `whoami` / `auth status` add one Empirical Tokens line while they are enforced (spec 8.4).
|
|
402
|
+
// Best effort with a short timeout; doctor does not ask for it.
|
|
403
|
+
let empiricalTokens = null;
|
|
404
|
+
if (includeEmpiricalTokens && token && !error) {
|
|
405
|
+
try {
|
|
406
|
+
const { fetchBillingMe, empiricalTokensLine } = require('./usageCommands');
|
|
407
|
+
empiricalTokens = empiricalTokensLine((await fetchBillingMe(3000)).empiricalTokenUsage);
|
|
408
|
+
} catch (_error) {
|
|
409
|
+
empiricalTokens = null;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
388
413
|
return {
|
|
389
414
|
authenticated: Boolean(token) && !error && tokenInfo.expired !== true,
|
|
390
415
|
tokenPresent: tokenInfo.present,
|
|
@@ -393,6 +418,9 @@ async function gatherAuthStatus() {
|
|
|
393
418
|
tokenExpired: tokenInfo.expired,
|
|
394
419
|
user,
|
|
395
420
|
workspaceId,
|
|
421
|
+
cliWorkspace,
|
|
422
|
+
// Present only while enforced for this account: a dark account's JSON has no such key.
|
|
423
|
+
...(empiricalTokens ? { empiricalTokens } : {}),
|
|
396
424
|
error
|
|
397
425
|
};
|
|
398
426
|
}
|
|
@@ -408,7 +436,7 @@ async function runAuthCommand(args) {
|
|
|
408
436
|
}
|
|
409
437
|
|
|
410
438
|
if (action === 'status' || action === 'whoami') {
|
|
411
|
-
const status = await gatherAuthStatus();
|
|
439
|
+
const status = await gatherAuthStatus({ includeEmpiricalTokens: true });
|
|
412
440
|
log(JSON.stringify(status));
|
|
413
441
|
if (!status.authenticated) {
|
|
414
442
|
process.exitCode = 1;
|
package/lib/blueprintCommands.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
const { httpJson, printApiError } = require('./http');
|
|
4
4
|
const { parseOption } = require('./env');
|
|
5
5
|
const { requireAccessToken, resolveApiBaseUrl, buildApiAuthHeaders } = require('./auth');
|
|
6
|
-
const { warn, log } = require('./ui');
|
|
6
|
+
const { warn, log, createPrompter } = require('./ui');
|
|
7
|
+
const { sanitizeForTerminal } = require('./setupCommands');
|
|
8
|
+
const { confirmCostOrExit, isCostPreview, isInteractiveTerminal } = require('./empiricalTokensFormat');
|
|
7
9
|
|
|
8
10
|
function apiUrl(pathSuffix) {
|
|
9
11
|
return new URL(`/api/v1/blueprints${pathSuffix}`, resolveApiBaseUrl()).toString();
|
|
@@ -61,17 +63,35 @@ async function runClaim(args) {
|
|
|
61
63
|
async function runInstall(args) {
|
|
62
64
|
const blueprintId = args[0] && !args[0].startsWith('--') ? args[0] : '';
|
|
63
65
|
if (!blueprintId) {
|
|
64
|
-
warn('Usage: empirical blueprint install <blueprintId> [--version <v>]');
|
|
66
|
+
warn('Usage: empirical blueprint install <blueprintId> [--version <v>] [--accept-cost]');
|
|
65
67
|
process.exit(1);
|
|
66
68
|
}
|
|
67
69
|
const version = parseOption(args, '--version', '');
|
|
70
|
+
const acceptCost = args.includes('--accept-cost');
|
|
68
71
|
|
|
69
72
|
const detail = await callApi('GET', `/${blueprintId}`, undefined);
|
|
70
73
|
if (!detail.owned && detail.priceModel === 'free') {
|
|
71
74
|
await callApi('POST', `/${blueprintId}/claim`, {});
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
const
|
|
77
|
+
const installBody = { ...(version ? { version } : {}), ...(acceptCost ? { acceptEmpiricalTokenCost: true } : {}) };
|
|
78
|
+
let installResult = await callApi('POST', `/${blueprintId}/install`, installBody);
|
|
79
|
+
if (isCostPreview(installResult)) {
|
|
80
|
+
// A priced blueprint in enforce answers 200 with the cost and starts nothing (no installId yet).
|
|
81
|
+
// Acceptance is sent only from --accept-cost or an explicit y at a real terminal, never for the person.
|
|
82
|
+
const prompter = isInteractiveTerminal() ? createPrompter(process.stderr) : null;
|
|
83
|
+
try {
|
|
84
|
+
await confirmCostOrExit(installResult, { prompter, warn, sanitize: sanitizeForTerminal });
|
|
85
|
+
} finally {
|
|
86
|
+
if (prompter) prompter.close();
|
|
87
|
+
}
|
|
88
|
+
installResult = await callApi('POST', `/${blueprintId}/install`, { ...installBody, acceptEmpiricalTokenCost: true });
|
|
89
|
+
}
|
|
90
|
+
if (!installResult || !installResult.installId) {
|
|
91
|
+
// Never poll /installs/undefined: a reply with no install id is not a started install.
|
|
92
|
+
log(JSON.stringify(installResult, null, 2));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
75
95
|
const finalStatus = await waitForInstall(installResult.installId);
|
|
76
96
|
log(JSON.stringify(finalStatus, null, 2));
|
|
77
97
|
}
|