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.
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/dist/commands/attest.js +442 -0
- package/dist/commands/attest.js.map +1 -0
- package/dist/commands/backup.js +370 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/claim.js +104 -0
- package/dist/commands/claim.js.map +1 -0
- package/dist/commands/log.js +188 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/login.js +147 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/prove.js +244 -0
- package/dist/commands/prove.js.map +1 -0
- package/dist/commands/publish.js +243 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/pull.js +174 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/quota.js +94 -0
- package/dist/commands/quota.js.map +1 -0
- package/dist/commands/revoke.js +97 -0
- package/dist/commands/revoke.js.map +1 -0
- package/dist/commands/snapshot.js +128 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/commands/status.js +234 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/verifyAttestation.js +212 -0
- package/dist/commands/verifyAttestation.js.map +1 -0
- package/dist/commands/verifyProof.js +145 -0
- package/dist/commands/verifyProof.js.map +1 -0
- package/dist/commands/wait.js +36 -0
- package/dist/commands/wait.js.map +1 -0
- package/dist/commands/who.js +55 -0
- package/dist/commands/who.js.map +1 -0
- package/dist/commands/why.js +412 -0
- package/dist/commands/why.js.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.js +69 -0
- package/dist/launcher.js.map +1 -0
- package/dist/services/api.js +51 -0
- package/dist/services/api.js.map +1 -0
- package/dist/services/apiClient.js +166 -0
- package/dist/services/apiClient.js.map +1 -0
- package/dist/services/authStore.js +84 -0
- package/dist/services/authStore.js.map +1 -0
- package/dist/services/config.js +19 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/confirm.js +58 -0
- package/dist/services/confirm.js.map +1 -0
- package/dist/services/crypto.js +38 -0
- package/dist/services/crypto.js.map +1 -0
- package/dist/services/errors.js +17 -0
- package/dist/services/errors.js.map +1 -0
- package/dist/services/fs.js +25 -0
- package/dist/services/fs.js.map +1 -0
- package/dist/services/git.js +121 -0
- package/dist/services/git.js.map +1 -0
- package/dist/services/manifests/attestationManifest.js +35 -0
- package/dist/services/manifests/attestationManifest.js.map +1 -0
- package/dist/services/manifests/proofManifest.js +151 -0
- package/dist/services/manifests/proofManifest.js.map +1 -0
- package/dist/services/manifests/snapshotManifest.js +214 -0
- package/dist/services/manifests/snapshotManifest.js.map +1 -0
- package/dist/services/merkle.js +92 -0
- package/dist/services/merkle.js.map +1 -0
- package/dist/services/paths.js +16 -0
- package/dist/services/paths.js.map +1 -0
- package/dist/services/snapshotIndex.js +401 -0
- package/dist/services/snapshotIndex.js.map +1 -0
- package/dist/services/txWaiter.js +84 -0
- package/dist/services/txWaiter.js.map +1 -0
- package/dist/services/ui.js +98 -0
- package/dist/services/ui.js.map +1 -0
- package/dist/services/utilities.js +45 -0
- package/dist/services/utilities.js.map +1 -0
- package/dist/services/zip.js +24 -0
- package/dist/services/zip.js.map +1 -0
- package/dist/types/api.js +2 -0
- package/dist/types/api.js.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CodeQuill
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
CodeQuill CLI
|
|
2
|
+
|
|
3
|
+
CodeQuill CLI lets you authenticate, claim repositories, create on-chain snapshots, and push backups via the CodeQuill backend. The CLI makes only HTTP requests; all on-chain activity and backup processing happen on the backend.
|
|
4
|
+
|
|
5
|
+
Requirements
|
|
6
|
+
- Node.js 18+
|
|
7
|
+
- TypeScript 5+
|
|
8
|
+
|
|
9
|
+
Install (from source)
|
|
10
|
+
- npm install
|
|
11
|
+
- npm run build
|
|
12
|
+
- npm link (optional, to get the `codequill` binary on PATH)
|
|
13
|
+
|
|
14
|
+
Configuration
|
|
15
|
+
- API base URL: set environment variable `CODEQUILL_API_BASE_URL` (defaults to `https://api.staging.codequill.dev`).
|
|
16
|
+
- Tokens are stored at `~/.config/codequill/config.json` with 0600 permissions.
|
|
17
|
+
- For testing or sandboxing, you can override the config directory with `CODEQUILL_CONFIG_DIR` (mainly used by unit tests).
|
|
18
|
+
|
|
19
|
+
Session duration and auto-refresh
|
|
20
|
+
- The CLI automatically refreshes your access token using the stored `refresh_token` when it expires.
|
|
21
|
+
- As long as your refresh token remains valid (typically around 30 days), you will stay signed in and won’t be prompted to log in again.
|
|
22
|
+
- If your access token is expired and no valid `refresh_token` is present, the CLI will ask you to run `codequill login` again.
|
|
23
|
+
|
|
24
|
+
Usage
|
|
25
|
+
- Show help
|
|
26
|
+
- `codequill --help`
|
|
27
|
+
- `codequill <command> --help`
|
|
28
|
+
|
|
29
|
+
Commands
|
|
30
|
+
- codequill login
|
|
31
|
+
- Authenticates via device-code flow.
|
|
32
|
+
- Behavior:
|
|
33
|
+
- POST `/api/v1/cli/device-code` with `{ client_name: "codequill-cli", client_version }`.
|
|
34
|
+
- Prints a `verification_url` — open it in your browser.
|
|
35
|
+
- Prerequisite: make sure you are already signed in to the CodeQuill web app in that browser session.
|
|
36
|
+
- Polls POST `/api/v1/cli/device-token` until approved.
|
|
37
|
+
- Saves tokens with a small expiry margin. Subsequent commands auto-refresh access tokens using the stored `refresh_token`.
|
|
38
|
+
|
|
39
|
+
- codequill whoami
|
|
40
|
+
- Displays the current authenticated user and repos.
|
|
41
|
+
- GET `/api/v1/cli/me` with `Authorization: Bearer <access_token>`.
|
|
42
|
+
|
|
43
|
+
- codequill quota
|
|
44
|
+
- Shows your subscription plan and quota usage details.
|
|
45
|
+
- GET `/v1/cli/quota` with `Authorization: Bearer <access_token>`.
|
|
46
|
+
- Displays:
|
|
47
|
+
- Plan code
|
|
48
|
+
- Claimed repos (public/private used vs limit)
|
|
49
|
+
- Snapshots used this month vs limit
|
|
50
|
+
- Backups used this month vs limit
|
|
51
|
+
- GitHub Actions used vs limit
|
|
52
|
+
- Plagiarism scans used this month vs limit
|
|
53
|
+
|
|
54
|
+
- codequill claim [--repo <name>] [--path <path>]
|
|
55
|
+
- Claims authorship of a repository via the backend.
|
|
56
|
+
- If run inside a git repo, auto-detects repo name from `origin` remote or folder name.
|
|
57
|
+
- POST `/api/v1/cli/claim` with `{ repo_name, path, git_remote }`.
|
|
58
|
+
|
|
59
|
+
- codequill snapshot [--repo <name>] [--commit <hash>] [--path <path>] [--dry-run]
|
|
60
|
+
- Creates a new on-chain snapshot for a repo+commit (backend performs on-chain work).
|
|
61
|
+
- If inside git, defaults to `HEAD` commit and derives repo name from remote.
|
|
62
|
+
- `--dry-run` prints resolved parameters without calling the API.
|
|
63
|
+
- POST `/api/v1/cli/snapshot` with `{ repo_name, commit_hash, path, git: { is_repo, remote } }`.
|
|
64
|
+
|
|
65
|
+
- codequill push [--repo <name>] [--path <path>] [--snapshot-id <id>] [--dry-run]
|
|
66
|
+
- Backs up the latest (or a specified) snapshot.
|
|
67
|
+
- Important: the backend performs zipping, encryption, and IPFS upload. The CLI only sends intent and metadata.
|
|
68
|
+
- `--dry-run` prints resolved parameters without calling the API.
|
|
69
|
+
- POST `/api/v1/cli/push` with `{ repo_name, path, snapshot_id }`.
|
|
70
|
+
|
|
71
|
+
Git-aware vs explicit mode
|
|
72
|
+
- When run inside a git repository, the CLI tries to determine:
|
|
73
|
+
- repo root (`git rev-parse --show-toplevel`)
|
|
74
|
+
- `HEAD` commit hash
|
|
75
|
+
- `origin` remote URL to derive `user/name`
|
|
76
|
+
- When run outside git, pass `--repo` and optionally `--commit` and `--path`.
|
|
77
|
+
|
|
78
|
+
Environment variables
|
|
79
|
+
- `CODEQUILL_API_BASE_URL` — base HTTP URL for backend (default: staging placeholder).
|
|
80
|
+
- `CODEQUILL_CONFIG_DIR` — override tokens/config directory (used by tests).
|
|
81
|
+
|
|
82
|
+
Development
|
|
83
|
+
- Build: `npm run build`
|
|
84
|
+
- Watch: `npm run dev`
|
|
85
|
+
- Tests: `npm test`
|
|
86
|
+
- Coverage: `npm run coverage`
|
|
87
|
+
|
|
88
|
+
Project Structure
|
|
89
|
+
- src/index.ts — Commander entrypoint
|
|
90
|
+
- src/version.ts — CLI version via package.json
|
|
91
|
+
- src/commands/login.ts — device-code login
|
|
92
|
+
- src/commands/whoami.ts — prints current user
|
|
93
|
+
- src/commands/claim.ts — claim authorship
|
|
94
|
+
- src/commands/snapshot.ts — create snapshots
|
|
95
|
+
- src/commands/push.ts — request backups (backend handles zip/encrypt/upload)
|
|
96
|
+
- src/services/apiClient.ts — HTTP wrapper with auth header injection
|
|
97
|
+
- src/services/authStore.ts — token persistence (0600)
|
|
98
|
+
- src/services/config.ts — config dir/file paths
|
|
99
|
+
- src/services/errors.ts — ApiError type
|
|
100
|
+
- src/services/ui.ts — colors, spinner, open browser helper
|
|
101
|
+
- src/services/git.ts — git detection (root/head/remote) and repo name derivation
|
|
102
|
+
- src/services/paths.ts — path helpers
|
|
103
|
+
- src/services/zip.ts — zip helper (currently unused in `push` since backend handles it)
|
|
104
|
+
- src/services/ipfs.ts — placeholder IPFS helper (currently unused)
|
|
105
|
+
- src/types/api.ts — API types
|
|
106
|
+
- test/*.test.ts — unit tests (Vitest)
|
|
107
|
+
|
|
108
|
+
Testing
|
|
109
|
+
- The test suite is API-free and uses mocks; it verifies:
|
|
110
|
+
- Token storage and permissions
|
|
111
|
+
- API client behavior and error handling
|
|
112
|
+
- Git remote parsing logic
|
|
113
|
+
- Command flows for `login`, `whoami`, `claim`, `snapshot` (incl. dry-run), and `push` (incl. dry-run)
|
|
114
|
+
- Run: `npm test`
|
|
115
|
+
|
|
116
|
+
Notes & assumptions
|
|
117
|
+
- The CLI relies on the backend for all on-chain actions and, for backups, for zipping/encryption/IPFS upload.
|
|
118
|
+
- Token refresh is not yet implemented; if expired, the CLI asks you to re-login.
|
|
119
|
+
|
|
120
|
+
License
|
|
121
|
+
MIT © CodeQuill
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import { gzipSync } from 'node:zlib';
|
|
4
|
+
import { colors, shortCommit, spinner } from '../services/ui.js';
|
|
5
|
+
import { apiClient } from '../services/apiClient.js';
|
|
6
|
+
import { assertAuthenticated } from '../services/utilities.js';
|
|
7
|
+
import { detectGitRepo } from '../services/git.js';
|
|
8
|
+
import { fileExists, readFileUtf8 } from '../services/fs.js';
|
|
9
|
+
import { getBaseUrl } from '../services/config.js';
|
|
10
|
+
import { waitForTxConfirmation } from '../services/txWaiter.js';
|
|
11
|
+
import { confirmDangerousAction } from '../services/confirm.js';
|
|
12
|
+
import { buildAttestationManifest, } from '../services/manifests/attestationManifest.js';
|
|
13
|
+
import { fetchSnapshot } from '../services/api.js';
|
|
14
|
+
import { sha256File } from '../services/crypto.js';
|
|
15
|
+
export async function handleAttest(buildPath, snapshotId, opts) {
|
|
16
|
+
if (!assertAuthenticated())
|
|
17
|
+
return;
|
|
18
|
+
const log = (...args) => { if (!opts.json)
|
|
19
|
+
console.log(...args); };
|
|
20
|
+
const git = detectGitRepo(process.cwd());
|
|
21
|
+
if (!git.isRepo || !git.root) {
|
|
22
|
+
console.error(colors.error('This command must be run inside a git repository.'));
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const buildAbs = path.resolve(String(buildPath || '').trim());
|
|
27
|
+
if (!buildAbs) {
|
|
28
|
+
console.error(colors.error('Missing <build> path.'));
|
|
29
|
+
process.exitCode = 1;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (!(await fileExists(buildAbs))) {
|
|
33
|
+
console.error(colors.error('Build artifact not found.'));
|
|
34
|
+
if (!opts.json) {
|
|
35
|
+
console.error(colors.dim(`Expected: ${path.relative(process.cwd(), buildAbs)}`));
|
|
36
|
+
}
|
|
37
|
+
process.exitCode = 1;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const snapId = String(snapshotId || '').trim();
|
|
41
|
+
if (!snapId) {
|
|
42
|
+
console.error(colors.error('Missing <snapshotId>.'));
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Normalize manual upstreams early (repeatable --upstream)
|
|
47
|
+
const manualUpstreams = normalizePurls(opts.upstreams ?? []);
|
|
48
|
+
// 1) Ecosystem (NO auto detection; used only for subject formatting)
|
|
49
|
+
const ecoRaw = String(opts.ecosystem ?? 'auto').trim().toLowerCase();
|
|
50
|
+
const allowed = ['npm', 'composer', 'pypi', 'docker', 'generic'];
|
|
51
|
+
let ecosystem;
|
|
52
|
+
if (ecoRaw === 'auto' || ecoRaw === '') {
|
|
53
|
+
ecosystem = await detectEcosystemForSubjectOnly(git.root); // ✅ still auto, but no deps
|
|
54
|
+
}
|
|
55
|
+
else if (allowed.includes(ecoRaw)) {
|
|
56
|
+
ecosystem = ecoRaw;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.error(colors.error(`Invalid --ecosystem "${ecoRaw}". Expected auto|${allowed.join('|')}.`));
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// 2) Fetch snapshot meta (must be fully published/anchored or FAIL)
|
|
64
|
+
const sSnap = spinner('Fetching published snapshot info ...', opts.json);
|
|
65
|
+
let snapshotMeta;
|
|
66
|
+
try {
|
|
67
|
+
snapshotMeta = await fetchSnapshot(snapId);
|
|
68
|
+
sSnap.succeed(colors.success('Snapshot is published & anchored.'));
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
sSnap.fail(colors.error('Snapshot is not ready.'));
|
|
72
|
+
console.error(colors.error(String(e?.message || e)));
|
|
73
|
+
if (!opts.json) {
|
|
74
|
+
console.error(colors.dim('Tip: run `codequill publish` and wait for confirmation before attesting.'));
|
|
75
|
+
}
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// 3) Compute artifact sha256 hex digest + metadata
|
|
80
|
+
const sHash = spinner('Hashing artifact (sha256) ...', opts.json);
|
|
81
|
+
let artifactDigest;
|
|
82
|
+
let artifactSize = 0;
|
|
83
|
+
try {
|
|
84
|
+
const fh = await fs.open(buildAbs, 'r');
|
|
85
|
+
const stat = await fh.stat();
|
|
86
|
+
artifactSize = Number(stat.size || 0);
|
|
87
|
+
artifactDigest = await sha256File(buildAbs);
|
|
88
|
+
sHash.succeed(colors.success(`sha256: ${artifactDigest.slice(0, 16)}… (${artifactSize} bytes)`));
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
sHash.fail(colors.error('Failed to hash artifact.'));
|
|
92
|
+
console.error(colors.error(String(e?.message || e)));
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// 4) Build subject (required; ecosystem-aware; generic uses repo-purl by snapshot meta)
|
|
97
|
+
const subject = await buildSubject({
|
|
98
|
+
ecosystem,
|
|
99
|
+
repoRoot: git.root,
|
|
100
|
+
artifactPathAbs: buildAbs,
|
|
101
|
+
artifactDigestHex: artifactDigest,
|
|
102
|
+
snapshotMeta,
|
|
103
|
+
});
|
|
104
|
+
// 5) Resolve upstreams (MANUAL ONLY; no lockfile-derived deps)
|
|
105
|
+
let upstreams;
|
|
106
|
+
const mergedPurls = normalizePurls(opts.upstreams ?? []);
|
|
107
|
+
if (mergedPurls.length > 0) {
|
|
108
|
+
const sUp = spinner('Resolving upstream attestations ...', opts.json);
|
|
109
|
+
try {
|
|
110
|
+
const resolved = await resolveUpstreamsByPurl(mergedPurls);
|
|
111
|
+
upstreams = resolved.map((r) => ({
|
|
112
|
+
purl: r.purl,
|
|
113
|
+
attestation: {
|
|
114
|
+
attestation_id: r.attestation_id,
|
|
115
|
+
artifact_digest: r.artifact_digest,
|
|
116
|
+
chain_id: r.chain_id,
|
|
117
|
+
tx_hash: r.tx_hash,
|
|
118
|
+
explorer_url: r.explorer_url,
|
|
119
|
+
},
|
|
120
|
+
}));
|
|
121
|
+
sUp.succeed(colors.success(`Upstreams: ${upstreams.length}/${mergedPurls.length} resolved on CodeQuill`));
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
sUp.fail(colors.error('Failed to resolve upstreams.'));
|
|
125
|
+
console.error(colors.error(String(e?.message || e)));
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// 6) Build manifest JSON (locked v1)
|
|
131
|
+
const manifest = buildAttestationManifest({
|
|
132
|
+
ecosystem,
|
|
133
|
+
snapshot: snapshotMeta,
|
|
134
|
+
artifact: {
|
|
135
|
+
kind: ecosystem === 'npm' ? 'npm' : ecosystem === 'docker' ? 'docker' : 'file',
|
|
136
|
+
algorithm: 'sha256',
|
|
137
|
+
digest: artifactDigest,
|
|
138
|
+
name: path.basename(buildAbs),
|
|
139
|
+
size: artifactSize,
|
|
140
|
+
media_type: guessMediaType(buildAbs),
|
|
141
|
+
},
|
|
142
|
+
subject,
|
|
143
|
+
upstreams
|
|
144
|
+
});
|
|
145
|
+
// 7) Serialize + gzip (like publish)
|
|
146
|
+
const rawJson = Buffer.from(JSON.stringify(manifest, null, 2), 'utf8');
|
|
147
|
+
const sGz = spinner('Compressing attestation manifest (gzip) ...', opts.json);
|
|
148
|
+
let gzBytes;
|
|
149
|
+
try {
|
|
150
|
+
gzBytes = gzipSync(rawJson, { level: 9 });
|
|
151
|
+
sGz.succeed(colors.success(`Compressed (${rawJson.length} → ${gzBytes.length} bytes).`));
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
sGz.fail(colors.error('Failed to gzip manifest.'));
|
|
155
|
+
console.error(colors.error(String(e?.message || e)));
|
|
156
|
+
process.exitCode = 1;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// 7.5) Human confirmation (default NO)
|
|
160
|
+
if (!opts.noConfirm && !opts.json) {
|
|
161
|
+
const ok = await confirmDangerousAction('You are about to create an irreversible attestation', [
|
|
162
|
+
` Repo ${snapshotMeta.repository_name}`,
|
|
163
|
+
` Snapshot ${snapshotMeta.snapshot_id}`,
|
|
164
|
+
` Commit ${shortCommit(snapshotMeta.commit_hash)}`,
|
|
165
|
+
` Artifact ${path.relative(process.cwd(), buildAbs)}`,
|
|
166
|
+
` Digest ${artifactDigest}`,
|
|
167
|
+
` Subject ${subject.purl}`,
|
|
168
|
+
` Upstreams ${upstreams?.length ?? 0}`,
|
|
169
|
+
], 'This action will permanently anchor a claim on-chain.');
|
|
170
|
+
if (!ok) {
|
|
171
|
+
log(colors.dim('Attestation cancelled.'));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 8) Upload attestation manifest
|
|
176
|
+
const sPub = spinner('Publishing attestation ...', opts.json);
|
|
177
|
+
let res;
|
|
178
|
+
try {
|
|
179
|
+
const form = new FormData();
|
|
180
|
+
form.append('snapshot_id', snapshotMeta.snapshot_id);
|
|
181
|
+
form.append('ecosystem', ecosystem);
|
|
182
|
+
form.append('artifact_digest', artifactDigest);
|
|
183
|
+
form.append('subject_purl', subject.purl);
|
|
184
|
+
form.append('version', manifest.version);
|
|
185
|
+
form.append('manifest_encoding', 'gzip');
|
|
186
|
+
const gzFilename = `attestation-${artifactDigest.slice(0, 12)}.json.gz`;
|
|
187
|
+
const file = new File([new Uint8Array(gzBytes)], gzFilename, { type: 'application/gzip' });
|
|
188
|
+
form.append('manifest', file);
|
|
189
|
+
res = await apiClient.postMultipart('/v1/cli/attest', form);
|
|
190
|
+
sPub.succeed(colors.success('Attestation submitted.'));
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
sPub.fail(colors.error('Attestation failed.'));
|
|
194
|
+
console.error(colors.error(String(e?.message || e)));
|
|
195
|
+
process.exitCode = 1;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// 9) Output
|
|
199
|
+
if (opts.json) {
|
|
200
|
+
console.log(JSON.stringify(res, null, 2));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
console.log('');
|
|
204
|
+
console.log(colors.bold('🧾 Attestation started'));
|
|
205
|
+
console.log(colors.dim('────────────────────────────────────────'));
|
|
206
|
+
console.log(colors.dim('Attestation'));
|
|
207
|
+
console.log(` Snapshot ID ${snapshotMeta.snapshot_id}`);
|
|
208
|
+
console.log(` Repo ${snapshotMeta.repository_name}`);
|
|
209
|
+
console.log(` Commit ${shortCommit(snapshotMeta.commit_hash)}`);
|
|
210
|
+
console.log(` Merkle Root ${snapshotMeta.merkle_root}`);
|
|
211
|
+
console.log(` Attestation URL ${getBaseUrl() + '/a/' + res.attestation_id}`);
|
|
212
|
+
console.log('');
|
|
213
|
+
console.log(colors.dim('Artifact'));
|
|
214
|
+
console.log(` File ${path.relative(process.cwd(), buildAbs)}`);
|
|
215
|
+
console.log(` Digest ${artifactDigest}`);
|
|
216
|
+
console.log(` Algorithm sha256`);
|
|
217
|
+
console.log('');
|
|
218
|
+
console.log(colors.dim('Subject'));
|
|
219
|
+
console.log(` PURL ${subject.purl}`);
|
|
220
|
+
console.log(` Name ${subject.name}`);
|
|
221
|
+
console.log(` Version ${subject.version}`);
|
|
222
|
+
if (upstreams && upstreams.length > 0) {
|
|
223
|
+
console.log('');
|
|
224
|
+
console.log(colors.dim('Upstreams'));
|
|
225
|
+
for (const u of upstreams) {
|
|
226
|
+
console.log(` ${u.purl}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
console.log('');
|
|
230
|
+
console.log(colors.dim('Chain'));
|
|
231
|
+
console.log(` Tx Hash ${res.tx_hash}`);
|
|
232
|
+
if (res.chain_id)
|
|
233
|
+
console.log(` Chain ID ${res.chain_id}`);
|
|
234
|
+
if (res.explorer_url)
|
|
235
|
+
console.log(` Explorer ${res.explorer_url}`);
|
|
236
|
+
console.log(colors.dim('────────────────────────────────────────'));
|
|
237
|
+
}
|
|
238
|
+
if (opts.noWait) {
|
|
239
|
+
log(colors.dim('Note: skipping confirmation wait (--no-wait).'));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// 10) Wait confirmation
|
|
243
|
+
const confTarget = Math.max(1, Number(opts.confirmations ?? 1));
|
|
244
|
+
try {
|
|
245
|
+
await waitForTxConfirmation({
|
|
246
|
+
txHash: res.tx_hash,
|
|
247
|
+
confirmations: confTarget,
|
|
248
|
+
timeoutMs: opts.timeoutMs,
|
|
249
|
+
silent: opts.json,
|
|
250
|
+
});
|
|
251
|
+
log(colors.success(`✓ Confirmed on-chain (${confTarget} confirmation${confTarget > 1 ? 's' : ''}).`));
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
console.error(colors.error(String(e?.message || e)));
|
|
255
|
+
process.exitCode = 1;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
export function registerAttestCommand(program) {
|
|
259
|
+
program
|
|
260
|
+
.command('attest <build> <snapshotId>')
|
|
261
|
+
.description('Create an attestation linking a build artifact to a published snapshot, and resolve upstream attestations by purl (manual --upstream only)')
|
|
262
|
+
.option('--ecosystem <type>', 'Ecosystem (auto|npm|composer|pypi|docker|generic). Default: auto', 'auto')
|
|
263
|
+
.option('--upstream <purl>', 'Upstream purl to resolve to an anchored CodeQuill attestation (repeatable)', collectRepeatableString, [])
|
|
264
|
+
.option('--confirmations <n>', 'Wait for N confirmations (default: 1)', (v) => parseInt(v, 10))
|
|
265
|
+
.option('--timeout <ms>', 'Timeout waiting for confirmation (ms)', (v) => parseInt(v, 10))
|
|
266
|
+
.option('--no-wait', 'Do not wait for confirmation')
|
|
267
|
+
.option('--no-confirm', 'Skip confirmation prompt (for CI)', false)
|
|
268
|
+
.option('--json', 'Output result in JSON format', false)
|
|
269
|
+
.action(async (build, snapshotId, options) => {
|
|
270
|
+
await handleAttest(build, snapshotId, {
|
|
271
|
+
ecosystem: options.ecosystem,
|
|
272
|
+
upstreams: Array.isArray(options.upstream) ? options.upstream : [],
|
|
273
|
+
confirmations: options.confirmations,
|
|
274
|
+
timeoutMs: options.timeout,
|
|
275
|
+
noWait: options.wait === false,
|
|
276
|
+
noConfirm: !!options.noConfirm,
|
|
277
|
+
json: !!options.json
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function collectRepeatableString(value, previous) {
|
|
282
|
+
const v = String(value ?? '').trim();
|
|
283
|
+
if (!v)
|
|
284
|
+
return previous;
|
|
285
|
+
return [...previous, v];
|
|
286
|
+
}
|
|
287
|
+
function uniqStrings(xs) {
|
|
288
|
+
const out = [];
|
|
289
|
+
const seen = new Set();
|
|
290
|
+
for (const x of xs) {
|
|
291
|
+
const k = String(x).trim();
|
|
292
|
+
if (!k)
|
|
293
|
+
continue;
|
|
294
|
+
const kk = k.toLowerCase();
|
|
295
|
+
if (seen.has(kk))
|
|
296
|
+
continue;
|
|
297
|
+
seen.add(kk);
|
|
298
|
+
out.push(k);
|
|
299
|
+
}
|
|
300
|
+
return out;
|
|
301
|
+
}
|
|
302
|
+
function normalizePurls(purls) {
|
|
303
|
+
return uniqStrings((purls ?? [])
|
|
304
|
+
.map((p) => (typeof p === 'string' ? p.trim() : ''))
|
|
305
|
+
.filter((p) => !!p));
|
|
306
|
+
}
|
|
307
|
+
function guessMediaType(p) {
|
|
308
|
+
const lower = p.toLowerCase();
|
|
309
|
+
if (lower.endsWith('.tgz') || lower.endsWith('.tar.gz'))
|
|
310
|
+
return 'application/gzip';
|
|
311
|
+
if (lower.endsWith('.zip'))
|
|
312
|
+
return 'application/zip';
|
|
313
|
+
if (lower.endsWith('.json'))
|
|
314
|
+
return 'application/json';
|
|
315
|
+
if (lower.endsWith('.tar'))
|
|
316
|
+
return 'application/x-tar';
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
async function detectEcosystemForSubjectOnly(repoRoot) {
|
|
320
|
+
// NO lockfiles. Only identity files.
|
|
321
|
+
if (await fileExists(path.join(repoRoot, 'package.json')))
|
|
322
|
+
return 'npm';
|
|
323
|
+
if (await fileExists(path.join(repoRoot, 'composer.json')))
|
|
324
|
+
return 'composer';
|
|
325
|
+
if (await fileExists(path.join(repoRoot, 'pyproject.toml')))
|
|
326
|
+
return 'pypi';
|
|
327
|
+
return 'generic';
|
|
328
|
+
}
|
|
329
|
+
async function buildSubject(args) {
|
|
330
|
+
// Must always return name/version/purl.
|
|
331
|
+
if (args.ecosystem === 'npm') {
|
|
332
|
+
// Best effort: package.json (more reliable than lock for project identity)
|
|
333
|
+
const pkgJson = path.join(args.repoRoot, 'package.json');
|
|
334
|
+
if (await fileExists(pkgJson)) {
|
|
335
|
+
try {
|
|
336
|
+
const raw = await readFileUtf8(pkgJson);
|
|
337
|
+
const obj = JSON.parse(raw);
|
|
338
|
+
const name = String(obj?.name || '').trim();
|
|
339
|
+
const version = String(obj?.version || '').trim();
|
|
340
|
+
if (name && version) {
|
|
341
|
+
const purl = toPurlNpm(name, version);
|
|
342
|
+
return { purl, name, version };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
/* fallback */
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (args.ecosystem === 'composer') {
|
|
351
|
+
const compJson = path.join(args.repoRoot, 'composer.json');
|
|
352
|
+
if (await fileExists(compJson)) {
|
|
353
|
+
try {
|
|
354
|
+
const raw = await readFileUtf8(compJson);
|
|
355
|
+
const obj = JSON.parse(raw);
|
|
356
|
+
const name = String(obj?.name || '').trim(); // vendor/package
|
|
357
|
+
const version = String(obj?.version || '').trim(); // may not exist
|
|
358
|
+
if (name) {
|
|
359
|
+
const v = version || 'unknown';
|
|
360
|
+
const purl = toPurlComposer(name, v);
|
|
361
|
+
return { purl, name, version: v };
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
/* fallback */
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (args.ecosystem === 'pypi') {
|
|
370
|
+
// v1: best effort from pyproject.toml (very rough)
|
|
371
|
+
const pyproj = path.join(args.repoRoot, 'pyproject.toml');
|
|
372
|
+
if (await fileExists(pyproj)) {
|
|
373
|
+
try {
|
|
374
|
+
const raw = await readFileUtf8(pyproj);
|
|
375
|
+
const name = matchTomlValue(raw, 'name');
|
|
376
|
+
const version = matchTomlValue(raw, 'version');
|
|
377
|
+
if (name && version) {
|
|
378
|
+
const purl = toPurlPypi(name, version);
|
|
379
|
+
return { purl, name, version };
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
/* fallback */
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const repoName = String(args.snapshotMeta.repository_name || '').trim(); // expected "org/repo"
|
|
388
|
+
const commit = String(args.snapshotMeta.commit_hash || '').trim();
|
|
389
|
+
if (repoName && commit && repoName.includes('/')) {
|
|
390
|
+
const purl = toPurlGithubRepo(repoName, commit);
|
|
391
|
+
// For display, name = "org/repo", version = commit SHA
|
|
392
|
+
return { purl, name: repoName, version: commit };
|
|
393
|
+
}
|
|
394
|
+
// Fallback: digest-derived identity
|
|
395
|
+
const baseName = path.basename(args.artifactPathAbs) || 'artifact';
|
|
396
|
+
const version = `sha256:${args.artifactDigestHex}`;
|
|
397
|
+
const purl = toPurlGeneric(baseName, version);
|
|
398
|
+
return { purl, name: baseName, version };
|
|
399
|
+
}
|
|
400
|
+
function matchTomlValue(raw, key) {
|
|
401
|
+
// extremely light parser: key = "value"
|
|
402
|
+
const re = new RegExp(`\\b${escapeRegExp(key)}\\s*=\\s*"(.*?)"`);
|
|
403
|
+
const m = raw.match(re);
|
|
404
|
+
return m && m[1] ? String(m[1]).trim() : null;
|
|
405
|
+
}
|
|
406
|
+
function escapeRegExp(s) {
|
|
407
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
408
|
+
}
|
|
409
|
+
function toPurlGeneric(name, version) {
|
|
410
|
+
return `pkg:generic/${encodeURIComponent(name)}@${encodeURIComponent(version)}`;
|
|
411
|
+
}
|
|
412
|
+
function toPurlGithubRepo(repoName, commit) {
|
|
413
|
+
// repoName should be "org/repo"
|
|
414
|
+
const [org, repo] = repoName.split('/', 2);
|
|
415
|
+
if (!org || !repo) {
|
|
416
|
+
// fallback (still deterministic)
|
|
417
|
+
return `pkg:github/${encodeURIComponent(repoName)}@${encodeURIComponent(commit)}`;
|
|
418
|
+
}
|
|
419
|
+
return `pkg:github/${encodeURIComponent(org)}/${encodeURIComponent(repo)}@${encodeURIComponent(commit)}`;
|
|
420
|
+
}
|
|
421
|
+
function toPurlNpm(name, version) {
|
|
422
|
+
const encoded = name.startsWith('@')
|
|
423
|
+
? `%40${encodeURIComponent(name.slice(1)).replace(/%2F/g, '/')}`
|
|
424
|
+
: encodeURIComponent(name);
|
|
425
|
+
return `pkg:npm/${encoded}@${encodeURIComponent(version)}`;
|
|
426
|
+
}
|
|
427
|
+
function toPurlComposer(name, version) {
|
|
428
|
+
return `pkg:composer/${encodeURIComponent(name)}@${encodeURIComponent(version)}`;
|
|
429
|
+
}
|
|
430
|
+
function toPurlPypi(name, version) {
|
|
431
|
+
return `pkg:pypi/${encodeURIComponent(name)}@${encodeURIComponent(version)}`;
|
|
432
|
+
}
|
|
433
|
+
async function resolveUpstreamsByPurl(purls) {
|
|
434
|
+
if (!purls.length)
|
|
435
|
+
return [];
|
|
436
|
+
const body = { purls };
|
|
437
|
+
const res = await apiClient.post('/v1/cli/upstreams/resolve', body);
|
|
438
|
+
const out = Array.isArray(res?.resolved) ? res.resolved : [];
|
|
439
|
+
// Filter only anchored (must have chain fields)
|
|
440
|
+
return out.filter((r) => r && r.purl && r.attestation_id && r.artifact_digest && r.chain_id && r.tx_hash && r.explorer_url);
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=attest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.js","sourceRoot":"","sources":["../../src/commands/attest.ts"],"names":[],"mappings":"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"}
|