@coderook/cli 0.31.10 → 0.31.12
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/.claude-plugin/plugin.json +1 -1
- package/dist/cli/src/api.js +32 -0
- package/dist/cli/src/cli.js +34 -8
- package/dist/cli/src/project_commands.js +0 -10
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "coderook",
|
|
3
3
|
"displayName": "CodeRook",
|
|
4
4
|
"description": "Save, browse and restore whole-snapshot versions of a project on CodeRook, from Claude Code.",
|
|
5
|
-
"version": "0.31.
|
|
5
|
+
"version": "0.31.12",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ACCA Gaming Productions",
|
|
8
8
|
"url": "https://coderook.com"
|
package/dist/cli/src/api.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.completeUpload = completeUpload;
|
|
|
7
7
|
exports.attachToVersion = attachToVersion;
|
|
8
8
|
exports.whoami = whoami;
|
|
9
9
|
exports.projects = projects;
|
|
10
|
+
exports.projectById = projectById;
|
|
10
11
|
exports.findPublicProject = findPublicProject;
|
|
11
12
|
exports.findProject = findProject;
|
|
12
13
|
exports.health = health;
|
|
@@ -184,6 +185,37 @@ async function projects() {
|
|
|
184
185
|
updatedAt: String(row.updatedAt ?? row.createdAt ?? ""),
|
|
185
186
|
}));
|
|
186
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* One project by its id, including somebody else's public or unlisted one.
|
|
190
|
+
*
|
|
191
|
+
* The account's own list holds only projects it is in, so a folder cloned
|
|
192
|
+
* from somebody else's public project had no way back to it: every command
|
|
193
|
+
* after the clone said the project was "no longer on your account". The
|
|
194
|
+
* service answers this route for anybody signed in when the project is open,
|
|
195
|
+
* and says whether the caller is one of its people.
|
|
196
|
+
*/
|
|
197
|
+
async function projectById(repositoryId) {
|
|
198
|
+
try {
|
|
199
|
+
const row = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}`);
|
|
200
|
+
if (!row.id)
|
|
201
|
+
return null;
|
|
202
|
+
return {
|
|
203
|
+
id: String(row.id),
|
|
204
|
+
slug: String(row.slug ?? ""),
|
|
205
|
+
name: String(row.displayName || row.slug || "Untitled"),
|
|
206
|
+
visibility: String(row.visibility ?? "public"),
|
|
207
|
+
defaultBranch: String(row.defaultBranch || "main"),
|
|
208
|
+
versionCount: Number(row.versionCount ?? 0),
|
|
209
|
+
fileCount: Number(row.fileCount ?? 0),
|
|
210
|
+
storedBytes: Number(row.storedSize ?? 0),
|
|
211
|
+
updatedAt: String(row.updatedAt ?? row.createdAt ?? ""),
|
|
212
|
+
member: row.member !== false,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
187
219
|
/**
|
|
188
220
|
* One public project, by the two names that identify it.
|
|
189
221
|
*
|
package/dist/cli/src/cli.js
CHANGED
|
@@ -195,9 +195,23 @@ const folderFor = (parsed, index = 0) => node_path_1.default.resolve(parsed.posi
|
|
|
195
195
|
async function reconcile(folder, options = {}) {
|
|
196
196
|
const link = await (0, config_js_1.readLink)(folder);
|
|
197
197
|
const reference = link?.slug ?? node_path_1.default.basename(folder);
|
|
198
|
-
|
|
198
|
+
let member = true;
|
|
199
|
+
let project = link
|
|
199
200
|
? (await (0, api_js_2.projects)()).find((candidate) => candidate.id === link.repositoryId)
|
|
200
201
|
: await (0, api_js_2.findProject)(reference);
|
|
202
|
+
/*
|
|
203
|
+
Not on the account's own list, which holds only projects it is in. A
|
|
204
|
+
folder cloned from somebody else's public project is exactly that, and
|
|
205
|
+
it was told the project had gone. Asked by id instead, the service still
|
|
206
|
+
answers for an open project and says the caller is a visitor.
|
|
207
|
+
*/
|
|
208
|
+
if (link && !project) {
|
|
209
|
+
const visited = await (0, api_js_2.projectById)(link.repositoryId);
|
|
210
|
+
if (visited) {
|
|
211
|
+
project = visited;
|
|
212
|
+
member = visited.member;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
201
215
|
/*
|
|
202
216
|
A link that has outlived the project it points at.
|
|
203
217
|
|
|
@@ -217,12 +231,12 @@ async function reconcile(folder, options = {}) {
|
|
|
217
231
|
}
|
|
218
232
|
if (!project?.versionCount) {
|
|
219
233
|
// Nothing saved on the account, so everything here is outstanding.
|
|
220
|
-
return { link: link ?? null, baseline: null, behind: null };
|
|
234
|
+
return { link: link ?? null, baseline: null, behind: null, member };
|
|
221
235
|
}
|
|
222
236
|
const downloader = new download_js_1.Downloader(config_js_1.credentials);
|
|
223
237
|
const latest = (await downloader.versions(project.id))[0];
|
|
224
238
|
if (!latest)
|
|
225
|
-
return { link: link ?? null, baseline: null, behind: null };
|
|
239
|
+
return { link: link ?? null, baseline: null, behind: null, member };
|
|
226
240
|
/*
|
|
227
241
|
A folder that already knows which version it stands on keeps it. Only a
|
|
228
242
|
folder that has never been reconciled — or was linked before versions
|
|
@@ -250,6 +264,7 @@ async function reconcile(folder, options = {}) {
|
|
|
250
264
|
*/
|
|
251
265
|
baseline: new Map(Object.entries(known.local ?? known.manifest)),
|
|
252
266
|
behind,
|
|
267
|
+
member,
|
|
253
268
|
};
|
|
254
269
|
}
|
|
255
270
|
const baseline = new Map();
|
|
@@ -271,7 +286,7 @@ async function reconcile(folder, options = {}) {
|
|
|
271
286
|
if (!options.quiet && !link) {
|
|
272
287
|
console.log(dim(`Linked this folder to ${project.slug}.`));
|
|
273
288
|
}
|
|
274
|
-
return { link: fresh, baseline, behind: null };
|
|
289
|
+
return { link: fresh, baseline, behind: null, member };
|
|
275
290
|
}
|
|
276
291
|
// ── commands ────────────────────────────────────────────────────────────────
|
|
277
292
|
async function commandSignIn(parsed) {
|
|
@@ -585,7 +600,19 @@ async function commandImport(parsed) {
|
|
|
585
600
|
async function commandSubmit(parsed) {
|
|
586
601
|
const folder = folderFor(parsed);
|
|
587
602
|
const message = flagText(parsed, "m", "message") ?? "";
|
|
588
|
-
const { link, baseline, behind } = await reconcile(folder);
|
|
603
|
+
const { link, baseline, behind, member } = await reconcile(folder);
|
|
604
|
+
/*
|
|
605
|
+
Somebody else's project, cloned from its public page. Reading and
|
|
606
|
+
fetching are fine; saving into it is not this account's to do, and the
|
|
607
|
+
service would refuse it anyway, less clearly.
|
|
608
|
+
*/
|
|
609
|
+
if (link && !member) {
|
|
610
|
+
console.error(red(`Access denied: you are not a collaborator on ${link.slug}.`) +
|
|
611
|
+
"\n" +
|
|
612
|
+
dim(` Ask its owner to invite you, or run ${accent("cbx unlink")} to start a project of ` +
|
|
613
|
+
"your own from these files."));
|
|
614
|
+
return 1;
|
|
615
|
+
}
|
|
589
616
|
/*
|
|
590
617
|
A first save gets a licence unless it is turned down.
|
|
591
618
|
|
|
@@ -2282,9 +2309,8 @@ const SPECS = [
|
|
|
2282
2309
|
"calls link only, keeps it off your profile and out of search. Public\n" +
|
|
2283
2310
|
"lists it on your profile, and its page offers the saves somebody named\n" +
|
|
2284
2311
|
"and did not hide.\n\n" +
|
|
2285
|
-
"Opening a project up asks first and says what becomes readable:
|
|
2286
|
-
"
|
|
2287
|
-
"through the API, not only the named versions. Going private asks\n" +
|
|
2312
|
+
"Opening a project up asks first and says what becomes readable: the\n" +
|
|
2313
|
+
"named versions nobody hid, and nothing else. Going private asks\n" +
|
|
2288
2314
|
"nothing.",
|
|
2289
2315
|
options: [
|
|
2290
2316
|
{ flags: "-y, --yes", description: "open it up without asking, for scripts" },
|
|
@@ -288,16 +288,6 @@ async function commandVisibility(parsed) {
|
|
|
288
288
|
else {
|
|
289
289
|
console.log(`Making ${bold(project.name)} link only keeps it off your profile and out of search.`);
|
|
290
290
|
}
|
|
291
|
-
/*
|
|
292
|
-
Said because it is true today, not because it is the design. The public
|
|
293
|
-
page follows the named-versions rule; the signed-in routes let any
|
|
294
|
-
account read an unlisted or public project whole, commits and hidden
|
|
295
|
-
versions included. Somebody deciding whether to open a project up
|
|
296
|
-
should be deciding about that.
|
|
297
|
-
*/
|
|
298
|
-
console.log(dim(" Any account signed in to CodeRook that has its link can open every save\n" +
|
|
299
|
-
" through the API, not only the named versions. Check the history holds\n" +
|
|
300
|
-
" nothing you would not share."));
|
|
301
291
|
if (!(await agreed(`Make ${project.name} ${wordFor(target)}? [y/N] `))) {
|
|
302
292
|
console.log(dim(`Nothing changed. ${project.name} is still ${wordFor(current)}.`));
|
|
303
293
|
return 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderook/cli",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.12",
|
|
4
4
|
"description": "The command line for CodeRook (coderook.com): version control and project hosting for projects of any size. Every save is a compressed snapshot, private or public, never used to train AI.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"homepage": "https://coderook.com",
|