@indecisivedev/openplan 0.2.0-alpha.2

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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/access-policy.d.ts +35 -0
  4. package/dist/access-policy.js +107 -0
  5. package/dist/access-policy.js.map +1 -0
  6. package/dist/access-store.d.ts +33 -0
  7. package/dist/access-store.js +212 -0
  8. package/dist/access-store.js.map +1 -0
  9. package/dist/admin.d.ts +1 -0
  10. package/dist/admin.js +13 -0
  11. package/dist/admin.js.map +1 -0
  12. package/dist/api.d.ts +2 -0
  13. package/dist/api.js +867 -0
  14. package/dist/api.js.map +1 -0
  15. package/dist/bootstrap-admin.d.ts +1 -0
  16. package/dist/bootstrap-admin.js +35 -0
  17. package/dist/bootstrap-admin.js.map +1 -0
  18. package/dist/browser-security.d.ts +5 -0
  19. package/dist/browser-security.js +53 -0
  20. package/dist/browser-security.js.map +1 -0
  21. package/dist/celld-quickstart.d.ts +51 -0
  22. package/dist/celld-quickstart.js +1175 -0
  23. package/dist/celld-quickstart.js.map +1 -0
  24. package/dist/cli-api-client.d.ts +78 -0
  25. package/dist/cli-api-client.js +272 -0
  26. package/dist/cli-api-client.js.map +1 -0
  27. package/dist/cli-credentials.d.ts +47 -0
  28. package/dist/cli-credentials.js +447 -0
  29. package/dist/cli-credentials.js.map +1 -0
  30. package/dist/cli-endpoint.d.ts +19 -0
  31. package/dist/cli-endpoint.js +56 -0
  32. package/dist/cli-endpoint.js.map +1 -0
  33. package/dist/cli-program.d.ts +11 -0
  34. package/dist/cli-program.js +934 -0
  35. package/dist/cli-program.js.map +1 -0
  36. package/dist/cli.d.ts +2 -0
  37. package/dist/cli.js +7 -0
  38. package/dist/cli.js.map +1 -0
  39. package/dist/client-ip.d.ts +4 -0
  40. package/dist/client-ip.js +49 -0
  41. package/dist/client-ip.js.map +1 -0
  42. package/dist/config.d.ts +35 -0
  43. package/dist/config.js +113 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/crypto.d.ts +3 -0
  46. package/dist/crypto.js +11 -0
  47. package/dist/crypto.js.map +1 -0
  48. package/dist/database.d.ts +15 -0
  49. package/dist/database.js +155 -0
  50. package/dist/database.js.map +1 -0
  51. package/dist/db.d.ts +31 -0
  52. package/dist/db.js +388 -0
  53. package/dist/db.js.map +1 -0
  54. package/dist/drafts.d.ts +43 -0
  55. package/dist/drafts.js +90 -0
  56. package/dist/drafts.js.map +1 -0
  57. package/dist/feature-settings.d.ts +7 -0
  58. package/dist/feature-settings.js +32 -0
  59. package/dist/feature-settings.js.map +1 -0
  60. package/dist/generated/annotation-client.d.ts +1 -0
  61. package/dist/generated/annotation-client.js +2 -0
  62. package/dist/generated/annotation-client.js.map +1 -0
  63. package/dist/html-policy.d.ts +15 -0
  64. package/dist/html-policy.js +172 -0
  65. package/dist/html-policy.js.map +1 -0
  66. package/dist/ids.d.ts +2 -0
  67. package/dist/ids.js +10 -0
  68. package/dist/ids.js.map +1 -0
  69. package/dist/local-auth.d.ts +36 -0
  70. package/dist/local-auth.js +215 -0
  71. package/dist/local-auth.js.map +1 -0
  72. package/dist/maintenance.d.ts +1 -0
  73. package/dist/maintenance.js +18 -0
  74. package/dist/maintenance.js.map +1 -0
  75. package/dist/oidc.d.ts +39 -0
  76. package/dist/oidc.js +194 -0
  77. package/dist/oidc.js.map +1 -0
  78. package/dist/public-url.d.ts +17 -0
  79. package/dist/public-url.js +96 -0
  80. package/dist/public-url.js.map +1 -0
  81. package/dist/rate-limit.d.ts +25 -0
  82. package/dist/rate-limit.js +55 -0
  83. package/dist/rate-limit.js.map +1 -0
  84. package/dist/reconcile.d.ts +5 -0
  85. package/dist/reconcile.js +18 -0
  86. package/dist/reconcile.js.map +1 -0
  87. package/dist/render-annotations.d.ts +10 -0
  88. package/dist/render-annotations.js +73 -0
  89. package/dist/render-annotations.js.map +1 -0
  90. package/dist/render-web.d.ts +74 -0
  91. package/dist/render-web.js +439 -0
  92. package/dist/render-web.js.map +1 -0
  93. package/dist/render.d.ts +4 -0
  94. package/dist/render.js +85 -0
  95. package/dist/render.js.map +1 -0
  96. package/dist/server.d.ts +1 -0
  97. package/dist/server.js +26 -0
  98. package/dist/server.js.map +1 -0
  99. package/dist/shoo.d.ts +26 -0
  100. package/dist/shoo.js +92 -0
  101. package/dist/shoo.js.map +1 -0
  102. package/dist/sqlite-migrations.d.ts +6 -0
  103. package/dist/sqlite-migrations.js +214 -0
  104. package/dist/sqlite-migrations.js.map +1 -0
  105. package/dist/storage.d.ts +14 -0
  106. package/dist/storage.js +86 -0
  107. package/dist/storage.js.map +1 -0
  108. package/dist/types.d.ts +24 -0
  109. package/dist/types.js +2 -0
  110. package/dist/types.js.map +1 -0
  111. package/dist/upload-state.d.ts +19 -0
  112. package/dist/upload-state.js +118 -0
  113. package/dist/upload-state.js.map +1 -0
  114. package/dist/web-auth.d.ts +33 -0
  115. package/dist/web-auth.js +122 -0
  116. package/dist/web-auth.js.map +1 -0
  117. package/dist/web.d.ts +2 -0
  118. package/dist/web.js +550 -0
  119. package/dist/web.js.map +1 -0
  120. package/package.json +70 -0
@@ -0,0 +1,447 @@
1
+ import fs from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import path from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
+ import { normalizeApiUrl } from "./cli-endpoint.js";
6
+ export class CredentialError extends Error {
7
+ code;
8
+ constructor(code, message) {
9
+ super(message);
10
+ this.code = code;
11
+ this.name = "CredentialError";
12
+ }
13
+ }
14
+ const MAX_STORE_BYTES = 1024 * 1024;
15
+ const metadataKeys = ["accountId", "accountName", "apiKeyId", "apiKeyName"];
16
+ function fail(code, message) { throw new CredentialError(code, message); }
17
+ function record(value) { return !!value && typeof value === "object" && !Array.isArray(value); }
18
+ export function validateApiKey(key) {
19
+ if (typeof key !== "string" || !key || key.length > 8192 || !/^[\x21-\x7e]+$/.test(key))
20
+ fail("INVALID_KEY", "API key must be a nonempty, bounded printable token without whitespace.");
21
+ }
22
+ /** Internal redaction primitive; supplied secrets never appear in its result. */
23
+ export function textContainsSecret(value, secret) {
24
+ let decoded = value;
25
+ for (let depth = 0; depth < 8; depth++) {
26
+ if (decoded.includes(secret))
27
+ return true;
28
+ // Keys are printable ASCII. Decode ASCII percent bytes individually so an
29
+ // unrelated malformed UTF-8 escape cannot hide an otherwise encoded key.
30
+ const next = decoded.replace(/%([0-9a-f]{2})/gi, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
31
+ if (next === decoded)
32
+ return false;
33
+ decoded = next;
34
+ }
35
+ // Refuse pathological multilayer escaping rather than unbounded CPU work or
36
+ // allowing another decoder to reveal secret text beyond our inspection bound.
37
+ return decoded.includes(secret) || /%[0-9a-f]{2}/i.test(decoded);
38
+ }
39
+ function validateSnapshotMetadata(data) {
40
+ const entries = Object.values(data.byOrigin);
41
+ const keys = [...entries.map(entry => entry.apiKey), ...(data.legacyUnbound ? [data.legacyUnbound.apiKey] : [])];
42
+ for (const entry of entries) {
43
+ for (const field of metadataKeys) {
44
+ const value = entry[field];
45
+ if (value !== undefined && keys.some(key => textContainsSecret(value, key)))
46
+ fail("INVALID_STORE", "Credential metadata contains secret material and cannot be displayed.");
47
+ }
48
+ }
49
+ }
50
+ function validEntry(value, legacy = false) {
51
+ if (!record(value) || Object.keys(value).some(k => !["apiKey", "updatedAt", ...(legacy ? [] : metadataKeys)].includes(k)))
52
+ fail("INVALID_STORE", "Credential store has an invalid record; preserve it for owner-controlled repair.");
53
+ try {
54
+ validateApiKey(value.apiKey);
55
+ }
56
+ catch {
57
+ fail("INVALID_STORE", "Credential store has an invalid key record; preserve it for owner-controlled repair.");
58
+ }
59
+ for (const key of ["updatedAt", ...metadataKeys]) {
60
+ if (value[key] !== undefined && (typeof value[key] !== "string" || value[key].length > 1024 || /[\x00-\x1f\x7f]/.test(value[key])))
61
+ fail("INVALID_STORE", "Credential store has invalid metadata.");
62
+ }
63
+ for (const key of metadataKeys) {
64
+ if (typeof value[key] === "string" && textContainsSecret(value[key], value.apiKey))
65
+ fail("INVALID_STORE", "Credential metadata contains secret material and cannot be displayed.");
66
+ }
67
+ return value;
68
+ }
69
+ function rejectDuplicateKeys(text) {
70
+ // JSON.parse otherwise silently discards duplicate records. Only scan after
71
+ // parsing succeeds, so colons following string tokens unambiguously mark keys.
72
+ const objects = [];
73
+ const tokens = /"(?:\\.|[^"\\])*"|[{}\[\]]/g;
74
+ for (const match of text.matchAll(tokens)) {
75
+ const token = match[0];
76
+ if (token === "{")
77
+ objects.push(new Set());
78
+ else if (token === "[")
79
+ objects.push(null);
80
+ else if (token === "}" || token === "]")
81
+ objects.pop();
82
+ else if (text.slice(match.index + token.length).trimStart().startsWith(":")) {
83
+ const keys = objects.at(-1);
84
+ const key = JSON.parse(token);
85
+ if (keys?.has(key))
86
+ fail("INVALID_STORE", "Credential store contains duplicate JSON keys; no records were merged.");
87
+ keys?.add(key);
88
+ }
89
+ }
90
+ }
91
+ function parseSnapshot(text) {
92
+ let value;
93
+ try {
94
+ value = JSON.parse(text);
95
+ }
96
+ catch {
97
+ fail("INVALID_STORE", "Credential store is not valid JSON; preserve it for owner-controlled repair.");
98
+ }
99
+ rejectDuplicateKeys(text);
100
+ if (!record(value))
101
+ fail("INVALID_STORE", "Credential store has an unsupported schema.");
102
+ if (!("version" in value)) {
103
+ if (!Object.hasOwn(value, "apiKey"))
104
+ fail("INVALID_STORE", "Credential store has an unsupported schema.");
105
+ return { kind: "legacy", entry: validEntry(value, true) };
106
+ }
107
+ if (value.version !== 2)
108
+ fail("UNSUPPORTED_VERSION", "Credential store version is unsupported; do not overwrite it with this client.");
109
+ if (Object.keys(value).some(k => !["version", "byOrigin", "legacyUnbound"].includes(k)) || !record(value.byOrigin))
110
+ fail("INVALID_STORE", "Credential store has an invalid v2 schema.");
111
+ const byOrigin = Object.create(null);
112
+ for (const [origin, entry] of Object.entries(value.byOrigin)) {
113
+ let normalized;
114
+ try {
115
+ normalized = normalizeApiUrl(origin);
116
+ }
117
+ catch {
118
+ fail("INVALID_STORE", "Credential store contains an invalid origin.");
119
+ }
120
+ if (normalized !== origin)
121
+ fail("INVALID_STORE", "Credential store origins must already be canonical; no entries were merged.");
122
+ byOrigin[origin] = validEntry(entry);
123
+ }
124
+ const data = { version: 2, byOrigin };
125
+ if (Object.hasOwn(value, "legacyUnbound"))
126
+ data.legacyUnbound = validEntry(value.legacyUnbound, true);
127
+ validateSnapshotMetadata(data);
128
+ return { kind: "v2", data };
129
+ }
130
+ function metadata(entry) {
131
+ const result = {};
132
+ for (const key of metadataKeys)
133
+ if (entry[key] !== undefined)
134
+ result[key] = entry[key];
135
+ return result;
136
+ }
137
+ function osCode(error) { return error?.code; }
138
+ function privateStat(stat, directory) {
139
+ if ((directory ? !stat.isDirectory() : !stat.isFile()) || stat.uid !== process.getuid?.() || (stat.mode & 0o7077) !== 0 || (!directory && stat.nlink !== 1)) {
140
+ fail("UNSAFE_STORE", "Unsafe credential state ownership, permissions or file type. Inspect ~/.openplan and repair ownership/private modes without following links.");
141
+ }
142
+ }
143
+ function sameFile(a, b) { return a.dev === b.dev && a.ino === b.ino; }
144
+ const secrets = new WeakMap();
145
+ export function enrollmentCredential(origin, apiKey) {
146
+ validateApiKey(apiKey);
147
+ return bind(normalizeApiUrl(origin), apiKey, "enrollment");
148
+ }
149
+ function bind(origin, key, source) {
150
+ const result = Object.freeze({ origin, source });
151
+ secrets.set(result, key);
152
+ return result;
153
+ }
154
+ /** Internal transport boundary: not a command-facing credential context. */
155
+ export function credentialAuthorization(credential, origin) {
156
+ const key = secrets.get(credential);
157
+ if (!key || credential.origin !== origin)
158
+ fail("ORIGIN_MISMATCH", "Credential does not belong to the selected origin.");
159
+ return `Bearer ${key}`;
160
+ }
161
+ function environmentCredential(origin, env) {
162
+ if (env.OPENPLAN_API_KEY === undefined && env.OPENPLAN_API_KEY_ORIGIN === undefined)
163
+ return undefined;
164
+ if (!env.OPENPLAN_API_KEY || !env.OPENPLAN_API_KEY_ORIGIN)
165
+ fail("INVALID_ENV_BINDING", "Set both OPENPLAN_API_KEY and OPENPLAN_API_KEY_ORIGIN, or unset both to use saved credentials.");
166
+ let bound;
167
+ try {
168
+ validateApiKey(env.OPENPLAN_API_KEY);
169
+ bound = normalizeApiUrl(env.OPENPLAN_API_KEY_ORIGIN);
170
+ }
171
+ catch {
172
+ fail("INVALID_ENV_BINDING", "The environment API key/origin binding is invalid; no saved credential was substituted.");
173
+ }
174
+ if (bound !== origin)
175
+ fail("ENV_ORIGIN_MISMATCH", "OPENPLAN_API_KEY_ORIGIN does not match the selected origin; no request was sent. Unset both key variables to use saved credentials.");
176
+ return bind(origin, env.OPENPLAN_API_KEY, "environment");
177
+ }
178
+ export class CredentialStore {
179
+ #directory;
180
+ #lockTimeoutMs;
181
+ #lockRetryMs;
182
+ constructor(homeDir, options = {}) {
183
+ this.#directory = path.join(path.resolve(homeDir), ".openplan");
184
+ this.#lockTimeoutMs = options.lockTimeoutMs ?? 3000;
185
+ this.#lockRetryMs = options.lockRetryMs ?? 25;
186
+ if (![this.#lockTimeoutMs, this.#lockRetryMs].every(x => Number.isSafeInteger(x) && x > 0 && x <= 60_000))
187
+ fail("INVALID_OPTIONS", "Credential lock timing must be finite and bounded.");
188
+ }
189
+ async #openDirectory(create) {
190
+ if (process.platform !== "linux") {
191
+ fail("UNSUPPORTED_PLATFORM", "Saved CLI credentials require Linux for this alpha. Run the CLI on Linux or in a Linux container; native macOS and Windows credential storage is not supported yet.");
192
+ }
193
+ try {
194
+ // Reject symlinks in the supplied home path as well as the state directory.
195
+ const home = path.dirname(this.#directory);
196
+ let cursor = path.parse(home).root;
197
+ for (const component of home.slice(cursor.length).split(path.sep).filter(Boolean)) {
198
+ cursor = path.join(cursor, component);
199
+ const stat = await fs.lstat(cursor);
200
+ if (!stat.isDirectory() || stat.isSymbolicLink())
201
+ fail("UNSAFE_STORE", "Credential home must use real directories, not symlinks.");
202
+ }
203
+ if (create) {
204
+ let created = false;
205
+ try {
206
+ await fs.mkdir(this.#directory, { mode: 0o700 });
207
+ created = true;
208
+ }
209
+ catch (error) {
210
+ if (osCode(error) !== "EEXIST")
211
+ throw error;
212
+ }
213
+ if (created) {
214
+ // Persist the new directory's entry as well, not just its contents.
215
+ const parent = await fs.open(home, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
216
+ try {
217
+ await parent.sync();
218
+ }
219
+ finally {
220
+ await parent.close();
221
+ }
222
+ }
223
+ }
224
+ let before;
225
+ try {
226
+ before = await fs.lstat(this.#directory);
227
+ }
228
+ catch (error) {
229
+ if (!create && osCode(error) === "ENOENT")
230
+ return undefined;
231
+ throw error;
232
+ }
233
+ privateStat(before, true);
234
+ const handle = await fs.open(this.#directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
235
+ try {
236
+ const after = await handle.stat();
237
+ privateStat(after, true);
238
+ if (!sameFile(before, after))
239
+ fail("UNSAFE_STORE", "Credential directory changed during inspection.");
240
+ return handle;
241
+ }
242
+ catch (error) {
243
+ await handle.close();
244
+ throw error;
245
+ }
246
+ }
247
+ catch (error) {
248
+ if (error instanceof CredentialError)
249
+ throw error;
250
+ fail("STORE_IO", "Cannot safely access the credential directory; inspect its ownership and private permissions.");
251
+ }
252
+ }
253
+ #at(directory, filename) {
254
+ // Supported Linux profile: anchor operations to the inspected open directory,
255
+ // rather than resolving a possibly replaced parent path again.
256
+ return `/proc/self/fd/${directory.fd}/${filename}`;
257
+ }
258
+ async #read(directory) {
259
+ let file;
260
+ try {
261
+ const filename = this.#at(directory, "credentials.json");
262
+ let before;
263
+ try {
264
+ before = await fs.lstat(filename);
265
+ }
266
+ catch (error) {
267
+ if (osCode(error) === "ENOENT")
268
+ return { kind: "missing" };
269
+ throw error;
270
+ }
271
+ privateStat(before, false);
272
+ file = await fs.open(filename, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
273
+ const stat = await file.stat();
274
+ privateStat(stat, false);
275
+ if (!sameFile(before, stat))
276
+ fail("UNSAFE_STORE", "Credential file changed during inspection.");
277
+ if (stat.size > MAX_STORE_BYTES)
278
+ fail("INVALID_STORE", "Credential store exceeds the supported size bound.");
279
+ const buffer = Buffer.alloc(MAX_STORE_BYTES + 1);
280
+ let offset = 0;
281
+ while (offset < buffer.length) {
282
+ const { bytesRead } = await file.read(buffer, offset, buffer.length - offset, null);
283
+ if (!bytesRead)
284
+ break;
285
+ offset += bytesRead;
286
+ }
287
+ if (offset > MAX_STORE_BYTES)
288
+ fail("INVALID_STORE", "Credential store exceeds the supported size bound.");
289
+ let text;
290
+ try {
291
+ text = new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
292
+ }
293
+ catch {
294
+ return fail("INVALID_STORE", "Credential store is not valid UTF-8; existing state was not replaced.");
295
+ }
296
+ return parseSnapshot(text);
297
+ }
298
+ catch (error) {
299
+ if (error instanceof CredentialError)
300
+ throw error;
301
+ return fail("STORE_IO", "Cannot safely read credential state; existing state was not replaced.");
302
+ }
303
+ finally {
304
+ await file?.close();
305
+ }
306
+ }
307
+ async #snapshot() {
308
+ const directory = await this.#openDirectory(false);
309
+ if (!directory)
310
+ return { kind: "missing" };
311
+ try {
312
+ return await this.#read(directory);
313
+ }
314
+ finally {
315
+ await directory.close();
316
+ }
317
+ }
318
+ async resolve(originInput, env = process.env) {
319
+ const origin = normalizeApiUrl(originInput);
320
+ const ambient = environmentCredential(origin, env);
321
+ if (ambient)
322
+ return ambient;
323
+ const snapshot = await this.#snapshot();
324
+ if (snapshot.kind === "v2" && snapshot.data.byOrigin[origin])
325
+ return bind(origin, snapshot.data.byOrigin[origin].apiKey, "saved");
326
+ if (snapshot.kind === "legacy")
327
+ fail("LEGACY_UNBOUND", "Legacy credentials are unbound and inactive. Reauthenticate explicitly with openplan auth login; no discovery request was sent.");
328
+ fail("MISSING_CREDENTIAL", "No saved credential for the selected origin. Run openplan auth login for this origin.");
329
+ }
330
+ async status(originInput, env = process.env) {
331
+ const origin = normalizeApiUrl(originInput);
332
+ const ambient = environmentCredential(origin, env);
333
+ const snapshot = await this.#snapshot();
334
+ const entry = snapshot.kind === "v2" ? snapshot.data.byOrigin[origin] : undefined;
335
+ const hasLegacyUnbound = snapshot.kind === "legacy" || (snapshot.kind === "v2" && !!snapshot.data.legacyUnbound);
336
+ return { origin, source: ambient ? "environment" : entry ? "saved" : hasLegacyUnbound ? "legacy" : "none", hasSavedCredential: !!entry, hasLegacyUnbound, ...(entry && !ambient ? { metadata: metadata(entry) } : {}) };
337
+ }
338
+ async #mutate(change) {
339
+ const directory = (await this.#openDirectory(true));
340
+ const lockPath = this.#at(directory, "credentials.lock");
341
+ let lock;
342
+ let lockStat;
343
+ let temp;
344
+ let committed = false;
345
+ try {
346
+ const start = Date.now();
347
+ while (!lock) {
348
+ try {
349
+ lock = await fs.open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
350
+ lockStat = await lock.stat();
351
+ privateStat(lockStat, false);
352
+ }
353
+ catch (error) {
354
+ if (osCode(error) !== "EEXIST")
355
+ throw error;
356
+ try {
357
+ privateStat(await fs.lstat(lockPath), false);
358
+ }
359
+ catch (e) {
360
+ if (osCode(e) === "ENOENT")
361
+ continue;
362
+ throw e;
363
+ }
364
+ if (Date.now() - start >= this.#lockTimeoutMs)
365
+ fail("LOCK_TIMEOUT", "Credential store is locked. Inspect the writer or abandoned lock; locks are never automatically broken.");
366
+ await new Promise(resolve => setTimeout(resolve, this.#lockRetryMs));
367
+ }
368
+ }
369
+ const { data, result } = change(await this.#read(directory));
370
+ if (!data)
371
+ return result;
372
+ validateSnapshotMetadata(data);
373
+ const serialized = `${JSON.stringify(data, null, 2)}\n`;
374
+ if (Buffer.byteLength(serialized) > MAX_STORE_BYTES)
375
+ fail("INVALID_STORE", "Credential store would exceed the supported size bound.");
376
+ temp = this.#at(directory, `.credentials-${randomUUID()}.tmp`);
377
+ const file = await fs.open(temp, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
378
+ try {
379
+ await file.writeFile(serialized, "utf8");
380
+ await file.sync();
381
+ }
382
+ finally {
383
+ await file.close();
384
+ }
385
+ // Refuse a newly unsafe destination, even though rename would not follow it.
386
+ await this.#read(directory);
387
+ await fs.rename(temp, this.#at(directory, "credentials.json"));
388
+ committed = true;
389
+ temp = undefined;
390
+ await directory.sync();
391
+ return result;
392
+ }
393
+ catch (error) {
394
+ if (committed)
395
+ fail("PERSISTENCE_UNCERTAIN", "Credential replacement occurred but durability could not be confirmed. Persistence is uncertain; inspect local auth status before retrying.");
396
+ if (error instanceof CredentialError)
397
+ throw error;
398
+ return fail("STORE_WRITE", "Credential update failed before replacement; existing credentials were preserved. Inspect local state before retrying.");
399
+ }
400
+ finally {
401
+ if (temp)
402
+ await fs.unlink(temp).catch(() => { });
403
+ if (lock) {
404
+ try {
405
+ const current = await fs.lstat(lockPath);
406
+ if (lockStat && sameFile(current, lockStat))
407
+ await fs.unlink(lockPath);
408
+ }
409
+ catch { /* Do not unlink another writer's lock or obscure the commit result. */ }
410
+ await lock.close().catch(() => { });
411
+ }
412
+ await directory.close().catch(() => { });
413
+ }
414
+ }
415
+ async save(originInput, apiKey, info = {}) {
416
+ const origin = normalizeApiUrl(originInput);
417
+ validateApiKey(apiKey);
418
+ const entry = validEntry({ apiKey, ...metadata({ apiKey, ...info }), updatedAt: new Date().toISOString() });
419
+ return this.#mutate(snapshot => {
420
+ const data = snapshot.kind === "v2" ? snapshot.data : { version: 2, byOrigin: Object.create(null), ...(snapshot.kind === "legacy" ? { legacyUnbound: snapshot.entry } : {}) };
421
+ data.byOrigin[origin] = entry;
422
+ if (data.legacyUnbound?.apiKey === apiKey)
423
+ delete data.legacyUnbound;
424
+ return { data, result: { hasLegacyUnbound: !!data.legacyUnbound } };
425
+ });
426
+ }
427
+ async remove(originInput) {
428
+ const origin = normalizeApiUrl(originInput);
429
+ return this.#mutate(snapshot => {
430
+ const hasLegacyUnbound = snapshot.kind === "legacy" || (snapshot.kind === "v2" && !!snapshot.data.legacyUnbound);
431
+ if (snapshot.kind !== "v2" || !snapshot.data.byOrigin[origin])
432
+ return { result: { removed: false, hasLegacyUnbound } };
433
+ delete snapshot.data.byOrigin[origin];
434
+ return { data: snapshot.data, result: { removed: true, hasLegacyUnbound } };
435
+ });
436
+ }
437
+ async removeLegacy() {
438
+ return this.#mutate(snapshot => {
439
+ if (snapshot.kind === "missing" || (snapshot.kind === "v2" && !snapshot.data.legacyUnbound))
440
+ return { result: { removed: false } };
441
+ const data = snapshot.kind === "v2" ? snapshot.data : { version: 2, byOrigin: Object.create(null) };
442
+ delete data.legacyUnbound;
443
+ return { data, result: { removed: true } };
444
+ });
445
+ }
446
+ }
447
+ //# sourceMappingURL=cli-credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-credentials.js","sourceRoot":"","sources":["../src/cli-credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare class EndpointError extends Error {
2
+ readonly code = "INVALID_ENDPOINT";
3
+ constructor(message: string);
4
+ }
5
+ /** Endpoint selection is deliberately independent of credential selection. */
6
+ export type ApiUrlSource = "command line" | "OPENPLAN_API_URL" | "saved config" | "package default";
7
+ export interface EndpointOptions {
8
+ apiUrlOverride?: unknown;
9
+ env?: NodeJS.ProcessEnv;
10
+ savedApiUrl?: unknown;
11
+ defaultApiUrl?: unknown;
12
+ }
13
+ export interface ResolvedEndpoint {
14
+ apiUrl: string;
15
+ source: ApiUrlSource;
16
+ }
17
+ export declare function normalizeApiUrl(value: unknown, label?: string): string;
18
+ export declare function resolveConfiguredApiUrl(options?: EndpointOptions): ResolvedEndpoint | null;
19
+ export declare function resolveApiUrl(options?: EndpointOptions): ResolvedEndpoint;
@@ -0,0 +1,56 @@
1
+ export class EndpointError extends Error {
2
+ code = "INVALID_ENDPOINT";
3
+ constructor(message) { super(message); this.name = "EndpointError"; }
4
+ }
5
+ export function normalizeApiUrl(value, label = "API URL") {
6
+ // Never include user input (which may contain userinfo or a token) in diagnostics.
7
+ const invalid = () => new EndpointError(`${label}: expected an HTTPS origin without credentials, path, query or fragment (HTTP is allowed only for loopback development).`);
8
+ if (typeof value !== "string" || !value || value !== value.trim() || /[\u0000-\u0020\u007f\\]/u.test(value))
9
+ throw invalid();
10
+ let url;
11
+ try {
12
+ url = new URL(value);
13
+ }
14
+ catch {
15
+ throw invalid();
16
+ }
17
+ if (!/^https?:\/\//i.test(value) || url.username || url.password || url.pathname !== "/" || url.search || url.hash || value.includes("?") || value.includes("#"))
18
+ throw invalid();
19
+ // The URL parser removes dot segments; reject them rather than accepting an
20
+ // input that happened to normalize back to the root.
21
+ const authorityAndPath = value.slice(value.indexOf("://") + 3);
22
+ const slash = authorityAndPath.indexOf("/");
23
+ if ((slash < 0 ? authorityAndPath : authorityAndPath.slice(0, slash)).includes("@"))
24
+ throw invalid();
25
+ if (slash !== -1 && authorityAndPath.slice(slash) !== "/")
26
+ throw invalid();
27
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))
28
+ throw invalid();
29
+ // Numeric/hex shorthand IPv4 forms must not widen the explicit loopback exception.
30
+ if (url.protocol === "http:") {
31
+ const authority = slash < 0 ? authorityAndPath : authorityAndPath.slice(0, slash);
32
+ const host = authority.startsWith("[") ? authority.slice(0, authority.indexOf("]") + 1) : authority.split(":")[0];
33
+ if (!["localhost", "127.0.0.1", "[::1]"].includes(host.toLowerCase()))
34
+ throw invalid();
35
+ }
36
+ return url.origin;
37
+ }
38
+ export function resolveConfiguredApiUrl(options = {}) {
39
+ const env = options.env ?? process.env;
40
+ const candidates = [
41
+ [options.apiUrlOverride, "command line"], [env.OPENPLAN_API_URL, "OPENPLAN_API_URL"],
42
+ [options.savedApiUrl, "saved config"], [options.defaultApiUrl, "package default"]
43
+ ];
44
+ for (const [value, source] of candidates) {
45
+ if (value !== undefined && value !== null)
46
+ return { apiUrl: normalizeApiUrl(value, source), source };
47
+ }
48
+ return null;
49
+ }
50
+ export function resolveApiUrl(options = {}) {
51
+ const result = resolveConfiguredApiUrl(options);
52
+ if (!result)
53
+ throw new EndpointError("No Openplan API URL is configured. Run: openplan endpoint set <url>");
54
+ return result;
55
+ }
56
+ //# sourceMappingURL=cli-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-endpoint.js","sourceRoot":"","sources":["../src/cli-endpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface CliPackageMetadata {
2
+ name: string;
3
+ version: string;
4
+ openplan?: {
5
+ defaultApiUrl?: string;
6
+ };
7
+ instructionCommand?: string;
8
+ localInstructionCommand?: string;
9
+ }
10
+ /** Run the shared CLI with metadata supplied by its registry-specific launcher. */
11
+ export declare function runCli(packageMetadata: CliPackageMetadata): Promise<void>;