@warmhub/cli 0.84.3 → 0.86.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/dist/wh.js +774 -561
- package/package.json +1 -1
package/dist/wh.js
CHANGED
|
@@ -4092,11 +4092,11 @@ var require_util2 = __commonJS((exports, module) => {
|
|
|
4092
4092
|
var { isUint8Array } = __require("node:util/types");
|
|
4093
4093
|
var { webidl } = require_webidl();
|
|
4094
4094
|
var supportedHashes = [];
|
|
4095
|
-
var
|
|
4095
|
+
var crypto;
|
|
4096
4096
|
try {
|
|
4097
|
-
|
|
4097
|
+
crypto = __require("node:crypto");
|
|
4098
4098
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
4099
|
-
supportedHashes =
|
|
4099
|
+
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
4100
4100
|
} catch {}
|
|
4101
4101
|
function responseURL(response) {
|
|
4102
4102
|
const urlList = response.urlList;
|
|
@@ -4355,7 +4355,7 @@ var require_util2 = __commonJS((exports, module) => {
|
|
|
4355
4355
|
}
|
|
4356
4356
|
}
|
|
4357
4357
|
function bytesMatch(bytes, metadataList) {
|
|
4358
|
-
if (
|
|
4358
|
+
if (crypto === undefined) {
|
|
4359
4359
|
return true;
|
|
4360
4360
|
}
|
|
4361
4361
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -4370,7 +4370,7 @@ var require_util2 = __commonJS((exports, module) => {
|
|
|
4370
4370
|
for (const item of metadata) {
|
|
4371
4371
|
const algorithm = item.algo;
|
|
4372
4372
|
const expectedValue = item.hash;
|
|
4373
|
-
let actualValue =
|
|
4373
|
+
let actualValue = crypto.createHash(algorithm).update(bytes).digest("base64");
|
|
4374
4374
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
4375
4375
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
4376
4376
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -5355,8 +5355,8 @@ var require_body = __commonJS((exports, module) => {
|
|
|
5355
5355
|
var { multipartFormDataParser } = require_formdata_parser();
|
|
5356
5356
|
var random;
|
|
5357
5357
|
try {
|
|
5358
|
-
const
|
|
5359
|
-
random = (max) =>
|
|
5358
|
+
const crypto = __require("node:crypto");
|
|
5359
|
+
random = (max) => crypto.randomInt(0, max);
|
|
5360
5360
|
} catch {
|
|
5361
5361
|
random = (max) => Math.floor(Math.random(max));
|
|
5362
5362
|
}
|
|
@@ -16107,13 +16107,13 @@ var require_util7 = __commonJS((exports, module) => {
|
|
|
16107
16107
|
var require_frame = __commonJS((exports, module) => {
|
|
16108
16108
|
var { maxUnsigned16Bit } = require_constants5();
|
|
16109
16109
|
var BUFFER_SIZE = 16386;
|
|
16110
|
-
var
|
|
16110
|
+
var crypto;
|
|
16111
16111
|
var buffer = null;
|
|
16112
16112
|
var bufIdx = BUFFER_SIZE;
|
|
16113
16113
|
try {
|
|
16114
|
-
|
|
16114
|
+
crypto = __require("node:crypto");
|
|
16115
16115
|
} catch {
|
|
16116
|
-
|
|
16116
|
+
crypto = {
|
|
16117
16117
|
randomFillSync: function randomFillSync(buffer2, _offset, _size) {
|
|
16118
16118
|
for (let i = 0;i < buffer2.length; ++i) {
|
|
16119
16119
|
buffer2[i] = Math.random() * 255 | 0;
|
|
@@ -16125,7 +16125,7 @@ var require_frame = __commonJS((exports, module) => {
|
|
|
16125
16125
|
function generateMask() {
|
|
16126
16126
|
if (bufIdx === BUFFER_SIZE) {
|
|
16127
16127
|
bufIdx = 0;
|
|
16128
|
-
|
|
16128
|
+
crypto.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE);
|
|
16129
16129
|
}
|
|
16130
16130
|
return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]];
|
|
16131
16131
|
}
|
|
@@ -16193,9 +16193,9 @@ var require_connection = __commonJS((exports, module) => {
|
|
|
16193
16193
|
var { Headers: Headers2, getHeadersList } = require_headers();
|
|
16194
16194
|
var { getDecodeSplit } = require_util2();
|
|
16195
16195
|
var { WebsocketFrameSend } = require_frame();
|
|
16196
|
-
var
|
|
16196
|
+
var crypto;
|
|
16197
16197
|
try {
|
|
16198
|
-
|
|
16198
|
+
crypto = __require("node:crypto");
|
|
16199
16199
|
} catch {}
|
|
16200
16200
|
function establishWebSocketConnection(url, protocols, client, ws, onEstablish, options) {
|
|
16201
16201
|
const requestURL = url;
|
|
@@ -16214,7 +16214,7 @@ var require_connection = __commonJS((exports, module) => {
|
|
|
16214
16214
|
const headersList = getHeadersList(new Headers2(options.headers));
|
|
16215
16215
|
request.headersList = headersList;
|
|
16216
16216
|
}
|
|
16217
|
-
const keyValue =
|
|
16217
|
+
const keyValue = crypto.randomBytes(16).toString("base64");
|
|
16218
16218
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
16219
16219
|
request.headersList.append("sec-websocket-version", "13");
|
|
16220
16220
|
for (const protocol of protocols) {
|
|
@@ -16244,7 +16244,7 @@ var require_connection = __commonJS((exports, module) => {
|
|
|
16244
16244
|
return;
|
|
16245
16245
|
}
|
|
16246
16246
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
16247
|
-
const digest2 =
|
|
16247
|
+
const digest2 = crypto.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
16248
16248
|
if (secWSAccept !== digest2) {
|
|
16249
16249
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
16250
16250
|
return;
|
|
@@ -19146,31 +19146,6 @@ var import_usingCtx = __toESM(require_usingCtx(), 1);
|
|
|
19146
19146
|
var import_awaitAsyncGenerator = __toESM(require_awaitAsyncGenerator(), 1);
|
|
19147
19147
|
var import_wrapAsyncGenerator = __toESM(require_wrapAsyncGenerator(), 1);
|
|
19148
19148
|
var import_objectSpread29 = __toESM(require_objectSpread2(), 1);
|
|
19149
|
-
// ../../packages/rules/src/authority-coverage.ts
|
|
19150
|
-
var EMPTY_COVERAGE = Object.freeze({
|
|
19151
|
-
include: Object.freeze([])
|
|
19152
|
-
});
|
|
19153
|
-
var FULL_REPO_COVERAGE = Object.freeze({
|
|
19154
|
-
include: Object.freeze(["**"])
|
|
19155
|
-
});
|
|
19156
|
-
var EMPTY_COVERAGE_SET = Object.freeze([]);
|
|
19157
|
-
var FULL_REPO_COVERAGE_SET = Object.freeze([
|
|
19158
|
-
Object.freeze([FULL_REPO_COVERAGE])
|
|
19159
|
-
]);
|
|
19160
|
-
// ../../packages/rules/src/stable-json.ts
|
|
19161
|
-
function stableJson(value) {
|
|
19162
|
-
if (!value || typeof value !== "object") {
|
|
19163
|
-
return JSON.stringify(value);
|
|
19164
|
-
}
|
|
19165
|
-
if (Array.isArray(value)) {
|
|
19166
|
-
return `[${value.map((entry) => stableJson(entry)).join(",")}]`;
|
|
19167
|
-
}
|
|
19168
|
-
const record = value;
|
|
19169
|
-
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
|
|
19170
|
-
}
|
|
19171
|
-
function stableJsonEquals(left, right) {
|
|
19172
|
-
return stableJson(left) === stableJson(right);
|
|
19173
|
-
}
|
|
19174
19149
|
// ../../packages/rules/src/builtin-shapes.ts
|
|
19175
19150
|
var BUILTIN_SHAPE_NAMES = [
|
|
19176
19151
|
"Arc",
|
|
@@ -19399,6 +19374,21 @@ function resolveComponentTemplate(value, ctx) {
|
|
|
19399
19374
|
});
|
|
19400
19375
|
}
|
|
19401
19376
|
|
|
19377
|
+
// ../../packages/rules/src/stable-json.ts
|
|
19378
|
+
function stableJson(value) {
|
|
19379
|
+
if (!value || typeof value !== "object") {
|
|
19380
|
+
return JSON.stringify(value);
|
|
19381
|
+
}
|
|
19382
|
+
if (Array.isArray(value)) {
|
|
19383
|
+
return `[${value.map((entry) => stableJson(entry)).join(",")}]`;
|
|
19384
|
+
}
|
|
19385
|
+
const record = value;
|
|
19386
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
|
|
19387
|
+
}
|
|
19388
|
+
function stableJsonEquals(left, right) {
|
|
19389
|
+
return stableJson(left) === stableJson(right);
|
|
19390
|
+
}
|
|
19391
|
+
|
|
19402
19392
|
// ../../packages/rules/src/org-activity-events.ts
|
|
19403
19393
|
var ORG_MEMBER_ADDED_EVENT_TYPE = "org.member_added";
|
|
19404
19394
|
var ORG_REPO_CREATED_EVENT_TYPE = "org.repo_created";
|
|
@@ -20410,7 +20400,304 @@ function joinFieldIdentityPath(...segments) {
|
|
|
20410
20400
|
function joinFieldPathWithEscaper(escapeSegment, segments) {
|
|
20411
20401
|
return segments.map((segment) => typeof segment === "number" ? `[${segment}]` : escapeSegment(segment)).join(".").replace(/\.\[/g, "[");
|
|
20412
20402
|
}
|
|
20403
|
+
// ../../packages/rules/src/tokens.ts
|
|
20404
|
+
var COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE = "$N/#N commit-token syntax is no longer supported. Use explicit names and explicit wrefs. For assertions about newly created things, create the thing with a deterministic name and set about to that wref in the same commit.";
|
|
20405
|
+
var ANY_TOKEN_RE = /[$#]\d+/;
|
|
20406
|
+
function hasAnyTokens(s) {
|
|
20407
|
+
return ANY_TOKEN_RE.test(s);
|
|
20408
|
+
}
|
|
20413
20409
|
|
|
20410
|
+
// ../../packages/rules/src/preflight-commit.ts
|
|
20411
|
+
function preflightCommitDiagnostics(operations, options) {
|
|
20412
|
+
const errors = [];
|
|
20413
|
+
rejectCommitTokenSyntax(operations, errors, options);
|
|
20414
|
+
illegalOpSequences(operations, errors, options?.checkAddAdd ?? true, options);
|
|
20415
|
+
return errors;
|
|
20416
|
+
}
|
|
20417
|
+
function sourceOperationIndex(filteredIndex, options) {
|
|
20418
|
+
return options?.sourceOperationIndexes?.[filteredIndex] ?? filteredIndex;
|
|
20419
|
+
}
|
|
20420
|
+
function getOpName(op) {
|
|
20421
|
+
return op.name;
|
|
20422
|
+
}
|
|
20423
|
+
function tokenStringFields(op) {
|
|
20424
|
+
const fields = [getOpName(op), op.newName];
|
|
20425
|
+
if (typeof op.about === "string") {
|
|
20426
|
+
fields.push(op.about);
|
|
20427
|
+
}
|
|
20428
|
+
if (op.members) {
|
|
20429
|
+
fields.push(...op.members);
|
|
20430
|
+
}
|
|
20431
|
+
return fields;
|
|
20432
|
+
}
|
|
20433
|
+
function rejectCommitTokenSyntax(operations, errors, options) {
|
|
20434
|
+
for (let i = 0;i < operations.length; i++) {
|
|
20435
|
+
const op = operations[i];
|
|
20436
|
+
if (!op)
|
|
20437
|
+
continue;
|
|
20438
|
+
for (const field of tokenStringFields(op)) {
|
|
20439
|
+
if (field && hasAnyTokens(field)) {
|
|
20440
|
+
errors.push({
|
|
20441
|
+
code: "COMMIT_TOKEN_SYNTAX_REMOVED",
|
|
20442
|
+
operationIndex: sourceOperationIndex(i, options),
|
|
20443
|
+
message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
|
|
20444
|
+
});
|
|
20445
|
+
break;
|
|
20446
|
+
}
|
|
20447
|
+
}
|
|
20448
|
+
}
|
|
20449
|
+
}
|
|
20450
|
+
function illegalOpSequences(operations, errors, checkAddAdd, options) {
|
|
20451
|
+
const opHistory = new Map;
|
|
20452
|
+
for (let i = 0;i < operations.length; i++) {
|
|
20453
|
+
const op = operations[i];
|
|
20454
|
+
if (!op)
|
|
20455
|
+
continue;
|
|
20456
|
+
const name = getOpName(op);
|
|
20457
|
+
if (!name)
|
|
20458
|
+
continue;
|
|
20459
|
+
if (hasAnyTokens(name))
|
|
20460
|
+
continue;
|
|
20461
|
+
const kind = inferOperationKind({ ...op, name });
|
|
20462
|
+
const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
|
|
20463
|
+
const history = opHistory.get(qualName) ?? [];
|
|
20464
|
+
history.push({
|
|
20465
|
+
operation: op.operation,
|
|
20466
|
+
index: sourceOperationIndex(i, options)
|
|
20467
|
+
});
|
|
20468
|
+
opHistory.set(qualName, history);
|
|
20469
|
+
}
|
|
20470
|
+
for (const [qualName, history] of opHistory) {
|
|
20471
|
+
if (history.length < 2)
|
|
20472
|
+
continue;
|
|
20473
|
+
for (let i = 1;i < history.length; i++) {
|
|
20474
|
+
const prev = history[i - 1];
|
|
20475
|
+
const curr = history[i];
|
|
20476
|
+
if (!prev || !curr)
|
|
20477
|
+
continue;
|
|
20478
|
+
const pair = `${prev.operation}+${curr.operation}`;
|
|
20479
|
+
if (checkAddAdd && pair === "add+add") {
|
|
20480
|
+
errors.push({
|
|
20481
|
+
code: "ILLEGAL_OP_SEQUENCE",
|
|
20482
|
+
operationIndex: curr.index,
|
|
20483
|
+
message: `Cannot add "${qualName}" twice in the same commit`
|
|
20484
|
+
});
|
|
20485
|
+
}
|
|
20486
|
+
if (pair === "revise+add") {
|
|
20487
|
+
errors.push({
|
|
20488
|
+
code: "ILLEGAL_OP_SEQUENCE",
|
|
20489
|
+
operationIndex: curr.index,
|
|
20490
|
+
message: `Cannot revise then add "${qualName}" in the same commit`
|
|
20491
|
+
});
|
|
20492
|
+
}
|
|
20493
|
+
}
|
|
20494
|
+
}
|
|
20495
|
+
}
|
|
20496
|
+
|
|
20497
|
+
// ../../packages/rules/src/preflight-operation.ts
|
|
20498
|
+
var collectionTypes = ["arc", "bond", "set", "list", "pair"];
|
|
20499
|
+
var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
|
|
20500
|
+
var collectionOps = ["add", "revise"];
|
|
20501
|
+
var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
|
|
20502
|
+
var COLLECTION_ABOUT_REMOVED_MESSAGE = 'about accepts a wref. Create the collection as its own named operation, then point the assertion at it. Prefer deterministic relationship names, for example: [{"operation":"add","kind":"collection","type":"arc","name":"a-to-b","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Arc/a-to-b","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
|
|
20503
|
+
function preflightOpDiagnostics(op, operationIndex) {
|
|
20504
|
+
const errors = [];
|
|
20505
|
+
errors.push(...builtinShapeGuard(op, operationIndex));
|
|
20506
|
+
errors.push(...contentNameGuard(op, operationIndex));
|
|
20507
|
+
errors.push(...plusSignGuard(op, operationIndex));
|
|
20508
|
+
errors.push(...validateCollectionAbouts(op, operationIndex));
|
|
20509
|
+
errors.push(...validateCollectionOps(op, operationIndex));
|
|
20510
|
+
return errors;
|
|
20511
|
+
}
|
|
20512
|
+
function builtinShapeGuard(op, operationIndex) {
|
|
20513
|
+
const errors = [];
|
|
20514
|
+
const name = op.name;
|
|
20515
|
+
const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
|
|
20516
|
+
const reservedSourcePassThrough = isShapeRename && name !== undefined && isRenameableSquattedShape(name) && op.newName !== undefined && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
|
|
20517
|
+
if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
|
|
20518
|
+
errors.push({
|
|
20519
|
+
code: "RESERVED_NAME",
|
|
20520
|
+
operationIndex,
|
|
20521
|
+
message: `Shape "${name}" is a retired collection shape and cannot be written manually`
|
|
20522
|
+
});
|
|
20523
|
+
}
|
|
20524
|
+
if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
|
|
20525
|
+
errors.push({
|
|
20526
|
+
code: "RESERVED_NAME",
|
|
20527
|
+
operationIndex,
|
|
20528
|
+
message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
|
|
20529
|
+
});
|
|
20530
|
+
} else {
|
|
20531
|
+
const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : undefined;
|
|
20532
|
+
if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
|
|
20533
|
+
const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
|
|
20534
|
+
errors.push({
|
|
20535
|
+
code: "RESERVED_NAME",
|
|
20536
|
+
operationIndex,
|
|
20537
|
+
message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
|
|
20538
|
+
});
|
|
20539
|
+
}
|
|
20540
|
+
}
|
|
20541
|
+
if (name) {
|
|
20542
|
+
const local = splitLocalPath(name);
|
|
20543
|
+
if (local && isRetiredCollectionShape(local.shapePrefix)) {
|
|
20544
|
+
errors.push({
|
|
20545
|
+
code: "VALIDATION_ERROR",
|
|
20546
|
+
operationIndex,
|
|
20547
|
+
message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
|
|
20548
|
+
});
|
|
20549
|
+
} else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
|
|
20550
|
+
const message = op.operation === "add" ? `Cannot add kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" instead.` : `Cannot revise kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" to revise a collection.`;
|
|
20551
|
+
errors.push({
|
|
20552
|
+
code: "VALIDATION_ERROR",
|
|
20553
|
+
operationIndex,
|
|
20554
|
+
message
|
|
20555
|
+
});
|
|
20556
|
+
}
|
|
20557
|
+
}
|
|
20558
|
+
return errors;
|
|
20559
|
+
}
|
|
20560
|
+
function contentNameGuard(op, operationIndex) {
|
|
20561
|
+
if (op.kind !== "thing" || !op.name)
|
|
20562
|
+
return [];
|
|
20563
|
+
const local = splitLocalPath(op.name);
|
|
20564
|
+
if (!local || !isContentShape(local.shapePrefix))
|
|
20565
|
+
return [];
|
|
20566
|
+
const bareName = local.bareName;
|
|
20567
|
+
if (isSynthesizedContentName(bareName)) {
|
|
20568
|
+
return [
|
|
20569
|
+
{
|
|
20570
|
+
code: "READ_ONLY_BUILTIN_CONTENT",
|
|
20571
|
+
operationIndex,
|
|
20572
|
+
message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
|
|
20573
|
+
}
|
|
20574
|
+
];
|
|
20575
|
+
}
|
|
20576
|
+
if (!isStoredContentName(bareName)) {
|
|
20577
|
+
return [
|
|
20578
|
+
{
|
|
20579
|
+
code: "UNKNOWN_CONTENT_NAME",
|
|
20580
|
+
operationIndex,
|
|
20581
|
+
message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
|
|
20582
|
+
}
|
|
20583
|
+
];
|
|
20584
|
+
}
|
|
20585
|
+
return [];
|
|
20586
|
+
}
|
|
20587
|
+
function plusSignGuard(op, operationIndex) {
|
|
20588
|
+
const errors = [];
|
|
20589
|
+
const name = op.name;
|
|
20590
|
+
if (op.newName?.includes("+")) {
|
|
20591
|
+
errors.push({
|
|
20592
|
+
code: "VALIDATION_ERROR",
|
|
20593
|
+
operationIndex,
|
|
20594
|
+
message: `Name "${op.newName}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
20595
|
+
});
|
|
20596
|
+
return errors;
|
|
20597
|
+
}
|
|
20598
|
+
if (name?.includes("+")) {
|
|
20599
|
+
if (op.kind === "collection" && op.operation === "add") {
|
|
20600
|
+
errors.push({
|
|
20601
|
+
code: "VALIDATION_ERROR",
|
|
20602
|
+
operationIndex,
|
|
20603
|
+
message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
20604
|
+
});
|
|
20605
|
+
return errors;
|
|
20606
|
+
}
|
|
20607
|
+
if (op.kind === "collection")
|
|
20608
|
+
return errors;
|
|
20609
|
+
const local = splitLocalPath(name);
|
|
20610
|
+
if (local && isReservedCollectionShape(local.shapePrefix))
|
|
20611
|
+
return errors;
|
|
20612
|
+
errors.push({
|
|
20613
|
+
code: "VALIDATION_ERROR",
|
|
20614
|
+
operationIndex,
|
|
20615
|
+
message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
20616
|
+
});
|
|
20617
|
+
}
|
|
20618
|
+
return errors;
|
|
20619
|
+
}
|
|
20620
|
+
function validateCollectionAbouts(op, operationIndex) {
|
|
20621
|
+
const errors = [];
|
|
20622
|
+
if (!op.about || typeof op.about === "string")
|
|
20623
|
+
return errors;
|
|
20624
|
+
errors.push({
|
|
20625
|
+
code: "VALIDATION_ERROR",
|
|
20626
|
+
operationIndex,
|
|
20627
|
+
message: COLLECTION_ABOUT_REMOVED_MESSAGE
|
|
20628
|
+
});
|
|
20629
|
+
return errors;
|
|
20630
|
+
}
|
|
20631
|
+
function validateCollectionOps(op, operationIndex) {
|
|
20632
|
+
const errors = [];
|
|
20633
|
+
if (op.kind !== "collection")
|
|
20634
|
+
return errors;
|
|
20635
|
+
if (!collectionOps.includes(op.operation)) {
|
|
20636
|
+
return errors;
|
|
20637
|
+
}
|
|
20638
|
+
if (op.operation === "add" && !op.name) {
|
|
20639
|
+
errors.push({
|
|
20640
|
+
code: "VALIDATION_ERROR",
|
|
20641
|
+
operationIndex,
|
|
20642
|
+
message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
|
|
20643
|
+
});
|
|
20644
|
+
}
|
|
20645
|
+
if (!op.type || !collectionTypes.includes(op.type)) {
|
|
20646
|
+
errors.push({
|
|
20647
|
+
code: "VALIDATION_ERROR",
|
|
20648
|
+
operationIndex,
|
|
20649
|
+
message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
|
|
20650
|
+
});
|
|
20651
|
+
}
|
|
20652
|
+
if (!op.members || !Array.isArray(op.members)) {
|
|
20653
|
+
errors.push({
|
|
20654
|
+
code: "VALIDATION_ERROR",
|
|
20655
|
+
operationIndex,
|
|
20656
|
+
message: 'Collection requires a "members" array'
|
|
20657
|
+
});
|
|
20658
|
+
} else {
|
|
20659
|
+
for (let i = 0;i < op.members.length; i++) {
|
|
20660
|
+
if (typeof op.members[i] !== "string") {
|
|
20661
|
+
errors.push({
|
|
20662
|
+
code: "VALIDATION_ERROR",
|
|
20663
|
+
operationIndex,
|
|
20664
|
+
message: `Collection member at index ${i} must be a string`
|
|
20665
|
+
});
|
|
20666
|
+
}
|
|
20667
|
+
}
|
|
20668
|
+
}
|
|
20669
|
+
if (op.type && op.members) {
|
|
20670
|
+
const arityError = collectionArityError(op.type, op.members);
|
|
20671
|
+
if (arityError) {
|
|
20672
|
+
errors.push({
|
|
20673
|
+
code: "VALIDATION_ERROR",
|
|
20674
|
+
operationIndex,
|
|
20675
|
+
message: arityError
|
|
20676
|
+
});
|
|
20677
|
+
}
|
|
20678
|
+
}
|
|
20679
|
+
return errors;
|
|
20680
|
+
}
|
|
20681
|
+
function collectionArityError(tag, members) {
|
|
20682
|
+
switch (tag) {
|
|
20683
|
+
case "arc":
|
|
20684
|
+
return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
|
|
20685
|
+
case "bond":
|
|
20686
|
+
return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
|
|
20687
|
+
case "pair":
|
|
20688
|
+
return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
|
|
20689
|
+
case "set":
|
|
20690
|
+
case "list":
|
|
20691
|
+
return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
|
|
20692
|
+
}
|
|
20693
|
+
}
|
|
20694
|
+
// ../../packages/rules/src/preflight.ts
|
|
20695
|
+
function preflightOpDiagnostics2(op, operationIndex) {
|
|
20696
|
+
return preflightOpDiagnostics(op, operationIndex);
|
|
20697
|
+
}
|
|
20698
|
+
function preflightCommitDiagnostics2(operations, options) {
|
|
20699
|
+
return preflightCommitDiagnostics(operations, options);
|
|
20700
|
+
}
|
|
20414
20701
|
// ../../packages/rules/src/shape-types.ts
|
|
20415
20702
|
var BASE_PRIMITIVE_TYPES = [
|
|
20416
20703
|
"number",
|
|
@@ -20608,6 +20895,14 @@ function displayFieldEntry(fieldType) {
|
|
|
20608
20895
|
return { type, description };
|
|
20609
20896
|
return type;
|
|
20610
20897
|
}
|
|
20898
|
+
// ../../packages/rules/src/shape-field-key.ts
|
|
20899
|
+
function foldFieldName(name) {
|
|
20900
|
+
const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
|
|
20901
|
+
return stripped.toLowerCase();
|
|
20902
|
+
}
|
|
20903
|
+
function foldFieldPath(path) {
|
|
20904
|
+
return path.split(".").map((segment) => foldFieldName(segment)).join(".");
|
|
20905
|
+
}
|
|
20611
20906
|
|
|
20612
20907
|
// ../../node_modules/.bun/re2js@2.8.3/node_modules/re2js/build/index.js
|
|
20613
20908
|
/*!
|
|
@@ -27102,372 +27397,7 @@ function normalizeOptionalTypeSpec(spec) {
|
|
|
27102
27397
|
}
|
|
27103
27398
|
return { spec, optionalByType: false };
|
|
27104
27399
|
}
|
|
27105
|
-
// ../../packages/rules/src/external-contract.ts
|
|
27106
|
-
var FORBIDDEN_EXTERNAL_FIELDS = new Set([
|
|
27107
|
-
"_id",
|
|
27108
|
-
"_creationTime",
|
|
27109
|
-
"repoId",
|
|
27110
|
-
"orgId",
|
|
27111
|
-
"thingId",
|
|
27112
|
-
"shapeThingId",
|
|
27113
|
-
"aboutThingId",
|
|
27114
|
-
"currentVersionId",
|
|
27115
|
-
"createdInCommitId",
|
|
27116
|
-
"validatedShapeVersionId"
|
|
27117
|
-
]);
|
|
27118
|
-
// ../../packages/rules/src/name-charset.ts
|
|
27119
|
-
var RESERVED_NAME_SEGMENT_CHARS = ["?", "#", "@", ":", "$"];
|
|
27120
|
-
function escapeForCharClass(char) {
|
|
27121
|
-
return char.replace(/[\\\]^-]/g, "\\$&");
|
|
27122
|
-
}
|
|
27123
|
-
var RESERVED_CLASS_BODY = RESERVED_NAME_SEGMENT_CHARS.map(escapeForCharClass).join("");
|
|
27124
|
-
var NAME_SEGMENT_FORBIDDEN_RE = new RegExp(`[${RESERVED_CLASS_BODY}\\s]`);
|
|
27125
|
-
var PATH_SEGMENT_FORBIDDEN_RE = new RegExp(`[/${RESERVED_CLASS_BODY}\\s]`);
|
|
27126
|
-
// ../../packages/rules/src/permission-scopes.ts
|
|
27127
|
-
var PUBLIC_ORG_PERMISSIONS = new Set([
|
|
27128
|
-
"org:read",
|
|
27129
|
-
"components:read"
|
|
27130
|
-
]);
|
|
27131
|
-
// ../../packages/rules/src/tokens.ts
|
|
27132
|
-
var COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE = "$N/#N commit-token syntax is no longer supported. Use explicit names and explicit wrefs. For assertions about newly created things, create the thing with a deterministic name and set about to that wref in the same commit.";
|
|
27133
|
-
var ANY_TOKEN_RE = /[$#]\d+/;
|
|
27134
|
-
function hasAnyTokens(s) {
|
|
27135
|
-
return ANY_TOKEN_RE.test(s);
|
|
27136
|
-
}
|
|
27137
|
-
|
|
27138
|
-
// ../../packages/rules/src/preflight-commit.ts
|
|
27139
|
-
function preflightCommitDiagnostics(operations, options) {
|
|
27140
|
-
const errors = [];
|
|
27141
|
-
rejectCommitTokenSyntax(operations, errors, options);
|
|
27142
|
-
illegalOpSequences(operations, errors, options?.checkAddAdd ?? true, options);
|
|
27143
|
-
return errors;
|
|
27144
|
-
}
|
|
27145
|
-
function sourceOperationIndex(filteredIndex, options) {
|
|
27146
|
-
return options?.sourceOperationIndexes?.[filteredIndex] ?? filteredIndex;
|
|
27147
|
-
}
|
|
27148
|
-
function getOpName(op) {
|
|
27149
|
-
return op.name;
|
|
27150
|
-
}
|
|
27151
|
-
function tokenStringFields(op) {
|
|
27152
|
-
const fields = [getOpName(op), op.newName];
|
|
27153
|
-
if (typeof op.about === "string") {
|
|
27154
|
-
fields.push(op.about);
|
|
27155
|
-
}
|
|
27156
|
-
if (op.members) {
|
|
27157
|
-
fields.push(...op.members);
|
|
27158
|
-
}
|
|
27159
|
-
return fields;
|
|
27160
|
-
}
|
|
27161
|
-
function rejectCommitTokenSyntax(operations, errors, options) {
|
|
27162
|
-
for (let i = 0;i < operations.length; i++) {
|
|
27163
|
-
const op = operations[i];
|
|
27164
|
-
if (!op)
|
|
27165
|
-
continue;
|
|
27166
|
-
for (const field of tokenStringFields(op)) {
|
|
27167
|
-
if (field && hasAnyTokens(field)) {
|
|
27168
|
-
errors.push({
|
|
27169
|
-
code: "COMMIT_TOKEN_SYNTAX_REMOVED",
|
|
27170
|
-
operationIndex: sourceOperationIndex(i, options),
|
|
27171
|
-
message: COMMIT_TOKEN_SYNTAX_REMOVED_MESSAGE
|
|
27172
|
-
});
|
|
27173
|
-
break;
|
|
27174
|
-
}
|
|
27175
|
-
}
|
|
27176
|
-
}
|
|
27177
|
-
}
|
|
27178
|
-
function illegalOpSequences(operations, errors, checkAddAdd, options) {
|
|
27179
|
-
const opHistory = new Map;
|
|
27180
|
-
for (let i = 0;i < operations.length; i++) {
|
|
27181
|
-
const op = operations[i];
|
|
27182
|
-
if (!op)
|
|
27183
|
-
continue;
|
|
27184
|
-
const name = getOpName(op);
|
|
27185
|
-
if (!name)
|
|
27186
|
-
continue;
|
|
27187
|
-
if (hasAnyTokens(name))
|
|
27188
|
-
continue;
|
|
27189
|
-
const kind = inferOperationKind({ ...op, name });
|
|
27190
|
-
const qualName = kind === "shape" ? `shape:${name}` : `thing:${name}`;
|
|
27191
|
-
const history = opHistory.get(qualName) ?? [];
|
|
27192
|
-
history.push({
|
|
27193
|
-
operation: op.operation,
|
|
27194
|
-
index: sourceOperationIndex(i, options)
|
|
27195
|
-
});
|
|
27196
|
-
opHistory.set(qualName, history);
|
|
27197
|
-
}
|
|
27198
|
-
for (const [qualName, history] of opHistory) {
|
|
27199
|
-
if (history.length < 2)
|
|
27200
|
-
continue;
|
|
27201
|
-
for (let i = 1;i < history.length; i++) {
|
|
27202
|
-
const prev = history[i - 1];
|
|
27203
|
-
const curr = history[i];
|
|
27204
|
-
if (!prev || !curr)
|
|
27205
|
-
continue;
|
|
27206
|
-
const pair = `${prev.operation}+${curr.operation}`;
|
|
27207
|
-
if (checkAddAdd && pair === "add+add") {
|
|
27208
|
-
errors.push({
|
|
27209
|
-
code: "ILLEGAL_OP_SEQUENCE",
|
|
27210
|
-
operationIndex: curr.index,
|
|
27211
|
-
message: `Cannot add "${qualName}" twice in the same commit`
|
|
27212
|
-
});
|
|
27213
|
-
}
|
|
27214
|
-
if (pair === "revise+add") {
|
|
27215
|
-
errors.push({
|
|
27216
|
-
code: "ILLEGAL_OP_SEQUENCE",
|
|
27217
|
-
operationIndex: curr.index,
|
|
27218
|
-
message: `Cannot revise then add "${qualName}" in the same commit`
|
|
27219
|
-
});
|
|
27220
|
-
}
|
|
27221
|
-
}
|
|
27222
|
-
}
|
|
27223
|
-
}
|
|
27224
27400
|
|
|
27225
|
-
// ../../packages/rules/src/preflight-operation.ts
|
|
27226
|
-
var collectionTypes = ["arc", "bond", "set", "list", "pair"];
|
|
27227
|
-
var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
|
|
27228
|
-
var collectionOps = ["add", "revise"];
|
|
27229
|
-
var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
|
|
27230
|
-
var COLLECTION_ABOUT_REMOVED_MESSAGE = 'about accepts a wref. Create the collection as its own named operation, then point the assertion at it. Prefer deterministic relationship names, for example: [{"operation":"add","kind":"collection","type":"arc","name":"a-to-b","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Arc/a-to-b","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
|
|
27231
|
-
function preflightOpDiagnostics(op, operationIndex) {
|
|
27232
|
-
const errors = [];
|
|
27233
|
-
errors.push(...builtinShapeGuard(op, operationIndex));
|
|
27234
|
-
errors.push(...contentNameGuard(op, operationIndex));
|
|
27235
|
-
errors.push(...plusSignGuard(op, operationIndex));
|
|
27236
|
-
errors.push(...validateCollectionAbouts(op, operationIndex));
|
|
27237
|
-
errors.push(...validateCollectionOps(op, operationIndex));
|
|
27238
|
-
return errors;
|
|
27239
|
-
}
|
|
27240
|
-
function builtinShapeGuard(op, operationIndex) {
|
|
27241
|
-
const errors = [];
|
|
27242
|
-
const name = op.name;
|
|
27243
|
-
const isShapeRename = op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name));
|
|
27244
|
-
const reservedSourcePassThrough = isShapeRename && name !== undefined && isRenameableSquattedShape(name) && op.newName !== undefined && !isReservedCollectionShape(op.newName) && !isBuiltinShape(op.newName);
|
|
27245
|
-
if (name && isRetiredCollectionShape(name) && !reservedSourcePassThrough) {
|
|
27246
|
-
errors.push({
|
|
27247
|
-
code: "RESERVED_NAME",
|
|
27248
|
-
operationIndex,
|
|
27249
|
-
message: `Shape "${name}" is a retired collection shape and cannot be written manually`
|
|
27250
|
-
});
|
|
27251
|
-
}
|
|
27252
|
-
if (op.operation === "rename" && (op.kind === "shape" || op.name !== undefined && !splitLocalPath(op.name)) && op.newName && isRetiredCollectionShape(op.newName)) {
|
|
27253
|
-
errors.push({
|
|
27254
|
-
code: "RESERVED_NAME",
|
|
27255
|
-
operationIndex,
|
|
27256
|
-
message: `Shape "${op.newName}" is a retired collection shape and cannot be written manually`
|
|
27257
|
-
});
|
|
27258
|
-
} else {
|
|
27259
|
-
const builtinShapeName = name && isBuiltinShape(name) && !reservedSourcePassThrough ? name : isShapeRename && op.newName && isBuiltinShape(op.newName) ? op.newName : undefined;
|
|
27260
|
-
if (builtinShapeName && (isShapeRename || op.operation !== "retract" && op.kind === "shape")) {
|
|
27261
|
-
const action = op.operation === "add" ? "created" : op.operation === "rename" ? "renamed" : "revised";
|
|
27262
|
-
errors.push({
|
|
27263
|
-
code: "RESERVED_NAME",
|
|
27264
|
-
operationIndex,
|
|
27265
|
-
message: `Shape "${builtinShapeName}" is a built-in shape and cannot be ${action} manually`
|
|
27266
|
-
});
|
|
27267
|
-
}
|
|
27268
|
-
}
|
|
27269
|
-
if (name) {
|
|
27270
|
-
const local = splitLocalPath(name);
|
|
27271
|
-
if (local && isRetiredCollectionShape(local.shapePrefix)) {
|
|
27272
|
-
errors.push({
|
|
27273
|
-
code: "VALIDATION_ERROR",
|
|
27274
|
-
operationIndex,
|
|
27275
|
-
message: `Cannot ${op.operation} under retired collection shape "${local.shapePrefix}". Triple is read-only and retired for new collection writes.`
|
|
27276
|
-
});
|
|
27277
|
-
} else if (op.kind === "thing" && local && isBuiltinCollectionShape(local.shapePrefix)) {
|
|
27278
|
-
const message = op.operation === "add" ? `Cannot add kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" instead.` : `Cannot revise kind="thing" under built-in shape "${local.shapePrefix}". Use kind="collection" to revise a collection.`;
|
|
27279
|
-
errors.push({
|
|
27280
|
-
code: "VALIDATION_ERROR",
|
|
27281
|
-
operationIndex,
|
|
27282
|
-
message
|
|
27283
|
-
});
|
|
27284
|
-
}
|
|
27285
|
-
}
|
|
27286
|
-
return errors;
|
|
27287
|
-
}
|
|
27288
|
-
function contentNameGuard(op, operationIndex) {
|
|
27289
|
-
if (op.kind !== "thing" || !op.name)
|
|
27290
|
-
return [];
|
|
27291
|
-
const local = splitLocalPath(op.name);
|
|
27292
|
-
if (!local || !isContentShape(local.shapePrefix))
|
|
27293
|
-
return [];
|
|
27294
|
-
const bareName = local.bareName;
|
|
27295
|
-
if (isSynthesizedContentName(bareName)) {
|
|
27296
|
-
return [
|
|
27297
|
-
{
|
|
27298
|
-
code: "READ_ONLY_BUILTIN_CONTENT",
|
|
27299
|
-
operationIndex,
|
|
27300
|
-
message: `${local.shapePrefix}/${bareName} is synthesized; writes are not allowed`
|
|
27301
|
-
}
|
|
27302
|
-
];
|
|
27303
|
-
}
|
|
27304
|
-
if (!isStoredContentName(bareName)) {
|
|
27305
|
-
return [
|
|
27306
|
-
{
|
|
27307
|
-
code: "UNKNOWN_CONTENT_NAME",
|
|
27308
|
-
operationIndex,
|
|
27309
|
-
message: `${local.shapePrefix}/${bareName} is not a recognized well-known content name`
|
|
27310
|
-
}
|
|
27311
|
-
];
|
|
27312
|
-
}
|
|
27313
|
-
return [];
|
|
27314
|
-
}
|
|
27315
|
-
function plusSignGuard(op, operationIndex) {
|
|
27316
|
-
const errors = [];
|
|
27317
|
-
const name = op.name;
|
|
27318
|
-
if (op.newName?.includes("+")) {
|
|
27319
|
-
errors.push({
|
|
27320
|
-
code: "VALIDATION_ERROR",
|
|
27321
|
-
operationIndex,
|
|
27322
|
-
message: `Name "${op.newName}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
27323
|
-
});
|
|
27324
|
-
return errors;
|
|
27325
|
-
}
|
|
27326
|
-
if (name?.includes("+")) {
|
|
27327
|
-
if (op.kind === "collection" && op.operation === "add") {
|
|
27328
|
-
errors.push({
|
|
27329
|
-
code: "VALIDATION_ERROR",
|
|
27330
|
-
operationIndex,
|
|
27331
|
-
message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
27332
|
-
});
|
|
27333
|
-
return errors;
|
|
27334
|
-
}
|
|
27335
|
-
if (op.kind === "collection")
|
|
27336
|
-
return errors;
|
|
27337
|
-
const local = splitLocalPath(name);
|
|
27338
|
-
if (local && isReservedCollectionShape(local.shapePrefix))
|
|
27339
|
-
return errors;
|
|
27340
|
-
errors.push({
|
|
27341
|
-
code: "VALIDATION_ERROR",
|
|
27342
|
-
operationIndex,
|
|
27343
|
-
message: `Name "${name}" contains reserved character "+". The "+" character is reserved for the historical collection auto-name namespace and is not allowed in user-supplied names.`
|
|
27344
|
-
});
|
|
27345
|
-
}
|
|
27346
|
-
return errors;
|
|
27347
|
-
}
|
|
27348
|
-
function validateCollectionAbouts(op, operationIndex) {
|
|
27349
|
-
const errors = [];
|
|
27350
|
-
if (!op.about || typeof op.about === "string")
|
|
27351
|
-
return errors;
|
|
27352
|
-
errors.push({
|
|
27353
|
-
code: "VALIDATION_ERROR",
|
|
27354
|
-
operationIndex,
|
|
27355
|
-
message: COLLECTION_ABOUT_REMOVED_MESSAGE
|
|
27356
|
-
});
|
|
27357
|
-
return errors;
|
|
27358
|
-
}
|
|
27359
|
-
function validateCollectionOps(op, operationIndex) {
|
|
27360
|
-
const errors = [];
|
|
27361
|
-
if (op.kind !== "collection")
|
|
27362
|
-
return errors;
|
|
27363
|
-
if (!collectionOps.includes(op.operation)) {
|
|
27364
|
-
return errors;
|
|
27365
|
-
}
|
|
27366
|
-
if (op.operation === "add" && !op.name) {
|
|
27367
|
-
errors.push({
|
|
27368
|
-
code: "VALIDATION_ERROR",
|
|
27369
|
-
operationIndex,
|
|
27370
|
-
message: COLLECTION_CREATE_REQUIRES_NAME_MESSAGE
|
|
27371
|
-
});
|
|
27372
|
-
}
|
|
27373
|
-
if (!op.type || !collectionTypes.includes(op.type)) {
|
|
27374
|
-
errors.push({
|
|
27375
|
-
code: "VALIDATION_ERROR",
|
|
27376
|
-
operationIndex,
|
|
27377
|
-
message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
|
|
27378
|
-
});
|
|
27379
|
-
}
|
|
27380
|
-
if (!op.members || !Array.isArray(op.members)) {
|
|
27381
|
-
errors.push({
|
|
27382
|
-
code: "VALIDATION_ERROR",
|
|
27383
|
-
operationIndex,
|
|
27384
|
-
message: 'Collection requires a "members" array'
|
|
27385
|
-
});
|
|
27386
|
-
} else {
|
|
27387
|
-
for (let i = 0;i < op.members.length; i++) {
|
|
27388
|
-
if (typeof op.members[i] !== "string") {
|
|
27389
|
-
errors.push({
|
|
27390
|
-
code: "VALIDATION_ERROR",
|
|
27391
|
-
operationIndex,
|
|
27392
|
-
message: `Collection member at index ${i} must be a string`
|
|
27393
|
-
});
|
|
27394
|
-
}
|
|
27395
|
-
}
|
|
27396
|
-
}
|
|
27397
|
-
if (op.type && op.members) {
|
|
27398
|
-
const arityError = collectionArityError(op.type, op.members);
|
|
27399
|
-
if (arityError) {
|
|
27400
|
-
errors.push({
|
|
27401
|
-
code: "VALIDATION_ERROR",
|
|
27402
|
-
operationIndex,
|
|
27403
|
-
message: arityError
|
|
27404
|
-
});
|
|
27405
|
-
}
|
|
27406
|
-
}
|
|
27407
|
-
return errors;
|
|
27408
|
-
}
|
|
27409
|
-
function collectionArityError(tag, members) {
|
|
27410
|
-
switch (tag) {
|
|
27411
|
-
case "arc":
|
|
27412
|
-
return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
|
|
27413
|
-
case "bond":
|
|
27414
|
-
return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
|
|
27415
|
-
case "pair":
|
|
27416
|
-
return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
|
|
27417
|
-
case "set":
|
|
27418
|
-
case "list":
|
|
27419
|
-
return members.length < 1 ? `${tag === "set" ? "Set" : "List"} requires at least 1 member, got 0` : null;
|
|
27420
|
-
}
|
|
27421
|
-
}
|
|
27422
|
-
// ../../packages/rules/src/preflight.ts
|
|
27423
|
-
function preflightOpDiagnostics2(op, operationIndex) {
|
|
27424
|
-
return preflightOpDiagnostics(op, operationIndex);
|
|
27425
|
-
}
|
|
27426
|
-
function preflightCommitDiagnostics2(operations, options) {
|
|
27427
|
-
return preflightCommitDiagnostics(operations, options);
|
|
27428
|
-
}
|
|
27429
|
-
// ../../packages/rules/src/read-limits.ts
|
|
27430
|
-
var MAX_GET_MANY_WREFS = 500;
|
|
27431
|
-
// ../../packages/rules/src/reserved-orgs.ts
|
|
27432
|
-
var RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES = [
|
|
27433
|
-
"_app",
|
|
27434
|
-
"_static",
|
|
27435
|
-
"api",
|
|
27436
|
-
"health",
|
|
27437
|
-
"healthz",
|
|
27438
|
-
"mcp",
|
|
27439
|
-
"readyz",
|
|
27440
|
-
"robots.txt",
|
|
27441
|
-
"sse",
|
|
27442
|
-
"trpc",
|
|
27443
|
-
"version"
|
|
27444
|
-
];
|
|
27445
|
-
var RESERVED_ORG_NAMES = [
|
|
27446
|
-
...RESERVED_RAW_CONTENT_TOP_LEVEL_NAMES,
|
|
27447
|
-
"admin",
|
|
27448
|
-
"billing",
|
|
27449
|
-
"blog",
|
|
27450
|
-
"docs",
|
|
27451
|
-
"help",
|
|
27452
|
-
"login",
|
|
27453
|
-
"public",
|
|
27454
|
-
"settings",
|
|
27455
|
-
"signup",
|
|
27456
|
-
"status",
|
|
27457
|
-
"support",
|
|
27458
|
-
"system",
|
|
27459
|
-
"warmhub",
|
|
27460
|
-
"www"
|
|
27461
|
-
];
|
|
27462
|
-
var RESERVED_ORG_NAME_SET = new Set(RESERVED_ORG_NAMES);
|
|
27463
|
-
// ../../packages/rules/src/shape-field-key.ts
|
|
27464
|
-
function foldFieldName(name) {
|
|
27465
|
-
const stripped = name.endsWith("?") ? name.slice(0, -1) : name;
|
|
27466
|
-
return stripped.toLowerCase();
|
|
27467
|
-
}
|
|
27468
|
-
function foldFieldPath(path) {
|
|
27469
|
-
return path.split(".").map((segment) => foldFieldName(segment)).join(".");
|
|
27470
|
-
}
|
|
27471
27401
|
// ../../packages/rules/src/shape-validation-runtime.ts
|
|
27472
27402
|
function validatePersistedStringFieldLimits(value, typeDef, errors, path) {
|
|
27473
27403
|
const normalized = normalizeOptionalTypeSpec(typeDef).spec;
|
|
@@ -28063,8 +27993,8 @@ function normalizeOptionalName(value) {
|
|
|
28063
27993
|
|
|
28064
27994
|
// ../../packages/sdk-ts/src/operation-normalize.ts
|
|
28065
27995
|
function toBackendStreamOperation(operation) {
|
|
28066
|
-
if (operation.expectedVersion !== undefined && operation.operation !== "revise") {
|
|
28067
|
-
throw new Error("expectedVersion is only valid on revise operations — set operation
|
|
27996
|
+
if (operation.expectedVersion !== undefined && operation.operation !== "revise" && operation.operation !== "retract") {
|
|
27997
|
+
throw new Error("expectedVersion is only valid on revise or retract operations — set an explicit operation discriminator");
|
|
28068
27998
|
}
|
|
28069
27999
|
if (operation.operation === "retract") {
|
|
28070
28000
|
return {
|
|
@@ -28072,6 +28002,7 @@ function toBackendStreamOperation(operation) {
|
|
|
28072
28002
|
name: operation.name,
|
|
28073
28003
|
...operation.kind ? { kind: operation.kind } : {},
|
|
28074
28004
|
...operation.reason ? { reason: operation.reason } : {},
|
|
28005
|
+
...operation.expectedVersion !== undefined ? { expectedVersion: operation.expectedVersion } : {},
|
|
28075
28006
|
...operation.leaseId ? { leaseId: operation.leaseId } : {}
|
|
28076
28007
|
};
|
|
28077
28008
|
}
|
|
@@ -28167,13 +28098,19 @@ class PartialStreamSubmissionError extends Error {
|
|
|
28167
28098
|
code = "PARTIAL_STREAM_SUBMISSION";
|
|
28168
28099
|
completedOperations;
|
|
28169
28100
|
acknowledgedOperationCount;
|
|
28101
|
+
lastAcknowledgedRepoSeq;
|
|
28102
|
+
attemptedAppendOutcome;
|
|
28170
28103
|
cause;
|
|
28171
28104
|
constructor(input) {
|
|
28172
|
-
super("Stream submission
|
|
28105
|
+
super("Stream submission outcome is incomplete or unknown. Stop sending writes; once any outstanding append can no longer apply, obtain a later verified checkpoint and reconcile before replanning.");
|
|
28173
28106
|
this.name = "WarmHubError";
|
|
28174
28107
|
this.cause = input.cause;
|
|
28175
28108
|
this.completedOperations = input.completedOperations;
|
|
28176
28109
|
this.acknowledgedOperationCount = input.acknowledgedOperationCount ?? input.completedOperations.length;
|
|
28110
|
+
this.attemptedAppendOutcome = input.attemptedAppendOutcome;
|
|
28111
|
+
if (input.lastAcknowledgedRepoSeq !== undefined) {
|
|
28112
|
+
this.lastAcknowledgedRepoSeq = input.lastAcknowledgedRepoSeq;
|
|
28113
|
+
}
|
|
28177
28114
|
}
|
|
28178
28115
|
}
|
|
28179
28116
|
|
|
@@ -28330,6 +28267,9 @@ function isTransientStreamFailure(cause) {
|
|
|
28330
28267
|
function isFetchNetworkTypeError(cause) {
|
|
28331
28268
|
return cause instanceof TypeError && /fetch/i.test(cause.message);
|
|
28332
28269
|
}
|
|
28270
|
+
function isReplaySafeOperation(operation) {
|
|
28271
|
+
return operation.operation !== "revise" || operation.expectedVersion !== undefined;
|
|
28272
|
+
}
|
|
28333
28273
|
function computeBackoffDelayMs(attempt, policy) {
|
|
28334
28274
|
const exponential = policy.baseDelayMs * 2 ** Math.max(0, attempt - 1);
|
|
28335
28275
|
const jitter = Math.random() * policy.baseDelayMs;
|
|
@@ -28379,7 +28319,8 @@ async function submitOperationsViaStream(client, args) {
|
|
|
28379
28319
|
for (const { operations: chunk, start: chunkStart } of chunkOperations(operations, chunkSize)) {
|
|
28380
28320
|
let attempt = 1;
|
|
28381
28321
|
let priorAttemptAmbiguous = false;
|
|
28382
|
-
const
|
|
28322
|
+
const chunkIsSingleOperation = chunk.length === 1;
|
|
28323
|
+
const chunkIsReplaySafe = chunk.every(isReplaySafeOperation);
|
|
28383
28324
|
while (true) {
|
|
28384
28325
|
try {
|
|
28385
28326
|
const appendResult = await client.stream.append({
|
|
@@ -28407,7 +28348,7 @@ async function submitOperationsViaStream(client, args) {
|
|
|
28407
28348
|
if (acknowledgedOperationCount === 0 && !priorAttemptAmbiguous && isDefiniteClientError(cause)) {
|
|
28408
28349
|
throw cause;
|
|
28409
28350
|
}
|
|
28410
|
-
if (acknowledgedOperationCount === 0 &&
|
|
28351
|
+
if (acknowledgedOperationCount === 0 && chunkIsSingleOperation && chunkIsReplaySafe && policy !== false && attempt < policy.maxAttempts && isTransientStreamFailure(cause)) {
|
|
28411
28352
|
await sleep2(computeBackoffDelayMs(attempt, policy));
|
|
28412
28353
|
attempt += 1;
|
|
28413
28354
|
priorAttemptAmbiguous = true;
|
|
@@ -28422,7 +28363,9 @@ async function submitOperationsViaStream(client, args) {
|
|
|
28422
28363
|
throw new PartialStreamSubmissionError({
|
|
28423
28364
|
cause,
|
|
28424
28365
|
completedOperations,
|
|
28425
|
-
acknowledgedOperationCount
|
|
28366
|
+
acknowledgedOperationCount,
|
|
28367
|
+
lastAcknowledgedRepoSeq: repoSeq,
|
|
28368
|
+
attemptedAppendOutcome: !priorAttemptAmbiguous && isDefiniteClientError(cause) ? "not_applied" : "unknown"
|
|
28426
28369
|
});
|
|
28427
28370
|
}
|
|
28428
28371
|
}
|
|
@@ -28436,7 +28379,9 @@ async function submitOperationsViaStream(client, args) {
|
|
|
28436
28379
|
throw new PartialStreamSubmissionError({
|
|
28437
28380
|
cause: failure,
|
|
28438
28381
|
completedOperations: completedOperationsFrom(result),
|
|
28439
|
-
acknowledgedOperationCount
|
|
28382
|
+
acknowledgedOperationCount,
|
|
28383
|
+
lastAcknowledgedRepoSeq: repoSeq,
|
|
28384
|
+
attemptedAppendOutcome: "unknown"
|
|
28440
28385
|
});
|
|
28441
28386
|
}
|
|
28442
28387
|
throw failure;
|
|
@@ -28550,7 +28495,7 @@ function dedupeDeprecationsByShape(results) {
|
|
|
28550
28495
|
// ../../packages/sdk-ts/package.json
|
|
28551
28496
|
var package_default = {
|
|
28552
28497
|
name: "@warmhub/sdk-ts",
|
|
28553
|
-
version: "0.
|
|
28498
|
+
version: "0.84.0",
|
|
28554
28499
|
private: false,
|
|
28555
28500
|
type: "module",
|
|
28556
28501
|
description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -28705,40 +28650,64 @@ function assertPaginatedCursorAdvanced(cursor, nextCursor, seenCursors) {
|
|
|
28705
28650
|
throw new WarmHubError("VALIDATION_ERROR", "Paginated result cursor did not advance");
|
|
28706
28651
|
}
|
|
28707
28652
|
}
|
|
28708
|
-
|
|
28653
|
+
function assertIncrementalLowerBound(sinceRepoSeq) {
|
|
28654
|
+
if (sinceRepoSeq === undefined) {
|
|
28655
|
+
throw new WarmHubError("VALIDATION_ERROR", "sinceRepoSeq is required for an incremental read");
|
|
28656
|
+
}
|
|
28657
|
+
}
|
|
28658
|
+
async function* paginatePages(fetchPage, initialCursor) {
|
|
28709
28659
|
let cursor = initialCursor;
|
|
28710
28660
|
const seenCursors = new Set;
|
|
28711
28661
|
for (;; ) {
|
|
28712
28662
|
if (cursor)
|
|
28713
28663
|
seenCursors.add(cursor);
|
|
28714
28664
|
const page = await fetchPage(cursor);
|
|
28715
|
-
|
|
28716
|
-
yield item;
|
|
28717
|
-
}
|
|
28665
|
+
yield page;
|
|
28718
28666
|
if (!page.nextCursor)
|
|
28719
28667
|
return;
|
|
28720
28668
|
assertPaginatedCursorAdvanced(cursor, page.nextCursor, seenCursors);
|
|
28721
28669
|
cursor = page.nextCursor;
|
|
28722
28670
|
}
|
|
28723
28671
|
}
|
|
28672
|
+
async function* paginate(fetchPage, extractItems, initialCursor) {
|
|
28673
|
+
for await (const page of paginatePages(fetchPage, initialCursor)) {
|
|
28674
|
+
yield* extractItems(page);
|
|
28675
|
+
}
|
|
28676
|
+
}
|
|
28724
28677
|
async function collectPaginatedPages(fetchPage, extractItems, max, initialCursor) {
|
|
28725
28678
|
if (max !== undefined && (!Number.isFinite(max) || Math.trunc(max) !== max || max < 0)) {
|
|
28726
28679
|
throw new WarmHubError("VALIDATION_ERROR", "max must be a nonnegative integer");
|
|
28727
28680
|
}
|
|
28728
28681
|
const items = [];
|
|
28729
|
-
|
|
28682
|
+
for await (const page of paginatePages(fetchPage, initialCursor)) {
|
|
28683
|
+
const pageItems = extractItems(page);
|
|
28684
|
+
if (max !== undefined && items.length + pageItems.length > max) {
|
|
28685
|
+
throw new WarmHubError("VALIDATION_ERROR", `Paginated result exceeded max=${max}`);
|
|
28686
|
+
}
|
|
28687
|
+
items.push(...pageItems);
|
|
28688
|
+
}
|
|
28689
|
+
return items;
|
|
28690
|
+
}
|
|
28691
|
+
function assertRepoExploreBrowseMode(opts) {
|
|
28692
|
+
if (opts?.slugs !== undefined) {
|
|
28693
|
+
throw new WarmHubError("VALIDATION_ERROR", "repo.explore pagination helpers do not support slugs mode");
|
|
28694
|
+
}
|
|
28695
|
+
}
|
|
28696
|
+
async function collectIncrementalPages(fetchPage) {
|
|
28697
|
+
const items = [];
|
|
28698
|
+
let cursor;
|
|
28730
28699
|
const seenCursors = new Set;
|
|
28731
28700
|
for (;; ) {
|
|
28732
28701
|
if (cursor)
|
|
28733
28702
|
seenCursors.add(cursor);
|
|
28734
28703
|
const page = await fetchPage(cursor);
|
|
28735
|
-
|
|
28736
|
-
if (
|
|
28737
|
-
|
|
28704
|
+
items.push(...page.items);
|
|
28705
|
+
if (!page.nextCursor) {
|
|
28706
|
+
if (page.repoSeq === undefined) {
|
|
28707
|
+
throw new WarmHubError("VALIDATION_ERROR", "Incremental read completed without repoSeq");
|
|
28708
|
+
}
|
|
28709
|
+
return { items, repoSeq: page.repoSeq };
|
|
28738
28710
|
}
|
|
28739
|
-
items.push(...pageItems);
|
|
28740
|
-
if (!page.nextCursor)
|
|
28741
|
-
return items;
|
|
28742
28711
|
assertPaginatedCursorAdvanced(cursor, page.nextCursor, seenCursors);
|
|
28743
28712
|
cursor = page.nextCursor;
|
|
28744
28713
|
}
|
|
@@ -28755,6 +28724,9 @@ function chunkArray(items, chunkSize) {
|
|
|
28755
28724
|
}
|
|
28756
28725
|
return chunks;
|
|
28757
28726
|
}
|
|
28727
|
+
function narrowKind(kind) {
|
|
28728
|
+
return kind !== undefined && COMMIT_OPERATION_KINDS.includes(kind) ? kind : undefined;
|
|
28729
|
+
}
|
|
28758
28730
|
function toSubscriptionRef(args) {
|
|
28759
28731
|
const [first, repoName, name] = args;
|
|
28760
28732
|
return typeof first === "string" ? { orgName: first, repoName, name } : first;
|
|
@@ -29141,6 +29113,13 @@ class WarmHubClient {
|
|
|
29141
29113
|
throw toWarmHubError(error);
|
|
29142
29114
|
}
|
|
29143
29115
|
},
|
|
29116
|
+
listIter: (orgName, repoName, opts) => {
|
|
29117
|
+
return paginate((cursor) => this.component.list(orgName, repoName, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29118
|
+
},
|
|
29119
|
+
listAll: async (orgName, repoName, opts) => {
|
|
29120
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29121
|
+
return await collectPaginatedPages((cursor) => this.component.list(orgName, repoName, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29122
|
+
},
|
|
29144
29123
|
search: async (query, opts) => {
|
|
29145
29124
|
try {
|
|
29146
29125
|
return await this.trpc.component.search.query({
|
|
@@ -29152,6 +29131,13 @@ class WarmHubClient {
|
|
|
29152
29131
|
throw toWarmHubError(error);
|
|
29153
29132
|
}
|
|
29154
29133
|
},
|
|
29134
|
+
searchIter: (query, opts) => {
|
|
29135
|
+
return paginate((cursor) => this.component.search(query, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29136
|
+
},
|
|
29137
|
+
searchAll: async (query, opts) => {
|
|
29138
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29139
|
+
return await collectPaginatedPages((cursor) => this.component.search(query, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29140
|
+
},
|
|
29155
29141
|
get: async (orgName, repoName, componentRef) => {
|
|
29156
29142
|
try {
|
|
29157
29143
|
return await this.trpc.component.get.query({
|
|
@@ -29531,6 +29517,13 @@ class WarmHubClient {
|
|
|
29531
29517
|
throw toWarmHubError(error);
|
|
29532
29518
|
}
|
|
29533
29519
|
},
|
|
29520
|
+
listIter: (orgName, opts) => {
|
|
29521
|
+
return paginate((cursor) => this.repo.list(orgName, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29522
|
+
},
|
|
29523
|
+
listAll: async (orgName, opts) => {
|
|
29524
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29525
|
+
return await collectPaginatedPages((cursor) => this.repo.list(orgName, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29526
|
+
},
|
|
29534
29527
|
search: async (query, opts) => {
|
|
29535
29528
|
try {
|
|
29536
29529
|
return await this.trpc.repo.search.query({
|
|
@@ -29542,6 +29535,13 @@ class WarmHubClient {
|
|
|
29542
29535
|
throw toWarmHubError(error);
|
|
29543
29536
|
}
|
|
29544
29537
|
},
|
|
29538
|
+
searchIter: (query, opts) => {
|
|
29539
|
+
return paginate((cursor) => this.repo.search(query, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29540
|
+
},
|
|
29541
|
+
searchAll: async (query, opts) => {
|
|
29542
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29543
|
+
return await collectPaginatedPages((cursor) => this.repo.search(query, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29544
|
+
},
|
|
29545
29545
|
create: async (orgName, repoName, description, visibility, displayName) => {
|
|
29546
29546
|
try {
|
|
29547
29547
|
return await this.trpc.repo.create.mutate({
|
|
@@ -29651,6 +29651,13 @@ class WarmHubClient {
|
|
|
29651
29651
|
throw toWarmHubError(error);
|
|
29652
29652
|
}
|
|
29653
29653
|
},
|
|
29654
|
+
listPageIter: (orgName, opts) => {
|
|
29655
|
+
return paginate((cursor) => this.repo.listPage(orgName, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29656
|
+
},
|
|
29657
|
+
listPageAll: async (orgName, opts) => {
|
|
29658
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29659
|
+
return await collectPaginatedPages((cursor) => this.repo.listPage(orgName, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29660
|
+
},
|
|
29654
29661
|
listForCaller: async (opts) => {
|
|
29655
29662
|
try {
|
|
29656
29663
|
return await this.trpc.repo.listForCaller.query({
|
|
@@ -29678,6 +29685,15 @@ class WarmHubClient {
|
|
|
29678
29685
|
throw toWarmHubError(error);
|
|
29679
29686
|
}
|
|
29680
29687
|
},
|
|
29688
|
+
exploreIter: (opts) => {
|
|
29689
|
+
assertRepoExploreBrowseMode(opts);
|
|
29690
|
+
return paginate((cursor) => this.repo.explore({ ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
29691
|
+
},
|
|
29692
|
+
exploreAll: async (opts) => {
|
|
29693
|
+
assertRepoExploreBrowseMode(opts);
|
|
29694
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29695
|
+
return await collectPaginatedPages((cursor) => this.repo.explore({ ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
29696
|
+
},
|
|
29681
29697
|
getReadme: async (orgName, repoName) => {
|
|
29682
29698
|
try {
|
|
29683
29699
|
return await this.trpc.repo.getReadme.query({
|
|
@@ -29866,6 +29882,13 @@ class WarmHubClient {
|
|
|
29866
29882
|
} catch (error) {
|
|
29867
29883
|
throw toWarmHubError(error);
|
|
29868
29884
|
}
|
|
29885
|
+
},
|
|
29886
|
+
historyIter: (orgName, repoName, name, opts = {}) => {
|
|
29887
|
+
return paginate((cursor) => this.shape.history(orgName, repoName, name, { ...opts, cursor }), (page) => page.versions, opts.cursor);
|
|
29888
|
+
},
|
|
29889
|
+
historyAll: async (orgName, repoName, name, opts) => {
|
|
29890
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
29891
|
+
return await collectPaginatedPages((cursor) => this.shape.history(orgName, repoName, name, { ...pageOpts, cursor }), (page) => page.versions, max, pageOpts.cursor);
|
|
29869
29892
|
}
|
|
29870
29893
|
};
|
|
29871
29894
|
subscription = {
|
|
@@ -30024,11 +30047,25 @@ class WarmHubClient {
|
|
|
30024
30047
|
throw toWarmHubError(error);
|
|
30025
30048
|
}
|
|
30026
30049
|
},
|
|
30050
|
+
liveFeedIter: (orgName, repoName, subscriptionName, opts) => {
|
|
30051
|
+
return paginate((cursor) => this.action.liveFeed(orgName, repoName, subscriptionName, {
|
|
30052
|
+
...opts,
|
|
30053
|
+
cursor
|
|
30054
|
+
}), (page) => page.items, opts?.cursor);
|
|
30055
|
+
},
|
|
30056
|
+
liveFeedAll: async (orgName, repoName, subscriptionName, opts) => {
|
|
30057
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
30058
|
+
return await collectPaginatedPages((cursor) => this.action.liveFeed(orgName, repoName, subscriptionName, {
|
|
30059
|
+
...pageOpts,
|
|
30060
|
+
cursor
|
|
30061
|
+
}), (page) => page.items, max, pageOpts.cursor);
|
|
30062
|
+
},
|
|
30027
30063
|
listRuns: async (orgName, repoName, opts) => {
|
|
30028
30064
|
try {
|
|
30029
30065
|
return await this.trpc.action.listRuns.query({
|
|
30030
30066
|
orgName,
|
|
30031
30067
|
repoName,
|
|
30068
|
+
runId: opts?.runId,
|
|
30032
30069
|
subscriptionName: opts?.subscriptionName,
|
|
30033
30070
|
status: opts?.status,
|
|
30034
30071
|
outcome: opts?.outcome,
|
|
@@ -30040,6 +30077,21 @@ class WarmHubClient {
|
|
|
30040
30077
|
throw toWarmHubError(error);
|
|
30041
30078
|
}
|
|
30042
30079
|
},
|
|
30080
|
+
listRunsIter: (orgName, repoName, opts) => {
|
|
30081
|
+
return paginate((cursor) => this.action.listRuns(orgName, repoName, {
|
|
30082
|
+
...opts,
|
|
30083
|
+
since: cursor === undefined ? opts?.since : undefined,
|
|
30084
|
+
cursor
|
|
30085
|
+
}), (page) => page.items, opts?.cursor);
|
|
30086
|
+
},
|
|
30087
|
+
listRunsAll: async (orgName, repoName, opts) => {
|
|
30088
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
30089
|
+
return await collectPaginatedPages((cursor) => this.action.listRuns(orgName, repoName, {
|
|
30090
|
+
...pageOpts,
|
|
30091
|
+
since: cursor === undefined ? pageOpts.since : undefined,
|
|
30092
|
+
cursor
|
|
30093
|
+
}), (page) => page.items, max, pageOpts.cursor);
|
|
30094
|
+
},
|
|
30043
30095
|
latestRuns: async (orgName, repoName) => {
|
|
30044
30096
|
try {
|
|
30045
30097
|
return await this.trpc.action.latestRuns.query({ orgName, repoName });
|
|
@@ -30224,12 +30276,11 @@ class WarmHubClient {
|
|
|
30224
30276
|
thing = {
|
|
30225
30277
|
head: async (orgName, repoName, opts) => {
|
|
30226
30278
|
try {
|
|
30227
|
-
const kind = opts?.kind === "shape" || opts?.kind === "thing" || opts?.kind === "assertion" || opts?.kind === "collection" ? opts.kind : undefined;
|
|
30228
30279
|
return await this.trpc.thing.head.query({
|
|
30229
30280
|
orgName,
|
|
30230
30281
|
repoName,
|
|
30231
30282
|
shape: opts?.shape,
|
|
30232
|
-
kind,
|
|
30283
|
+
kind: narrowKind(opts?.kind),
|
|
30233
30284
|
match: opts?.match,
|
|
30234
30285
|
dataMode: opts?.dataMode,
|
|
30235
30286
|
includeRetracted: opts?.includeRetracted,
|
|
@@ -30238,7 +30289,8 @@ class WarmHubClient {
|
|
|
30238
30289
|
componentRef: opts?.componentRef,
|
|
30239
30290
|
excludeComponents: opts?.excludeComponents,
|
|
30240
30291
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
30241
|
-
where: opts?.where
|
|
30292
|
+
where: opts?.where,
|
|
30293
|
+
sinceRepoSeq: opts?.sinceRepoSeq
|
|
30242
30294
|
});
|
|
30243
30295
|
} catch (error) {
|
|
30244
30296
|
throw toWarmHubError(error);
|
|
@@ -30251,6 +30303,14 @@ class WarmHubClient {
|
|
|
30251
30303
|
const { max, ...pageOpts } = opts ?? {};
|
|
30252
30304
|
return await collectPaginatedPages((cursor) => this.thing.head(orgName, repoName, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
30253
30305
|
},
|
|
30306
|
+
headChanges: async (orgName, repoName, opts) => {
|
|
30307
|
+
assertIncrementalLowerBound(opts?.sinceRepoSeq);
|
|
30308
|
+
return await collectIncrementalPages((cursor) => this.thing.head(orgName, repoName, {
|
|
30309
|
+
...opts,
|
|
30310
|
+
includeRetracted: true,
|
|
30311
|
+
cursor
|
|
30312
|
+
}));
|
|
30313
|
+
},
|
|
30254
30314
|
get: async (orgName, repoName, wref, version, opts) => {
|
|
30255
30315
|
try {
|
|
30256
30316
|
return await this.trpc.thing.get.query({
|
|
@@ -30394,6 +30454,13 @@ class WarmHubClient {
|
|
|
30394
30454
|
throw toWarmHubError(error);
|
|
30395
30455
|
}
|
|
30396
30456
|
},
|
|
30457
|
+
historyIter: (orgName, repoName, opts) => {
|
|
30458
|
+
return paginate((cursor) => this.thing.history(orgName, repoName, { ...opts, cursor }), (page) => page.versions, opts.cursor);
|
|
30459
|
+
},
|
|
30460
|
+
historyAll: async (orgName, repoName, opts) => {
|
|
30461
|
+
const { max, ...pageOpts } = opts;
|
|
30462
|
+
return await collectPaginatedPages((cursor) => this.thing.history(orgName, repoName, { ...pageOpts, cursor }), (page) => page.versions, max, pageOpts.cursor);
|
|
30463
|
+
},
|
|
30397
30464
|
rename: async (orgName, repoName, shapeName, oldName, newName) => {
|
|
30398
30465
|
try {
|
|
30399
30466
|
return await this.trpc.thing.rename.mutate({
|
|
@@ -30447,13 +30514,12 @@ class WarmHubClient {
|
|
|
30447
30514
|
},
|
|
30448
30515
|
query: async (orgName, repoName, opts) => {
|
|
30449
30516
|
try {
|
|
30450
|
-
const kind = opts?.kind === "shape" || opts?.kind === "thing" || opts?.kind === "assertion" || opts?.kind === "collection" ? opts.kind : undefined;
|
|
30451
30517
|
return await this.trpc.thing.query.query({
|
|
30452
30518
|
orgName,
|
|
30453
30519
|
repoName,
|
|
30454
30520
|
shape: opts?.shape,
|
|
30455
30521
|
about: opts?.about,
|
|
30456
|
-
kind,
|
|
30522
|
+
kind: narrowKind(opts?.kind),
|
|
30457
30523
|
match: opts?.match,
|
|
30458
30524
|
includeRetracted: opts?.includeRetracted,
|
|
30459
30525
|
resolveCollections: opts?.resolveCollections,
|
|
@@ -30463,7 +30529,8 @@ class WarmHubClient {
|
|
|
30463
30529
|
componentRef: opts?.componentRef,
|
|
30464
30530
|
excludeComponents: opts?.excludeComponents,
|
|
30465
30531
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
30466
|
-
where: opts?.where
|
|
30532
|
+
where: opts?.where,
|
|
30533
|
+
sinceRepoSeq: opts?.sinceRepoSeq
|
|
30467
30534
|
});
|
|
30468
30535
|
} catch (error) {
|
|
30469
30536
|
throw toWarmHubError(error);
|
|
@@ -30476,16 +30543,23 @@ class WarmHubClient {
|
|
|
30476
30543
|
const { max, ...pageOpts } = opts ?? {};
|
|
30477
30544
|
return await collectPaginatedPages((cursor) => this.thing.query(orgName, repoName, { ...pageOpts, cursor }), (page) => page.items, max, pageOpts.cursor);
|
|
30478
30545
|
},
|
|
30546
|
+
queryChanges: async (orgName, repoName, opts) => {
|
|
30547
|
+
assertIncrementalLowerBound(opts?.sinceRepoSeq);
|
|
30548
|
+
return await collectIncrementalPages((cursor) => this.thing.query(orgName, repoName, {
|
|
30549
|
+
...opts,
|
|
30550
|
+
includeRetracted: true,
|
|
30551
|
+
cursor
|
|
30552
|
+
}));
|
|
30553
|
+
},
|
|
30479
30554
|
search: async (orgName, repoName, query, opts) => {
|
|
30480
30555
|
try {
|
|
30481
|
-
const kind = opts?.kind === "shape" || opts?.kind === "thing" || opts?.kind === "assertion" || opts?.kind === "collection" ? opts.kind : undefined;
|
|
30482
30556
|
return await this.trpc.thing.search.query({
|
|
30483
30557
|
orgName,
|
|
30484
30558
|
repoName,
|
|
30485
30559
|
query,
|
|
30486
30560
|
shape: opts?.shape,
|
|
30487
30561
|
about: opts?.about,
|
|
30488
|
-
kind,
|
|
30562
|
+
kind: narrowKind(opts?.kind),
|
|
30489
30563
|
match: opts?.match,
|
|
30490
30564
|
includeRetracted: opts?.includeRetracted,
|
|
30491
30565
|
resolveCollections: opts?.resolveCollections,
|
|
@@ -30501,22 +30575,32 @@ class WarmHubClient {
|
|
|
30501
30575
|
throw toWarmHubError(error);
|
|
30502
30576
|
}
|
|
30503
30577
|
},
|
|
30578
|
+
searchIter: (orgName, repoName, query, opts) => {
|
|
30579
|
+
return paginate((cursor) => this.thing.search(orgName, repoName, query, { ...opts, cursor }), (page) => page.items, opts?.cursor);
|
|
30580
|
+
},
|
|
30581
|
+
searchAll: async (orgName, repoName, query, opts) => {
|
|
30582
|
+
const { max, ...pageOpts } = opts ?? {};
|
|
30583
|
+
return await collectPaginatedPages((cursor) => this.thing.search(orgName, repoName, query, {
|
|
30584
|
+
...pageOpts,
|
|
30585
|
+
cursor
|
|
30586
|
+
}), (page) => page.items, max, pageOpts.cursor);
|
|
30587
|
+
},
|
|
30504
30588
|
count: async (orgName, repoName, opts) => {
|
|
30505
30589
|
try {
|
|
30506
|
-
const kind = opts?.kind === "shape" || opts?.kind === "thing" || opts?.kind === "assertion" || opts?.kind === "collection" ? opts.kind : undefined;
|
|
30507
30590
|
return await this.trpc.thing.count.query({
|
|
30508
30591
|
orgName,
|
|
30509
30592
|
repoName,
|
|
30510
30593
|
shape: opts?.shape,
|
|
30511
30594
|
about: opts?.about,
|
|
30512
|
-
kind,
|
|
30595
|
+
kind: narrowKind(opts?.kind),
|
|
30513
30596
|
match: opts?.match,
|
|
30514
30597
|
includeRetracted: opts?.includeRetracted,
|
|
30515
30598
|
resolveCollections: opts?.resolveCollections,
|
|
30516
30599
|
componentRef: opts?.componentRef,
|
|
30517
30600
|
excludeComponents: opts?.excludeComponents,
|
|
30518
30601
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
30519
|
-
where: opts?.where
|
|
30602
|
+
where: opts?.where,
|
|
30603
|
+
sinceRepoSeq: opts?.sinceRepoSeq
|
|
30520
30604
|
});
|
|
30521
30605
|
} catch (error) {
|
|
30522
30606
|
throw toWarmHubError(error);
|
|
@@ -31044,6 +31128,7 @@ var _orgActivityNeedsNoFilter = ["org.member_added", "org.repo_created", "org.re
|
|
|
31044
31128
|
}));
|
|
31045
31129
|
|
|
31046
31130
|
// ../../packages/warmhub-cli/src/errors-classification.ts
|
|
31131
|
+
var INCREMENTAL_READ_UNAVAILABLE_GUIDANCE = "Retry the same incremental request after incremental reads are enabled, or simplify the query to a supported form. Do not fall back to a full read.";
|
|
31047
31132
|
function unauthenticatedHint(message) {
|
|
31048
31133
|
if (message.includes("Authentication required")) {
|
|
31049
31134
|
return "Not logged in. Run `wh auth login` to authenticate.";
|
|
@@ -31070,6 +31155,8 @@ function classifyConflict(message, code) {
|
|
|
31070
31155
|
return "pending-delete";
|
|
31071
31156
|
case "LEASE_UNAVAILABLE":
|
|
31072
31157
|
return "lease-held";
|
|
31158
|
+
case "INCREMENTAL_READ_UNAVAILABLE":
|
|
31159
|
+
return "incremental-read-unavailable";
|
|
31073
31160
|
default:
|
|
31074
31161
|
break;
|
|
31075
31162
|
}
|
|
@@ -31103,6 +31190,8 @@ function conflictHint(message, code) {
|
|
|
31103
31190
|
return "Repo is being deleted. Wait for the delete to finish or cancel it before retrying.";
|
|
31104
31191
|
case "lease-held":
|
|
31105
31192
|
return "This thing is leased by another holder. Back off until the lease expires (see leaseExpiresAt / retryAfter), then retry.";
|
|
31193
|
+
case "incremental-read-unavailable":
|
|
31194
|
+
return INCREMENTAL_READ_UNAVAILABLE_GUIDANCE;
|
|
31106
31195
|
case "other":
|
|
31107
31196
|
return "Resolve the conflicting existing state and try again.";
|
|
31108
31197
|
}
|
|
@@ -31130,7 +31219,8 @@ var CONFLICT_SHAPED_CODES = new Set([
|
|
|
31130
31219
|
"HAS_INBOUND_REFS",
|
|
31131
31220
|
"REPO_PENDING_DELETE",
|
|
31132
31221
|
"ALREADY_RETRACTED",
|
|
31133
|
-
"LEASE_UNAVAILABLE"
|
|
31222
|
+
"LEASE_UNAVAILABLE",
|
|
31223
|
+
"INCREMENTAL_READ_UNAVAILABLE"
|
|
31134
31224
|
]);
|
|
31135
31225
|
|
|
31136
31226
|
// ../../packages/warmhub-cli/src/errors-types.ts
|
|
@@ -31140,20 +31230,101 @@ class CliError extends Error {
|
|
|
31140
31230
|
cause;
|
|
31141
31231
|
hint;
|
|
31142
31232
|
backendCode;
|
|
31233
|
+
recovery;
|
|
31143
31234
|
context;
|
|
31144
|
-
constructor(code, kind, message, cause, hint, context, backendCode) {
|
|
31235
|
+
constructor(code, kind, message, cause, hint, context, backendCode, recovery) {
|
|
31145
31236
|
super(message);
|
|
31146
31237
|
this.code = code;
|
|
31147
31238
|
this.kind = kind;
|
|
31148
31239
|
this.cause = cause;
|
|
31149
31240
|
this.hint = hint;
|
|
31150
31241
|
this.backendCode = backendCode;
|
|
31242
|
+
this.recovery = recovery;
|
|
31151
31243
|
this.context = context;
|
|
31152
31244
|
}
|
|
31153
31245
|
get errorCode() {
|
|
31154
31246
|
return this.backendCode;
|
|
31155
31247
|
}
|
|
31156
31248
|
}
|
|
31249
|
+
|
|
31250
|
+
// ../../packages/warmhub-cli/src/stream-recovery.ts
|
|
31251
|
+
function failureCode(error) {
|
|
31252
|
+
if (typeof error !== "object" || error === null)
|
|
31253
|
+
return;
|
|
31254
|
+
const typed = error;
|
|
31255
|
+
if (typeof typed.errorCode === "string")
|
|
31256
|
+
return typed.errorCode;
|
|
31257
|
+
if (typeof typed.backendCode === "string")
|
|
31258
|
+
return typed.backendCode;
|
|
31259
|
+
if (typeof typed.data?.warmhub?.code === "string") {
|
|
31260
|
+
return typed.data.warmhub.code;
|
|
31261
|
+
}
|
|
31262
|
+
if (typeof typed.data?.code === "string")
|
|
31263
|
+
return typed.data.code;
|
|
31264
|
+
return failureCode(typed.cause);
|
|
31265
|
+
}
|
|
31266
|
+
function failureStatus(error) {
|
|
31267
|
+
if (typeof error !== "object" || error === null)
|
|
31268
|
+
return;
|
|
31269
|
+
const typed = error;
|
|
31270
|
+
if (typeof typed.status === "number")
|
|
31271
|
+
return typed.status;
|
|
31272
|
+
if (typeof typed.data?.warmhub?.status === "number") {
|
|
31273
|
+
return typed.data.warmhub.status;
|
|
31274
|
+
}
|
|
31275
|
+
if (typeof typed.data?.status === "number")
|
|
31276
|
+
return typed.data.status;
|
|
31277
|
+
if (typeof typed.data?.httpStatus === "number") {
|
|
31278
|
+
return typed.data.httpStatus;
|
|
31279
|
+
}
|
|
31280
|
+
return failureStatus(typed.cause);
|
|
31281
|
+
}
|
|
31282
|
+
function streamAppendWasExplicitlyRejected(cause) {
|
|
31283
|
+
const normalized = toWarmHubError(cause);
|
|
31284
|
+
const code = failureCode(cause) ?? normalized.errorCode ?? normalized.code;
|
|
31285
|
+
if (code === "COMMIT_OUTCOME_UNKNOWN")
|
|
31286
|
+
return false;
|
|
31287
|
+
const status = failureStatus(cause) ?? normalized.status;
|
|
31288
|
+
return status !== undefined && status >= 400 && status < 500 && status !== 408;
|
|
31289
|
+
}
|
|
31290
|
+
function streamFailureCode(cause) {
|
|
31291
|
+
const normalized = toWarmHubError(cause);
|
|
31292
|
+
const wireCode = failureCode(cause) ?? normalized.errorCode;
|
|
31293
|
+
if (wireCode !== undefined)
|
|
31294
|
+
return wireCode;
|
|
31295
|
+
return normalized.status !== undefined && normalized.code !== "BACKEND" ? normalized.code : undefined;
|
|
31296
|
+
}
|
|
31297
|
+
function buildStreamRecoveryReceipt(args) {
|
|
31298
|
+
const {
|
|
31299
|
+
acknowledgedOperationCount,
|
|
31300
|
+
lastAcknowledgedRepoSeq,
|
|
31301
|
+
cause,
|
|
31302
|
+
attemptedAppendOutcome
|
|
31303
|
+
} = args;
|
|
31304
|
+
const sequenceReceipt = lastAcknowledgedRepoSeq === undefined ? "" : ` Last acknowledged repo sequence: ${lastAcknowledgedRepoSeq}.`;
|
|
31305
|
+
const errorCode = streamFailureCode(cause);
|
|
31306
|
+
const backendSuffix = errorCode ? ` (backend: ${errorCode})` : "";
|
|
31307
|
+
const recovery = {
|
|
31308
|
+
acknowledgedOperationCount,
|
|
31309
|
+
...lastAcknowledgedRepoSeq === undefined ? {} : { lastAcknowledgedRepoSeq },
|
|
31310
|
+
attemptedAppendOutcome
|
|
31311
|
+
};
|
|
31312
|
+
if (attemptedAppendOutcome === "unknown") {
|
|
31313
|
+
return {
|
|
31314
|
+
message: `Stream append outcome is unknown after ${acknowledgedOperationCount} acknowledged operation(s).${sequenceReceipt}${backendSuffix}`,
|
|
31315
|
+
hint: "Stop submitting writes. The attempted append may have landed after the last acknowledgement; once it can no longer apply, obtain and verify a later checkpoint, then reconcile the attempted append and unsent work.",
|
|
31316
|
+
errorCode,
|
|
31317
|
+
recovery
|
|
31318
|
+
};
|
|
31319
|
+
}
|
|
31320
|
+
const causeMessage = cause instanceof Error ? cause.message : String(cause);
|
|
31321
|
+
return {
|
|
31322
|
+
message: `${causeMessage} (${acknowledgedOperationCount} earlier operation(s) already acknowledged before this failure).${sequenceReceipt}${backendSuffix}`,
|
|
31323
|
+
hint: "The failed input or rejected append was not applied. Keep the acknowledged prefix receipt, then correct or replan the rejected and unsent operations.",
|
|
31324
|
+
errorCode,
|
|
31325
|
+
recovery
|
|
31326
|
+
};
|
|
31327
|
+
}
|
|
31157
31328
|
// ../../packages/warmhub-cli/src/errors-logging.ts
|
|
31158
31329
|
function shouldLogToErrorTier(err) {
|
|
31159
31330
|
switch (err.kind) {
|
|
@@ -31274,6 +31445,11 @@ function generateSuggestions(code, message, context, errorCode) {
|
|
|
31274
31445
|
action: "Another holder leased this thing. Back off until the lease expires (leaseExpiresAt / retryAfter), then retry"
|
|
31275
31446
|
});
|
|
31276
31447
|
break;
|
|
31448
|
+
case "incremental-read-unavailable":
|
|
31449
|
+
suggestions.push({
|
|
31450
|
+
action: INCREMENTAL_READ_UNAVAILABLE_GUIDANCE
|
|
31451
|
+
});
|
|
31452
|
+
break;
|
|
31277
31453
|
case "other":
|
|
31278
31454
|
suggestions.push({
|
|
31279
31455
|
action: "Resolve the conflicting existing state and retry"
|
|
@@ -31373,7 +31549,8 @@ function printCliError(err, errWriter, opts = {}) {
|
|
|
31373
31549
|
message: err.message,
|
|
31374
31550
|
...err.hint ? { hint: err.hint } : {},
|
|
31375
31551
|
...suggestions.length > 0 ? { suggestions } : {},
|
|
31376
|
-
...err.context ? { context: err.context } : {}
|
|
31552
|
+
...err.context ? { context: err.context } : {},
|
|
31553
|
+
...err.recovery ? { recovery: err.recovery } : {}
|
|
31377
31554
|
}
|
|
31378
31555
|
};
|
|
31379
31556
|
errWriter(JSON.stringify(envelope));
|
|
@@ -31413,8 +31590,13 @@ function toCliError(err) {
|
|
|
31413
31590
|
return cliErrorFromAllFailed(err.operations);
|
|
31414
31591
|
}
|
|
31415
31592
|
if (err instanceof PartialStreamSubmissionError) {
|
|
31416
|
-
const
|
|
31417
|
-
|
|
31593
|
+
const receipt = buildStreamRecoveryReceipt({
|
|
31594
|
+
acknowledgedOperationCount: err.acknowledgedOperationCount,
|
|
31595
|
+
lastAcknowledgedRepoSeq: err.lastAcknowledgedRepoSeq,
|
|
31596
|
+
cause: err.cause,
|
|
31597
|
+
attemptedAppendOutcome: err.attemptedAppendOutcome
|
|
31598
|
+
});
|
|
31599
|
+
return new CliError(4 /* Backend */, "BACKEND", receipt.message, err, receipt.hint, undefined, receipt.errorCode, receipt.recovery);
|
|
31418
31600
|
}
|
|
31419
31601
|
if (err instanceof WarmHubError) {
|
|
31420
31602
|
if (err.code === "CURSOR_EPOCH_INVALID" || err.errorCode === "CURSOR_EPOCH_INVALID") {
|
|
@@ -34886,6 +35068,7 @@ function pageEnvelope(items, opts) {
|
|
|
34886
35068
|
const nextCursor = opts.nextCursor ?? null;
|
|
34887
35069
|
return {
|
|
34888
35070
|
items,
|
|
35071
|
+
...opts.repoSeq === undefined ? {} : { repoSeq: opts.repoSeq },
|
|
34889
35072
|
page: {
|
|
34890
35073
|
limit: opts.limit,
|
|
34891
35074
|
count: items.length,
|
|
@@ -35038,6 +35221,9 @@ var reviseFlags = {
|
|
|
35038
35221
|
};
|
|
35039
35222
|
var retractFlags = {
|
|
35040
35223
|
reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
|
|
35224
|
+
"expected-version": flag.number({
|
|
35225
|
+
description: "only retract if the target is still at this version (optimistic concurrency)"
|
|
35226
|
+
}),
|
|
35041
35227
|
message: flag.string({ short: "m", description: "Commit message" }),
|
|
35042
35228
|
committer: flag.string({
|
|
35043
35229
|
description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
|
|
@@ -35072,15 +35258,17 @@ var handleRevise = async (ctx, { flags, args }) => {
|
|
|
35072
35258
|
var handleRetract = async (ctx, { flags, args }) => {
|
|
35073
35259
|
const name = args[0];
|
|
35074
35260
|
if (!name) {
|
|
35075
|
-
usageError("Usage: wh assertion retract <wref> -m <message>", 'wh assertion retract Belief/cave-safe -m "withdraw claim"');
|
|
35261
|
+
usageError("Usage: wh assertion retract <wref> -m <message> [--expected-version <n>]", 'wh assertion retract Belief/cave-safe -m "withdraw claim"');
|
|
35076
35262
|
}
|
|
35077
35263
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
35264
|
+
const expectedVersion = parsePositiveIntFlag(flags["expected-version"], "--expected-version", "wh assertion retract Belief/cave-safe --expected-version 3");
|
|
35078
35265
|
const result = await ctx.client.commit.apply(org, repo, flags.message ?? `retract ${name}`, [
|
|
35079
35266
|
{
|
|
35080
35267
|
operation: "retract",
|
|
35081
35268
|
kind: "assertion",
|
|
35082
35269
|
name,
|
|
35083
|
-
...flags.reason ? { reason: flags.reason } : {}
|
|
35270
|
+
...flags.reason ? { reason: flags.reason } : {},
|
|
35271
|
+
...expectedVersion !== undefined ? { expectedVersion } : {}
|
|
35084
35272
|
}
|
|
35085
35273
|
], {
|
|
35086
35274
|
committer: flags.committer
|
|
@@ -35155,6 +35343,47 @@ function parseCollectionRoleFlag(value, example) {
|
|
|
35155
35343
|
return value;
|
|
35156
35344
|
usageError("Invalid --role. Expected from, to, or ends.", example);
|
|
35157
35345
|
}
|
|
35346
|
+
function parseSinceRepoSeqFlag(value) {
|
|
35347
|
+
if (value === undefined)
|
|
35348
|
+
return;
|
|
35349
|
+
if (Number.isSafeInteger(value) && value >= -1)
|
|
35350
|
+
return value;
|
|
35351
|
+
usageError("--since-repo-seq must be -1 or a nonnegative safe integer.", "wh thing list --since-repo-seq -1 --all --format json");
|
|
35352
|
+
}
|
|
35353
|
+
function requireIncrementalCheckpoint(repoSeq, required) {
|
|
35354
|
+
if (required && repoSeq === undefined) {
|
|
35355
|
+
throw new CliError(4 /* Backend */, "BACKEND", "Incremental read completed without repoSeq", undefined, "Retry the read. If the checkpoint remains absent, report a backend incremental-read contract violation.");
|
|
35356
|
+
}
|
|
35357
|
+
}
|
|
35358
|
+
async function collectThingPages(args) {
|
|
35359
|
+
const items = [];
|
|
35360
|
+
let cursor = args.initialCursor;
|
|
35361
|
+
const seenCursors = new Set(cursor ? [cursor] : []);
|
|
35362
|
+
while (true) {
|
|
35363
|
+
const page = await args.fetchPage(cursor);
|
|
35364
|
+
const pageItems = page.items ?? [];
|
|
35365
|
+
if (args.onPage) {
|
|
35366
|
+
if (!await args.onPage(pageItems)) {
|
|
35367
|
+
return { items, nextCursor: undefined };
|
|
35368
|
+
}
|
|
35369
|
+
} else {
|
|
35370
|
+
items.push(...pageItems);
|
|
35371
|
+
}
|
|
35372
|
+
if (!page.nextCursor) {
|
|
35373
|
+
requireIncrementalCheckpoint(page.repoSeq, args.requireRepoSeq);
|
|
35374
|
+
return {
|
|
35375
|
+
items,
|
|
35376
|
+
nextCursor: undefined,
|
|
35377
|
+
...page.repoSeq === undefined ? {} : { repoSeq: page.repoSeq }
|
|
35378
|
+
};
|
|
35379
|
+
}
|
|
35380
|
+
if (seenCursors.has(page.nextCursor)) {
|
|
35381
|
+
throw new CliError(4 /* Backend */, "BACKEND", `${args.title} pagination cursor repeated; aborting --all to avoid an infinite loop.`, undefined, "Retry without --all to fetch one page and inspect page.nextCursor. If cursors repeat, report this as a backend pagination issue.");
|
|
35382
|
+
}
|
|
35383
|
+
seenCursors.add(page.nextCursor);
|
|
35384
|
+
cursor = page.nextCursor;
|
|
35385
|
+
}
|
|
35386
|
+
}
|
|
35158
35387
|
async function handleCount(ctx, org, repo, opts) {
|
|
35159
35388
|
const result = await ctx.client.thing.count(org, repo, opts);
|
|
35160
35389
|
writeOutput(ctx, result, () => ctx.out(`${result.count}`));
|
|
@@ -36110,6 +36339,9 @@ var headFlags = {
|
|
|
36110
36339
|
description: "Max items per page (default: 50, max: 500)"
|
|
36111
36340
|
}),
|
|
36112
36341
|
cursor: flag.string({ description: "Opaque pagination cursor" }),
|
|
36342
|
+
"since-repo-seq": flag.number({
|
|
36343
|
+
description: "Return identities changed after this repository sequence"
|
|
36344
|
+
}),
|
|
36113
36345
|
all: flag.boolean({ description: "Fetch all pages" }),
|
|
36114
36346
|
match: flag.string({ description: "Filter by wref glob pattern" }),
|
|
36115
36347
|
count: flag.boolean({ description: "Return count of matching items" }),
|
|
@@ -36133,15 +36365,19 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
36133
36365
|
const kind = validateKind(flags.kind);
|
|
36134
36366
|
const limit = flags.limit;
|
|
36135
36367
|
const cursor = flags.cursor;
|
|
36368
|
+
const sinceRepoSeq = parseSinceRepoSeqFlag(flags["since-repo-seq"]);
|
|
36136
36369
|
const all = flags.all;
|
|
36137
36370
|
const match = flags.match;
|
|
36138
36371
|
const count = flags.count;
|
|
36139
36372
|
const includeRetracted = flags["include-retracted"];
|
|
36140
36373
|
const whereRaw = flags.where ?? [];
|
|
36141
36374
|
const where = whereRaw.map(parseWhereFlag);
|
|
36375
|
+
if (ctx.liveMode && sinceRepoSeq !== undefined) {
|
|
36376
|
+
usageError("--since-repo-seq cannot be used with --live.", "wh thing list --since-repo-seq 42 --all --format json");
|
|
36377
|
+
}
|
|
36142
36378
|
if (count) {
|
|
36143
36379
|
if (cursor || all || limit || ctx.liveMode) {
|
|
36144
|
-
usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN]", "wh thing list --shape Player --count");
|
|
36380
|
+
usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN] [--since-repo-seq N]", "wh thing list --shape Player --count --since-repo-seq 42");
|
|
36145
36381
|
}
|
|
36146
36382
|
const componentRef2 = flags.component;
|
|
36147
36383
|
const strictExclude2 = !!flags["exclude-components"];
|
|
@@ -36154,7 +36390,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
36154
36390
|
componentRef: componentRef2,
|
|
36155
36391
|
excludeComponents: strictExclude2,
|
|
36156
36392
|
excludeInfraShapes: !strictExclude2 && !shape,
|
|
36157
|
-
where: where.length > 0 ? where : undefined
|
|
36393
|
+
where: where.length > 0 ? where : undefined,
|
|
36394
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36158
36395
|
});
|
|
36159
36396
|
}
|
|
36160
36397
|
if (cursor && !limit) {
|
|
@@ -36181,7 +36418,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
36181
36418
|
componentRef,
|
|
36182
36419
|
excludeComponents,
|
|
36183
36420
|
excludeInfraShapes,
|
|
36184
|
-
where: where.length > 0 ? where : undefined
|
|
36421
|
+
where: where.length > 0 ? where : undefined,
|
|
36422
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36185
36423
|
};
|
|
36186
36424
|
if (ctx.liveMode) {
|
|
36187
36425
|
await runLive({
|
|
@@ -36214,7 +36452,8 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
36214
36452
|
componentRef,
|
|
36215
36453
|
excludeComponents,
|
|
36216
36454
|
excludeInfraShapes,
|
|
36217
|
-
where: where.length > 0 ? where : undefined
|
|
36455
|
+
where: where.length > 0 ? where : undefined,
|
|
36456
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36218
36457
|
}, streamJsonl ? async (items) => {
|
|
36219
36458
|
writePageOutput(ctx, items, { limit: pageLimit }, () => {});
|
|
36220
36459
|
return await ctx.flushOut?.() ?? true;
|
|
@@ -36228,23 +36467,25 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
36228
36467
|
componentRef,
|
|
36229
36468
|
excludeComponents,
|
|
36230
36469
|
excludeInfraShapes,
|
|
36231
|
-
where: where.length > 0 ? where : undefined
|
|
36470
|
+
where: where.length > 0 ? where : undefined,
|
|
36471
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36232
36472
|
});
|
|
36233
36473
|
if (streamJsonl)
|
|
36234
36474
|
return;
|
|
36475
|
+
requireIncrementalCheckpoint(result.repoSeq, sinceRepoSeq !== undefined && !result.nextCursor);
|
|
36235
36476
|
if (!all && result.nextCursor) {
|
|
36236
36477
|
emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
|
|
36237
36478
|
}
|
|
36238
36479
|
writePageOutput(ctx, result.items ?? [], {
|
|
36239
36480
|
limit: all ? pageLimit : boundedLimit,
|
|
36240
|
-
nextCursor: result.nextCursor ?? null
|
|
36481
|
+
nextCursor: result.nextCursor ?? null,
|
|
36482
|
+
...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq }
|
|
36241
36483
|
}, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
|
|
36242
36484
|
};
|
|
36243
36485
|
async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
|
|
36244
|
-
|
|
36245
|
-
|
|
36246
|
-
|
|
36247
|
-
const page = await ctx.client.thing.head(org, repo, {
|
|
36486
|
+
return collectThingPages({
|
|
36487
|
+
initialCursor: opts.cursor,
|
|
36488
|
+
fetchPage: (cursor) => ctx.client.thing.head(org, repo, {
|
|
36248
36489
|
shape: opts.shape,
|
|
36249
36490
|
kind: opts.kind,
|
|
36250
36491
|
match: opts.match,
|
|
@@ -36254,20 +36495,13 @@ async function fetchAllHeadPages(ctx, org, repo, opts, onPage) {
|
|
|
36254
36495
|
componentRef: opts.componentRef,
|
|
36255
36496
|
excludeComponents: opts.excludeComponents,
|
|
36256
36497
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
36257
|
-
where: opts.where
|
|
36258
|
-
|
|
36259
|
-
|
|
36260
|
-
|
|
36261
|
-
|
|
36262
|
-
|
|
36263
|
-
|
|
36264
|
-
items.push(...pageItems);
|
|
36265
|
-
}
|
|
36266
|
-
if (!page.nextCursor)
|
|
36267
|
-
break;
|
|
36268
|
-
cursor = page.nextCursor;
|
|
36269
|
-
}
|
|
36270
|
-
return { items, nextCursor: undefined };
|
|
36498
|
+
where: opts.where,
|
|
36499
|
+
...opts.sinceRepoSeq === undefined ? {} : { sinceRepoSeq: opts.sinceRepoSeq }
|
|
36500
|
+
}),
|
|
36501
|
+
onPage,
|
|
36502
|
+
requireRepoSeq: opts.sinceRepoSeq !== undefined,
|
|
36503
|
+
title: "Thing list"
|
|
36504
|
+
});
|
|
36271
36505
|
}
|
|
36272
36506
|
|
|
36273
36507
|
// ../../packages/warmhub-cli/src/domains/thing/query.ts
|
|
@@ -36279,6 +36513,9 @@ var queryFlags = {
|
|
|
36279
36513
|
description: "Max results per page (default: 50, max: 500)"
|
|
36280
36514
|
}),
|
|
36281
36515
|
cursor: flag.string({ description: "Opaque pagination cursor" }),
|
|
36516
|
+
"since-repo-seq": flag.number({
|
|
36517
|
+
description: "Return identities changed after this repository sequence"
|
|
36518
|
+
}),
|
|
36282
36519
|
all: flag.boolean({ description: "Fetch all pages" }),
|
|
36283
36520
|
match: flag.string({ description: "Filter by wref glob pattern" }),
|
|
36284
36521
|
count: flag.boolean({ description: "Return count of matching items" }),
|
|
@@ -36309,6 +36546,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36309
36546
|
const kind = validateKind(flags.kind);
|
|
36310
36547
|
const limit = flags.limit;
|
|
36311
36548
|
const cursor = flags.cursor;
|
|
36549
|
+
const sinceRepoSeq = parseSinceRepoSeqFlag(flags["since-repo-seq"]);
|
|
36312
36550
|
const all = flags.all;
|
|
36313
36551
|
const match = flags.match;
|
|
36314
36552
|
const count = flags.count;
|
|
@@ -36324,9 +36562,12 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36324
36562
|
const c = ctx.colors;
|
|
36325
36563
|
const whereRaw = flags.where ?? [];
|
|
36326
36564
|
const where = whereRaw.map(parseWhereFlag);
|
|
36565
|
+
if (ctx.liveMode && sinceRepoSeq !== undefined) {
|
|
36566
|
+
usageError("--since-repo-seq cannot be used with --live.", "wh thing query --since-repo-seq 42 --all --format json");
|
|
36567
|
+
}
|
|
36327
36568
|
if (count) {
|
|
36328
36569
|
if (cursor || all || limit || ctx.liveMode || role) {
|
|
36329
|
-
usageError("Usage: wh thing query --count [--shape SHAPE] [--about WREF] [--kind KIND] [--match PATTERN]", "wh thing query --kind assertion --about Player/alice --count");
|
|
36570
|
+
usageError("Usage: wh thing query --count [--shape SHAPE] [--about WREF] [--kind KIND] [--match PATTERN] [--since-repo-seq N]", "wh thing query --kind assertion --about Player/alice --count --since-repo-seq 42");
|
|
36330
36571
|
}
|
|
36331
36572
|
return handleCount(ctx, org, repo, {
|
|
36332
36573
|
shape,
|
|
@@ -36338,7 +36579,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36338
36579
|
componentRef,
|
|
36339
36580
|
excludeComponents,
|
|
36340
36581
|
excludeInfraShapes,
|
|
36341
|
-
where: where.length > 0 ? where : undefined
|
|
36582
|
+
where: where.length > 0 ? where : undefined,
|
|
36583
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36342
36584
|
});
|
|
36343
36585
|
}
|
|
36344
36586
|
if (role && (!about || !resolveCollections)) {
|
|
@@ -36365,7 +36607,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36365
36607
|
componentRef,
|
|
36366
36608
|
excludeComponents,
|
|
36367
36609
|
excludeInfraShapes,
|
|
36368
|
-
where: where.length > 0 ? where : undefined
|
|
36610
|
+
where: where.length > 0 ? where : undefined,
|
|
36611
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36369
36612
|
};
|
|
36370
36613
|
if (ctx.liveMode) {
|
|
36371
36614
|
await runLive({
|
|
@@ -36401,7 +36644,8 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36401
36644
|
componentRef,
|
|
36402
36645
|
excludeComponents,
|
|
36403
36646
|
excludeInfraShapes,
|
|
36404
|
-
where: where.length > 0 ? where : undefined
|
|
36647
|
+
where: where.length > 0 ? where : undefined,
|
|
36648
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36405
36649
|
}, streamJsonl ? async (items) => {
|
|
36406
36650
|
writePageOutput(ctx, items, { limit: pageLimit }, () => {});
|
|
36407
36651
|
return await ctx.flushOut?.() ?? true;
|
|
@@ -36418,23 +36662,25 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
36418
36662
|
componentRef,
|
|
36419
36663
|
excludeComponents,
|
|
36420
36664
|
excludeInfraShapes,
|
|
36421
|
-
where: where.length > 0 ? where : undefined
|
|
36665
|
+
where: where.length > 0 ? where : undefined,
|
|
36666
|
+
...sinceRepoSeq === undefined ? {} : { sinceRepoSeq }
|
|
36422
36667
|
});
|
|
36423
36668
|
if (streamJsonl)
|
|
36424
36669
|
return;
|
|
36670
|
+
requireIncrementalCheckpoint(result.repoSeq, sinceRepoSeq !== undefined && !result.nextCursor);
|
|
36425
36671
|
if (!all && result.nextCursor) {
|
|
36426
36672
|
emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
|
|
36427
36673
|
}
|
|
36428
36674
|
writePageOutput(ctx, result.items ?? [], {
|
|
36429
36675
|
limit: all ? pageLimit : boundedLimit,
|
|
36430
|
-
nextCursor: result.nextCursor ?? null
|
|
36676
|
+
nextCursor: result.nextCursor ?? null,
|
|
36677
|
+
...result.repoSeq === undefined ? {} : { repoSeq: result.repoSeq }
|
|
36431
36678
|
}, () => renderQueryResults(ctx.out, c, result));
|
|
36432
36679
|
};
|
|
36433
36680
|
async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
|
|
36434
|
-
|
|
36435
|
-
|
|
36436
|
-
|
|
36437
|
-
const page = await ctx.client.thing.query(org, repo, {
|
|
36681
|
+
return collectThingPages({
|
|
36682
|
+
initialCursor: opts.cursor,
|
|
36683
|
+
fetchPage: (cursor) => ctx.client.thing.query(org, repo, {
|
|
36438
36684
|
shape: opts.shape,
|
|
36439
36685
|
about: opts.about,
|
|
36440
36686
|
kind: opts.kind,
|
|
@@ -36447,20 +36693,13 @@ async function fetchAllQueryPages(ctx, org, repo, opts, onPage) {
|
|
|
36447
36693
|
componentRef: opts.componentRef,
|
|
36448
36694
|
excludeComponents: opts.excludeComponents,
|
|
36449
36695
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
36450
|
-
where: opts.where
|
|
36451
|
-
|
|
36452
|
-
|
|
36453
|
-
|
|
36454
|
-
|
|
36455
|
-
|
|
36456
|
-
|
|
36457
|
-
items.push(...pageItems);
|
|
36458
|
-
}
|
|
36459
|
-
if (!page.nextCursor)
|
|
36460
|
-
break;
|
|
36461
|
-
cursor = page.nextCursor;
|
|
36462
|
-
}
|
|
36463
|
-
return { items, nextCursor: undefined };
|
|
36696
|
+
where: opts.where,
|
|
36697
|
+
...opts.sinceRepoSeq === undefined ? {} : { sinceRepoSeq: opts.sinceRepoSeq }
|
|
36698
|
+
}),
|
|
36699
|
+
onPage,
|
|
36700
|
+
requireRepoSeq: opts.sinceRepoSeq !== undefined,
|
|
36701
|
+
title: "Thing query"
|
|
36702
|
+
});
|
|
36464
36703
|
}
|
|
36465
36704
|
function renderQueryResults(out, c, result) {
|
|
36466
36705
|
const items = result.items ?? [];
|
|
@@ -36629,6 +36868,9 @@ var retractFlags2 = {
|
|
|
36629
36868
|
description: "Optional safety check: thing|assertion|shape|collection (errors on mismatch)"
|
|
36630
36869
|
}),
|
|
36631
36870
|
reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
|
|
36871
|
+
"expected-version": flag.number({
|
|
36872
|
+
description: "only retract if the target is still at this version (optimistic concurrency)"
|
|
36873
|
+
}),
|
|
36632
36874
|
message: flag.string({ short: "m", description: "Commit message" }),
|
|
36633
36875
|
committer: flag.string({
|
|
36634
36876
|
description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
|
|
@@ -36640,13 +36882,14 @@ var retractFlags2 = {
|
|
|
36640
36882
|
var handleThingRetract = async (ctx, { flags, args }) => {
|
|
36641
36883
|
const name = args[0];
|
|
36642
36884
|
if (!name) {
|
|
36643
|
-
usageError("Usage: wh thing retract <wref> -m <message> [--reason <text>] [--kind thing|assertion|shape|collection]", 'wh thing retract Measurement/m1 -m "cleanup" --reason "bad source"');
|
|
36885
|
+
usageError("Usage: wh thing retract <wref> -m <message> [--reason <text>] [--kind thing|assertion|shape|collection] [--expected-version <n>]", 'wh thing retract Measurement/m1 -m "cleanup" --reason "bad source"');
|
|
36644
36886
|
}
|
|
36645
36887
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
36646
36888
|
const committer = flags.committer;
|
|
36647
36889
|
const message = flags.message;
|
|
36648
36890
|
const kind = flags.kind;
|
|
36649
36891
|
const reason = flags.reason;
|
|
36892
|
+
const expectedVersion = parsePositiveIntFlag(flags["expected-version"], "--expected-version", "wh thing retract Player/alice --expected-version 3");
|
|
36650
36893
|
const leaseId = requireLeaseIdFlag(flags["lease-id"], "wh thing retract Player/alice --lease-id <id>");
|
|
36651
36894
|
const c = ctx.colors;
|
|
36652
36895
|
const result = await ctx.client.commit.apply(org, repo, message ?? `retract ${name}`, [
|
|
@@ -36655,6 +36898,7 @@ var handleThingRetract = async (ctx, { flags, args }) => {
|
|
|
36655
36898
|
name,
|
|
36656
36899
|
...kind ? { kind } : {},
|
|
36657
36900
|
...reason ? { reason } : {},
|
|
36901
|
+
...expectedVersion !== undefined ? { expectedVersion } : {},
|
|
36658
36902
|
...leaseId ? { leaseId } : {}
|
|
36659
36903
|
}
|
|
36660
36904
|
], { committer });
|
|
@@ -36842,6 +37086,9 @@ async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
|
|
|
36842
37086
|
// ../../packages/warmhub-cli/src/domains/thing/view.ts
|
|
36843
37087
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
36844
37088
|
|
|
37089
|
+
// ../../packages/rules/src/read-limits.ts
|
|
37090
|
+
var MAX_GET_MANY_WREFS2 = 500;
|
|
37091
|
+
|
|
36845
37092
|
// ../../packages/warmhub-cli/src/io.ts
|
|
36846
37093
|
function isBrokenPipe(error) {
|
|
36847
37094
|
return error instanceof Error && "code" in error && error.code === "EPIPE";
|
|
@@ -37078,8 +37325,8 @@ var handleView = async (ctx, { flags, args, terminator }) => {
|
|
|
37078
37325
|
if (wrefs.length === 0) {
|
|
37079
37326
|
throw new CliError(2 /* UserInput */, "USER_INPUT", "Missing required <wref>. Pass a wref as a positional arg, via --file <path>, or pipe newline-delimited wrefs on stdin.", undefined, "Example: wh thing view Game/base --depth 2");
|
|
37080
37327
|
}
|
|
37081
|
-
if (wrefs.length >
|
|
37082
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Too many wrefs: ${wrefs.length} (max ${
|
|
37328
|
+
if (wrefs.length > MAX_GET_MANY_WREFS2) {
|
|
37329
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Too many wrefs: ${wrefs.length} (max ${MAX_GET_MANY_WREFS2} per call).`, undefined, `Split your input into chunks of ${MAX_GET_MANY_WREFS2} or fewer.`);
|
|
37083
37330
|
}
|
|
37084
37331
|
const isBatch = wrefs.length > 1 || flags.file !== undefined;
|
|
37085
37332
|
if (isBatch && flags.depth !== undefined) {
|
|
@@ -39236,7 +39483,7 @@ var createFlags3 = {
|
|
|
39236
39483
|
description: "collection members (comma-separated wrefs)"
|
|
39237
39484
|
}),
|
|
39238
39485
|
"expected-version": flag.number({
|
|
39239
|
-
description: "
|
|
39486
|
+
description: "only apply if the --revise or single --retract target is still at this version (optimistic concurrency)."
|
|
39240
39487
|
}),
|
|
39241
39488
|
"lease-id": flag.string({
|
|
39242
39489
|
description: "read-lease token from `wh thing lease`, bound to --revise or one --retract target (auto-released on success)"
|
|
@@ -39499,7 +39746,7 @@ function buildAddOperations(input) {
|
|
|
39499
39746
|
});
|
|
39500
39747
|
}
|
|
39501
39748
|
function buildRetractOperations(input) {
|
|
39502
|
-
const { retractNames, kinds, reasons, leaseId } = input;
|
|
39749
|
+
const { retractNames, kinds, reasons, expectedVersion, leaseId } = input;
|
|
39503
39750
|
if (leaseId !== undefined && retractNames.length !== 1) {
|
|
39504
39751
|
throw new CliError(2 /* UserInput */, "USER_INPUT", `--lease-id requires exactly one --retract target; received ${retractNames.length}.`, undefined, "wh commit submit --retract Player/alice --lease-id lease-xyz --repo acme/world");
|
|
39505
39752
|
}
|
|
@@ -39529,6 +39776,7 @@ function buildRetractOperations(input) {
|
|
|
39529
39776
|
name,
|
|
39530
39777
|
...kind ? { kind } : {},
|
|
39531
39778
|
...reason ? { reason } : {},
|
|
39779
|
+
...expectedVersion !== undefined ? { expectedVersion } : {},
|
|
39532
39780
|
...leaseId ? { leaseId } : {}
|
|
39533
39781
|
};
|
|
39534
39782
|
});
|
|
@@ -39628,15 +39876,14 @@ import { createInterface as createInterface2 } from "node:readline";
|
|
|
39628
39876
|
class JsonlPartialSubmissionError extends CliError {
|
|
39629
39877
|
}
|
|
39630
39878
|
function jsonlPartialSubmissionError(args) {
|
|
39631
|
-
const
|
|
39632
|
-
|
|
39633
|
-
|
|
39634
|
-
|
|
39635
|
-
|
|
39636
|
-
}
|
|
39637
|
-
const
|
|
39638
|
-
|
|
39639
|
-
return new JsonlPartialSubmissionError(4 /* Backend */, "BACKEND", `${message} (${acknowledgedOperationCount} earlier operation(s) already acknowledged by the server before this input failure).`, cause, `${causeHint}Earlier chunks have landed; inspect repository state before submitting any remaining JSONL operations.`);
|
|
39879
|
+
const receipt = buildStreamRecoveryReceipt({
|
|
39880
|
+
acknowledgedOperationCount: args.acknowledgedOperationCount,
|
|
39881
|
+
lastAcknowledgedRepoSeq: args.lastAcknowledgedRepoSeq,
|
|
39882
|
+
cause: args.cause,
|
|
39883
|
+
attemptedAppendOutcome: args.failedAppendMayHaveLanded === true ? "unknown" : "not_applied"
|
|
39884
|
+
});
|
|
39885
|
+
const causeHint = args.cause instanceof CliError && args.cause.hint ? `${args.cause.hint} ` : "";
|
|
39886
|
+
return new JsonlPartialSubmissionError(4 /* Backend */, "BACKEND", receipt.message, args.cause, `${causeHint}${receipt.hint}`, undefined, receipt.errorCode, receipt.recovery);
|
|
39640
39887
|
}
|
|
39641
39888
|
|
|
39642
39889
|
// ../../packages/warmhub-cli/src/domains/commit-submit-utils.ts
|
|
@@ -39721,50 +39968,6 @@ function toCommitSubmitResult(args) {
|
|
|
39721
39968
|
operations
|
|
39722
39969
|
};
|
|
39723
39970
|
}
|
|
39724
|
-
function backendErrorCode(error) {
|
|
39725
|
-
if (typeof error !== "object" || error === null) {
|
|
39726
|
-
return;
|
|
39727
|
-
}
|
|
39728
|
-
const typed = error;
|
|
39729
|
-
if (typeof typed.data === "object" && typed.data !== null) {
|
|
39730
|
-
const data = typed.data;
|
|
39731
|
-
if (typeof data.code === "string") {
|
|
39732
|
-
return data.code;
|
|
39733
|
-
}
|
|
39734
|
-
}
|
|
39735
|
-
const causeCode = backendErrorCode(typed.cause);
|
|
39736
|
-
if (causeCode !== undefined) {
|
|
39737
|
-
return causeCode;
|
|
39738
|
-
}
|
|
39739
|
-
return typeof typed.code === "string" ? typed.code : undefined;
|
|
39740
|
-
}
|
|
39741
|
-
function backendErrorStatus(error) {
|
|
39742
|
-
if (typeof error !== "object" || error === null) {
|
|
39743
|
-
return;
|
|
39744
|
-
}
|
|
39745
|
-
const typed = error;
|
|
39746
|
-
if (typeof typed.status === "number") {
|
|
39747
|
-
return typed.status;
|
|
39748
|
-
}
|
|
39749
|
-
if (typeof typed.data === "object" && typed.data !== null) {
|
|
39750
|
-
const data = typed.data;
|
|
39751
|
-
if (typeof data.status === "number") {
|
|
39752
|
-
return data.status;
|
|
39753
|
-
}
|
|
39754
|
-
if (typeof data.httpStatus === "number") {
|
|
39755
|
-
return data.httpStatus;
|
|
39756
|
-
}
|
|
39757
|
-
if (typeof data.warmhub?.status === "number") {
|
|
39758
|
-
return data.warmhub.status;
|
|
39759
|
-
}
|
|
39760
|
-
}
|
|
39761
|
-
return backendErrorStatus(typed.cause);
|
|
39762
|
-
}
|
|
39763
|
-
function firstJsonlAppendErrorMayHaveCommitted(error) {
|
|
39764
|
-
const errorCode = backendErrorCode(error);
|
|
39765
|
-
const errorStatus = backendErrorStatus(error);
|
|
39766
|
-
return errorCode === undefined || errorCode === "COMMIT_OUTCOME_UNKNOWN" || errorCode === "INTERNAL_ERROR" || errorCode === "NETWORK" || errorCode === "SERVICE_UNAVAILABLE" || errorCode === "BACKEND" && errorStatus !== undefined && errorStatus >= 500;
|
|
39767
|
-
}
|
|
39768
39971
|
|
|
39769
39972
|
// ../../packages/warmhub-cli/src/domains/stream-progress.ts
|
|
39770
39973
|
import { createReadStream } from "node:fs";
|
|
@@ -39949,12 +40152,12 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
39949
40152
|
const tAppendStart = performance.now();
|
|
39950
40153
|
progress.start(t0);
|
|
39951
40154
|
let opCount = 0;
|
|
40155
|
+
let repoSeq;
|
|
39952
40156
|
try {
|
|
39953
40157
|
const operations = [];
|
|
39954
40158
|
const submittedOperations = [];
|
|
39955
40159
|
let allocatedTokenRanges = [];
|
|
39956
40160
|
let createdByEmail;
|
|
39957
|
-
let repoSeq;
|
|
39958
40161
|
let parsedOpCount = 0;
|
|
39959
40162
|
let chunk = [];
|
|
39960
40163
|
let lineNumber = 0;
|
|
@@ -39977,11 +40180,13 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
39977
40180
|
});
|
|
39978
40181
|
} catch (cause) {
|
|
39979
40182
|
const completed = opCount;
|
|
39980
|
-
|
|
40183
|
+
const failedAppendMayHaveLanded = !streamAppendWasExplicitlyRejected(cause);
|
|
40184
|
+
if (opCount > 0 || failedAppendMayHaveLanded) {
|
|
39981
40185
|
throw jsonlPartialSubmissionError({
|
|
39982
40186
|
acknowledgedOperationCount: completed,
|
|
39983
40187
|
cause,
|
|
39984
|
-
failedAppendMayHaveLanded
|
|
40188
|
+
failedAppendMayHaveLanded,
|
|
40189
|
+
lastAcknowledgedRepoSeq: repoSeq
|
|
39985
40190
|
});
|
|
39986
40191
|
}
|
|
39987
40192
|
throw cause;
|
|
@@ -40176,7 +40381,8 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
40176
40381
|
}
|
|
40177
40382
|
throw jsonlPartialSubmissionError({
|
|
40178
40383
|
acknowledgedOperationCount: opCount,
|
|
40179
|
-
cause: error
|
|
40384
|
+
cause: error,
|
|
40385
|
+
lastAcknowledgedRepoSeq: repoSeq
|
|
40180
40386
|
});
|
|
40181
40387
|
}
|
|
40182
40388
|
}
|
|
@@ -40246,9 +40452,10 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
40246
40452
|
const abouts = flags.about ?? [];
|
|
40247
40453
|
const reasons = flags.reason ?? [];
|
|
40248
40454
|
const kinds = flags.kind ?? [];
|
|
40249
|
-
const
|
|
40250
|
-
|
|
40251
|
-
|
|
40455
|
+
const expectedVersionExample = retractNames.length > 0 ? "wh commit submit --retract Player/alice --expected-version 3" : "wh commit submit --revise Player/alice --data '{...}' --expected-version 3";
|
|
40456
|
+
const expectedVersion = parsePositiveIntFlag(flags["expected-version"], "--expected-version", expectedVersionExample);
|
|
40457
|
+
if (expectedVersion !== undefined && reviseName === undefined && retractNames.length !== 1) {
|
|
40458
|
+
usageError("--expected-version requires --revise or exactly one --retract", "wh commit submit --retract Player/alice --expected-version 3");
|
|
40252
40459
|
}
|
|
40253
40460
|
const leaseIdFlag = requireLeaseIdFlag(flags["lease-id"], `wh commit submit --revise Player/alice --data '{"score":2}' --lease-id <id>`);
|
|
40254
40461
|
if (leaseIdFlag !== undefined && reviseName === undefined && retractNames.length === 0) {
|
|
@@ -40372,6 +40579,7 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
40372
40579
|
retractNames,
|
|
40373
40580
|
kinds,
|
|
40374
40581
|
reasons,
|
|
40582
|
+
expectedVersion,
|
|
40375
40583
|
leaseId: leaseIdFlag
|
|
40376
40584
|
});
|
|
40377
40585
|
} else if (operationSource === "--revise") {
|
|
@@ -44293,7 +44501,7 @@ var ORG_DOMAIN = defineDomain({
|
|
|
44293
44501
|
});
|
|
44294
44502
|
|
|
44295
44503
|
// ../../packages/warmhub-cli/src/domains/prime-content.md
|
|
44296
|
-
var prime_content_default = "# WarmHub CLI Context\n> **Context Recovery**: Run `wh prime` after compaction or new session\n\n## Environment\n{{REPO_LINE}}\n\n## Core Concepts\n- **Thing**: A named entity versioned by writes. **Assertion**: A thing that makes a shape-validated claim about another thing.\n- **Shape**: A thing defining data structure; every other thing has one. **Write**: One or more add/revise/retract operations with per-operation results.\n- **wref**: A reference to a thing. Local: `Player` (the shape) or `Player/alice` (a thing with that shape). Cross-repo: `wh:org/repo/Shape` or `wh:org/repo/Shape/name`.\n\n## Versioned Wrefs\n- `Shape` addresses the shape itself; `Shape/name` addresses a thing with that shape. `@vN` pins either.\n- Floating write refs to retracted targets fail; existing pinned versions remain valid.\n- Rename invalidates old spellings, including `@vN`; the new name resolves history.\n- Untyped wrefs accept any thing. `wref<T>` requires the target's shape to be `T`; a shape has no shape, so never satisfies it. `wref?` coalesces only `thing_absent`, never a missing shape.\n\n## Key Workflows\n\n**Write data** (discover shapes → scaffold ops → submit):\n```bash\nwh shape list --repo org/repo # list available shapes\nwh shape view ShapeName --repo org/repo # inspect fields\nwh shape template ShapeName -o ops.json --repo org/repo # scaffold write ops (supports --kind assertion)\n# edit ops.json — fill FILL_IN placeholders — then:\nwh commit submit --file ops.json -m \"msg\" --repo org/repo # submit operations (bare `wh commit` also works)\n# or single assertion (no file needed):\nwh assertion create --shape ShapeName --about Target/name --name my-assertion --data '{\"field\":1}' --repo org/repo\n# Relay failed operation details when present. Never hand-guess ops JSON — use `wh shape template <Shape>`.\n```\n\n**Read data:**\n```bash\nwh thing list --repo org/repo # all things at HEAD\nwh thing view Shape/name --repo org/repo # inspect a thing\nwh thing query --shape MyShape --repo org/repo # find things by shape\nwh thing about Shape --repo org/repo # assertions about a shape\nwh assertion list --repo org/repo # all assertions at HEAD\nwh thing history Shape/name --repo org/repo # version history\n\n# Batch read — wh thing view is variadic (max 500 wrefs/call):\nwh thing view Player/alice Player/bob # variadic positionals\nwh thing view --file wrefs.txt --json # one wref per line\ncat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped* requested wref\n```\n\n## Wref Quick Reference\n\nWrites use explicit names and wrefs. Untyped fields, collection members,\nassertion `about`, and committers accept any thing. Create a deterministic\ntarget before referencing it in the same commit.\n\n## Command Reference\n\n**Global flags**: `--repo`, `--format`, `--json`, `--live`\n### thing — Thing operations\n- `wh thing list [--shape] [--kind] [--match] [--include-retracted]` — Current HEAD state\n- `wh thing view [<wref>...] [--file <path>] [--version] [--depth] [--include-retracted] [--data-mode auto|full]` — Thing details. Variadic (max 500). `--version` implies `--include-retracted`. Batch JSON returns `{ requested, items, missing }`; jsonl emits one row per deduped requested wref. Large Set/List bodies summarize by default; use `--data-mode full` for canonical collection JSON.\n- `wh thing history [wref] [--shape] [--about] [--include-retracted]` — Version history\n- `wh thing resolve <wref>` — Resolve a wref to its canonical thing identity\n- `wh thing create <name|Shape/name> (--data|--file) [--shape]` — Create\n- `wh thing revise <name> [--data] [--message] [--committer] [--expected-version]` — Revise (CONFLICT if HEAD≠n)\n- `wh thing retract <wref> -m <message> [--reason] [--kind]` — Retract\n- `wh thing query [--shape] [--kind] [--about] [--match]` — Query by filters\n- `wh thing search <query> [--shape] [--kind] [--about] [--mode]` — Search text\n- `wh thing rename <Shape/oldName> <newName>` — Rename\n- `wh thing refs <wref> [--inbound] [--outbound] [--field]` — Show field references; use `wh thing about` for assertions about the target thing\n- `wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--role from|to|ends] [--limit] [--include-retracted]` — Show assertions about the target identity; `--resolve-collections` expands bare/@HEAD/@ALL members, `--role` filters direction; not pinned @vN\n\n### commit — Write operations\n- `wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]` — Submit operations (bare `wh commit` is equivalent). Use `--file ops.jsonl --stream-id <id> --chunk-size 5000 --skip-existing` for bulk ingest.\n- `wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]` — Generate sample ops\n\n### assertion — Assertion operations\n- `wh assertion list [--about wref] [--shape] [--match] [--include-retracted]` — Browse assertions\n- `wh assertion view <wref> [--version] [--include-retracted]` — Assertion details\n- `wh assertion create --shape <s> --name <n> --about <wref> [--data] [-m] [--committer]` — Create assertion\n- `wh assertion revise <wref> --data <json> [--message] [--committer]` — Revise assertion\n- `wh assertion retract <wref> -m <message> [--reason] [--committer]` — Retract assertion\n- `wh assertion history <wref> [--include-retracted]` — Assertion history\n\n### shape — Shape management\n- `wh shape list [--match] [--include-retracted]` — List all shapes\n- `wh shape view <name> [--include-retracted]` — Shape details\n- `wh shape revise <name> (--fields|--file)`\n- `wh shape create <name> (--fields|--file)`\n- `wh shape retract <name> -m <message> [--reason]` — Retract shape\n- `wh shape history <name> [--include-retracted]` — Shape history\n- `wh shape rename <oldName> <newName>` — Rename shape\n\n### repo — Repository management\n- `wh repo create <org/name> [--display-name] [--description] [--visibility]` — Create repo\n- `wh repo list [org]` — List repos\n- `wh repo view [org/repo]` — Repo details\n\n### org — Organization management\n- `wh org create <name> [--display-name]` — Create a new organization\n- `wh org view <name>` — View organization details (alias: info)\n- `wh org list` — List all organizations\n\n### sub — Subscription management\n- `wh sub create <name> [flags]` — Create a subscription\n- `wh sub view <name>` — View subscription details\n- `wh sub list` — List all subscriptions\n- `wh sub log <name>` — Tail subscription delivery feed\n- `wh sub attempts <runId>` — Show attempt history for a run\n- `wh sub pause <name>` — Pause a subscription\n- `wh sub resume <name>` — Resume a paused subscription\n- `wh sub bind <name> [--credentials]` — Bind a credential set to a subscription for webhook auth\n- `wh sub unbind <name>` — Remove credential binding from a subscription\n- `wh sub delete <name>` — Delete a subscription\n\n### notifications — Action notification listing\n- `wh notifications [--limit] [--since]` — List repo-scoped action notifications\n\n### credential — Credential set management\n- `wh credential create <name> [--repo org/repo | --org org] [--scope] [--description]` — Create an empty credential set\n- `wh credential list [--repo org/repo | --org org]` — List credential sets accessible from a repo or org\n- `wh credential view <name> [--repo org/repo | --org org]` — View a credential set (key names only, no values)\n- `wh credential delete <name> [--repo org/repo | --org org]` — Delete a credential set and its Vault object\n- `wh credential set <setName> [<keyName>] [--repo org/repo | --org org] [--value]` — Set credential key(s). With `<keyName>`: single-key form (reads value from `--value` or stdin). Without `<keyName>`: batch form (reads JSON object from stdin, e.g. `{\"KEY\":\"val\"}`)\n- `wh credential unset <setName> <keyName> [--repo org/repo | --org org]` — Remove a key from a credential set\n- `wh credential audit <setName> [--repo org/repo | --org org]` — View audit log for a credential set\n- `wh credential revoke <setName> [--repo org/repo | --org org] [--reason]` — Revoke a credential set (blocks new binds and stops bound webhook deliveries)\n\n### component — Component management\n- `wh component validate <path>` — Validate package\n- `wh component install <org/name>` — Install a registered component\n- `wh component register <name> --org <org> --manifest <path> [flags]` — Register component identity\n- `wh component unregister <org/name>` — Remove a registered component identity\n- `wh component registry list --org <org>` — List registered components\n- `wh component registry view <org/name>` — View a registered component\n- `wh component registry update <org/name> [flags]` — Update a registered component\n- `wh component list` — List installed components\n- `wh component update <org/name>` — Update installed component\n- `wh component view <org/name>` — Show component details (alias: show)\n- `wh component doctor <org/name>` — Run component health checks\n- `wh component teardown <org/name>` — Pause component subscriptions\n\n### Getting More Info\n- `wh help` — help overview\n- `wh <domain>` — domain verbs\n- `wh <domain> <verb> --help` — verb flags and examples\n- `wh help --format json` — `CliSpecV2` (`schemaVersion: 2`): global/contextual/root tables and command overrides\n\n## Common Workflows\n\n**Explore a repo:**\n```bash\nwh thing list --repo org/repo # see all things in HEAD\nwh thing view Shape/name --repo org/repo # inspect a specific thing\nwh thing history Shape/name --repo org/repo # inspect version history\nwh thing about Shape/name # assertions about thing/shape\n```\n\n**Create an assertion** (most common write):\n```bash\n# --about takes an untyped target wref: Shape or Shape/name.\nwh assertion create --shape MyShape --about TargetShape/target-name \\\n --name my-assertion --data '{\"field_a\":1,\"field_b\":\"value\"}' --repo org/repo\n# Output includes per-operation status; relay failures when present.\n```\n\n**Create via write entrypoint** (alternative, supports batches and streams):\n```bash\nwh commit submit --add my-item --shape MyShape --kind assertion \\\n --about TargetShape/target-name --data '{\"field_a\":1}' --repo org/repo\n```\n\n**Batch write via file** (generate template → edit → submit):\n```bash\nwh shape template Hypothesis Evidence -o ops.json # add --kind assertion --about TargetShape/name for assertions\n# edit ops.json — fill FILL_IN placeholders\nwh commit submit --file ops.json -m \"batch update\" # submit all operations (bare `wh commit` is equivalent)\n# --file format: docs.warmhub.ai/cli-reference/commit-operations\n```\n\n**Bulk write (JSONL stream, >1k ops)** — one chunked stream beats per-record commits (~60× faster):\n```bash\nwh shape template MyShape -o ops.jsonl # one op per line (.jsonl)\nID=\"bulk-$(date +%s)\" # caller id for chunk correlation\nwh commit submit --file ops.jsonl --stream-id \"$ID\" --chunk-size 5000 \\\n --skip-existing --progress -m \"bulk ingest\" --repo org/repo\n# --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower\n# --skip-existing: skips already-written add ops (drops per-row read-before-write)\n# Add-only restart: rerun the WHOLE file. --skip-existing makes fixed-name adds\n# idempotent; --stream-id only identifies the submission. Mid-stream resume is\n# not a CLI mode. Revise/retract JSONL is not full-rerun safe after an ambiguous\n# append; inspect repo state and reconcile.\n```\n\n**Create collections:**\n```bash\nwh commit submit --type arc --name route --members Location/a,Location/b --repo org/repo\nwh assertion create --shape Supports --name route-support --about Arc/route --data '{\"confidence\":0.8}' --repo org/repo\n```\n\n**Modify data:**\n```bash\nwh thing revise Shape/name --data '{\"x\":5,\"y\":3}' -m \"update\" --repo org/repo\nwh thing retract Shape/old-item -m \"withdrawn\" --reason \"data feed contaminated\" --repo org/repo\n```\n\n**Query and filter:**\n```bash\nwh thing query --shape MyShape # by shape\nwh thing query --kind assertion --about Shape/name # by kind + target\nwh thing history Shape/name --limit 10 # version history\n```\n\n## Built-in Content shape\n\nWarmHub repos expose three well-known content wrefs:\n- `Content/Readme` — stored markdown for humans\n- `Content/Agents` — stored markdown guidance for AI agents\n- `Content/LlmsTxt` — synthesized per-request sitemap (read-only)\n\nFetch via `wh repo content get --kind readme|agents|llms-txt`,\n`client.repo.getReadme/getAgents/getLlmsTxt`, MCP `warmhub_repo_content_get`,\nor raw HTTP `GET /{org}/{repo}/readme.md|agents.md|llms.txt`.\nSee `wh repo describe` → `additionalInformation` for the discovery field.\n\n## Query Discipline\n- Plan the repo, shapes, and wrefs you need before the first query.\n- Gather the needed facts from one repo before switching to another.\n- Do the queries first, then write one complete answer.\n\n## Agent Tips\n- **Always run commands for live data** — this context describes the CLI, not repo contents\n- **Before writing, discover wrefs** — run `wh thing list` or `wh shape list`\n- **Shape field types**: `string`, `number`, `boolean`, `wref`, arrays, optionals, nested objects\n- **Write commands return per-operation results** — relay failures and affected wrefs to the user\n- **Pass data inline** with `--data '{...}'` — do NOT create temp files\n- Add `--json` to any command for machine-readable JSON output\n- **Aliases teach canonical commands** — executing aliases emit a status hint; misleading lifecycle aliases reject and point to `retract`\n- Writes go through `wh commit submit` (or bare `wh commit`) or wrappers (`create`, `revise`, `retract`, `assertion create`). `retract` irreversibly withdraws an identity and creates a history entry.\n- Use `wh doctor` to check environment health\n";
|
|
44504
|
+
var prime_content_default = "# WarmHub CLI Context\n> **Context Recovery**: Run `wh prime` after compaction or new session\n\n## Environment\n{{REPO_LINE}}\n\n## Core Concepts\n- **Thing**: A named entity versioned by writes. **Assertion**: A thing that makes a shape-validated claim about another thing.\n- **Shape**: A thing defining data structure; every other thing has one. **Write**: One or more add/revise/retract operations with per-operation results.\n- **wref**: A reference to a thing. Local: `Player` (the shape) or `Player/alice` (a thing with that shape). Cross-repo: `wh:org/repo/Shape` or `wh:org/repo/Shape/name`.\n\n## Versioned Wrefs\n- `Shape` addresses the shape itself; `Shape/name` addresses a thing with that shape. `@vN` pins either.\n- Floating write refs to retracted targets fail; existing pinned versions remain valid.\n- Rename invalidates old spellings, including `@vN`; the new name resolves history.\n- Untyped wrefs accept any thing. `wref<T>` requires the target's shape to be `T`; a shape has no shape, so never satisfies it. `wref?` coalesces only `thing_absent`, never a missing shape.\n\n## Key Workflows\n\n**Write data** (discover shapes → scaffold ops → submit):\n```bash\nwh shape list --repo org/repo # list available shapes\nwh shape view ShapeName --repo org/repo # inspect fields\nwh shape template ShapeName -o ops.json --repo org/repo # scaffold write ops (supports --kind assertion)\n# edit ops.json — fill FILL_IN placeholders — then:\nwh commit submit --file ops.json -m \"msg\" --repo org/repo # submit operations (bare `wh commit` also works)\n# or single assertion (no file needed):\nwh assertion create --shape ShapeName --about Target/name --name my-assertion --data '{\"field\":1}' --repo org/repo\n# Relay failed operation details when present. Never hand-guess ops JSON — use `wh shape template <Shape>`.\n```\n\n**Read data:**\n```bash\nwh thing list --repo org/repo # all things at HEAD\nwh thing view Shape/name --repo org/repo # inspect a thing\nwh thing query --shape MyShape --repo org/repo # find things by shape\nwh thing about Shape --repo org/repo # assertions about a shape\nwh assertion list --repo org/repo # all assertions at HEAD\nwh thing history Shape/name --repo org/repo # version history\n\n# Batch read — wh thing view is variadic (max 500 wrefs/call):\nwh thing view Player/alice Player/bob # variadic positionals\nwh thing view --file wrefs.txt --json # one wref per line\ncat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped* requested wref\n```\n\n## Wref Quick Reference\n\nWrites use explicit names and wrefs. Untyped fields, collection members,\nassertion `about`, and committers accept any thing. Create a deterministic\ntarget before referencing it in the same commit.\n\n## Command Reference\n\n**Global flags**: `--repo`, `--format`, `--json`, `--live`\n### thing — Thing operations\n- `wh thing list [--shape] [--kind] [--match] [--include-retracted]` — Current HEAD state\n- `wh thing view [<wref>...] [--file <path>] [--version] [--depth] [--include-retracted] [--data-mode auto|full]` — Thing details. Variadic (max 500). `--version` implies `--include-retracted`. Batch JSON returns `{ requested, items, missing }`; jsonl emits one row per deduped requested wref. Large Set/List bodies summarize by default; use `--data-mode full` for canonical collection JSON.\n- `wh thing history [wref] [--shape] [--about] [--include-retracted]` — Version history\n- `wh thing resolve <wref>` — Resolve a wref to its canonical thing identity\n- `wh thing create <name|Shape/name> (--data|--file) [--shape]` — Create\n- `wh thing revise <name> [--data] [--message] [--committer] [--expected-version]` — Revise (CONFLICT if HEAD≠n)\n- `wh thing retract <wref> -m <message> [--reason] [--kind] [--expected-version]` — Retract\n- `wh thing query [--shape] [--kind] [--about] [--match]` — Query by filters\n- `wh thing search <query> [--shape] [--kind] [--about] [--mode]` — Search text\n- `wh thing rename <Shape/oldName> <newName>` — Rename\n- `wh thing refs <wref> [--inbound] [--outbound] [--field]` — Show field references; use `wh thing about` for assertions about the target thing\n- `wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--role from|to|ends] [--limit] [--include-retracted]` — Show assertions about the target identity; `--resolve-collections` expands bare/@HEAD/@ALL members, `--role` filters direction; not pinned @vN\n\n### commit — Write operations\n- `wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]` — Submit operations (bare `wh commit` is equivalent). Use `--file ops.jsonl --stream-id <id> --chunk-size 5000 --skip-existing` for bulk ingest.\n- `wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]` — Generate sample ops\n\n### assertion — Assertion operations\n- `wh assertion list [--about wref] [--shape] [--match] [--include-retracted]` — Browse assertions\n- `wh assertion view <wref> [--version] [--include-retracted]` — Assertion details\n- `wh assertion create --shape <s> --name <n> --about <wref> [--data] [-m] [--committer]` — Create assertion\n- `wh assertion revise <wref> --data <json> [--message] [--committer]` — Revise assertion\n- `wh assertion retract <wref> -m <message> [--reason] [--committer] [--expected-version]` — Retract assertion\n- `wh assertion history <wref> [--include-retracted]` — Assertion history\n\n### shape — Shape management\n- `wh shape list [--match] [--include-retracted]` — List all shapes\n- `wh shape view <name> [--include-retracted]` — Shape details\n- `wh shape revise <name> (--fields|--file)`\n- `wh shape create <name> (--fields|--file)`\n- `wh shape retract <name> -m <message> [--reason] [--expected-version]` — Retract shape\n- `wh shape history <name> [--include-retracted]` — Shape history\n- `wh shape rename <oldName> <newName>` — Rename shape\n\n### repo — Repository management\n- `wh repo create <org/name> [--display-name] [--description] [--visibility]` — Create repo\n- `wh repo list [org]` — List repos\n- `wh repo view [org/repo]` — Repo details\n\n### org — Organization management\n- `wh org create <name> [--display-name]` — Create a new organization\n- `wh org view <name>` — View organization details (alias: info)\n- `wh org list` — List all organizations\n\n### sub — Subscription management\n- `wh sub create <name> [flags]` — Create a subscription\n- `wh sub view <name>` — View subscription details\n- `wh sub list` — List all subscriptions\n- `wh sub log <name>` — Tail subscription delivery feed\n- `wh sub attempts <runId>` — Show attempt history for a run\n- `wh sub pause <name>` — Pause a subscription\n- `wh sub resume <name>` — Resume a paused subscription\n- `wh sub bind <name> [--credentials]` — Bind a credential set to a subscription for webhook auth\n- `wh sub unbind <name>` — Remove credential binding from a subscription\n- `wh sub delete <name>` — Delete a subscription\n\n### notifications — Action notification listing\n- `wh notifications [--limit] [--since]` — List repo-scoped action notifications\n\n### credential — Credential set management\n- `wh credential create <name> [--repo org/repo | --org org] [--scope] [--description]` — Create an empty credential set\n- `wh credential list [--repo org/repo | --org org]` — List credential sets accessible from a repo or org\n- `wh credential view <name> [--repo org/repo | --org org]` — View a credential set (key names only, no values)\n- `wh credential delete <name> [--repo org/repo | --org org]` — Delete a credential set and its Vault object\n- `wh credential set <setName> [<keyName>] [--repo org/repo | --org org] [--value]` — Set credential key(s). With `<keyName>`: single-key form (reads value from `--value` or stdin). Without `<keyName>`: batch form (reads JSON object from stdin, e.g. `{\"KEY\":\"val\"}`)\n- `wh credential unset <setName> <keyName> [--repo org/repo | --org org]` — Remove a key from a credential set\n- `wh credential audit <setName> [--repo org/repo | --org org]` — View audit log for a credential set\n- `wh credential revoke <setName> [--repo org/repo | --org org] [--reason]` — Revoke a credential set (blocks new binds and stops bound webhook deliveries)\n\n### component — Component management\n- `wh component validate <path>` — Validate package\n- `wh component install <org/name>` — Install a registered component\n- `wh component register <name> --org <org> --manifest <path> [flags]` — Register component identity\n- `wh component unregister <org/name>` — Remove a registered component identity\n- `wh component registry list --org <org>` — List registered components\n- `wh component registry view <org/name>` — View a registered component\n- `wh component registry update <org/name> [flags]` — Update a registered component\n- `wh component list` — List installed components\n- `wh component update <org/name>` — Update installed component\n- `wh component view <org/name>` — Show component details (alias: show)\n- `wh component doctor <org/name>` — Run component health checks\n- `wh component teardown <org/name>` — Pause component subscriptions\n\n### Getting More Info\n- `wh help` — help overview\n- `wh <domain>` — domain verbs\n- `wh <domain> <verb> --help` — verb flags and examples\n- `wh help --format json` — `CliSpecV2` (`schemaVersion: 2`): global/contextual/root tables and command overrides\n\n## Common Workflows\n\n**Explore a repo:**\n```bash\nwh thing list --repo org/repo # see all things in HEAD\nwh thing view Shape/name --repo org/repo # inspect a specific thing\nwh thing history Shape/name --repo org/repo # inspect version history\nwh thing about Shape/name # assertions about thing/shape\n```\n\n**Create an assertion** (most common write):\n```bash\n# --about takes an untyped target wref: Shape or Shape/name.\nwh assertion create --shape MyShape --about TargetShape/target-name \\\n --name my-assertion --data '{\"field_a\":1,\"field_b\":\"value\"}' --repo org/repo\n# Output includes per-operation status; relay failures when present.\n```\n\n**Create via write entrypoint** (alternative, supports batches and streams):\n```bash\nwh commit submit --add my-item --shape MyShape --kind assertion \\\n --about TargetShape/target-name --data '{\"field_a\":1}' --repo org/repo\n```\n\n**Batch write via file** (generate template → edit → submit):\n```bash\nwh shape template Hypothesis Evidence -o ops.json # add --kind assertion --about TargetShape/name for assertions\n# edit ops.json — fill FILL_IN placeholders\nwh commit submit --file ops.json -m \"batch update\" # submit all operations (bare `wh commit` is equivalent)\n# --file format: docs.warmhub.ai/cli-reference/commit-operations\n```\n\n**Bulk write (JSONL stream, >1k ops)** — one chunked stream beats per-record commits (~60× faster):\n```bash\nwh shape template MyShape -o ops.jsonl # one op per line (.jsonl)\nID=\"bulk-$(date +%s)\" # caller id for chunk correlation\nwh commit submit --file ops.jsonl --stream-id \"$ID\" --chunk-size 5000 \\\n --skip-existing --progress -m \"bulk ingest\" --repo org/repo\n# --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower\n# --skip-existing: skips already-written add ops (drops per-row read-before-write)\n# --stream-id identifies the submission but provides no receipt or resume.\n# After an outcome-unknown append, stop writes and reconcile attempted + unsent\n# work from a later verified checkpoint; never blindly replay revise/retract.\n```\n\n**Create collections:**\n```bash\nwh commit submit --type arc --name route --members Location/a,Location/b --repo org/repo\nwh assertion create --shape Supports --name route-support --about Arc/route --data '{\"confidence\":0.8}' --repo org/repo\n```\n\n**Modify data:**\n```bash\nwh thing revise Shape/name --data '{\"x\":5,\"y\":3}' -m \"update\" --repo org/repo\nwh thing retract Shape/old-item -m \"withdrawn\" --reason \"data feed contaminated\" --repo org/repo\n```\n\n**Query and filter:**\n```bash\nwh thing query --shape MyShape # by shape\nwh thing query --kind assertion --about Shape/name # by kind + target\nwh thing history Shape/name --limit 10 # version history\n```\n\n## Built-in Content shape\n\nWarmHub repos expose three well-known content wrefs:\n- `Content/Readme` — stored markdown for humans\n- `Content/Agents` — stored markdown guidance for AI agents\n- `Content/LlmsTxt` — synthesized per-request sitemap (read-only)\n\nFetch via `wh repo content get --kind readme|agents|llms-txt`,\n`client.repo.getReadme/getAgents/getLlmsTxt`, MCP `warmhub_repo_content_get`,\nor raw HTTP `GET /{org}/{repo}/readme.md|agents.md|llms.txt`.\nSee `wh repo describe` → `additionalInformation` for the discovery field.\n\n## Query Discipline\n- Plan the repo, shapes, and wrefs you need before the first query.\n- Gather the needed facts from one repo before switching to another.\n- Do the queries first, then write one complete answer.\n\n## Agent Tips\n- **Always run commands for live data** — this context describes the CLI, not repo contents\n- **Before writing, discover wrefs** — run `wh thing list` or `wh shape list`\n- **Shape field types**: `string`, `number`, `boolean`, `wref`, arrays, optionals, nested objects\n- **Write commands return per-operation results** — relay failures and affected wrefs to the user\n- **Pass data inline** with `--data '{...}'` — do NOT create temp files\n- Add `--json` to any command for machine-readable JSON output\n- **Aliases teach canonical commands** — executing aliases emit a status hint; misleading lifecycle aliases reject and point to `retract`\n- Writes go through `wh commit submit` (or bare `wh commit`) or wrappers (`create`, `revise`, `retract`, `assertion create`). `retract` irreversibly withdraws an identity and creates a history entry.\n- Use `wh doctor` to check environment health\n";
|
|
44297
44505
|
|
|
44298
44506
|
// ../../packages/warmhub-cli/src/domains/prime.ts
|
|
44299
44507
|
function buildMarkdown(config) {
|
|
@@ -45522,6 +45730,9 @@ function renderShapeFieldDiff(out, diff) {
|
|
|
45522
45730
|
}
|
|
45523
45731
|
var retractFlags3 = {
|
|
45524
45732
|
reason: flag.string({ description: "Reason for retraction (<=500 chars)" }),
|
|
45733
|
+
"expected-version": flag.number({
|
|
45734
|
+
description: "only retract if the target is still at this version (optimistic concurrency)"
|
|
45735
|
+
}),
|
|
45525
45736
|
message: flag.string({ short: "m", description: "Commit message" }),
|
|
45526
45737
|
committer: flag.string({
|
|
45527
45738
|
description: "Committer wref (shape or shaped thing; e.g. Agent/bot-1)"
|
|
@@ -45598,16 +45809,18 @@ var handleRevise3 = async (ctx, { flags, args }) => {
|
|
|
45598
45809
|
var handleRetract2 = async (ctx, { flags, args }) => {
|
|
45599
45810
|
const shapeName = args[0];
|
|
45600
45811
|
if (!shapeName) {
|
|
45601
|
-
usageError("Usage: wh shape retract <name>", "wh shape retract Location");
|
|
45812
|
+
usageError("Usage: wh shape retract <name> [--expected-version <n>]", "wh shape retract Location");
|
|
45602
45813
|
}
|
|
45603
45814
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
45815
|
+
const expectedVersion = parsePositiveIntFlag(flags["expected-version"], "--expected-version", "wh shape retract Location --expected-version 3");
|
|
45604
45816
|
const c = ctx.colors;
|
|
45605
45817
|
const result = await ctx.client.commit.apply(org, repo, flags.message ?? `retract shape ${shapeName}`, [
|
|
45606
45818
|
{
|
|
45607
45819
|
operation: "retract",
|
|
45608
45820
|
kind: "shape",
|
|
45609
45821
|
name: shapeName,
|
|
45610
|
-
...flags.reason ? { reason: flags.reason } : {}
|
|
45822
|
+
...flags.reason ? { reason: flags.reason } : {},
|
|
45823
|
+
...expectedVersion !== undefined ? { expectedVersion } : {}
|
|
45611
45824
|
}
|
|
45612
45825
|
], { committer: flags.committer });
|
|
45613
45826
|
assertSingleOpSuccess(result);
|
|
@@ -49120,7 +49333,7 @@ function resolveLogLevel(flagLevel, env) {
|
|
|
49120
49333
|
// package.json
|
|
49121
49334
|
var package_default3 = {
|
|
49122
49335
|
name: "@warmhub/cli",
|
|
49123
|
-
version: "0.
|
|
49336
|
+
version: "0.86.0",
|
|
49124
49337
|
private: false,
|
|
49125
49338
|
type: "module",
|
|
49126
49339
|
description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -49737,5 +49950,5 @@ process.exitCode = interceptedExitCode === undefined ? await runPreparedCli(laun
|
|
|
49737
49950
|
version: package_default3.version
|
|
49738
49951
|
}) : interceptedExitCode;
|
|
49739
49952
|
|
|
49740
|
-
//# debugId=
|
|
49741
|
-
//# warmhub-cli-build-info {"cliVersion":"0.
|
|
49953
|
+
//# debugId=864ACFE03DA5766664756E2164756E21
|
|
49954
|
+
//# warmhub-cli-build-info {"cliVersion":"0.86.0","sdkVersion":"0.84.0"}
|