@coderook/cli 0.38.1 → 0.38.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -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, with cbx or plain git, from Claude Code.",
|
|
5
|
-
"version": "0.38.
|
|
5
|
+
"version": "0.38.2",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ACCA Gaming Productions",
|
|
8
8
|
"url": "https://coderook.com"
|
|
@@ -30,6 +30,7 @@ const solid_js_1 = require("./solid.js");
|
|
|
30
30
|
const retry_js_1 = require("./retry.js");
|
|
31
31
|
const staging_js_1 = require("./staging.js");
|
|
32
32
|
const transfer_progress_js_1 = require("./transfer_progress.js");
|
|
33
|
+
const upload_completion_js_1 = require("./upload_completion.js");
|
|
33
34
|
const delta_js_1 = require("../shared/delta.js");
|
|
34
35
|
const telemetry_js_1 = require("../shared/telemetry.js");
|
|
35
36
|
/** Above this the API insists on a multipart session. */
|
|
@@ -230,6 +231,7 @@ class Uploader {
|
|
|
230
231
|
// waiting rather than serve out its backoff first.
|
|
231
232
|
this.check();
|
|
232
233
|
try {
|
|
234
|
+
init.onAttempt?.(attempt);
|
|
233
235
|
return await this.attempt(route, init);
|
|
234
236
|
}
|
|
235
237
|
catch (error) {
|
|
@@ -243,6 +245,7 @@ class Uploader {
|
|
|
243
245
|
if (attempt >= retry_js_1.RETRY_ATTEMPTS || !(0, retry_js_1.worthRetrying)(error))
|
|
244
246
|
throw error;
|
|
245
247
|
this.telemetry.retry();
|
|
248
|
+
init.onRetry?.(attempt + 1, wait);
|
|
246
249
|
await this.pause(wait);
|
|
247
250
|
wait *= 2;
|
|
248
251
|
}
|
|
@@ -928,27 +931,22 @@ class Uploader {
|
|
|
928
931
|
(details ? ` Details: ${details}` : ""));
|
|
929
932
|
}
|
|
930
933
|
async publishVersion(at) {
|
|
934
|
+
const initial = {
|
|
935
|
+
stage: "publish", files: at.declarations.length, totalFiles: at.declarations.length,
|
|
936
|
+
bytes: at.progress.sentBytes, totalBytes: at.totalBytes, percent: 96,
|
|
937
|
+
bytesPerSecond: 0, path: "Preparing the file manifest",
|
|
938
|
+
completion: { phase: "preparing", elapsedSeconds: 0 },
|
|
939
|
+
};
|
|
940
|
+
return (0, upload_completion_js_1.withCompletionProgress)(initial, at.report, (report) => this.recordVersion({ ...at, report }));
|
|
941
|
+
}
|
|
942
|
+
async recordVersion(at) {
|
|
931
943
|
const { request, repositoryId, declarations, uploaded, reused, prior, everything, ticked, deletions, readFailures, vanished, totalBytes, progress, report, } = at;
|
|
932
944
|
// 4. Name the version, which is what makes the upload visible.
|
|
933
945
|
this.check();
|
|
934
|
-
report({
|
|
935
|
-
stage: "publish",
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
bytes: progress.sentBytes,
|
|
939
|
-
totalBytes,
|
|
940
|
-
/*
|
|
941
|
-
A save, not a version.
|
|
942
|
-
|
|
943
|
-
Sending produces a commit; it becomes a version when somebody names
|
|
944
|
-
it, which happens later and on purpose. This line said "Recording the
|
|
945
|
-
version" while doing neither — it was the last wording left over from
|
|
946
|
-
before the two were separate, and it sat on the one screen a person
|
|
947
|
-
watches to the end.
|
|
948
|
-
*/
|
|
949
|
-
path: "Writing down what was sent",
|
|
950
|
-
percent: 96,
|
|
951
|
-
bytesPerSecond: progress.rate(),
|
|
946
|
+
const completing = (phase, path) => report({
|
|
947
|
+
stage: "publish", files: declarations.length, totalFiles: declarations.length,
|
|
948
|
+
bytes: progress.sentBytes, totalBytes, percent: 96, bytesPerSecond: 0,
|
|
949
|
+
path, completion: { phase, elapsedSeconds: 0 },
|
|
952
950
|
});
|
|
953
951
|
// The version names everything the project holds: what was just sent,
|
|
954
952
|
// plus every file that kept the object the last version pointed at.
|
|
@@ -1081,53 +1079,61 @@ class Uploader {
|
|
|
1081
1079
|
},
|
|
1082
1080
|
}
|
|
1083
1081
|
: null;
|
|
1084
|
-
const send = (asChanges) =>
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1082
|
+
const send = (asChanges) => {
|
|
1083
|
+
completing("confirming", "Files uploaded · waiting for CodeRook to confirm the save");
|
|
1084
|
+
return (0, profile_js_1.timed)("publish the version", () => this.call(`/v1/repositories/${repositoryId}/versions`, {
|
|
1085
|
+
method: "POST",
|
|
1086
|
+
contentType: "application/json",
|
|
1087
|
+
onAttempt: (attempt) => {
|
|
1088
|
+
if (attempt > 1)
|
|
1089
|
+
completing("confirming", `Retry ${attempt} · waiting for CodeRook to confirm the save`);
|
|
1090
|
+
},
|
|
1091
|
+
onRetry: (attempt, waitMs) => completing("retrying", `Confirmation interrupted · retry ${attempt} in ${Math.ceil(waitMs / 1000)} s · uploaded files are reused`),
|
|
1092
|
+
body: JSON.stringify({
|
|
1093
|
+
message: request.message.trim() || "Saved from the CodeRook desktop app",
|
|
1094
|
+
...(request.baseVersionId === undefined
|
|
1095
|
+
? {}
|
|
1096
|
+
: {
|
|
1097
|
+
ancestryMode: "required",
|
|
1098
|
+
baseVersionId: request.baseVersionId,
|
|
1099
|
+
}),
|
|
1100
|
+
...(request.expectedHeadVersionId === undefined
|
|
1101
|
+
? {}
|
|
1102
|
+
: { expectedHeadVersionId: request.expectedHeadVersionId }),
|
|
1103
|
+
...(request.track ? { track: request.track } : {}),
|
|
1104
|
+
...(request.allowIgnored ? { allowIgnored: true } : {}),
|
|
1105
|
+
...(this.trackedByGit.length ? { trackedByGit: this.trackedByGit } : {}),
|
|
1106
|
+
...(request.allowSecrets ? { allowSecrets: true } : {}),
|
|
1107
|
+
...(linesAdded === undefined ? {} : { linesAdded }),
|
|
1108
|
+
...(linesRemoved === undefined ? {} : { linesRemoved }),
|
|
1109
|
+
/*
|
|
1110
|
+
Names this attempt so a retry after a lost connection is answered
|
|
1111
|
+
with the version already made, rather than making a second one.
|
|
1112
|
+
*/
|
|
1113
|
+
idempotencyKey: (0, publish_name_js_1.publishAttemptName)({
|
|
1114
|
+
repositoryId,
|
|
1115
|
+
expectedHeadVersionId: request.expectedHeadVersionId,
|
|
1116
|
+
message: request.message,
|
|
1117
|
+
/*
|
|
1118
|
+
Named by what each file is. A whole file is its object; a chunked
|
|
1119
|
+
one is the digest of its contents — so retrying the same publish
|
|
1120
|
+
produces the same key either way, which is the point of it.
|
|
1121
|
+
*/
|
|
1122
|
+
files: contents.map((item) => ({
|
|
1123
|
+
path: item.path,
|
|
1124
|
+
objectId: item.objectId ?? item.sha256 ?? "",
|
|
1125
|
+
})),
|
|
1094
1126
|
}),
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
: { expectedHeadVersionId: request.expectedHeadVersionId }),
|
|
1098
|
-
...(request.track ? { track: request.track } : {}),
|
|
1099
|
-
...(request.allowIgnored ? { allowIgnored: true } : {}),
|
|
1100
|
-
...(this.trackedByGit.length ? { trackedByGit: this.trackedByGit } : {}),
|
|
1101
|
-
...(request.allowSecrets ? { allowSecrets: true } : {}),
|
|
1102
|
-
...(linesAdded === undefined ? {} : { linesAdded }),
|
|
1103
|
-
...(linesRemoved === undefined ? {} : { linesRemoved }),
|
|
1104
|
-
/*
|
|
1105
|
-
Names this attempt so a retry after a lost connection is answered
|
|
1106
|
-
with the version already made, rather than making a second one.
|
|
1107
|
-
*/
|
|
1108
|
-
idempotencyKey: (0, publish_name_js_1.publishAttemptName)({
|
|
1109
|
-
repositoryId,
|
|
1110
|
-
expectedHeadVersionId: request.expectedHeadVersionId,
|
|
1111
|
-
message: request.message,
|
|
1127
|
+
sourceSize: sourceBytes,
|
|
1128
|
+
storedSize: storedBytes,
|
|
1112
1129
|
/*
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
produces the same key either way, which is the point of it.
|
|
1130
|
+
One shape or the other, never both — the service refuses a file that
|
|
1131
|
+
names an object and a chunk list, and so does its database.
|
|
1116
1132
|
*/
|
|
1117
|
-
files:
|
|
1118
|
-
path: item.path,
|
|
1119
|
-
objectId: item.objectId ?? item.sha256 ?? "",
|
|
1120
|
-
})),
|
|
1133
|
+
...(asChanges && changesOnly ? changesOnly : { files: wire }),
|
|
1121
1134
|
}),
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
/*
|
|
1125
|
-
One shape or the other, never both — the service refuses a file that
|
|
1126
|
-
names an object and a chunk list, and so does its database.
|
|
1127
|
-
*/
|
|
1128
|
-
...(asChanges && changesOnly ? changesOnly : { files: wire }),
|
|
1129
|
-
}),
|
|
1130
|
-
}));
|
|
1135
|
+
}));
|
|
1136
|
+
};
|
|
1131
1137
|
/*
|
|
1132
1138
|
A service that cannot build on the version named (it was taken down,
|
|
1133
1139
|
say) answers files_from_*; the whole list is then sent instead, which
|
|
@@ -1147,6 +1153,7 @@ class Uploader {
|
|
|
1147
1153
|
instead. A repeated attempt predates manifest echoing, so read that
|
|
1148
1154
|
Version once rather than guessing.
|
|
1149
1155
|
*/
|
|
1156
|
+
completing("local", "CodeRook confirmed the save · updating local records");
|
|
1150
1157
|
let acceptedManifest = (0, publication_js_1.acceptedManifestDigests)(completed.manifest?.files);
|
|
1151
1158
|
/*
|
|
1152
1159
|
A service that lists version-delta-v1 also says when it combined this
|
|
@@ -1162,6 +1169,7 @@ class Uploader {
|
|
|
1162
1169
|
!request.allowSecrets &&
|
|
1163
1170
|
(await this.versionDeltaAllowed());
|
|
1164
1171
|
if (!completed.mergeTrack && !landedAsSent && !Object.keys(acceptedManifest).length) {
|
|
1172
|
+
completing("local", "CodeRook confirmed the save · reading the accepted file manifest");
|
|
1165
1173
|
acceptedManifest = Object.fromEntries([...(await this.versionFiles(repositoryId, completed.version.id, request.localPath))].map(([file, descriptor]) => [file, descriptor.sha256]));
|
|
1166
1174
|
}
|
|
1167
1175
|
const manifest = Object.keys(acceptedManifest).length
|
|
@@ -1181,6 +1189,7 @@ class Uploader {
|
|
|
1181
1189
|
file, which on a 47,000-file project was over a billion comparisons at
|
|
1182
1190
|
the very end of a save.
|
|
1183
1191
|
*/
|
|
1192
|
+
completing("local", "CodeRook confirmed the save · updating local file records");
|
|
1184
1193
|
const sentDigest = new Map(declarations.map((declaration) => [declaration.path, declaration.sha256]));
|
|
1185
1194
|
/*
|
|
1186
1195
|
A file named from bytes already stored, at a path the last version did
|
|
@@ -1231,6 +1240,7 @@ class Uploader {
|
|
|
1231
1240
|
if (rows.every((row) => typeof row.sha256 === "string" && row.sha256.length === 64)) {
|
|
1232
1241
|
const key = `${repositoryId}/${completed.version.id}`;
|
|
1233
1242
|
versionListings.set(key, Promise.resolve(rows));
|
|
1243
|
+
completing("local", "CodeRook confirmed the save · caching the file listing for next time");
|
|
1234
1244
|
await writeListing(request.localPath, repositoryId, completed.version.id, rows);
|
|
1235
1245
|
}
|
|
1236
1246
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withCompletionProgress = withCompletionProgress;
|
|
4
|
+
/** Keep a pending completion visible without inventing server-side progress.
|
|
5
|
+
* Every phase change comes from the uploader; ticks only measure elapsed time.
|
|
6
|
+
*/
|
|
7
|
+
async function withCompletionProgress(initial, report, work) {
|
|
8
|
+
const started = performance.now();
|
|
9
|
+
let latest = initial;
|
|
10
|
+
let active = true;
|
|
11
|
+
const emit = (progress) => {
|
|
12
|
+
latest = progress;
|
|
13
|
+
if (progress.stage !== "publish")
|
|
14
|
+
active = false;
|
|
15
|
+
report(progress.stage === "publish" ? {
|
|
16
|
+
...progress,
|
|
17
|
+
completion: {
|
|
18
|
+
phase: progress.completion?.phase ?? "preparing",
|
|
19
|
+
elapsedSeconds: Math.max(0, (performance.now() - started) / 1000),
|
|
20
|
+
},
|
|
21
|
+
} : progress);
|
|
22
|
+
};
|
|
23
|
+
emit(initial);
|
|
24
|
+
const timer = setInterval(() => { if (active)
|
|
25
|
+
emit(latest); }, 1000);
|
|
26
|
+
timer.unref?.();
|
|
27
|
+
try {
|
|
28
|
+
return await work(emit);
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
active = false;
|
|
32
|
+
clearInterval(timer);
|
|
33
|
+
}
|
|
34
|
+
}
|
package/dist/cli/src/cli.js
CHANGED
|
@@ -27,6 +27,7 @@ const api_js_1 = require("./api.js");
|
|
|
27
27
|
const registry_js_1 = require("./registry.js");
|
|
28
28
|
const help_js_1 = require("./help.js");
|
|
29
29
|
const progress_js_1 = require("./progress.js");
|
|
30
|
+
const upload_progress_js_1 = require("./upload_progress.js");
|
|
30
31
|
const publish_js_1 = require("./publish.js");
|
|
31
32
|
const attach_command_js_1 = require("./attach_command.js");
|
|
32
33
|
const build_command_js_1 = require("./build_command.js");
|
|
@@ -1071,6 +1072,7 @@ Pass ${accent("--allow-secrets")} if these are not real keys.`);
|
|
|
1071
1072
|
console.log("");
|
|
1072
1073
|
}
|
|
1073
1074
|
const line = progressLine();
|
|
1075
|
+
const uploadDisplay = new upload_progress_js_1.UploadDisplay();
|
|
1074
1076
|
let uploader = new upload_js_1.Uploader(config_js_1.credentials);
|
|
1075
1077
|
/*
|
|
1076
1078
|
Built by the shared description, so this and the git remote helper cannot
|
|
@@ -1226,14 +1228,12 @@ Pass ${accent("--allow-secrets")} if these are not real keys.`);
|
|
|
1226
1228
|
console.log("Nothing was uploaded and no Version was created.");
|
|
1227
1229
|
return 0;
|
|
1228
1230
|
}
|
|
1229
|
-
result = await uploader.execute(uploadRequest, plan, (progress) =>
|
|
1230
|
-
|
|
1231
|
-
`${progress.stage.padEnd(7)} ${progress.files}/${progress.totalFiles} ` +
|
|
1232
|
-
dim(progress.path.slice(-40)));
|
|
1233
|
-
});
|
|
1231
|
+
result = await uploader.execute(uploadRequest, plan, (progress) => uploadDisplay.report(progress));
|
|
1232
|
+
uploadDisplay.done();
|
|
1234
1233
|
break;
|
|
1235
1234
|
}
|
|
1236
1235
|
catch (error) {
|
|
1236
|
+
uploadDisplay.done();
|
|
1237
1237
|
done(line);
|
|
1238
1238
|
/*
|
|
1239
1239
|
Classified by the shared description rather than by a private regular
|
|
@@ -26,6 +26,7 @@ exports.localMerge = localMerge;
|
|
|
26
26
|
*/
|
|
27
27
|
const node_path_1 = __importDefault(require("node:path"));
|
|
28
28
|
const node_process_1 = __importDefault(require("node:process"));
|
|
29
|
+
const upload_progress_js_1 = require("./upload_progress.js");
|
|
29
30
|
const history_js_1 = require("../../cbx/src/local/history.js");
|
|
30
31
|
const merge_js_1 = require("../../cbx/src/local/merge.js");
|
|
31
32
|
const repository_js_1 = require("../../cbx/src/local/repository.js");
|
|
@@ -384,6 +385,7 @@ async function localPush(parsed, repository) {
|
|
|
384
385
|
return 1;
|
|
385
386
|
}
|
|
386
387
|
const interactive = node_process_1.default.stdout.isTTY;
|
|
388
|
+
const uploadDisplay = new upload_progress_js_1.UploadDisplay();
|
|
387
389
|
const result = await (0, remote_js_1.push)(repository, {
|
|
388
390
|
credentials: config_js_1.credentials,
|
|
389
391
|
projectName: link?.slug ?? (chosen ? ("id" in chosen ? chosen.slug : chosen.name) : node_path_1.default.basename(repository.root)),
|
|
@@ -392,10 +394,13 @@ async function localPush(parsed, repository) {
|
|
|
392
394
|
allowSecrets: has(parsed, "allow-secrets"),
|
|
393
395
|
acknowledged: has(parsed, "yes", "y"),
|
|
394
396
|
report: (event) => {
|
|
397
|
+
if (event.kind === "upload")
|
|
398
|
+
uploadDisplay.report(event.progress);
|
|
395
399
|
if (event.kind === "save" && interactive) {
|
|
396
400
|
node_process_1.default.stdout.write(`\r${dim(`Sending ${event.index + 1} of ${event.total}: ${event.save.message.split("\n")[0].slice(0, 50)}`)} `);
|
|
397
401
|
}
|
|
398
402
|
if (event.kind === "pushed" || event.kind === "unchanged") {
|
|
403
|
+
uploadDisplay.done();
|
|
399
404
|
if (interactive)
|
|
400
405
|
node_process_1.default.stdout.write(`\r${" ".repeat(80)}\r`);
|
|
401
406
|
console.log(` ${accent(short(event.save.id))} ` +
|
|
@@ -403,7 +408,7 @@ async function localPush(parsed, repository) {
|
|
|
403
408
|
` ${event.save.message.split("\n")[0]}`);
|
|
404
409
|
}
|
|
405
410
|
},
|
|
406
|
-
});
|
|
411
|
+
}).finally(() => uploadDisplay.done());
|
|
407
412
|
if (!result.pushed.length) {
|
|
408
413
|
console.log(`Everything on ${accent(result.line)} is already on CodeRook.`);
|
|
409
414
|
return 0;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UploadDisplay = void 0;
|
|
7
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
8
|
+
const progress_1 = require("./progress");
|
|
9
|
+
/** The timer in the shared uploader keeps finalization visible in every client. */
|
|
10
|
+
class UploadDisplay {
|
|
11
|
+
interactive;
|
|
12
|
+
write;
|
|
13
|
+
phase = "";
|
|
14
|
+
frame = 0;
|
|
15
|
+
constructor(interactive = Boolean(node_process_1.default.stdout.isTTY), write = (text) => { node_process_1.default.stdout.write(text); }) {
|
|
16
|
+
this.interactive = interactive;
|
|
17
|
+
this.write = write;
|
|
18
|
+
}
|
|
19
|
+
report(progress) {
|
|
20
|
+
const finishing = progress.stage === "publish";
|
|
21
|
+
const phase = finishing ? progress.path : progress.stage;
|
|
22
|
+
if (!this.interactive) {
|
|
23
|
+
if (finishing && phase !== this.phase)
|
|
24
|
+
this.write(` ${phase}\n`);
|
|
25
|
+
this.phase = phase;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
this.phase = phase;
|
|
29
|
+
const seconds = Math.floor(progress.completion?.elapsedSeconds ?? 0);
|
|
30
|
+
const clock = `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")}`;
|
|
31
|
+
const detail = finishing
|
|
32
|
+
? `${["|", "/", "-", "\\"][this.frame++ % 4]} Finalizing save · ${clock} elapsed · ${progress.path}`
|
|
33
|
+
: `${(0, progress_1.bar)(progress.percent / 100, 18, (text) => text)} ${progress.percent}% ${progress.stage} ${progress.files}/${progress.totalFiles} ${progress.path}`;
|
|
34
|
+
// Keep status on one terminal row, including narrow windows.
|
|
35
|
+
const width = Math.max(1, (node_process_1.default.stdout.columns ?? 120) - 3);
|
|
36
|
+
this.write(`\r\x1b[2K ${detail.replace(/[\x00-\x1f\x7f]/g, " ").slice(0, width)}`);
|
|
37
|
+
}
|
|
38
|
+
done() { if (this.interactive)
|
|
39
|
+
this.write("\r\x1b[2K"); }
|
|
40
|
+
}
|
|
41
|
+
exports.UploadDisplay = UploadDisplay;
|
package/package.json
CHANGED
|
@@ -1,66 +1,67 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@coderook/cli",
|
|
3
|
-
"version": "0.38.
|
|
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
|
-
"license": "Apache-2.0",
|
|
6
|
-
"homepage": "https://coderook.com",
|
|
7
|
-
"bugs": {
|
|
8
|
-
"url": "https://github.com/AlexC1991/cbx/issues"
|
|
9
|
-
},
|
|
10
|
-
"keywords": [
|
|
11
|
-
"coderook",
|
|
12
|
-
"cbx",
|
|
13
|
-
"version-control",
|
|
14
|
-
"vcs",
|
|
15
|
-
"versioning",
|
|
16
|
-
"project-hosting",
|
|
17
|
-
"backup",
|
|
18
|
-
"snapshots",
|
|
19
|
-
"large-files",
|
|
20
|
-
"gamedev"
|
|
21
|
-
],
|
|
22
|
-
"engines": {
|
|
23
|
-
"node": ">=22.15.0"
|
|
24
|
-
},
|
|
25
|
-
"bin": {
|
|
26
|
-
"cbx": "dist/cli/src/cli.js",
|
|
27
|
-
"coderook": "dist/cli/src/cli.js",
|
|
28
|
-
"git-remote-coderook": "dist/cli/src/git_remote_bin.js"
|
|
29
|
-
},
|
|
30
|
-
"files": [
|
|
31
|
-
".claude-plugin",
|
|
32
|
-
"dist",
|
|
33
|
-
"skills",
|
|
34
|
-
"NOTICE"
|
|
35
|
-
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.json && node scripts/copy-cbx-licence.mjs",
|
|
38
|
-
"check": "tsc -p tsconfig.json --noEmit",
|
|
39
|
-
"test": "tsc -p tsconfig.json && node --test --experimental-strip-types test/*.test.ts",
|
|
40
|
-
"start": "node dist/cli/src/cli.js",
|
|
41
|
-
"prepublishOnly": "npm run sync:plugin && npm run build",
|
|
42
|
-
"test:e2e": "node test/e2e.mjs",
|
|
43
|
-
"test:matrix": "node test/state-matrix.mjs",
|
|
44
|
-
"test:attempt": "node test/attempt-identity.mjs",
|
|
45
|
-
"test:get": "node test/get-safety.mjs",
|
|
46
|
-
"test:live": "node test/e2e.mjs --allow-production && node test/state-matrix.mjs --allow-production && node test/get-safety.mjs --allow-production && node test/get-track.mjs --allow-production && node test/get-protects-edits.mjs --allow-production && node test/upgrade-migration.mjs --allow-production && node test/fault-get.mjs --allow-production && node test/version-floor.mjs --allow-production && node test/fault-submit.mjs --allow-production && node test/race-attempts.mjs --allow-production && node test/attempt-identity.mjs --allow-production",
|
|
47
|
-
"test:getedits": "node test/get-protects-edits.mjs",
|
|
48
|
-
"test:upgrade": "node test/upgrade-migration.mjs",
|
|
49
|
-
"test:faultget": "node test/fault-get.mjs",
|
|
50
|
-
"test:floor": "node test/version-floor.mjs",
|
|
51
|
-
"test:faultsubmit": "node test/fault-submit.mjs",
|
|
52
|
-
"test:race": "node test/race-attempts.mjs",
|
|
53
|
-
"test:runner": "node test/runner-live.mjs",
|
|
54
|
-
"sync:plugin": "node scripts/sync-plugin-version.mjs",
|
|
55
|
-
"test:track": "node test/get-track.mjs"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@coderook/cli",
|
|
3
|
+
"version": "0.38.2",
|
|
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
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://coderook.com",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/AlexC1991/cbx/issues"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"coderook",
|
|
12
|
+
"cbx",
|
|
13
|
+
"version-control",
|
|
14
|
+
"vcs",
|
|
15
|
+
"versioning",
|
|
16
|
+
"project-hosting",
|
|
17
|
+
"backup",
|
|
18
|
+
"snapshots",
|
|
19
|
+
"large-files",
|
|
20
|
+
"gamedev"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22.15.0"
|
|
24
|
+
},
|
|
25
|
+
"bin": {
|
|
26
|
+
"cbx": "dist/cli/src/cli.js",
|
|
27
|
+
"coderook": "dist/cli/src/cli.js",
|
|
28
|
+
"git-remote-coderook": "dist/cli/src/git_remote_bin.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
".claude-plugin",
|
|
32
|
+
"dist",
|
|
33
|
+
"skills",
|
|
34
|
+
"NOTICE"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.json && node scripts/copy-cbx-licence.mjs",
|
|
38
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
39
|
+
"test": "tsc -p tsconfig.json && node --test --experimental-strip-types test/*.test.ts",
|
|
40
|
+
"start": "node dist/cli/src/cli.js",
|
|
41
|
+
"prepublishOnly": "npm run sync:plugin && npm run build",
|
|
42
|
+
"test:e2e": "node test/e2e.mjs",
|
|
43
|
+
"test:matrix": "node test/state-matrix.mjs",
|
|
44
|
+
"test:attempt": "node test/attempt-identity.mjs",
|
|
45
|
+
"test:get": "node test/get-safety.mjs",
|
|
46
|
+
"test:live": "node test/e2e.mjs --allow-production && node test/state-matrix.mjs --allow-production && node test/get-safety.mjs --allow-production && node test/get-track.mjs --allow-production && node test/get-protects-edits.mjs --allow-production && node test/upgrade-migration.mjs --allow-production && node test/fault-get.mjs --allow-production && node test/version-floor.mjs --allow-production && node test/fault-submit.mjs --allow-production && node test/race-attempts.mjs --allow-production && node test/attempt-identity.mjs --allow-production",
|
|
47
|
+
"test:getedits": "node test/get-protects-edits.mjs",
|
|
48
|
+
"test:upgrade": "node test/upgrade-migration.mjs",
|
|
49
|
+
"test:faultget": "node test/fault-get.mjs",
|
|
50
|
+
"test:floor": "node test/version-floor.mjs",
|
|
51
|
+
"test:faultsubmit": "node test/fault-submit.mjs",
|
|
52
|
+
"test:race": "node test/race-attempts.mjs",
|
|
53
|
+
"test:runner": "node test/runner-live.mjs",
|
|
54
|
+
"sync:plugin": "node scripts/sync-plugin-version.mjs",
|
|
55
|
+
"test:track": "node test/get-track.mjs",
|
|
56
|
+
"package:remote": "node ../scripts/package-cli-release.mjs"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "24.10.1",
|
|
60
|
+
"typescript": "5.9.3"
|
|
61
|
+
},
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "git+https://github.com/AlexC1991/cbx.git",
|
|
65
|
+
"directory": "cli"
|
|
66
|
+
}
|
|
67
|
+
}
|