@inquir/compute-cli 0.2.2 → 0.4.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/README.md +228 -21
- package/dist/commands/admin-tenants.d.ts +11 -0
- package/dist/commands/admin-tenants.d.ts.map +1 -0
- package/dist/commands/admin-tenants.js +318 -0
- package/dist/commands/admin-tenants.js.map +1 -0
- package/dist/commands/admin.d.ts +2 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +445 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/apps-describe.d.ts +9 -0
- package/dist/commands/apps-describe.d.ts.map +1 -0
- package/dist/commands/apps-describe.js +118 -0
- package/dist/commands/apps-describe.js.map +1 -0
- package/dist/commands/apps-observability.d.ts +9 -0
- package/dist/commands/apps-observability.d.ts.map +1 -0
- package/dist/commands/apps-observability.js +281 -0
- package/dist/commands/apps-observability.js.map +1 -0
- package/dist/commands/apps-promote.d.ts +31 -0
- package/dist/commands/apps-promote.d.ts.map +1 -0
- package/dist/commands/apps-promote.js +115 -0
- package/dist/commands/apps-promote.js.map +1 -0
- package/dist/commands/apps-resources.d.ts +6 -0
- package/dist/commands/apps-resources.d.ts.map +1 -0
- package/dist/commands/apps-resources.js +107 -0
- package/dist/commands/apps-resources.js.map +1 -0
- package/dist/commands/apps.d.ts +65 -5
- package/dist/commands/apps.d.ts.map +1 -1
- package/dist/commands/apps.js +1293 -89
- package/dist/commands/apps.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +7 -3
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +10 -2
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/deploy.d.ts +38 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +165 -12
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +96 -20
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +37 -5
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +184 -77
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/projects.d.ts +2 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +194 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/finite-source-command-client.d.ts +3 -0
- package/dist/lib/finite-source-command-client.d.ts.map +1 -0
- package/dist/lib/finite-source-command-client.js +3 -0
- package/dist/lib/finite-source-command-client.js.map +1 -0
- package/dist/lib/mcp-io.d.ts +23 -0
- package/dist/lib/mcp-io.d.ts.map +1 -0
- package/dist/lib/mcp-io.js +185 -0
- package/dist/lib/mcp-io.js.map +1 -0
- package/dist/lib/mcp-source-commands.d.ts +17 -0
- package/dist/lib/mcp-source-commands.d.ts.map +1 -0
- package/dist/lib/mcp-source-commands.js +345 -0
- package/dist/lib/mcp-source-commands.js.map +1 -0
- package/dist/utils/api.d.ts +58 -8
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +86 -7
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/apps-presentation.d.ts +11 -1
- package/dist/utils/apps-presentation.d.ts.map +1 -1
- package/dist/utils/apps-presentation.js +37 -0
- package/dist/utils/apps-presentation.js.map +1 -1
- package/dist/utils/args.d.ts.map +1 -1
- package/dist/utils/args.js +8 -1
- package/dist/utils/args.js.map +1 -1
- package/dist/utils/assets.d.ts +48 -1
- package/dist/utils/assets.d.ts.map +1 -1
- package/dist/utils/assets.js +185 -7
- package/dist/utils/assets.js.map +1 -1
- package/dist/utils/auth.d.ts +29 -2
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +164 -27
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/browser.d.ts +12 -0
- package/dist/utils/browser.d.ts.map +1 -1
- package/dist/utils/browser.js +37 -16
- package/dist/utils/browser.js.map +1 -1
- package/dist/utils/context.d.ts.map +1 -1
- package/dist/utils/context.js +2 -0
- package/dist/utils/context.js.map +1 -1
- package/dist/utils/deploy-follow.d.ts +4 -3
- package/dist/utils/deploy-follow.d.ts.map +1 -1
- package/dist/utils/deploy-follow.js +76 -17
- package/dist/utils/deploy-follow.js.map +1 -1
- package/dist/utils/detect.d.ts +49 -1
- package/dist/utils/detect.d.ts.map +1 -1
- package/dist/utils/detect.js +153 -12
- package/dist/utils/detect.js.map +1 -1
- package/dist/utils/ensure-auth.d.ts.map +1 -1
- package/dist/utils/ensure-auth.js +6 -2
- package/dist/utils/ensure-auth.js.map +1 -1
- package/dist/utils/package-metadata.js +1 -1
- package/dist/utils/project-context.d.ts +17 -0
- package/dist/utils/project-context.d.ts.map +1 -0
- package/dist/utils/project-context.js +96 -0
- package/dist/utils/project-context.js.map +1 -0
- package/dist/utils/project-lookup.d.ts +10 -0
- package/dist/utils/project-lookup.d.ts.map +1 -0
- package/dist/utils/project-lookup.js +52 -0
- package/dist/utils/project-lookup.js.map +1 -0
- package/package.json +7 -4
- package/skill/SKILL.md +15 -2
package/dist/utils/assets.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
import { CliError, ExitCode } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Opening words of the explanation findAssetOrExplain builds for an identifier
|
|
4
|
+
* that matches more than one asset, so assetNotFoundError can recognise its own
|
|
5
|
+
* message. The two have to agree through a plain string because the callers in
|
|
6
|
+
* between (deploy.ts, run.ts) forward only `{ error }`; keeping the prefix in one
|
|
7
|
+
* constant is what stops the producer and the detector drifting apart. It sits at
|
|
8
|
+
* position 0 and both other explanations start with `Asset `, so no asset name,
|
|
9
|
+
* path or export can spoof it.
|
|
10
|
+
*/
|
|
11
|
+
const AMBIGUOUS_PREFIX = 'Ambiguous asset ';
|
|
2
12
|
/**
|
|
3
13
|
* A friendly, actionable error for a local asset that could not be resolved.
|
|
4
14
|
* Treated as a usage error (exit 2) — the user typed a name that doesn't match
|
|
5
|
-
* (or that fails to compile) — with a hint to
|
|
15
|
+
* (or that fails to compile, or that matches several assets) — with a hint to
|
|
16
|
+
* list what's available.
|
|
6
17
|
*/
|
|
7
18
|
export function assetNotFoundError(identifier, explanation) {
|
|
19
|
+
if (explanation.startsWith(AMBIGUOUS_PREFIX)) {
|
|
20
|
+
// The way out is spelled out per collision in `explanation`, because that is
|
|
21
|
+
// the only free-text field `--json` renders (renderError drops fix/command).
|
|
22
|
+
return new CliError(`Asset "${identifier}" is ambiguous`, {
|
|
23
|
+
code: 'ASSET_AMBIGUOUS',
|
|
24
|
+
exitCode: ExitCode.USAGE,
|
|
25
|
+
explanation,
|
|
26
|
+
// Deliberately vaguer than "one of the values listed": when every colliding
|
|
27
|
+
// asset is reachable only through a value that is itself ambiguous, the
|
|
28
|
+
// explanation lists no value at all and asks for the rename instead.
|
|
29
|
+
fix: 'Use one of the values named in the explanation above, or rename the colliding asset.',
|
|
30
|
+
command: 'inquir list',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
8
33
|
const isImportFailure = explanation.includes('failed to import');
|
|
9
34
|
return new CliError(isImportFailure ? `Asset "${identifier}" failed to load` : `Asset "${identifier}" not found`, {
|
|
10
35
|
code: isImportFailure ? 'ASSET_IMPORT_FAILED' : 'ASSET_NOT_FOUND',
|
|
@@ -16,15 +41,168 @@ export function assetNotFoundError(identifier, explanation) {
|
|
|
16
41
|
command: 'inquir list',
|
|
17
42
|
});
|
|
18
43
|
}
|
|
44
|
+
/** The fields a caller may type to address a local asset, in resolution order. */
|
|
45
|
+
const IDENTIFIER_FIELDS = ['name', 'localPath', 'exportName'];
|
|
46
|
+
/** How each field is named to the user, so an offered value says what it is. */
|
|
47
|
+
const FIELD_LABEL = {
|
|
48
|
+
name: 'asset name',
|
|
49
|
+
localPath: 'file path',
|
|
50
|
+
exportName: 'export name',
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The only advice that always terminates: once the duplicates carry distinct
|
|
54
|
+
* names the `name` tier resolves each of them on its own. Phrased for any number
|
|
55
|
+
* of duplicates — renaming *one* of three same-named assets still leaves a tie —
|
|
56
|
+
* and it names both defining calls, because a name tie is compared across kinds,
|
|
57
|
+
* so the duplicate to rename can be a definePipeline.
|
|
58
|
+
*/
|
|
59
|
+
const RENAME_CURE = 'give the duplicates distinct defineFunction/definePipeline names';
|
|
60
|
+
/**
|
|
61
|
+
* Match `identifier` against one field at a time — `name`, then `localPath`,
|
|
62
|
+
* then `exportName` — and report a tie instead of breaking it.
|
|
63
|
+
*
|
|
64
|
+
* Each field is searched on its own so that an export called `invoice` in one
|
|
65
|
+
* file can no longer outrank the asset actually *named* `invoice` in another —
|
|
66
|
+
* the old single `find()` merged all three namespaces and let discovery order
|
|
67
|
+
* decide. Within a field a tie is left unresolved: discoverAssets keeps every
|
|
68
|
+
* same-named asset and only *reports* the clash, as a DUPLICATE_NAME diagnostic
|
|
69
|
+
* that `inquir list` and `inquir codegen` print but the deploy/run lookup never
|
|
70
|
+
* reads. Refusing here is what stops `inquir deploy invoice` silently shipping
|
|
71
|
+
* whichever file sorted first.
|
|
72
|
+
*
|
|
73
|
+
* Names are compared across kinds on purpose, so a function and a pipeline that
|
|
74
|
+
* share a name are a tie as well and `inquir deploy <name>` / `inquir run <name>`
|
|
75
|
+
* now refuse where discoverAssets' leading `kind.localeCompare` sort used to hand
|
|
76
|
+
* the function over silently. That is the same clash discoverAssets already
|
|
77
|
+
* reports: it groups DUPLICATE_NAME by name alone, without looking at kind.
|
|
78
|
+
*/
|
|
79
|
+
export function resolveAsset(assets, identifier) {
|
|
80
|
+
for (const field of IDENTIFIER_FIELDS) {
|
|
81
|
+
const matches = assets.filter((asset) => asset[field] === identifier);
|
|
82
|
+
if (matches.length === 1)
|
|
83
|
+
return { kind: 'found', asset: matches[0] };
|
|
84
|
+
if (matches.length > 1)
|
|
85
|
+
return { kind: 'ambiguous', field, matches };
|
|
86
|
+
}
|
|
87
|
+
return { kind: 'none' };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The asset addressed by `identifier`, or undefined when nothing matches *or*
|
|
91
|
+
* when several assets do. Callers that want to tell those two apart (and to tell
|
|
92
|
+
* the user which assets collided) should use resolveAsset or findAssetOrExplain.
|
|
93
|
+
*
|
|
94
|
+
* What this does not fix: refusing the ambiguous *lookup* does not make two
|
|
95
|
+
* same-named assets deployable. deployAsset takes `name` and `linkedLocalName`
|
|
96
|
+
* from the asset itself, so addressing either one by its unique file path still
|
|
97
|
+
* deploys it onto the single remote function of that name, and the second deploy
|
|
98
|
+
* overwrites the first. Giving the duplicates distinct defineFunction names is
|
|
99
|
+
* the only cure, which is why the ambiguity explanation asks for it.
|
|
100
|
+
*/
|
|
19
101
|
export function findAsset(assets, identifier) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
102
|
+
const match = resolveAsset(assets, identifier);
|
|
103
|
+
return match.kind === 'found' ? match.asset : undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A value that addresses exactly `asset` and nothing else, or undefined when
|
|
107
|
+
* neither of the two remaining fields does.
|
|
108
|
+
*
|
|
109
|
+
* The candidate is checked with resolveAsset over the *whole* discovered set and
|
|
110
|
+
* has to land back on this very asset. Uniqueness inside the colliding subset is
|
|
111
|
+
* not enough: with two assets named `invoice`, one of them in a file that also
|
|
112
|
+
* exports `refund`, that file path is unique among the two `invoice` rows yet
|
|
113
|
+
* ambiguous overall, so offering it would bounce the caller into a second
|
|
114
|
+
* refusal that points back at the name they started from.
|
|
115
|
+
*
|
|
116
|
+
* Candidates are tried in IDENTIFIER_FIELDS order, so a file path is preferred
|
|
117
|
+
* over an export name when both address the asset. That order is a preference and
|
|
118
|
+
* nothing more: a candidate is stolen by an *earlier* tier, never a later one — an
|
|
119
|
+
* export name `v2` loses to an asset actually named `v2` — and it is the
|
|
120
|
+
* round-trip above, not the order, that rules such a value out.
|
|
121
|
+
*/
|
|
122
|
+
function addressableValue(assets, asset, collided) {
|
|
123
|
+
for (const field of IDENTIFIER_FIELDS) {
|
|
124
|
+
if (field === collided)
|
|
125
|
+
continue;
|
|
126
|
+
const candidate = asset[field];
|
|
127
|
+
const match = resolveAsset(assets, candidate);
|
|
128
|
+
if (match.kind === 'found' && match.asset === asset)
|
|
129
|
+
return { value: candidate, field };
|
|
130
|
+
}
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Name the way out in terms of the field the caller actually typed.
|
|
135
|
+
*
|
|
136
|
+
* Every value printed as an alternative has been verified with addressableValue
|
|
137
|
+
* against the full asset list, so typing it ends the search instead of raising
|
|
138
|
+
* the next ambiguity. A colliding asset that no single value reaches is reported
|
|
139
|
+
* rather than offered.
|
|
140
|
+
*
|
|
141
|
+
* Where RENAME_CURE appears is not uniform, because the rename is not always the
|
|
142
|
+
* cure. The name branch always ends in it: a path addresses one of the duplicates
|
|
143
|
+
* for this lookup but leaves the names tied, and when two of the tied assets are
|
|
144
|
+
* functions they also share one remote function on deploy. The path and export
|
|
145
|
+
* branches print it only when some match is unreachable, which happens only
|
|
146
|
+
* because that match's asset name is shared with a further asset — a file that
|
|
147
|
+
* merely exports two well-named assets needs no rename, and its advice already
|
|
148
|
+
* terminates.
|
|
149
|
+
*/
|
|
150
|
+
function describeAmbiguity(assets, identifier, field, matches) {
|
|
151
|
+
const offers = matches
|
|
152
|
+
.map((asset) => addressableValue(assets, asset, field))
|
|
153
|
+
.filter((offer) => offer !== undefined);
|
|
154
|
+
const advice = offers.length > 0
|
|
155
|
+
? `Pass one of these values in place of the ${FIELD_LABEL[field]} to address a single asset: `
|
|
156
|
+
+ `${offers.map((offer) => `"${offer.value}" (${FIELD_LABEL[offer.field]})`).join(', ')}.`
|
|
157
|
+
: 'No single value addresses any one of them.';
|
|
158
|
+
const unreachable = matches.length - offers.length;
|
|
159
|
+
// Counting the unreachable matches is only worth a sentence when some other
|
|
160
|
+
// match *was* offered; with no offer at all `advice` has already said it, and
|
|
161
|
+
// repeating the same fact as a count reads like a second, different problem.
|
|
162
|
+
const partial = offers.length > 0 && unreachable > 0;
|
|
163
|
+
if (field === 'name') {
|
|
164
|
+
const owners = matches.map((asset) => `${asset.localPath} (export ${asset.exportName})`);
|
|
165
|
+
const shortfall = partial
|
|
166
|
+
? ` ${unreachable} of the ${matches.length} cannot be addressed by any single value.`
|
|
167
|
+
: '';
|
|
168
|
+
// A name tie is compared across kinds, but deployAsset refuses every kind
|
|
169
|
+
// except `function`, so only two or more *functions* can overwrite each other
|
|
170
|
+
// on the remote side. With a pipeline in the tie the rename is still the cure
|
|
171
|
+
// for the lookup, and claiming an overwrite that deploy would refuse outright
|
|
172
|
+
// would be inventing a consequence.
|
|
173
|
+
const cure = matches.filter((asset) => asset.kind === 'function').length > 1
|
|
174
|
+
? `Deploy takes the remote function name from the asset either way, so each of them deploys onto the one remote function "${identifier}" — ${RENAME_CURE}.`
|
|
175
|
+
: `The only lasting fix is to ${RENAME_CURE}.`;
|
|
176
|
+
return `${AMBIGUOUS_PREFIX}"${identifier}": ${matches.length} local assets are named "${identifier}": ${owners.join(', ')}. `
|
|
177
|
+
+ `${advice}${shortfall} ${cure}`;
|
|
178
|
+
}
|
|
179
|
+
// Only the two fields other than the collided one are ever offered, so an
|
|
180
|
+
// unreachable match is exactly one whose *both* remaining fields are shared;
|
|
181
|
+
// each branch spells out which two, and the rename un-shares the asset name.
|
|
182
|
+
const shortfall = (reason) => {
|
|
183
|
+
if (unreachable === 0)
|
|
184
|
+
return '';
|
|
185
|
+
const lead = partial
|
|
186
|
+
? `${unreachable} of the ${matches.length} cannot be addressed by any single value, because`
|
|
187
|
+
: 'That is because';
|
|
188
|
+
return ` ${lead} ${reason} — ${RENAME_CURE}.`;
|
|
189
|
+
};
|
|
190
|
+
if (field === 'localPath') {
|
|
191
|
+
const owners = matches.map((asset) => `${asset.name} (export ${asset.exportName})`);
|
|
192
|
+
return `${AMBIGUOUS_PREFIX}"${identifier}": that file exports ${matches.length} assets: ${owners.join(', ')}. `
|
|
193
|
+
+ `${advice}${shortfall('their asset name and their export name are each shared with a further asset')}`;
|
|
194
|
+
}
|
|
195
|
+
const owners = matches.map((asset) => `${asset.name} in ${asset.localPath}`);
|
|
196
|
+
return `${AMBIGUOUS_PREFIX}"${identifier}": ${matches.length} assets use "${identifier}" as their export name: ${owners.join(', ')}. `
|
|
197
|
+
+ `${advice}${shortfall('their asset name is shared with a further asset and their file exports more than one')}`;
|
|
23
198
|
}
|
|
24
199
|
export function findAssetOrExplain(registry, identifier) {
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
return { asset };
|
|
200
|
+
const match = resolveAsset(registry.assets, identifier);
|
|
201
|
+
if (match.kind === 'found')
|
|
202
|
+
return { asset: match.asset };
|
|
203
|
+
if (match.kind === 'ambiguous') {
|
|
204
|
+
return { error: describeAmbiguity(registry.assets, identifier, match.field, match.matches) };
|
|
205
|
+
}
|
|
28
206
|
// Check if any IMPORT_FAILED diagnostic mentions a path containing the identifier
|
|
29
207
|
const relatedDiag = registry.diagnostics.find((d) => d.code === 'IMPORT_FAILED' && d.filePath && d.filePath.includes(identifier));
|
|
30
208
|
if (relatedDiag) {
|
package/dist/utils/assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/utils/assets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/utils/assets.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/auth.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export interface EnvironmentConfig {
|
|
|
8
8
|
apiKey?: string;
|
|
9
9
|
/** Personal Access Token from `inquir login` (user-scoped credential). */
|
|
10
10
|
token?: string;
|
|
11
|
+
/** Only browser-issued sessions belong to the CLI; imported PATs do not. */
|
|
12
|
+
tokenSession?: StoredCliSession;
|
|
13
|
+
/** Explicit logout prevents a partial profile from inheriting credentials. */
|
|
14
|
+
loggedOut?: boolean;
|
|
11
15
|
/** Active workspace selector (tenant id or slug) for user-scoped credentials. */
|
|
12
16
|
workspaceId?: string;
|
|
13
17
|
/** Cached identity for `inquir whoami` after login. */
|
|
@@ -27,6 +31,23 @@ export interface ResolvedAuthConfig {
|
|
|
27
31
|
}
|
|
28
32
|
/** Default when no config, env, or flags set — first-party prod API (see proxy/Caddyfile). */
|
|
29
33
|
export declare const DEFAULT_API_URL = "https://api.inquir.org";
|
|
34
|
+
/** API base identity: URL canonicalization includes the scheme and base path. */
|
|
35
|
+
export declare function sameApiEndpoint(left: string, right: string): boolean;
|
|
36
|
+
export interface StoredCliSession {
|
|
37
|
+
source: 'cli-browser';
|
|
38
|
+
apiUrl: string;
|
|
39
|
+
tokenHash: string;
|
|
40
|
+
tokenId?: string;
|
|
41
|
+
expiresAt?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function cliSession(apiUrl: string, token: string, details?: {
|
|
44
|
+
tokenId?: string;
|
|
45
|
+
expiresAt?: string;
|
|
46
|
+
}): StoredCliSession;
|
|
47
|
+
/** Stale metadata must never turn a subsequently imported PAT into an owned session. */
|
|
48
|
+
export declare function ownedCliSession(slice: EnvironmentConfig): StoredCliSession | undefined;
|
|
49
|
+
/** Compare raw credentials too: another profile may use this token as an API key. */
|
|
50
|
+
export declare function configReferencesToken(config: AuthConfig, token: string, except?: EnvironmentConfig): boolean;
|
|
30
51
|
/** Absolute path to the active CLI config file (for `config path` / `doctor`). */
|
|
31
52
|
export declare function getConfigFilePath(): string;
|
|
32
53
|
export declare function loadAuthConfig(): Promise<AuthConfig>;
|
|
@@ -34,13 +55,19 @@ export declare function saveAuthConfig(nextConfig: AuthConfig): Promise<void>;
|
|
|
34
55
|
export declare function clearAuthConfig(): Promise<void>;
|
|
35
56
|
/** Resolve the active environment name from overrides or environment variables. */
|
|
36
57
|
export declare function resolveEnvironmentName(override?: string): string | undefined;
|
|
58
|
+
export declare function updateAuthConfig<T>(mutate: (config: AuthConfig) => T | Promise<T>): Promise<T>;
|
|
37
59
|
export declare function resolveAuthConfig(overrides?: Partial<AuthConfig> & {
|
|
38
60
|
environment?: string;
|
|
39
61
|
projectWorkspaceId?: string;
|
|
62
|
+
},
|
|
63
|
+
/** Only login may resolve defaults while creating a new named environment. */
|
|
64
|
+
behavior?: {
|
|
65
|
+
allowMissingEnvironment?: boolean;
|
|
40
66
|
}): Promise<ResolvedAuthConfig>;
|
|
41
67
|
/**
|
|
42
68
|
* Mutate the config slice for the active environment (top-level when no `--env`)
|
|
43
|
-
* and persist.
|
|
69
|
+
* and persist. The same loaded config is available for coordinated profile
|
|
70
|
+
* updates, such as retaining API bindings when login changes the default.
|
|
44
71
|
*/
|
|
45
|
-
export declare function updateEnvironmentConfig(environment: string | undefined, mutate: (slice: EnvironmentConfig) => void): Promise<
|
|
72
|
+
export declare function updateEnvironmentConfig<T>(environment: string | undefined, mutate: (slice: EnvironmentConfig, config: AuthConfig) => T | Promise<T>, afterSave?: (result: T, config: AuthConfig) => Promise<void>): Promise<T>;
|
|
46
73
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/utils/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/auth.js
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
5
|
+
import { CliError, ExitCode, usageError } from './errors.js';
|
|
4
6
|
/** Default when no config, env, or flags set — first-party prod API (see proxy/Caddyfile). */
|
|
5
7
|
export const DEFAULT_API_URL = 'https://api.inquir.org';
|
|
8
|
+
/** API base identity: URL canonicalization includes the scheme and base path. */
|
|
9
|
+
export function sameApiEndpoint(left, right) {
|
|
10
|
+
try {
|
|
11
|
+
return new URL(left).href.replace(/\/+$/, '') === new URL(right).href.replace(/\/+$/, '');
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return left === right;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function cliSession(apiUrl, token, details = {}) {
|
|
18
|
+
return { source: 'cli-browser', apiUrl, tokenHash: createHash('sha256').update(token).digest('hex'), ...details };
|
|
19
|
+
}
|
|
20
|
+
/** Stale metadata must never turn a subsequently imported PAT into an owned session. */
|
|
21
|
+
export function ownedCliSession(slice) {
|
|
22
|
+
const session = slice.tokenSession;
|
|
23
|
+
return slice.token && session?.source === 'cli-browser' &&
|
|
24
|
+
session.tokenHash === createHash('sha256').update(slice.token).digest('hex')
|
|
25
|
+
? session : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** Compare raw credentials too: another profile may use this token as an API key. */
|
|
28
|
+
export function configReferencesToken(config, token, except) {
|
|
29
|
+
return [process.env.INQUIR_TOKEN, process.env.INQUIR_API_KEY, process.env.LAMBDA_API_KEY].includes(token) ||
|
|
30
|
+
[config, ...Object.values(config.environments ?? {})].some((slice) => slice && slice !== except && !slice.loggedOut && (slice.token === token || slice.apiKey === token));
|
|
31
|
+
}
|
|
6
32
|
// Paths are resolved lazily (not module-level constants) so `os.homedir()` can
|
|
7
33
|
// be overridden in tests and respects HOME changes at runtime.
|
|
8
34
|
function configDir() {
|
|
@@ -52,8 +78,27 @@ export async function loadAuthConfig() {
|
|
|
52
78
|
}
|
|
53
79
|
export async function saveAuthConfig(nextConfig) {
|
|
54
80
|
await fs.mkdir(configDir(), { recursive: true, mode: 0o700 });
|
|
55
|
-
//
|
|
56
|
-
|
|
81
|
+
// Readers (including an older CLI) see a complete old or new file, never a
|
|
82
|
+
// truncated credential store. Keep the temporary file on the same volume.
|
|
83
|
+
const target = configFile();
|
|
84
|
+
const temporary = `${target}.${randomUUID()}.tmp`;
|
|
85
|
+
try {
|
|
86
|
+
const file = await fs.open(temporary, 'wx', 0o600);
|
|
87
|
+
try {
|
|
88
|
+
await file.writeFile(`${JSON.stringify(nextConfig, null, 2)}\n`, 'utf8');
|
|
89
|
+
await file.sync();
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await file.close();
|
|
93
|
+
}
|
|
94
|
+
await fs.rename(temporary, target);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
await fs.unlink(temporary).catch((error) => {
|
|
98
|
+
if (error.code !== 'ENOENT')
|
|
99
|
+
throw error;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
57
102
|
try {
|
|
58
103
|
await fs.chmod(configFile(), 0o600);
|
|
59
104
|
}
|
|
@@ -79,14 +124,93 @@ function envValue(value) {
|
|
|
79
124
|
}
|
|
80
125
|
/** Resolve the active environment name from overrides or environment variables. */
|
|
81
126
|
export function resolveEnvironmentName(override) {
|
|
127
|
+
if (override !== undefined && !override.trim()) {
|
|
128
|
+
throw usageError('Missing credential environment name', 'inquir config show --env <name>');
|
|
129
|
+
}
|
|
82
130
|
return override ?? envValue(process.env.INQUIR_ENV) ?? envValue(process.env.LAMBDA_ENV) ?? undefined;
|
|
83
131
|
}
|
|
84
|
-
|
|
132
|
+
/** Serialize credential mutations across CLI processes, including self-revocation. */
|
|
133
|
+
async function withAuthConfigLock(operation) {
|
|
134
|
+
await fs.mkdir(configDir(), { recursive: true, mode: 0o700 });
|
|
135
|
+
const lockPath = `${configFile()}.lock`;
|
|
136
|
+
const deadline = Date.now() + 10_000;
|
|
137
|
+
let lock;
|
|
138
|
+
for (;;) {
|
|
139
|
+
try {
|
|
140
|
+
lock = await fs.open(lockPath, 'wx', 0o600);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error.code !== 'EEXIST')
|
|
145
|
+
throw error;
|
|
146
|
+
if (Date.now() >= deadline) {
|
|
147
|
+
// Never steal a lock on a timeout: its owner may be between a remote
|
|
148
|
+
// revocation and a local write. A crash needs explicit local recovery.
|
|
149
|
+
throw new CliError('CLI configuration is locked by another command.', {
|
|
150
|
+
code: 'AUTH_CONFIG_LOCKED',
|
|
151
|
+
fix: `Wait for the other CLI command. If it crashed, close all CLI commands before removing ${lockPath}.`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
await lock.writeFile(JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() }), 'utf8');
|
|
159
|
+
return await operation();
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await lock.close();
|
|
163
|
+
await fs.unlink(lockPath);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export async function updateAuthConfig(mutate) {
|
|
167
|
+
return withAuthConfigLock(async () => {
|
|
168
|
+
const config = await loadAuthConfig();
|
|
169
|
+
const before = JSON.stringify(config);
|
|
170
|
+
const result = await mutate(config);
|
|
171
|
+
await assertConfigUnchanged(before);
|
|
172
|
+
await saveAuthConfig(config);
|
|
173
|
+
return result;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
async function assertConfigUnchanged(before) {
|
|
177
|
+
// An older CLI or an editor may ignore the lock. Do not overwrite a change
|
|
178
|
+
// observed while awaiting remote revocation or other asynchronous work.
|
|
179
|
+
if (JSON.stringify(await loadAuthConfig()) !== before) {
|
|
180
|
+
throw new CliError('CLI configuration changed during this command.', {
|
|
181
|
+
code: 'AUTH_CONFIG_CHANGED', fix: 'Retry after the other CLI command has finished.',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export async function resolveAuthConfig(overrides = {},
|
|
186
|
+
/** Only login may resolve defaults while creating a new named environment. */
|
|
187
|
+
behavior = {}) {
|
|
85
188
|
const fileConfig = await loadAuthConfig();
|
|
86
189
|
const selectedEnvironment = resolveEnvironmentName(overrides.environment);
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
190
|
+
const hasEnvironment = selectedEnvironment !== undefined &&
|
|
191
|
+
Object.prototype.hasOwnProperty.call(fileConfig.environments ?? {}, selectedEnvironment);
|
|
192
|
+
if (selectedEnvironment !== undefined && !hasEnvironment && !behavior.allowMissingEnvironment) {
|
|
193
|
+
throw new CliError(`Unknown credential environment: ${selectedEnvironment}`, {
|
|
194
|
+
code: 'UNKNOWN_ENVIRONMENT',
|
|
195
|
+
exitCode: ExitCode.USAGE,
|
|
196
|
+
explanation: `Credential environment "${selectedEnvironment}" is not configured. Choose an existing name, or create it with \`inquir login --env <name>\` or \`inquir config set apiUrl <url> --env <name>\`.`,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
const environmentConfig = hasEnvironment ? fileConfig.environments[selectedEnvironment] : {};
|
|
200
|
+
if (!environmentConfig || typeof environmentConfig !== 'object' || Array.isArray(environmentConfig)) {
|
|
201
|
+
throw new CliError(`Invalid credential environment: ${selectedEnvironment}`, {
|
|
202
|
+
code: 'INVALID_ENVIRONMENT',
|
|
203
|
+
exitCode: ExitCode.USAGE,
|
|
204
|
+
explanation: `Credential environment "${selectedEnvironment}" must be a configuration object. Correct it in ~/.inquir/config.json before retrying.`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// Partial named profiles may share the default credential only while they
|
|
208
|
+
// target the same API. A profile pointing elsewhere must never resurrect a
|
|
209
|
+
// default token/key or workspace after its own login is cleared.
|
|
210
|
+
const inheritedConfig = environmentConfig.loggedOut || fileConfig.loggedOut || (environmentConfig.apiUrl &&
|
|
211
|
+
!sameApiEndpoint(environmentConfig.apiUrl, fileConfig.apiUrl ?? DEFAULT_API_URL)) ? {}
|
|
212
|
+
: fileConfig;
|
|
213
|
+
const storedEnvironment = environmentConfig.loggedOut ? {} : environmentConfig;
|
|
90
214
|
const apiUrl = overrides.apiUrl
|
|
91
215
|
?? envValue(process.env.INQUIR_API_URL)
|
|
92
216
|
?? envValue(process.env.LAMBDA_API_URL)
|
|
@@ -96,39 +220,52 @@ export async function resolveAuthConfig(overrides = {}) {
|
|
|
96
220
|
const apiKey = overrides.apiKey
|
|
97
221
|
?? envValue(process.env.INQUIR_API_KEY)
|
|
98
222
|
?? envValue(process.env.LAMBDA_API_KEY)
|
|
99
|
-
??
|
|
100
|
-
??
|
|
223
|
+
?? storedEnvironment.apiKey
|
|
224
|
+
?? inheritedConfig.apiKey
|
|
101
225
|
?? undefined;
|
|
102
226
|
const token = overrides.token
|
|
103
227
|
?? envValue(process.env.INQUIR_TOKEN)
|
|
104
|
-
??
|
|
105
|
-
??
|
|
228
|
+
?? storedEnvironment.token
|
|
229
|
+
?? inheritedConfig.token
|
|
106
230
|
?? undefined;
|
|
107
231
|
const workspaceId = overrides.workspaceId // explicit --workspace
|
|
108
232
|
?? envValue(process.env.INQUIR_WORKSPACE) // env var
|
|
109
|
-
??
|
|
233
|
+
?? storedEnvironment.workspaceId // named credential environment
|
|
110
234
|
?? overrides.projectWorkspaceId // project link (inquir.config.json)
|
|
111
|
-
??
|
|
235
|
+
?? inheritedConfig.workspaceId // stored default for the same API
|
|
112
236
|
?? undefined;
|
|
113
|
-
|
|
237
|
+
// A cached identity from another token is not this profile's identity.
|
|
238
|
+
const user = storedEnvironment.user ?? (storedEnvironment.token && storedEnvironment.token !== inheritedConfig.token
|
|
239
|
+
? undefined
|
|
240
|
+
: inheritedConfig.user);
|
|
114
241
|
return { apiUrl, apiKey, token, workspaceId, user };
|
|
115
242
|
}
|
|
116
243
|
/**
|
|
117
244
|
* Mutate the config slice for the active environment (top-level when no `--env`)
|
|
118
|
-
* and persist.
|
|
245
|
+
* and persist. The same loaded config is available for coordinated profile
|
|
246
|
+
* updates, such as retaining API bindings when login changes the default.
|
|
119
247
|
*/
|
|
120
|
-
export async function updateEnvironmentConfig(environment, mutate) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
248
|
+
export async function updateEnvironmentConfig(environment, mutate, afterSave) {
|
|
249
|
+
return withAuthConfigLock(async () => {
|
|
250
|
+
const config = await loadAuthConfig();
|
|
251
|
+
const before = JSON.stringify(config);
|
|
252
|
+
const envName = resolveEnvironmentName(environment);
|
|
253
|
+
let slice = config;
|
|
254
|
+
if (envName) {
|
|
255
|
+
config.environments = config.environments ?? {};
|
|
256
|
+
const existing = Object.prototype.hasOwnProperty.call(config.environments, envName)
|
|
257
|
+
? config.environments[envName] : undefined;
|
|
258
|
+
if (existing !== undefined && (!existing || typeof existing !== 'object' || Array.isArray(existing))) {
|
|
259
|
+
throw new CliError(`Invalid credential environment: ${envName}`, { code: 'INVALID_ENVIRONMENT', exitCode: ExitCode.USAGE });
|
|
260
|
+
}
|
|
261
|
+
slice = existing ?? {};
|
|
262
|
+
Object.defineProperty(config.environments, envName, { value: slice, writable: true, enumerable: true, configurable: true });
|
|
263
|
+
}
|
|
264
|
+
const result = await mutate(slice, config);
|
|
265
|
+
await assertConfigUnchanged(before);
|
|
266
|
+
await saveAuthConfig(config);
|
|
267
|
+
await afterSave?.(result, config);
|
|
268
|
+
return result;
|
|
269
|
+
});
|
|
133
270
|
}
|
|
134
271
|
//# sourceMappingURL=auth.js.map
|
package/dist/utils/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/browser.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Only absolute http(s) URLs are ever handed to a launcher. The URL can come
|
|
3
|
+
* from the server (device-login verification URL), so anything else — other
|
|
4
|
+
* schemes, option-looking strings, or text with shell metacharacters that
|
|
5
|
+
* would not survive URL parsing — is refused.
|
|
6
|
+
*/
|
|
7
|
+
export declare function browserLaunchUrl(url: string): string | null;
|
|
8
|
+
/** Launcher command for the platform. No shell is involved on any platform. */
|
|
9
|
+
export declare function browserLaunchCommand(href: string, platform?: NodeJS.Platform): {
|
|
10
|
+
command: string;
|
|
11
|
+
args: string[];
|
|
12
|
+
};
|
|
1
13
|
/**
|
|
2
14
|
* Best-effort open of a URL in the user's default browser. Resolves to `true`
|
|
3
15
|
* if a launcher process was spawned, `false` otherwise (caller should then print
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAWrC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAchD"}
|