@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.
Files changed (119) hide show
  1. package/README.md +228 -21
  2. package/dist/commands/admin-tenants.d.ts +11 -0
  3. package/dist/commands/admin-tenants.d.ts.map +1 -0
  4. package/dist/commands/admin-tenants.js +318 -0
  5. package/dist/commands/admin-tenants.js.map +1 -0
  6. package/dist/commands/admin.d.ts +2 -0
  7. package/dist/commands/admin.d.ts.map +1 -0
  8. package/dist/commands/admin.js +445 -0
  9. package/dist/commands/admin.js.map +1 -0
  10. package/dist/commands/apps-describe.d.ts +9 -0
  11. package/dist/commands/apps-describe.d.ts.map +1 -0
  12. package/dist/commands/apps-describe.js +118 -0
  13. package/dist/commands/apps-describe.js.map +1 -0
  14. package/dist/commands/apps-observability.d.ts +9 -0
  15. package/dist/commands/apps-observability.d.ts.map +1 -0
  16. package/dist/commands/apps-observability.js +281 -0
  17. package/dist/commands/apps-observability.js.map +1 -0
  18. package/dist/commands/apps-promote.d.ts +31 -0
  19. package/dist/commands/apps-promote.d.ts.map +1 -0
  20. package/dist/commands/apps-promote.js +115 -0
  21. package/dist/commands/apps-promote.js.map +1 -0
  22. package/dist/commands/apps-resources.d.ts +6 -0
  23. package/dist/commands/apps-resources.d.ts.map +1 -0
  24. package/dist/commands/apps-resources.js +107 -0
  25. package/dist/commands/apps-resources.js.map +1 -0
  26. package/dist/commands/apps.d.ts +65 -5
  27. package/dist/commands/apps.d.ts.map +1 -1
  28. package/dist/commands/apps.js +1293 -89
  29. package/dist/commands/apps.js.map +1 -1
  30. package/dist/commands/config.d.ts.map +1 -1
  31. package/dist/commands/config.js +7 -3
  32. package/dist/commands/config.js.map +1 -1
  33. package/dist/commands/delete.d.ts.map +1 -1
  34. package/dist/commands/delete.js +10 -2
  35. package/dist/commands/delete.js.map +1 -1
  36. package/dist/commands/deploy.d.ts +38 -0
  37. package/dist/commands/deploy.d.ts.map +1 -1
  38. package/dist/commands/deploy.js +165 -12
  39. package/dist/commands/deploy.js.map +1 -1
  40. package/dist/commands/doctor.js +2 -2
  41. package/dist/commands/init.d.ts.map +1 -1
  42. package/dist/commands/init.js +3 -0
  43. package/dist/commands/init.js.map +1 -1
  44. package/dist/commands/login.d.ts.map +1 -1
  45. package/dist/commands/login.js +96 -20
  46. package/dist/commands/login.js.map +1 -1
  47. package/dist/commands/logout.d.ts.map +1 -1
  48. package/dist/commands/logout.js +37 -5
  49. package/dist/commands/logout.js.map +1 -1
  50. package/dist/commands/mcp.d.ts +13 -0
  51. package/dist/commands/mcp.d.ts.map +1 -1
  52. package/dist/commands/mcp.js +184 -77
  53. package/dist/commands/mcp.js.map +1 -1
  54. package/dist/commands/projects.d.ts +2 -0
  55. package/dist/commands/projects.d.ts.map +1 -0
  56. package/dist/commands/projects.js +194 -0
  57. package/dist/commands/projects.js.map +1 -0
  58. package/dist/index.js +11 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/lib/finite-source-command-client.d.ts +3 -0
  61. package/dist/lib/finite-source-command-client.d.ts.map +1 -0
  62. package/dist/lib/finite-source-command-client.js +3 -0
  63. package/dist/lib/finite-source-command-client.js.map +1 -0
  64. package/dist/lib/mcp-io.d.ts +23 -0
  65. package/dist/lib/mcp-io.d.ts.map +1 -0
  66. package/dist/lib/mcp-io.js +185 -0
  67. package/dist/lib/mcp-io.js.map +1 -0
  68. package/dist/lib/mcp-source-commands.d.ts +17 -0
  69. package/dist/lib/mcp-source-commands.d.ts.map +1 -0
  70. package/dist/lib/mcp-source-commands.js +345 -0
  71. package/dist/lib/mcp-source-commands.js.map +1 -0
  72. package/dist/utils/api.d.ts +58 -8
  73. package/dist/utils/api.d.ts.map +1 -1
  74. package/dist/utils/api.js +86 -7
  75. package/dist/utils/api.js.map +1 -1
  76. package/dist/utils/apps-presentation.d.ts +11 -1
  77. package/dist/utils/apps-presentation.d.ts.map +1 -1
  78. package/dist/utils/apps-presentation.js +37 -0
  79. package/dist/utils/apps-presentation.js.map +1 -1
  80. package/dist/utils/args.d.ts.map +1 -1
  81. package/dist/utils/args.js +8 -1
  82. package/dist/utils/args.js.map +1 -1
  83. package/dist/utils/assets.d.ts +48 -1
  84. package/dist/utils/assets.d.ts.map +1 -1
  85. package/dist/utils/assets.js +185 -7
  86. package/dist/utils/assets.js.map +1 -1
  87. package/dist/utils/auth.d.ts +29 -2
  88. package/dist/utils/auth.d.ts.map +1 -1
  89. package/dist/utils/auth.js +164 -27
  90. package/dist/utils/auth.js.map +1 -1
  91. package/dist/utils/browser.d.ts +12 -0
  92. package/dist/utils/browser.d.ts.map +1 -1
  93. package/dist/utils/browser.js +37 -16
  94. package/dist/utils/browser.js.map +1 -1
  95. package/dist/utils/context.d.ts.map +1 -1
  96. package/dist/utils/context.js +2 -0
  97. package/dist/utils/context.js.map +1 -1
  98. package/dist/utils/deploy-follow.d.ts +4 -3
  99. package/dist/utils/deploy-follow.d.ts.map +1 -1
  100. package/dist/utils/deploy-follow.js +76 -17
  101. package/dist/utils/deploy-follow.js.map +1 -1
  102. package/dist/utils/detect.d.ts +49 -1
  103. package/dist/utils/detect.d.ts.map +1 -1
  104. package/dist/utils/detect.js +153 -12
  105. package/dist/utils/detect.js.map +1 -1
  106. package/dist/utils/ensure-auth.d.ts.map +1 -1
  107. package/dist/utils/ensure-auth.js +6 -2
  108. package/dist/utils/ensure-auth.js.map +1 -1
  109. package/dist/utils/package-metadata.js +1 -1
  110. package/dist/utils/project-context.d.ts +17 -0
  111. package/dist/utils/project-context.d.ts.map +1 -0
  112. package/dist/utils/project-context.js +96 -0
  113. package/dist/utils/project-context.js.map +1 -0
  114. package/dist/utils/project-lookup.d.ts +10 -0
  115. package/dist/utils/project-lookup.d.ts.map +1 -0
  116. package/dist/utils/project-lookup.js +52 -0
  117. package/dist/utils/project-lookup.js.map +1 -0
  118. package/package.json +7 -4
  119. package/skill/SKILL.md +15 -2
@@ -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 list what's available.
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
- return assets.find((asset) => asset.name === identifier
21
- || asset.exportName === identifier
22
- || asset.localPath === identifier);
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 asset = findAsset(registry.assets, identifier);
26
- if (asset)
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) {
@@ -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;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,WAAmB;IACxE,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACjE,OAAO,IAAI,QAAQ,CACjB,eAAe,CAAC,CAAC,CAAC,UAAU,UAAU,kBAAkB,CAAC,CAAC,CAAC,UAAU,UAAU,aAAa,EAC5F;QACE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB;QACjE,QAAQ,EAAE,QAAQ,CAAC,KAAK;QACxB,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACtD,GAAG,EAAE,eAAe;YAClB,CAAC,CAAC,iDAAiD;YACnD,CAAC,CAAC,uCAAuC;QAC3C,OAAO,EAAE,aAAa;KACvB,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,UAAkB;IAChE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,KAAK,CAAC,IAAI,KAAK,UAAU;WACtB,KAAK,CAAC,UAAU,KAAK,UAAU;WAC/B,KAAK,CAAC,SAAS,KAAK,UAAU,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,QAAuB,EACvB,UAAkB;IAElB,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrD,IAAI,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAE5B,kFAAkF;IAClF,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CACnF,CAAC;IAEF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,KAAK,EAAE,UAAU,UAAU,uBAAuB,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;SACnI,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,oBAAoB,UAAU,EAAE,EAAE,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/utils/assets.ts"],"names":[],"mappings":"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"}
@@ -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. Used by login/logout/use to update credentials in place.
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<void>;
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
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,iBAAiB;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACjD,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,8FAA8F;AAC9F,eAAO,MAAM,eAAe,2BAA2B,CAAC;AAcxD,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CA2B1D;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAS1E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAMrD;AAWD,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E;AAED,wBAAsB,iBAAiB,CACrC,SAAS,GAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1F,OAAO,CAAC,kBAAkB,CAAC,CAwC7B;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GACzC,OAAO,CAAC,IAAI,CAAC,CAYf"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
@@ -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
- // Credentials live here — write with owner-only permissions.
56
- await fs.writeFile(configFile(), `${JSON.stringify(nextConfig, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
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
- export async function resolveAuthConfig(overrides = {}) {
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 environmentConfig = selectedEnvironment
88
- ? fileConfig.environments?.[selectedEnvironment] ?? {}
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
- ?? environmentConfig.apiKey
100
- ?? fileConfig.apiKey
223
+ ?? storedEnvironment.apiKey
224
+ ?? inheritedConfig.apiKey
101
225
  ?? undefined;
102
226
  const token = overrides.token
103
227
  ?? envValue(process.env.INQUIR_TOKEN)
104
- ?? environmentConfig.token
105
- ?? fileConfig.token
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
- ?? environmentConfig.workspaceId // named credential environment
233
+ ?? storedEnvironment.workspaceId // named credential environment
110
234
  ?? overrides.projectWorkspaceId // project link (inquir.config.json)
111
- ?? fileConfig.workspaceId // stored global default
235
+ ?? inheritedConfig.workspaceId // stored default for the same API
112
236
  ?? undefined;
113
- const user = environmentConfig.user ?? fileConfig.user;
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. Used by login/logout/use to update credentials in place.
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
- const config = await loadAuthConfig();
122
- const envName = resolveEnvironmentName(environment);
123
- if (envName) {
124
- config.environments = config.environments ?? {};
125
- const slice = config.environments[envName] ?? {};
126
- mutate(slice);
127
- config.environments[envName] = slice;
128
- }
129
- else {
130
- mutate(config);
131
- }
132
- await saveAuthConfig(config);
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
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
@@ -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,CAyBhD"}
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"}