codequill 0.8.1-beta.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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/dist/commands/attest.js +442 -0
  4. package/dist/commands/attest.js.map +1 -0
  5. package/dist/commands/backup.js +370 -0
  6. package/dist/commands/backup.js.map +1 -0
  7. package/dist/commands/claim.js +104 -0
  8. package/dist/commands/claim.js.map +1 -0
  9. package/dist/commands/log.js +188 -0
  10. package/dist/commands/log.js.map +1 -0
  11. package/dist/commands/login.js +147 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/prove.js +244 -0
  14. package/dist/commands/prove.js.map +1 -0
  15. package/dist/commands/publish.js +243 -0
  16. package/dist/commands/publish.js.map +1 -0
  17. package/dist/commands/pull.js +174 -0
  18. package/dist/commands/pull.js.map +1 -0
  19. package/dist/commands/quota.js +94 -0
  20. package/dist/commands/quota.js.map +1 -0
  21. package/dist/commands/revoke.js +97 -0
  22. package/dist/commands/revoke.js.map +1 -0
  23. package/dist/commands/snapshot.js +128 -0
  24. package/dist/commands/snapshot.js.map +1 -0
  25. package/dist/commands/status.js +234 -0
  26. package/dist/commands/status.js.map +1 -0
  27. package/dist/commands/verifyAttestation.js +212 -0
  28. package/dist/commands/verifyAttestation.js.map +1 -0
  29. package/dist/commands/verifyProof.js +145 -0
  30. package/dist/commands/verifyProof.js.map +1 -0
  31. package/dist/commands/wait.js +36 -0
  32. package/dist/commands/wait.js.map +1 -0
  33. package/dist/commands/who.js +55 -0
  34. package/dist/commands/who.js.map +1 -0
  35. package/dist/commands/why.js +412 -0
  36. package/dist/commands/why.js.map +1 -0
  37. package/dist/index.js +50 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/launcher.js +69 -0
  40. package/dist/launcher.js.map +1 -0
  41. package/dist/services/api.js +51 -0
  42. package/dist/services/api.js.map +1 -0
  43. package/dist/services/apiClient.js +166 -0
  44. package/dist/services/apiClient.js.map +1 -0
  45. package/dist/services/authStore.js +84 -0
  46. package/dist/services/authStore.js.map +1 -0
  47. package/dist/services/config.js +19 -0
  48. package/dist/services/config.js.map +1 -0
  49. package/dist/services/confirm.js +58 -0
  50. package/dist/services/confirm.js.map +1 -0
  51. package/dist/services/crypto.js +38 -0
  52. package/dist/services/crypto.js.map +1 -0
  53. package/dist/services/errors.js +17 -0
  54. package/dist/services/errors.js.map +1 -0
  55. package/dist/services/fs.js +25 -0
  56. package/dist/services/fs.js.map +1 -0
  57. package/dist/services/git.js +121 -0
  58. package/dist/services/git.js.map +1 -0
  59. package/dist/services/manifests/attestationManifest.js +35 -0
  60. package/dist/services/manifests/attestationManifest.js.map +1 -0
  61. package/dist/services/manifests/proofManifest.js +151 -0
  62. package/dist/services/manifests/proofManifest.js.map +1 -0
  63. package/dist/services/manifests/snapshotManifest.js +214 -0
  64. package/dist/services/manifests/snapshotManifest.js.map +1 -0
  65. package/dist/services/merkle.js +92 -0
  66. package/dist/services/merkle.js.map +1 -0
  67. package/dist/services/paths.js +16 -0
  68. package/dist/services/paths.js.map +1 -0
  69. package/dist/services/snapshotIndex.js +401 -0
  70. package/dist/services/snapshotIndex.js.map +1 -0
  71. package/dist/services/txWaiter.js +84 -0
  72. package/dist/services/txWaiter.js.map +1 -0
  73. package/dist/services/ui.js +98 -0
  74. package/dist/services/ui.js.map +1 -0
  75. package/dist/services/utilities.js +45 -0
  76. package/dist/services/utilities.js.map +1 -0
  77. package/dist/services/zip.js +24 -0
  78. package/dist/services/zip.js.map +1 -0
  79. package/dist/types/api.js +2 -0
  80. package/dist/types/api.js.map +1 -0
  81. package/dist/version.js +7 -0
  82. package/dist/version.js.map +1 -0
  83. package/package.json +52 -0
@@ -0,0 +1,401 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { ensureDir, fileExists } from "./fs.js";
4
+ export function defaultSnapshotIndexPaths() {
5
+ const codequillDir = '.codequill';
6
+ const snapshotsDir = path.join(codequillDir, 'snapshots');
7
+ return {
8
+ codequillDir,
9
+ snapshotsDir,
10
+ indexFile: path.join(snapshotsDir, 'index.json'),
11
+ };
12
+ }
13
+ function nowSec() {
14
+ return Math.floor(Date.now() / 1000);
15
+ }
16
+ function safeNum(n, fallback = 0) {
17
+ const v = typeof n === 'number' && Number.isFinite(n) ? n : fallback;
18
+ return v;
19
+ }
20
+ /**
21
+ * Atomic JSON write:
22
+ * - write tmp in same directory
23
+ * - rename over target
24
+ */
25
+ async function writeJsonAtomic(filePath, obj) {
26
+ const dir = path.dirname(filePath);
27
+ await ensureDir(dir);
28
+ const tmp = `${filePath}.tmp`;
29
+ await fs.writeFile(tmp, JSON.stringify(obj, null, 2), 'utf8');
30
+ await fs.rename(tmp, filePath);
31
+ }
32
+ function sortNewestFirst(a, b) {
33
+ const ap = safeNum(a.published?.published_at, 0);
34
+ const bp = safeNum(b.published?.published_at, 0);
35
+ // Prefer published timestamp if exists; else fall back to manifest timestamp.
36
+ const at = ap > 0 ? ap : safeNum(a.timestamp, 0);
37
+ const bt = bp > 0 ? bp : safeNum(b.timestamp, 0);
38
+ if (bt !== at)
39
+ return bt - at;
40
+ // stable tie-breakers
41
+ const ar = String(a.merkle_root);
42
+ const br = String(b.merkle_root);
43
+ if (ar !== br)
44
+ return ar.localeCompare(br);
45
+ const af = String(a.file ?? '');
46
+ const bf = String(b.file ?? '');
47
+ return af.localeCompare(bf);
48
+ }
49
+ function computeLatest(idx) {
50
+ // latest.local: newest item that has a local file (local or pulled)
51
+ const localCandidate = idx.items
52
+ .filter((it) => it.file && (it.kind === 'local' || it.kind === 'pulled'))
53
+ .sort(sortNewestFirst)[0];
54
+ // latest.published: newest item that has published meta (could be remote-only)
55
+ const pubCandidate = idx.items
56
+ .filter((it) => !!it.published)
57
+ .sort(sortNewestFirst)[0];
58
+ idx.latest = {
59
+ local: localCandidate?.merkle_root ?? null,
60
+ published: pubCandidate?.merkle_root ?? null,
61
+ };
62
+ }
63
+ async function readJsonFileSafe(filePathAbs) {
64
+ try {
65
+ const raw = await fs.readFile(filePathAbs, 'utf8');
66
+ if (!raw)
67
+ return null;
68
+ return JSON.parse(raw);
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ export class SnapshotIndex {
75
+ repoRoot;
76
+ repoName;
77
+ paths;
78
+ idx = null;
79
+ constructor(args) {
80
+ this.repoRoot = path.resolve(args.repoRoot);
81
+ this.repoName = args.repoName;
82
+ this.paths = args.paths ?? defaultSnapshotIndexPaths();
83
+ }
84
+ abs(rel) {
85
+ return path.join(this.repoRoot, rel);
86
+ }
87
+ get indexFileAbs() {
88
+ return this.abs(this.paths.indexFile);
89
+ }
90
+ get snapshotsDirAbs() {
91
+ return this.abs(this.paths.snapshotsDir);
92
+ }
93
+ /**
94
+ * Load index if present & valid; otherwise rebuild from disk.
95
+ * Always ensures .codequill/snapshots exists.
96
+ */
97
+ async load() {
98
+ await ensureDir(this.snapshotsDirAbs);
99
+ const file = this.indexFileAbs;
100
+ if (!(await fileExists(file))) {
101
+ // no index -> rebuild
102
+ this.idx = await this.rebuildFromDisk();
103
+ await this.save();
104
+ return this.idx;
105
+ }
106
+ const parsed = await readJsonFileSafe(file);
107
+ if (!parsed || parsed.version !== 'codequill-index:v1' || !Array.isArray(parsed.items) || typeof parsed.repo_name !== 'string') {
108
+ this.idx = await this.rebuildFromDisk();
109
+ await this.save();
110
+ return this.idx;
111
+ }
112
+ // Accept it, but still self-heal repo name & missing files quickly.
113
+ const idx = parsed;
114
+ idx.repo_name = this.repoName;
115
+ idx.updated_at = nowSec();
116
+ // Drop items pointing to missing files (they can come back on rebuild/pull)
117
+ idx.items = await this.filterMissingFiles(idx.items);
118
+ // Normalize roots + recompute latest/sort
119
+ idx.items = this.normalizeItems(idx.items);
120
+ idx.items.sort(sortNewestFirst);
121
+ computeLatest(idx);
122
+ this.idx = idx;
123
+ await this.save();
124
+ return idx;
125
+ }
126
+ get() {
127
+ if (!this.idx)
128
+ throw new Error('SnapshotIndex not loaded. Call await index.load() first.');
129
+ return this.idx;
130
+ }
131
+ async save() {
132
+ const idx = this.get();
133
+ idx.updated_at = nowSec();
134
+ idx.items = this.normalizeItems(idx.items);
135
+ idx.items.sort(sortNewestFirst);
136
+ computeLatest(idx);
137
+ await writeJsonAtomic(this.indexFileAbs, idx);
138
+ }
139
+ /**
140
+ * Hard rebuild from disk (snapshot folder is the source of truth).
141
+ * This is safe to call anytime (index deleted/corrupt, etc).
142
+ */
143
+ async rebuildFromDisk() {
144
+ await ensureDir(this.snapshotsDirAbs);
145
+ let entries = [];
146
+ try {
147
+ entries = await fs.readdir(this.snapshotsDirAbs);
148
+ }
149
+ catch {
150
+ entries = [];
151
+ }
152
+ const jsonFiles = entries
153
+ .filter((f) => f.toLowerCase().endsWith('.json'))
154
+ .filter((f) => f.toLowerCase() !== 'index.json');
155
+ const byRoot = new Map();
156
+ for (const fname of jsonFiles) {
157
+ const fileAbs = path.join(this.snapshotsDirAbs, fname);
158
+ const obj = await readJsonFileSafe(fileAbs);
159
+ if (!obj || typeof obj !== 'object')
160
+ continue;
161
+ const commit = String(obj.commit ?? '').trim();
162
+ const rootRaw = String(obj.merkle_root ?? '').trim();
163
+ const ts = safeNum(obj.timestamp, 0);
164
+ if (!rootRaw || !commit)
165
+ continue;
166
+ const relFile = path.join(this.paths.snapshotsDir, fname).split(path.sep).join('/');
167
+ const kind = fname.toLowerCase().startsWith('published-') ? 'pulled' : 'local';
168
+ const next = {
169
+ merkle_root: rootRaw,
170
+ commit,
171
+ timestamp: ts,
172
+ file: relFile,
173
+ kind,
174
+ published: null,
175
+ };
176
+ const existing = byRoot.get(rootRaw);
177
+ if (!existing) {
178
+ byRoot.set(rootRaw, next);
179
+ continue;
180
+ }
181
+ // ✅ Dedup rule: prefer LOCAL over PULLED, otherwise prefer newer timestamp
182
+ const existingScore = (existing.kind === 'local' ? 10 : 0) + safeNum(existing.timestamp, 0);
183
+ const nextScore = (next.kind === 'local' ? 10 : 0) + safeNum(next.timestamp, 0);
184
+ if (nextScore > existingScore) {
185
+ // keep published meta if it was already attached on the existing entry
186
+ byRoot.set(rootRaw, { ...next, published: existing.published ?? null });
187
+ }
188
+ }
189
+ const items = Array.from(byRoot.values());
190
+ const idx = {
191
+ version: 'codequill-index:v1',
192
+ repo_name: this.repoName,
193
+ updated_at: nowSec(),
194
+ items,
195
+ latest: { local: null, published: null },
196
+ };
197
+ idx.items = this.normalizeItems(idx.items);
198
+ idx.items.sort(sortNewestFirst);
199
+ computeLatest(idx);
200
+ this.idx = idx;
201
+ return idx;
202
+ }
203
+ /**
204
+ * Optional: enrich index with backend "published" list.
205
+ * - Matches by merkle_root (primary)
206
+ * - If a published snapshot exists but no local file exists, we add a remote-only item
207
+ * so `log --on-chain` can still show it.
208
+ */
209
+ enrichFromBackend(published) {
210
+ const idx = this.get();
211
+ const byRoot = new Map();
212
+ for (const p of published) {
213
+ const r = p.merkle_root;
214
+ if (r)
215
+ byRoot.set(r, p);
216
+ }
217
+ // Attach to existing items
218
+ for (const it of idx.items) {
219
+ const p = byRoot.get(it.merkle_root);
220
+ if (!p)
221
+ continue;
222
+ it.published = {
223
+ snapshot_id: p.snapshot_id,
224
+ published_at: safeNum(p.published_at, 0),
225
+ tx_hash: p.tx_hash,
226
+ chain_id: p.chain_id,
227
+ manifest_cid: p.manifest_cid,
228
+ wallet_address: p.wallet_address,
229
+ };
230
+ // If file exists locally but was marked remote earlier, fix kind.
231
+ if (it.file && it.kind === 'remote') {
232
+ it.kind = it.file.toLowerCase().includes('published-') ? 'pulled' : 'local';
233
+ }
234
+ }
235
+ // Add remote-only items for published snapshots not present locally
236
+ const localRoots = new Set(idx.items.map((x) => x.merkle_root).filter(Boolean));
237
+ for (const p of published) {
238
+ const r = p.merkle_root;
239
+ if (!r || localRoots.has(r))
240
+ continue;
241
+ idx.items.push({
242
+ merkle_root: r,
243
+ commit: String(p.commit_hash ?? '').trim(),
244
+ timestamp: 0,
245
+ file: null,
246
+ kind: 'remote',
247
+ published: {
248
+ snapshot_id: p.snapshot_id,
249
+ published_at: safeNum(p.published_at, 0),
250
+ tx_hash: p.tx_hash,
251
+ chain_id: p.chain_id,
252
+ manifest_cid: p.manifest_cid,
253
+ wallet_address: p.wallet_address,
254
+ },
255
+ });
256
+ }
257
+ idx.items = this.normalizeItems(idx.items);
258
+ idx.items.sort(sortNewestFirst);
259
+ computeLatest(idx);
260
+ }
261
+ /**
262
+ * Convenience: after you write a manifest file (snapshot/pull),
263
+ * call this to upsert the disk item without scanning the whole folder.
264
+ * (Still safe even if you forget; rebuildFromDisk will fix.)
265
+ */
266
+ upsertFromManifestFile(args) {
267
+ const idx = this.get();
268
+ const commit = String(args.manifest?.commit ?? '').trim();
269
+ const root = String(args.manifest?.merkle_root ?? '').trim();
270
+ const ts = safeNum(args.manifest?.timestamp, 0);
271
+ if (!commit || !root)
272
+ return;
273
+ const kind = args.kind ?? 'local';
274
+ const file = String(args.manifestFileRel ?? '').split(path.sep).join('/');
275
+ // ✅ Uniqueness by file path
276
+ const existingIdx = idx.items.findIndex((it) => {
277
+ if (!it.file)
278
+ return false;
279
+ const f = String(it.file).split(path.sep).join('/');
280
+ return f === file;
281
+ });
282
+ if (existingIdx >= 0) {
283
+ const existing = idx.items[existingIdx];
284
+ // 🚫 If that indexed file is already published, do NOT replace it
285
+ if (existing.published) {
286
+ throw new Error(`Refusing to overwrite a published snapshot in the index.\n` +
287
+ `File: ${file}\n` +
288
+ `Published snapshot_id: ${existing.published.snapshot_id}\n` +
289
+ `Tip: create a new snapshot for a different commit, or publish a different manifest file.`);
290
+ }
291
+ // Replace/update the existing local entry for that file
292
+ idx.items[existingIdx] = {
293
+ ...existing,
294
+ merkle_root: root,
295
+ commit,
296
+ timestamp: ts,
297
+ file,
298
+ kind,
299
+ published: null, // stays unpublished
300
+ };
301
+ }
302
+ else {
303
+ idx.items.push({
304
+ merkle_root: root,
305
+ commit,
306
+ timestamp: ts,
307
+ file,
308
+ kind,
309
+ published: null,
310
+ });
311
+ }
312
+ idx.items = this.normalizeItems(idx.items);
313
+ idx.items.sort(sortNewestFirst);
314
+ computeLatest(idx);
315
+ }
316
+ /**
317
+ * Convenience: after publish succeeds, attach published meta by merkle_root.
318
+ */
319
+ attachPublishedByRoot(args) {
320
+ const idx = this.get();
321
+ const r = args.merkle_root;
322
+ if (!r)
323
+ return;
324
+ const item = idx.items.find((x) => x.merkle_root === r);
325
+ if (item) {
326
+ item.published = args.meta;
327
+ }
328
+ else {
329
+ // If we don't have the manifest locally, still record as remote-only
330
+ idx.items.push({
331
+ merkle_root: r,
332
+ commit: '',
333
+ timestamp: 0,
334
+ file: null,
335
+ kind: 'remote',
336
+ published: args.meta,
337
+ });
338
+ }
339
+ idx.items = this.normalizeItems(idx.items);
340
+ idx.items.sort(sortNewestFirst);
341
+ computeLatest(idx);
342
+ }
343
+ /**
344
+ * Helper for status/log: list items (already sorted after load/save).
345
+ */
346
+ list() {
347
+ return this.get().items;
348
+ }
349
+ /**
350
+ * Quick accessors
351
+ */
352
+ latestLocalRoot() {
353
+ return this.get().latest.local ?? null;
354
+ }
355
+ latestPublishedRoot() {
356
+ return this.get().latest.published ?? null;
357
+ }
358
+ // ------------------------
359
+ // internal helpers
360
+ // ------------------------
361
+ normalizeItems(items) {
362
+ return items
363
+ .map((it) => {
364
+ const mr = it.merkle_root;
365
+ return {
366
+ ...it,
367
+ merkle_root: mr || (String(it.merkle_root ?? '')) || String(it.merkle_root ?? '').trim().toLowerCase(),
368
+ commit: String(it.commit ?? '').trim(),
369
+ timestamp: safeNum(it.timestamp, 0),
370
+ file: it.file ? String(it.file) : null,
371
+ kind: it.kind ?? (it.file ? 'local' : 'remote'),
372
+ published: it.published
373
+ ? {
374
+ snapshot_id: String(it.published.snapshot_id),
375
+ published_at: safeNum(it.published.published_at, 0),
376
+ tx_hash: it.published.tx_hash ? String(it.published.tx_hash) : undefined,
377
+ chain_id: typeof it.published.chain_id === 'number' ? it.published.chain_id : undefined,
378
+ manifest_cid: it.published.manifest_cid ? String(it.published.manifest_cid) : undefined,
379
+ wallet_address: it.published.wallet_address ? String(it.published.wallet_address) : undefined,
380
+ }
381
+ : null,
382
+ };
383
+ })
384
+ .filter((it) => !!it.merkle_root); // require root
385
+ }
386
+ async filterMissingFiles(items) {
387
+ const out = [];
388
+ for (const it of items) {
389
+ if (!it.file) {
390
+ out.push(it);
391
+ continue;
392
+ }
393
+ const absP = this.abs(it.file);
394
+ if (await fileExists(absP))
395
+ out.push(it);
396
+ // if file missing, drop it; rebuild/pull can restore
397
+ }
398
+ return out;
399
+ }
400
+ }
401
+ //# sourceMappingURL=snapshotIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotIndex.js","sourceRoot":"","sources":["../../src/services/snapshotIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { spinner, colors } from './ui.js';
2
+ import { apiClient } from './apiClient.js';
3
+ import { ApiError } from './errors.js';
4
+ /**
5
+ * Wait for a tx to be confirmed (or fail), using backend polling (seamless for npm CLI).
6
+ * Backend endpoint expected:
7
+ * GET /v1/cli/tx/:txHash?chain_id=137
8
+ */
9
+ export async function waitForTxConfirmation(opts) {
10
+ const confirmationsTarget = Math.max(1, Number(opts.confirmations ?? 1));
11
+ const pollIntervalMs = Math.max(500, Number(opts.pollIntervalMs ?? 3000));
12
+ const timeoutMs = Math.max(10_000, Number(opts.timeoutMs ?? 5 * 60_000));
13
+ const endpointBase = (opts.endpointBase ?? '/v1/cli/tx').replace(/\/+$/, '');
14
+ const txHash = String(opts.txHash);
15
+ const s = spinner(`Waiting for confirmation (${confirmationsTarget}+ conf)…`, opts.silent);
16
+ const started = Date.now();
17
+ let last = null;
18
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
19
+ try {
20
+ while (true) {
21
+ const elapsed = Date.now() - started;
22
+ if (elapsed > timeoutMs) {
23
+ s.fail(colors.warn('Timed out waiting for confirmation.'));
24
+ const hint = last?.explorer_url ? `\nExplorer: ${last.explorer_url}` : '';
25
+ throw new Error(`Timeout waiting for tx ${txHash}.${hint}`);
26
+ }
27
+ let res;
28
+ try {
29
+ res = await apiClient.get(`${endpointBase}/${txHash}`);
30
+ last = res;
31
+ }
32
+ catch (e) {
33
+ // If backend endpoint not implemented yet, make this error helpful
34
+ if (e instanceof ApiError) {
35
+ s.fail(colors.error('Failed to check tx status.'));
36
+ const extra = [
37
+ `Status: ${e.status}`,
38
+ e.requestId ? `Request ID: ${e.requestId}` : null,
39
+ e.method && e.url ? `Endpoint: ${e.method} ${e.url}` : null,
40
+ '',
41
+ 'Hint: backend needs a tx status endpoint:',
42
+ ` GET ${endpointBase}/:txHash?chain_id=<id>`,
43
+ ].filter(Boolean).join('\n');
44
+ throw new Error(`${e.message}\n${extra}`);
45
+ }
46
+ s.fail(colors.error('Failed to check tx status.'));
47
+ throw e;
48
+ }
49
+ if (res.status === 'failed') {
50
+ s.fail(colors.error('Transaction failed.'));
51
+ const reason = res.reason ? `\nReason: ${res.reason}` : '';
52
+ const hint = res.explorer_url ? `\nExplorer: ${res.explorer_url}` : '';
53
+ throw new Error(`Tx failed: ${txHash}.${reason}${hint}`);
54
+ }
55
+ if (res.status === 'confirmed') {
56
+ const confNow = Number(res.confirmations ?? confirmationsTarget);
57
+ if (confNow >= confirmationsTarget) {
58
+ const blockTxt = res.block_number ? `block ${res.block_number}` : 'confirmed';
59
+ s.succeed(colors.success(`Confirmed (${blockTxt})`));
60
+ return res;
61
+ }
62
+ s.text = `Waiting for confirmation (${confNow}/${confirmationsTarget})…`;
63
+ }
64
+ else {
65
+ // pending
66
+ const confNow = Number(res.confirmations ?? 0);
67
+ s.text = confNow > 0
68
+ ? `Waiting for confirmation (${confNow}/${confirmationsTarget})…`
69
+ : `Waiting for transaction to be mined…`;
70
+ }
71
+ const waitMs = Math.max(500, Number(res.next_poll_ms ?? pollIntervalMs));
72
+ await sleep(waitMs);
73
+ }
74
+ }
75
+ catch (e) {
76
+ // ensure spinner stops
77
+ try {
78
+ s.stop();
79
+ }
80
+ catch { }
81
+ throw e;
82
+ }
83
+ }
84
+ //# sourceMappingURL=txWaiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"txWaiter.js","sourceRoot":"","sources":["../../src/services/txWaiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import kleur from 'kleur';
2
+ import ora from 'ora';
3
+ import { spawn } from 'node:child_process';
4
+ export const colors = {
5
+ success: (s) => kleur.green(s),
6
+ error: (s) => kleur.red(s),
7
+ warn: (s) => kleur.yellow(s),
8
+ info: (s) => kleur.cyan(s),
9
+ bold: (s) => kleur.bold(s),
10
+ dim: (s) => kleur.dim(s),
11
+ };
12
+ export function spinner(text, silent) {
13
+ const s = ora({ text, spinner: 'dots' });
14
+ if (silent) {
15
+ // @ts-ignore
16
+ s.start = () => s;
17
+ // @ts-ignore
18
+ s.stop = () => s;
19
+ // @ts-ignore
20
+ s.succeed = () => s;
21
+ // @ts-ignore
22
+ s.fail = () => s;
23
+ // @ts-ignore
24
+ s.stopAndPersist = () => s;
25
+ }
26
+ else {
27
+ s.start();
28
+ }
29
+ return s;
30
+ }
31
+ export function shortAddr(a) {
32
+ const x = String(a || '').trim();
33
+ if (!x)
34
+ return '—';
35
+ if (x.length <= 18)
36
+ return x;
37
+ return `${x.slice(0, 6)}...${x.slice(-4)}`;
38
+ }
39
+ export function shortHash(hash, length = 12) {
40
+ const s = String(hash ?? '');
41
+ return s.length > length ? s.slice(0, length) : s;
42
+ }
43
+ export function shortCommit(commit, length = 12) {
44
+ const s = String(commit ?? '').trim();
45
+ return s.length > 12 ? s.slice(0, 12) : s;
46
+ }
47
+ export function fmtTime(ts) {
48
+ if (!ts || !Number.isFinite(ts))
49
+ return '—';
50
+ try {
51
+ return new Date(ts * 1000).toISOString().replace('T', ' ').replace('.000Z', ' UTC');
52
+ }
53
+ catch {
54
+ return '—';
55
+ }
56
+ }
57
+ export function relativeTime(ts) {
58
+ const now = Math.floor(Date.now() / 1000);
59
+ const diff = Math.max(0, now - ts);
60
+ const min = Math.floor(diff / 60);
61
+ const hr = Math.floor(diff / 3600);
62
+ const day = Math.floor(diff / 86400);
63
+ const wk = Math.floor(diff / 604800);
64
+ if (diff < 60)
65
+ return 'just now';
66
+ if (min < 60)
67
+ return `${min} min ago`;
68
+ if (hr < 48)
69
+ return `${hr} hour${hr === 1 ? '' : 's'} ago`;
70
+ if (day < 14)
71
+ return `${day} day${day === 1 ? '' : 's'} ago`;
72
+ return `${wk} week${wk === 1 ? '' : 's'} ago`;
73
+ }
74
+ export function tryOpenBrowser(url) {
75
+ const platform = process.platform;
76
+ let cmd;
77
+ let args = [];
78
+ if (platform === 'darwin') {
79
+ cmd = 'open';
80
+ args = [url];
81
+ }
82
+ else if (platform === 'win32') {
83
+ cmd = 'cmd';
84
+ args = ['/c', 'start', '""', url];
85
+ }
86
+ else {
87
+ cmd = 'xdg-open';
88
+ args = [url];
89
+ }
90
+ try {
91
+ const child = spawn(cmd, args, { stdio: 'ignore', detached: true });
92
+ child.unref();
93
+ }
94
+ catch {
95
+ // ignore
96
+ }
97
+ }
98
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/services/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { isExpired, loadTokens } from "./authStore.js";
2
+ import { colors } from "./ui.js";
3
+ import { getConfigFilePath } from "./config.js";
4
+ import { randomBytes } from "node:crypto";
5
+ import { createRequire } from "node:module";
6
+ export function assertAuthenticated() {
7
+ const tokens = loadTokens();
8
+ if (!tokens) {
9
+ console.error(colors.error('Not logged in. Run `codequill login` first.'));
10
+ console.error(colors.dim(`No tokens found at: ${getConfigFilePath()}`));
11
+ process.exitCode = 1;
12
+ return false;
13
+ }
14
+ if (isExpired(tokens) && !tokens.refresh_token) {
15
+ console.error(colors.error('Session expired. Run `codequill login` to re-authenticate.'));
16
+ console.error(colors.dim(`Token file: ${getConfigFilePath()}`));
17
+ process.exitCode = 1;
18
+ return false;
19
+ }
20
+ return true;
21
+ }
22
+ export function getCliVersion() {
23
+ // ESM-safe way to read package.json
24
+ try {
25
+ const require = createRequire(import.meta.url);
26
+ const pkg = require('../../package.json');
27
+ return String(pkg?.version ?? 'unknown');
28
+ }
29
+ catch {
30
+ return 'unknown';
31
+ }
32
+ }
33
+ export function randomSaltHex32() {
34
+ return randomBytes(32).toString('hex');
35
+ }
36
+ export function chainName(chainId) {
37
+ if (!chainId || !Number.isFinite(chainId))
38
+ return null;
39
+ if (chainId === 11155111)
40
+ return 'Sepolia Testnet';
41
+ if (chainId === 1)
42
+ return 'Ethereum Mainnet';
43
+ return `chain ${chainId}`;
44
+ }
45
+ //# sourceMappingURL=utilities.js.map