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,166 @@
1
+ import { loadTokens, isExpired, saveTokens, clearTokens } from './authStore.js';
2
+ import { ApiError } from './errors.js';
3
+ const DEFAULT_BASE_URL = 'https://api.codequill.xyz';
4
+ export class ApiClient {
5
+ baseUrl;
6
+ constructor(baseUrl) {
7
+ this.baseUrl = (baseUrl || process.env.CODEQUILL_API_BASE_URL || DEFAULT_BASE_URL).replace(/\/$/, '');
8
+ }
9
+ async ensureAuthHeader() {
10
+ const headers = {};
11
+ // 1) Explicit token override (CI / GHA)
12
+ const envToken = String(process.env.CODEQUILL_TOKEN || "").trim();
13
+ if (envToken) {
14
+ headers.Authorization = `Bearer ${envToken}`;
15
+ const githubId = String(process.env.CODEQUILL_GITHUB_ID || "").trim();
16
+ if (githubId) {
17
+ headers["X-GITHUB-ID"] = githubId;
18
+ }
19
+ return headers;
20
+ }
21
+ // 2) Normal interactive login tokens
22
+ const tokens = loadTokens();
23
+ if (!tokens)
24
+ return headers;
25
+ if (isExpired(tokens)) {
26
+ if (!tokens.refresh_token) {
27
+ throw new ApiError("Session expired. Please run `codequill login` again.", 401);
28
+ }
29
+ await this.refreshTokens(tokens.refresh_token);
30
+ const refreshed = loadTokens();
31
+ if (!refreshed) {
32
+ throw new ApiError("Session expired. Please run `codequill login` again.", 401);
33
+ }
34
+ headers.Authorization = `Bearer ${refreshed.access_token}`;
35
+ return headers;
36
+ }
37
+ headers.Authorization = `Bearer ${tokens.access_token}`;
38
+ return headers;
39
+ }
40
+ async refreshTokens(refreshToken) {
41
+ const url = `${this.baseUrl}/v1/cli/auth/refresh`;
42
+ const res = await fetch(url, {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ Accept: 'application/json',
47
+ 'X-Nonce': this.makeNonce(),
48
+ },
49
+ body: JSON.stringify({ refresh_token: refreshToken }),
50
+ });
51
+ const text = await res.text();
52
+ let data = undefined;
53
+ try {
54
+ data = text ? JSON.parse(text) : undefined;
55
+ }
56
+ catch {
57
+ data = text;
58
+ }
59
+ if (!res.ok) {
60
+ const reqId = res?.headers?.get?.('x-request-id')
61
+ || res?.headers?.get?.('request-id')
62
+ || res?.headers?.get?.('x-amzn-trace-id')
63
+ || undefined;
64
+ if (res.status === 400 || res.status === 401 || res.status === 403) {
65
+ // Invalid/expired refresh token — clear local credentials
66
+ clearTokens();
67
+ const msg = 'Failed to refresh session (token expired or invalid). Please run `codequill login` again.';
68
+ throw new ApiError(msg, res.status, data, url, 'POST', reqId);
69
+ }
70
+ const msg = typeof data?.message === 'string' ? data.message : `Request failed with ${res.status}`;
71
+ throw new ApiError(msg, res.status, data, url, 'POST', reqId);
72
+ }
73
+ const success = data;
74
+ const margin = 30; // seconds safety margin
75
+ const nowSec = Math.floor(Date.now() / 1000);
76
+ const accessTtl = success.access_expires_in ?? success.expires_in ?? 0;
77
+ const refreshTtl = success.refresh_expires_in ?? 0;
78
+ const access_expires_at = nowSec + Math.max(0, accessTtl - margin);
79
+ const refresh_expires_at = refreshTtl ? nowSec + Math.max(0, refreshTtl - margin) : undefined;
80
+ saveTokens({
81
+ access_token: success.access_token,
82
+ refresh_token: success.refresh_token ?? refreshToken,
83
+ expires_at: access_expires_at,
84
+ access_expires_at,
85
+ refresh_expires_at,
86
+ });
87
+ }
88
+ async get(path, opts) {
89
+ return this.request('GET', path, undefined, opts);
90
+ }
91
+ async post(path, body, opts) {
92
+ return this.request('POST', path, body, opts);
93
+ }
94
+ async postMultipart(path, form, opts) {
95
+ const url = `${this.baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;
96
+ const headers = {
97
+ Accept: 'application/json',
98
+ 'X-Nonce': this.makeNonce(),
99
+ };
100
+ if (opts?.auth !== false) {
101
+ Object.assign(headers, await this.ensureAuthHeader());
102
+ }
103
+ const res = await fetch(url, {
104
+ method: 'POST',
105
+ headers,
106
+ body: form,
107
+ });
108
+ const text = await res.text();
109
+ let data = undefined;
110
+ try {
111
+ data = text ? JSON.parse(text) : undefined;
112
+ }
113
+ catch {
114
+ // keep raw text
115
+ data = text;
116
+ }
117
+ if (!res.ok) {
118
+ const msg = typeof data?.error === 'string' ? data.error : `Request failed with ${res.status}`;
119
+ const reqId = res?.headers?.get?.('x-request-id')
120
+ || res?.headers?.get?.('request-id')
121
+ || res?.headers?.get?.('x-amzn-trace-id')
122
+ || undefined;
123
+ throw new ApiError(msg, res.status, data, url, 'POST', reqId);
124
+ }
125
+ return data;
126
+ }
127
+ async request(method, path, body, opts) {
128
+ const url = `${this.baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;
129
+ const headers = {
130
+ 'Content-Type': 'application/json',
131
+ 'X-Nonce': this.makeNonce(),
132
+ Accept: 'application/json',
133
+ };
134
+ if (opts?.auth !== false) {
135
+ Object.assign(headers, await this.ensureAuthHeader());
136
+ }
137
+ const res = await fetch(url, {
138
+ method,
139
+ headers,
140
+ body: body !== undefined ? JSON.stringify(body) : undefined,
141
+ });
142
+ const text = await res.text();
143
+ let data = undefined;
144
+ try {
145
+ data = text ? JSON.parse(text) : undefined;
146
+ }
147
+ catch {
148
+ // keep raw text
149
+ data = text;
150
+ }
151
+ if (!res.ok) {
152
+ const msg = typeof data?.error === 'string' ? data.error : `Request failed with ${res.status}`;
153
+ const reqId = res?.headers?.get?.('x-request-id')
154
+ || res?.headers?.get?.('request-id')
155
+ || res?.headers?.get?.('x-amzn-trace-id')
156
+ || undefined;
157
+ throw new ApiError(msg, res.status, data, url, method, reqId);
158
+ }
159
+ return data;
160
+ }
161
+ makeNonce() {
162
+ return crypto.randomUUID();
163
+ }
164
+ }
165
+ export const apiClient = new ApiClient();
166
+ //# sourceMappingURL=apiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../../src/services/apiClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { ensureConfigDir, getConfigFilePath } from './config.js';
4
+ function readFileIfExists(file) {
5
+ try {
6
+ return fs.readFileSync(file, 'utf8');
7
+ }
8
+ catch (e) {
9
+ if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR'))
10
+ return null;
11
+ throw e;
12
+ }
13
+ }
14
+ export function loadTokens() {
15
+ const file = getConfigFilePath();
16
+ const raw = readFileIfExists(file);
17
+ if (!raw)
18
+ return null;
19
+ try {
20
+ const parsed = JSON.parse(raw);
21
+ // Accept tokens if access_token + any access expiry are present
22
+ if (typeof parsed?.access_token === 'string') {
23
+ if (typeof parsed?.expires_at === 'number' || typeof parsed?.access_expires_at === 'number') {
24
+ return parsed;
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ export function saveTokens(tokens) {
34
+ ensureConfigDir();
35
+ const file = getConfigFilePath();
36
+ const dir = path.dirname(file);
37
+ if (!fs.existsSync(dir)) {
38
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
39
+ }
40
+ // Ensure back-compat aliasing: mirror access_expires_at into expires_at if provided
41
+ const accessExp = typeof tokens.access_expires_at === 'number' ? tokens.access_expires_at : tokens.expires_at;
42
+ const toSave = { ...tokens, expires_at: accessExp };
43
+ const data = JSON.stringify(toSave, null, 2);
44
+ const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
45
+ try {
46
+ fs.writeFileSync(tmp, data, { mode: 0o600 });
47
+ fs.renameSync(tmp, file); // atomic on POSIX
48
+ }
49
+ finally {
50
+ try {
51
+ if (fs.existsSync(tmp))
52
+ fs.rmSync(tmp, { force: true });
53
+ }
54
+ catch { /* ignore */ }
55
+ }
56
+ try {
57
+ fs.chmodSync(file, 0o600);
58
+ }
59
+ catch { /* ignore */ }
60
+ }
61
+ export function isExpired(tokens) {
62
+ const now = Math.floor(Date.now() / 1000);
63
+ const accessExp = tokens.access_expires_at ?? tokens.expires_at;
64
+ return accessExp <= now;
65
+ }
66
+ export function isRefreshExpired(tokens) {
67
+ if (!tokens.refresh_token)
68
+ return true;
69
+ if (!tokens.refresh_expires_at)
70
+ return false; // unknown expiry; assume valid
71
+ const now = Math.floor(Date.now() / 1000);
72
+ return tokens.refresh_expires_at <= now;
73
+ }
74
+ export function clearTokens() {
75
+ const file = getConfigFilePath();
76
+ try {
77
+ if (fs.existsSync(file))
78
+ fs.rmSync(file, { force: true });
79
+ }
80
+ catch {
81
+ // ignore
82
+ }
83
+ }
84
+ //# sourceMappingURL=authStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authStore.js","sourceRoot":"","sources":["../../src/services/authStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { homedir } from 'node:os';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ const DEFAULT_CONFIG_DIR = path.join(homedir(), '.config', 'codequill');
5
+ const CONFIG_DIR = process.env.CODEQUILL_CONFIG_DIR || DEFAULT_CONFIG_DIR;
6
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
7
+ const BASE_URL = (process.env.CODEQUILL_BASE_URL || "https://app.codequill.xyz").replace(/\/$/, '');
8
+ export function getBaseUrl() {
9
+ return BASE_URL;
10
+ }
11
+ export function getConfigFilePath() {
12
+ return CONFIG_FILE;
13
+ }
14
+ export function ensureConfigDir() {
15
+ if (!fs.existsSync(CONFIG_DIR)) {
16
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
17
+ }
18
+ }
19
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACxE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,kBAAkB,CAAC;AAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AACzD,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAEpG,MAAM,UAAU,UAAU;IACtB,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC7B,OAAO,WAAW,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,CAAC;AACL,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { colors } from './ui.js';
2
+ export async function confirmDangerousAction(title, lines, subtitle, opts = {}) {
3
+ const prompt = opts.prompt ?? 'Proceed? (y/N): ';
4
+ const requireTty = opts.requireTty ?? true;
5
+ const defaultNo = opts.defaultNo ?? true;
6
+ // Guard: CI/non-interactive
7
+ if (requireTty && !process.stdin.isTTY) {
8
+ console.error(colors.error('Interactive confirmation requires a TTY.'));
9
+ console.error(colors.dim('Tip: pass --no-confirm to skip confirmation in CI.'));
10
+ return false;
11
+ }
12
+ // Pretty header
13
+ console.log('');
14
+ console.log(colors.bold(`⚠️ ${title}`));
15
+ console.log(colors.dim('────────────────────────────────────────'));
16
+ for (const l of lines)
17
+ console.log(l);
18
+ console.log(colors.dim('────────────────────────────────────────'));
19
+ if (subtitle) {
20
+ console.log(colors.dim(subtitle));
21
+ }
22
+ console.log('');
23
+ const stdin = process.stdin;
24
+ const stdout = process.stdout;
25
+ return new Promise((resolve) => {
26
+ const wasRaw = stdin.isRaw;
27
+ if (stdin.isTTY) {
28
+ stdin.setEncoding('utf8');
29
+ stdin.resume();
30
+ try {
31
+ stdin.setRawMode(false);
32
+ }
33
+ catch { }
34
+ }
35
+ stdout.write(prompt);
36
+ const onData = (data) => {
37
+ const input = String(data ?? '').trim();
38
+ cleanup();
39
+ if (!input)
40
+ return resolve(!defaultNo);
41
+ const v = input.toLowerCase();
42
+ resolve(v === 'y' || v === 'yes');
43
+ };
44
+ const cleanup = () => {
45
+ stdin.removeListener('data', onData);
46
+ if (stdin.isTTY && wasRaw) {
47
+ try {
48
+ stdin.setRawMode(true);
49
+ }
50
+ catch { }
51
+ }
52
+ stdin.pause();
53
+ stdout.write('\n');
54
+ };
55
+ stdin.on('data', onData);
56
+ });
57
+ }
58
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/services/confirm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { keccak256, toUtf8Bytes } from 'ethers';
2
+ import fs from "node:fs/promises";
3
+ import { createHash } from "node:crypto";
4
+ // Returns 64-hex string (no 0x), lowercase
5
+ export function keccakHex(data) {
6
+ const h = keccak256(data); // ethers returns 0x-prefixed hex
7
+ return h.replace(/^0x/, '').toLowerCase();
8
+ }
9
+ // Returns 64-hex string (no 0x), lowercase
10
+ export function keccakUtf8(text) {
11
+ const bytes = toUtf8Bytes(text);
12
+ const h = keccak256(bytes);
13
+ return h.replace(/^0x/, '').toLowerCase();
14
+ }
15
+ export function hexToBytes(hexNo0x) {
16
+ const hex = hexNo0x.length % 2 === 1 ? `0${hexNo0x}` : hexNo0x;
17
+ const len = hex.length / 2;
18
+ const out = new Uint8Array(len);
19
+ for (let i = 0; i < len; i++) {
20
+ out[i] = parseInt(hex.substr(i * 2, 2), 16);
21
+ }
22
+ return out;
23
+ }
24
+ export function concatBytes(a, b) {
25
+ const out = new Uint8Array(a.length + b.length);
26
+ out.set(a, 0);
27
+ out.set(b, a.length);
28
+ return out;
29
+ }
30
+ export async function sha256File(filePathAbs) {
31
+ const buf = await fs.readFile(filePathAbs);
32
+ return createHash('sha256').update(buf).digest('hex');
33
+ }
34
+ export async function sha512File(filePathAbs) {
35
+ const buf = await fs.readFile(filePathAbs);
36
+ return createHash('sha512').update(buf).digest('hex');
37
+ }
38
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/services/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAEvC,2CAA2C;AAC3C,MAAM,UAAU,SAAS,CAAC,IAAyB;IAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAW,CAAC,CAAC,CAAC,iCAAiC;IACnE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/D,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAa,EAAE,CAAa;IACpD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACd,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,GAAG,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB;IAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB;IAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,17 @@
1
+ export class ApiError extends Error {
2
+ status;
3
+ body;
4
+ url;
5
+ method;
6
+ requestId;
7
+ constructor(message, status, body, url, method, requestId) {
8
+ super(message);
9
+ this.name = 'ApiError';
10
+ this.status = status;
11
+ this.body = body;
12
+ this.url = url;
13
+ this.method = method;
14
+ this.requestId = requestId;
15
+ }
16
+ }
17
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,MAAM,CAAS;IACf,IAAI,CAAW;IACf,GAAG,CAAU;IACb,MAAM,CAAU;IAChB,SAAS,CAAU;IACnB,YACE,OAAe,EACf,MAAc,EACd,IAAc,EACd,GAAY,EACZ,MAAe,EACf,SAAkB;QAElB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ export async function readFileUtf8(filePath) {
4
+ return await fs.readFile(filePath, 'utf8');
5
+ }
6
+ export async function writeFileUtf8(filePath, data) {
7
+ const dir = path.dirname(filePath);
8
+ // Ensure parent directory exists (mkdir -p)
9
+ await fs.mkdir(dir, { recursive: true });
10
+ // Write (creates file if missing, truncates if exists)
11
+ await fs.writeFile(filePath, data, 'utf8');
12
+ }
13
+ export async function ensureDir(p) {
14
+ await fs.mkdir(p, { recursive: true });
15
+ }
16
+ export async function fileExists(p) {
17
+ try {
18
+ await fs.stat(p);
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/services/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC/C,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,IAAY;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,4CAA4C;IAC5C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,uDAAuD;IACvD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,CAAS;IACrC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,CAAS;IACtC,IAAI,CAAC;QACD,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC"}
@@ -0,0 +1,121 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { execFile, execFileSync } from 'node:child_process';
4
+ import { normalizePath } from "./merkle.js";
5
+ export function runGit(args, opts) {
6
+ return new Promise((resolve) => {
7
+ const child = execFile('git', ['-C', opts.cwd, ...args], { encoding: 'buffer', windowsHide: true });
8
+ const chunksOut = [];
9
+ const chunksErr = [];
10
+ child.stdout?.on('data', (c) => chunksOut.push(c));
11
+ child.stderr?.on('data', (c) => chunksErr.push(c));
12
+ child.on('close', (code) => resolve({ stdout: Buffer.concat(chunksOut), stderr: Buffer.concat(chunksErr), code }));
13
+ });
14
+ }
15
+ function tryGit(args, opts) {
16
+ try {
17
+ const out = execFileSync('git', args, { cwd: opts.cwd, stdio: ['ignore', 'pipe', 'ignore'] });
18
+ return String(out).trim();
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ export function detectGitRepo(dir) {
25
+ // Quick check: look for .git or use git command
26
+ const gitDir = path.join(dir, '.git');
27
+ let isRepo = false;
28
+ if (fs.existsSync(gitDir)) {
29
+ isRepo = true;
30
+ }
31
+ else {
32
+ const inside = tryGit(['rev-parse', '--is-inside-work-tree'], { cwd: dir });
33
+ isRepo = inside === 'true';
34
+ }
35
+ if (!isRepo)
36
+ return { isRepo: false, remote: null };
37
+ const root = tryGit(['rev-parse', '--show-toplevel'], { cwd: dir }) || dir;
38
+ const head = tryGit(['rev-parse', 'HEAD'], { cwd: dir }) || undefined;
39
+ const branchRaw = tryGit(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: dir }) || null;
40
+ const branch = branchRaw && branchRaw !== 'HEAD' ? branchRaw : null; // null when detached
41
+ const remote = tryGit(['remote', 'get-url', 'origin'], { cwd: dir }) || null;
42
+ return { isRepo, root, head, branch, remote };
43
+ }
44
+ export function deriveRepoNameFromRemote(remote) {
45
+ if (!remote)
46
+ return null;
47
+ // Examples:
48
+ // git@github.com:user/name.git
49
+ // https://github.com/user/name.git
50
+ // https://github.com/user/name
51
+ let r = remote.trim();
52
+ r = r.replace(/\.git$/i, '');
53
+ const sshMatch = r.match(/^git@[^:]+:([^/]+)\/(.+)$/);
54
+ if (sshMatch) {
55
+ return `${sshMatch[1]}/${sshMatch[2]}`;
56
+ }
57
+ try {
58
+ const u = new URL(r);
59
+ if (u.hostname.toLowerCase().includes('github.com')) {
60
+ const parts = u.pathname.replace(/^\//, '').split('/');
61
+ if (parts.length >= 2 && parts[0] && parts[1]) {
62
+ return `${parts[0]}/${parts[1]}`;
63
+ }
64
+ }
65
+ }
66
+ catch {
67
+ // ignore
68
+ }
69
+ return null;
70
+ }
71
+ export function deriveRepoName(rootDir, remote) {
72
+ const fromRemote = deriveRepoNameFromRemote(remote);
73
+ if (fromRemote)
74
+ return fromRemote;
75
+ if (!rootDir)
76
+ return null;
77
+ return path.basename(rootDir) || null;
78
+ }
79
+ export async function listFilesAtCommit(repoRoot, commitHash) {
80
+ // Use -z to safely parse paths with spaces/newlines; keep mode to skip symlinks (120000)
81
+ const res = await runGit(['ls-tree', '-r', '-z', commitHash], { cwd: repoRoot, encoding: null });
82
+ if (res.code !== 0) {
83
+ const errTxt = res.stderr.toString('utf8').trim();
84
+ throw new Error(`Git error listing files for ${commitHash}: ${errTxt || 'unknown error'}`);
85
+ }
86
+ const entries = res.stdout.toString('utf8').split('\u0000').filter(Boolean);
87
+ const out = [];
88
+ for (const ent of entries) {
89
+ const tabIdx = ent.indexOf('\t');
90
+ if (tabIdx === -1)
91
+ continue;
92
+ const header = ent.slice(0, tabIdx);
93
+ const file = ent.slice(tabIdx + 1);
94
+ const parts = header.split(' ');
95
+ if (parts.length < 3)
96
+ continue;
97
+ const mode = parts[0];
98
+ if (mode.startsWith('120000'))
99
+ continue; // skip symlinks
100
+ out.push(normalizePath(file));
101
+ }
102
+ return out;
103
+ }
104
+ export async function listFilesForWorkingTree(repoRoot) {
105
+ // Tracked files in the working tree (respects gitignore for untracked by not including them)
106
+ const res = await runGit(['ls-files', '-z'], { cwd: repoRoot, encoding: null });
107
+ if (res.code !== 0) {
108
+ const errTxt = res.stderr.toString('utf8').trim();
109
+ throw new Error(`Git error listing files: ${errTxt || 'unknown error'}`);
110
+ }
111
+ return res.stdout.toString('utf8').split('\u0000').filter(Boolean).map(normalizePath);
112
+ }
113
+ export async function readFileAtCommit(repoRoot, commitHash, filePath) {
114
+ const res = await runGit(['show', `${commitHash}:${filePath}`], { cwd: repoRoot, encoding: null });
115
+ if (res.code !== 0) {
116
+ const errTxt = res.stderr.toString('utf8').trim();
117
+ throw new Error(`Git error reading ${filePath} at ${commitHash}: ${errTxt || 'unknown error'}`);
118
+ }
119
+ return res.stdout;
120
+ }
121
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/services/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { getCliVersion } from "../utilities.js";
2
+ export function buildAttestationManifest(params) {
3
+ const timestamp = Math.floor(Date.now() / 1000);
4
+ const cliVersion = getCliVersion();
5
+ return {
6
+ version: 'codequill-attestation:v1',
7
+ ecosystem: params.ecosystem,
8
+ statement: buildAttestationStatement({
9
+ ecosystem: params.ecosystem,
10
+ subjectPurl: params.subject.purl,
11
+ snapshotId: params.snapshot.snapshot_id,
12
+ snapshotRepo: params.snapshot.repository_name,
13
+ snapshotCommit: params.snapshot.commit_hash,
14
+ snapshotRoot: params.snapshot.merkle_root,
15
+ artifactDigest: params.artifact.digest,
16
+ }),
17
+ snapshot: params.snapshot,
18
+ artifact: params.artifact,
19
+ subject: params.subject,
20
+ ...(params.upstreams && params.upstreams.length ? { upstreams: params.upstreams } : {}),
21
+ timestamp,
22
+ generator: {
23
+ name: 'codequill-cli',
24
+ version: cliVersion,
25
+ },
26
+ };
27
+ }
28
+ function buildAttestationStatement(args) {
29
+ return (`This document is a CodeQuill attestation manifest (v1). It asserts that the artifact ` +
30
+ `with sha256 digest ${args.artifactDigest} (subject: ${args.subjectPurl}) was built from ` +
31
+ `the published CodeQuill snapshot ${args.snapshotId} for repository "${args.snapshotRepo}" ` +
32
+ `at commit "${args.snapshotCommit}", anchored by Merkle root ${args.snapshotRoot}. ` +
33
+ `Upstream entries (if present) reference anchored CodeQuill attestations resolved by purl.`);
34
+ }
35
+ //# sourceMappingURL=attestationManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestationManifest.js","sourceRoot":"","sources":["../../../src/services/manifests/attestationManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAmD9C,MAAM,UAAU,wBAAwB,CAAC,MAMxC;IACG,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO;QACH,OAAO,EAAE,0BAA0B;QACnC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,yBAAyB,CAAC;YACjC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;YAChC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW;YACvC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,eAAe;YAC7C,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW;YAC3C,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW;YACzC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;SACzC,CAAC;QACF,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,SAAS;QACT,SAAS,EAAE;YACP,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,UAAU;SACtB;KACJ,CAAC;AACN,CAAC;AAED,SAAS,yBAAyB,CAAC,IAQlC;IACG,OAAO,CACH,uFAAuF;QACvF,sBAAsB,IAAI,CAAC,cAAc,cAAc,IAAI,CAAC,WAAW,mBAAmB;QAC1F,oCAAoC,IAAI,CAAC,UAAU,oBAAoB,IAAI,CAAC,YAAY,IAAI;QAC5F,cAAc,IAAI,CAAC,cAAc,8BAA8B,IAAI,CAAC,YAAY,IAAI;QACpF,2FAA2F,CAC9F,CAAC;AACN,CAAC"}