@warmhub/cli 0.52.1 → 0.54.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 +625 -318
- package/package.json +1 -1
package/dist/wh.js
CHANGED
|
@@ -18914,6 +18914,10 @@ var RUNTIME_ACCESS_BUILTINS = new Set([
|
|
|
18914
18914
|
"ComponentConfig",
|
|
18915
18915
|
...BUILTIN_SHAPE_NAMES
|
|
18916
18916
|
]);
|
|
18917
|
+
var SUBSCRIPTION_TRIGGER_BUILTINS = new Set([
|
|
18918
|
+
"ComponentInstall",
|
|
18919
|
+
"ComponentConfig"
|
|
18920
|
+
]);
|
|
18917
18921
|
function validateProvisioning(obj, path, errors) {
|
|
18918
18922
|
if (!("provisioning" in obj))
|
|
18919
18923
|
return;
|
|
@@ -19206,8 +19210,19 @@ function validateManifestSemantics(manifest) {
|
|
|
19206
19210
|
}
|
|
19207
19211
|
const shapeNames = new Set(manifest.shapes.map((s) => s.name));
|
|
19208
19212
|
const credentialNames = new Set(manifest.credentials.map((c) => c.name));
|
|
19209
|
-
const
|
|
19213
|
+
const knownSubscriptionTriggerShapes = new Set([
|
|
19214
|
+
...shapeNames,
|
|
19215
|
+
...SUBSCRIPTION_TRIGGER_BUILTINS
|
|
19216
|
+
]);
|
|
19217
|
+
const knownSeedShapes = new Set([...shapeNames, "ComponentConfig"]);
|
|
19210
19218
|
for (const sub of manifest.subscriptions) {
|
|
19219
|
+
if (sub.trigger.kind === "event" && !knownSubscriptionTriggerShapes.has(sub.trigger.shape)) {
|
|
19220
|
+
findings.push({
|
|
19221
|
+
level: "error",
|
|
19222
|
+
code: "MISSING_SUBSCRIPTION_TRIGGER_SHAPE_REF",
|
|
19223
|
+
message: `subscription "${sub.name}" trigger references shape "${sub.trigger.shape}" which is not declared and is not a supported subscription trigger built-in`
|
|
19224
|
+
});
|
|
19225
|
+
}
|
|
19211
19226
|
if (sub.credentials) {
|
|
19212
19227
|
if (sub.credentials.length > 1) {
|
|
19213
19228
|
findings.push({
|
|
@@ -19236,7 +19251,7 @@ function validateManifestSemantics(manifest) {
|
|
|
19236
19251
|
}
|
|
19237
19252
|
}
|
|
19238
19253
|
for (const seed of manifest.seeds) {
|
|
19239
|
-
if (!
|
|
19254
|
+
if (!knownSeedShapes.has(seed.shape)) {
|
|
19240
19255
|
findings.push({
|
|
19241
19256
|
level: "error",
|
|
19242
19257
|
code: "MISSING_SHAPE_REF",
|
|
@@ -19381,6 +19396,11 @@ function joinFieldIdentityPath(...segments) {
|
|
|
19381
19396
|
function joinFieldPathWithEscaper(escapeSegment, segments) {
|
|
19382
19397
|
return segments.map((segment) => typeof segment === "number" ? `[${segment}]` : escapeSegment(segment)).join(".").replace(/\.\[/g, "[");
|
|
19383
19398
|
}
|
|
19399
|
+
// ../../packages/rules/src/permission-scopes.ts
|
|
19400
|
+
var PUBLIC_ORG_PERMISSIONS = new Set([
|
|
19401
|
+
"org:read",
|
|
19402
|
+
"components:read"
|
|
19403
|
+
]);
|
|
19384
19404
|
// ../../packages/rules/src/platform-status.ts
|
|
19385
19405
|
var PLATFORM_STATUS_CATALOG_SHAPE = "PlatformStatusCatalog";
|
|
19386
19406
|
var PLATFORM_STATUS_CATALOG_NAME = "main";
|
|
@@ -21213,6 +21233,7 @@ function nestedObjectFields(typeDef) {
|
|
|
21213
21233
|
}
|
|
21214
21234
|
// ../../packages/rules/src/system-components/system.ts
|
|
21215
21235
|
var SYSTEM_COMPONENT_ID = "com.warmhub.system";
|
|
21236
|
+
var SYSTEM_REGISTERED_COMPONENT_REF = "warmhub/system";
|
|
21216
21237
|
var COMPONENT_INSTALL_FIELDS = {
|
|
21217
21238
|
componentId: "string",
|
|
21218
21239
|
name: "string",
|
|
@@ -21273,7 +21294,7 @@ function findSystemComponent(componentId) {
|
|
|
21273
21294
|
// ../../packages/sdk-ts/package.json
|
|
21274
21295
|
var package_default = {
|
|
21275
21296
|
name: "@warmhub/sdk-ts",
|
|
21276
|
-
version: "0.
|
|
21297
|
+
version: "0.53.0",
|
|
21277
21298
|
private: false,
|
|
21278
21299
|
type: "module",
|
|
21279
21300
|
description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -21601,7 +21622,7 @@ async function submitOperationsViaStream(client, args) {
|
|
|
21601
21622
|
orgName: args.orgName,
|
|
21602
21623
|
repoName: args.repoName,
|
|
21603
21624
|
streamId,
|
|
21604
|
-
|
|
21625
|
+
componentRef: args.componentRef,
|
|
21605
21626
|
committer: args.committer,
|
|
21606
21627
|
message: args.message,
|
|
21607
21628
|
operations: chunk
|
|
@@ -22107,23 +22128,9 @@ class WarmHubClient {
|
|
|
22107
22128
|
}
|
|
22108
22129
|
};
|
|
22109
22130
|
access = {
|
|
22110
|
-
|
|
22111
|
-
try {
|
|
22112
|
-
return await this.trpc.access.checkRepoPermission.query({
|
|
22113
|
-
orgName,
|
|
22114
|
-
repoName,
|
|
22115
|
-
permission
|
|
22116
|
-
});
|
|
22117
|
-
} catch (error) {
|
|
22118
|
-
throw toWarmHubError(error);
|
|
22119
|
-
}
|
|
22120
|
-
},
|
|
22121
|
-
checkOrgPermission: async (orgName, permission) => {
|
|
22131
|
+
resolve: async (input) => {
|
|
22122
22132
|
try {
|
|
22123
|
-
return await this.trpc.access.
|
|
22124
|
-
orgName,
|
|
22125
|
-
permission
|
|
22126
|
-
});
|
|
22133
|
+
return await this.trpc.access.resolve.query(input);
|
|
22127
22134
|
} catch (error) {
|
|
22128
22135
|
throw toWarmHubError(error);
|
|
22129
22136
|
}
|
|
@@ -22177,12 +22184,23 @@ class WarmHubClient {
|
|
|
22177
22184
|
throw toWarmHubError(error);
|
|
22178
22185
|
}
|
|
22179
22186
|
},
|
|
22180
|
-
|
|
22187
|
+
search: async (query, opts) => {
|
|
22188
|
+
try {
|
|
22189
|
+
return await this.trpc.component.search.query({
|
|
22190
|
+
query,
|
|
22191
|
+
limit: opts?.limit,
|
|
22192
|
+
cursor: opts?.cursor
|
|
22193
|
+
});
|
|
22194
|
+
} catch (error) {
|
|
22195
|
+
throw toWarmHubError(error);
|
|
22196
|
+
}
|
|
22197
|
+
},
|
|
22198
|
+
get: async (orgName, repoName, componentRef) => {
|
|
22181
22199
|
try {
|
|
22182
22200
|
return await this.trpc.component.get.query({
|
|
22183
22201
|
orgName,
|
|
22184
22202
|
repoName,
|
|
22185
|
-
|
|
22203
|
+
componentRef
|
|
22186
22204
|
});
|
|
22187
22205
|
} catch (error) {
|
|
22188
22206
|
throw toWarmHubError(error);
|
|
@@ -22277,7 +22295,7 @@ class WarmHubClient {
|
|
|
22277
22295
|
repoName,
|
|
22278
22296
|
committer: opts?.committer,
|
|
22279
22297
|
message,
|
|
22280
|
-
|
|
22298
|
+
componentRef: opts?.componentRef,
|
|
22281
22299
|
chunkSize: opts?.chunkSize,
|
|
22282
22300
|
skipExisting: opts?.skipExisting,
|
|
22283
22301
|
streamId: opts?.streamId,
|
|
@@ -22512,6 +22530,17 @@ class WarmHubClient {
|
|
|
22512
22530
|
throw toWarmHubError(error);
|
|
22513
22531
|
}
|
|
22514
22532
|
},
|
|
22533
|
+
search: async (query, opts) => {
|
|
22534
|
+
try {
|
|
22535
|
+
return await this.trpc.repo.search.query({
|
|
22536
|
+
query,
|
|
22537
|
+
limit: opts?.limit,
|
|
22538
|
+
cursor: opts?.cursor
|
|
22539
|
+
});
|
|
22540
|
+
} catch (error) {
|
|
22541
|
+
throw toWarmHubError(error);
|
|
22542
|
+
}
|
|
22543
|
+
},
|
|
22515
22544
|
create: async (orgName, repoName, description, visibility, displayName) => {
|
|
22516
22545
|
try {
|
|
22517
22546
|
return await this.trpc.repo.create.mutate({
|
|
@@ -22715,7 +22744,7 @@ class WarmHubClient {
|
|
|
22715
22744
|
orgName,
|
|
22716
22745
|
repoName,
|
|
22717
22746
|
match: opts?.match,
|
|
22718
|
-
|
|
22747
|
+
componentRef: opts?.componentRef,
|
|
22719
22748
|
excludeComponents: opts?.excludeComponents,
|
|
22720
22749
|
includeRetracted: opts?.includeRetracted
|
|
22721
22750
|
});
|
|
@@ -23061,7 +23090,7 @@ class WarmHubClient {
|
|
|
23061
23090
|
includeRetracted: opts?.includeRetracted,
|
|
23062
23091
|
limit: opts?.limit,
|
|
23063
23092
|
cursor: opts?.cursor,
|
|
23064
|
-
|
|
23093
|
+
componentRef: opts?.componentRef,
|
|
23065
23094
|
excludeComponents: opts?.excludeComponents,
|
|
23066
23095
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23067
23096
|
where: opts?.where
|
|
@@ -23282,7 +23311,7 @@ class WarmHubClient {
|
|
|
23282
23311
|
resolveCollections: opts?.resolveCollections,
|
|
23283
23312
|
limit: opts?.limit,
|
|
23284
23313
|
cursor: opts?.cursor,
|
|
23285
|
-
|
|
23314
|
+
componentRef: opts?.componentRef,
|
|
23286
23315
|
excludeComponents: opts?.excludeComponents,
|
|
23287
23316
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23288
23317
|
where: opts?.where
|
|
@@ -23313,7 +23342,7 @@ class WarmHubClient {
|
|
|
23313
23342
|
resolveCollections: opts?.resolveCollections,
|
|
23314
23343
|
limit: opts?.limit,
|
|
23315
23344
|
cursor: opts?.cursor,
|
|
23316
|
-
|
|
23345
|
+
componentRef: opts?.componentRef,
|
|
23317
23346
|
excludeComponents: opts?.excludeComponents,
|
|
23318
23347
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23319
23348
|
mode: opts?.mode
|
|
@@ -23334,7 +23363,7 @@ class WarmHubClient {
|
|
|
23334
23363
|
match: opts?.match,
|
|
23335
23364
|
includeRetracted: opts?.includeRetracted,
|
|
23336
23365
|
resolveCollections: opts?.resolveCollections,
|
|
23337
|
-
|
|
23366
|
+
componentRef: opts?.componentRef,
|
|
23338
23367
|
excludeComponents: opts?.excludeComponents,
|
|
23339
23368
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23340
23369
|
where: opts?.where
|
|
@@ -24698,37 +24727,65 @@ function makeStderrSink(minLevel) {
|
|
|
24698
24727
|
function enforceLineCap(record) {
|
|
24699
24728
|
const initial = `${JSON.stringify(record)}
|
|
24700
24729
|
`;
|
|
24701
|
-
if (initial
|
|
24730
|
+
if (lineByteLength(initial) <= LINE_CAP + 1)
|
|
24702
24731
|
return initial;
|
|
24703
24732
|
const trimmed = { ...record };
|
|
24704
24733
|
for (let pass = 0;pass < 8; pass++) {
|
|
24705
24734
|
const candidate = `${JSON.stringify(trimmed)}
|
|
24706
24735
|
`;
|
|
24707
|
-
if (candidate
|
|
24736
|
+
if (lineByteLength(candidate) <= LINE_CAP + 1)
|
|
24708
24737
|
return candidate;
|
|
24709
24738
|
let largestKey = null;
|
|
24710
24739
|
let largestLen = 0;
|
|
24711
24740
|
for (const [key, val] of Object.entries(trimmed)) {
|
|
24712
|
-
if (typeof val === "string"
|
|
24741
|
+
if (typeof val === "string") {
|
|
24742
|
+
const byteLen = lineByteLength(val);
|
|
24743
|
+
if (byteLen <= largestLen)
|
|
24744
|
+
continue;
|
|
24713
24745
|
largestKey = key;
|
|
24714
|
-
largestLen =
|
|
24746
|
+
largestLen = byteLen;
|
|
24715
24747
|
}
|
|
24716
24748
|
}
|
|
24717
24749
|
if (largestKey === null)
|
|
24718
24750
|
break;
|
|
24719
|
-
const overage = candidate
|
|
24751
|
+
const overage = lineByteLength(candidate) - LINE_CAP - 1;
|
|
24720
24752
|
const current = trimmed[largestKey];
|
|
24721
|
-
const
|
|
24722
|
-
trimmed[largestKey] = `${current
|
|
24753
|
+
const allowedBytes = Math.max(0, lineByteLength(current) - overage - lineByteLength(TRUNCATED_MARKER));
|
|
24754
|
+
trimmed[largestKey] = `${sliceUtf8Bytes(current, allowedBytes)}${TRUNCATED_MARKER}`;
|
|
24723
24755
|
}
|
|
24724
|
-
|
|
24756
|
+
const fallback = {
|
|
24725
24757
|
v: trimmed.v,
|
|
24726
24758
|
ts: trimmed.ts,
|
|
24727
24759
|
level: trimmed.level,
|
|
24728
24760
|
msg: trimmed.msg,
|
|
24729
24761
|
truncated: TRUNCATED_MARKER
|
|
24730
|
-
}
|
|
24762
|
+
};
|
|
24763
|
+
let line = `${JSON.stringify(fallback)}
|
|
24764
|
+
`;
|
|
24765
|
+
if (lineByteLength(line) <= LINE_CAP + 1)
|
|
24766
|
+
return line;
|
|
24767
|
+
const emptyMsgLine = `${JSON.stringify({ ...fallback, msg: "" })}
|
|
24768
|
+
`;
|
|
24769
|
+
const msgBudget = Math.max(0, LINE_CAP + 1 - lineByteLength(emptyMsgLine));
|
|
24770
|
+
fallback.msg = sliceUtf8Bytes(fallback.msg, msgBudget);
|
|
24771
|
+
line = `${JSON.stringify(fallback)}
|
|
24731
24772
|
`;
|
|
24773
|
+
return line;
|
|
24774
|
+
}
|
|
24775
|
+
function lineByteLength(value) {
|
|
24776
|
+
return Buffer.byteLength(value, "utf8");
|
|
24777
|
+
}
|
|
24778
|
+
function sliceUtf8Bytes(value, maxBytes) {
|
|
24779
|
+
let bytes = 0;
|
|
24780
|
+
let result = "";
|
|
24781
|
+
for (const char of value) {
|
|
24782
|
+
const charBytes = lineByteLength(char);
|
|
24783
|
+
if (bytes + charBytes > maxBytes)
|
|
24784
|
+
break;
|
|
24785
|
+
result += char;
|
|
24786
|
+
bytes += charBytes;
|
|
24787
|
+
}
|
|
24788
|
+
return result;
|
|
24732
24789
|
}
|
|
24733
24790
|
function rotateIfNeeded(path, dir) {
|
|
24734
24791
|
if (!existsSync(path))
|
|
@@ -25176,7 +25233,7 @@ function loadProfileStore(path) {
|
|
|
25176
25233
|
} catch (cause) {
|
|
25177
25234
|
throw corruptedAuthError(p, cause);
|
|
25178
25235
|
}
|
|
25179
|
-
if (parsed === null || typeof parsed !== "object" || parsed.version !== 1 || parsed.profiles === null || typeof parsed.profiles !== "object") {
|
|
25236
|
+
if (parsed === null || typeof parsed !== "object" || parsed.version !== 1 || parsed.profiles === null || typeof parsed.profiles !== "object" || Array.isArray(parsed.profiles)) {
|
|
25180
25237
|
throw corruptedAuthError(p);
|
|
25181
25238
|
}
|
|
25182
25239
|
return parsed;
|
|
@@ -25403,10 +25460,11 @@ async function getValidToken(profile) {
|
|
|
25403
25460
|
});
|
|
25404
25461
|
await delay(1000);
|
|
25405
25462
|
log.info("auth.refresh.retry", { profile: profileName, attempt: 2 });
|
|
25463
|
+
let retryStarted = Date.now();
|
|
25406
25464
|
try {
|
|
25407
25465
|
const retryProf = getProfile(profileName, authPath);
|
|
25408
25466
|
const retryTokens = retryProf?.tokens ?? lockedTokens;
|
|
25409
|
-
|
|
25467
|
+
retryStarted = Date.now();
|
|
25410
25468
|
const refreshed = await refreshAccessToken(retryTokens);
|
|
25411
25469
|
saveProfileWhileLocked(profileName, { ...retryProf ?? lockedProf, tokens: refreshed }, authPath);
|
|
25412
25470
|
log.info("auth.refresh.ok", {
|
|
@@ -25421,7 +25479,7 @@ async function getValidToken(profile) {
|
|
|
25421
25479
|
const fields = {
|
|
25422
25480
|
profile: profileName,
|
|
25423
25481
|
classification,
|
|
25424
|
-
duration_ms: Date.now() -
|
|
25482
|
+
duration_ms: Date.now() - retryStarted,
|
|
25425
25483
|
error_name: retryErr instanceof Error ? retryErr.name : "Unknown",
|
|
25426
25484
|
on_retry: true
|
|
25427
25485
|
};
|
|
@@ -25481,20 +25539,34 @@ function recordBenchmarkResponse(response, benchmarkId) {
|
|
|
25481
25539
|
benchmarkTelemetry.requestDbQueryCountSum += requestDbQueryCount;
|
|
25482
25540
|
}
|
|
25483
25541
|
}
|
|
25484
|
-
function createBenchmarkAwareFetch(benchmarkId) {
|
|
25485
|
-
if (!benchmarkId)
|
|
25542
|
+
function createBenchmarkAwareFetch(benchmarkId, signal) {
|
|
25543
|
+
if (!benchmarkId && !signal)
|
|
25486
25544
|
return;
|
|
25487
25545
|
return async (input, init) => {
|
|
25488
25546
|
const headers = new Headers(init?.headers);
|
|
25489
|
-
|
|
25547
|
+
if (benchmarkId)
|
|
25548
|
+
headers.set(BENCHMARK_HEADER, benchmarkId);
|
|
25490
25549
|
const response = await fetch(input, {
|
|
25491
25550
|
...init,
|
|
25492
|
-
headers
|
|
25551
|
+
headers,
|
|
25552
|
+
signal: mergeAbortSignals(init?.signal, signal)
|
|
25493
25553
|
});
|
|
25494
|
-
|
|
25554
|
+
if (benchmarkId)
|
|
25555
|
+
recordBenchmarkResponse(response, benchmarkId);
|
|
25495
25556
|
return response;
|
|
25496
25557
|
};
|
|
25497
25558
|
}
|
|
25559
|
+
function mergeAbortSignals(requestSignal, liveSignal) {
|
|
25560
|
+
if (!requestSignal)
|
|
25561
|
+
return liveSignal;
|
|
25562
|
+
if (!liveSignal)
|
|
25563
|
+
return requestSignal;
|
|
25564
|
+
if (requestSignal.aborted)
|
|
25565
|
+
return requestSignal;
|
|
25566
|
+
if (liveSignal.aborted)
|
|
25567
|
+
return liveSignal;
|
|
25568
|
+
return AbortSignal.any([requestSignal, liveSignal]);
|
|
25569
|
+
}
|
|
25498
25570
|
function resetBenchmarkTelemetry() {
|
|
25499
25571
|
benchmarkTelemetry = emptyBenchmarkTelemetry();
|
|
25500
25572
|
}
|
|
@@ -25522,18 +25594,34 @@ function createClient(config, opts = {}) {
|
|
|
25522
25594
|
function wantsStructuredLiveOutput(format) {
|
|
25523
25595
|
return format === "json" || format === "jsonl";
|
|
25524
25596
|
}
|
|
25597
|
+
var LIVE_ABORTED = Symbol("live-aborted");
|
|
25598
|
+
function pollUntilAbort(poll, signal) {
|
|
25599
|
+
if (signal.aborted)
|
|
25600
|
+
return Promise.resolve(LIVE_ABORTED);
|
|
25601
|
+
return new Promise((resolve, reject) => {
|
|
25602
|
+
const onAbort = () => resolve(LIVE_ABORTED);
|
|
25603
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
25604
|
+
poll.then((result) => {
|
|
25605
|
+
signal.removeEventListener("abort", onAbort);
|
|
25606
|
+
resolve(result);
|
|
25607
|
+
}, (error) => {
|
|
25608
|
+
signal.removeEventListener("abort", onAbort);
|
|
25609
|
+
reject(error);
|
|
25610
|
+
});
|
|
25611
|
+
});
|
|
25612
|
+
}
|
|
25525
25613
|
async function runLive(opts) {
|
|
25526
25614
|
const auth = opts.auth ?? {
|
|
25527
25615
|
getToken: async () => await getValidToken(opts.profile) ?? undefined
|
|
25528
25616
|
};
|
|
25529
25617
|
const benchmarkId = process.env.WH_BENCHMARK_ID?.trim();
|
|
25618
|
+
const controller = new AbortController;
|
|
25530
25619
|
const client = new WarmHubClient({
|
|
25531
25620
|
apiUrl: opts.apiUrl,
|
|
25532
25621
|
auth,
|
|
25533
|
-
fetch: createBenchmarkAwareFetch(benchmarkId),
|
|
25622
|
+
fetch: createBenchmarkAwareFetch(benchmarkId, controller.signal),
|
|
25534
25623
|
functionLogs: opts.functionLogs
|
|
25535
25624
|
});
|
|
25536
|
-
const controller = new AbortController;
|
|
25537
25625
|
if (opts.signal) {
|
|
25538
25626
|
if (opts.signal.aborted)
|
|
25539
25627
|
controller.abort();
|
|
@@ -25557,7 +25645,12 @@ async function runLive(opts) {
|
|
|
25557
25645
|
startTimer = setTimeout(() => controller.abort(), opts.startTimeoutMs);
|
|
25558
25646
|
}
|
|
25559
25647
|
while (!controller.signal.aborted) {
|
|
25560
|
-
const
|
|
25648
|
+
const poll = opts.poll(client, controller.signal);
|
|
25649
|
+
const result = await pollUntilAbort(poll, controller.signal);
|
|
25650
|
+
if (result === LIVE_ABORTED) {
|
|
25651
|
+
poll.catch(() => {});
|
|
25652
|
+
break;
|
|
25653
|
+
}
|
|
25561
25654
|
updates += 1;
|
|
25562
25655
|
if (startTimer) {
|
|
25563
25656
|
clearTimeout(startTimer);
|
|
@@ -26130,9 +26223,34 @@ function writeOutput(ctx, data, prettyFn) {
|
|
|
26130
26223
|
}
|
|
26131
26224
|
prettyFn();
|
|
26132
26225
|
}
|
|
26133
|
-
function
|
|
26226
|
+
function pageEnvelope(items, opts) {
|
|
26227
|
+
const nextCursor = opts.nextCursor ?? null;
|
|
26228
|
+
return {
|
|
26229
|
+
items,
|
|
26230
|
+
page: {
|
|
26231
|
+
limit: opts.limit,
|
|
26232
|
+
count: items.length,
|
|
26233
|
+
hasMore: nextCursor !== null,
|
|
26234
|
+
nextCursor
|
|
26235
|
+
}
|
|
26236
|
+
};
|
|
26237
|
+
}
|
|
26238
|
+
function writePageOutput(ctx, items, opts, prettyFn) {
|
|
26239
|
+
if (ctx.format === "json") {
|
|
26240
|
+
printJson(ctx.out, pageEnvelope(items, opts));
|
|
26241
|
+
return;
|
|
26242
|
+
}
|
|
26243
|
+
if (ctx.format === "jsonl") {
|
|
26244
|
+
printJsonl(ctx.out, items);
|
|
26245
|
+
return;
|
|
26246
|
+
}
|
|
26247
|
+
prettyFn();
|
|
26248
|
+
}
|
|
26249
|
+
function emitPartialPageHint(ctx, count, _nextCursor, _limit) {
|
|
26250
|
+
if (ctx.format === "json" || ctx.format === "jsonl")
|
|
26251
|
+
return;
|
|
26134
26252
|
const c = ctx.colors;
|
|
26135
|
-
ctx.status(`${c.yellow}${count} shown
|
|
26253
|
+
ctx.status(`${c.yellow}${count} shown; more available${c.reset}. Use ${c.cyan}--all${c.reset} to fetch every page.`);
|
|
26136
26254
|
}
|
|
26137
26255
|
|
|
26138
26256
|
// ../../packages/warmhub-cli/src/domains/thing/shared.ts
|
|
@@ -26208,7 +26326,7 @@ var handleAbout = async (ctx, { flags, args }) => {
|
|
|
26208
26326
|
apiUrl: ctx.config.apiUrl,
|
|
26209
26327
|
poll: (c) => c.thing.about(org, repo, wref, aboutOpts),
|
|
26210
26328
|
render: (r) => {
|
|
26211
|
-
renderAboutResult(ctx.out, ctx.colors, r, wref
|
|
26329
|
+
renderAboutResult(ctx.out, ctx.colors, r, wref);
|
|
26212
26330
|
},
|
|
26213
26331
|
out: ctx.out,
|
|
26214
26332
|
err: ctx.err,
|
|
@@ -26236,22 +26354,21 @@ var handleAbout = async (ctx, { flags, args }) => {
|
|
|
26236
26354
|
cur = page.nextCursor;
|
|
26237
26355
|
}
|
|
26238
26356
|
const result2 = { target, assertions, nextCursor: undefined };
|
|
26239
|
-
|
|
26357
|
+
writePageOutput(ctx, assertions, { limit: pageLimit, nextCursor: null }, () => renderAboutResult(ctx.out, ctx.colors, result2, wref));
|
|
26240
26358
|
return;
|
|
26241
26359
|
}
|
|
26242
26360
|
const result = await fetchPage(cursor);
|
|
26243
26361
|
if (result.nextCursor) {
|
|
26244
26362
|
emitPartialPageHint(ctx, result.assertions.length, result.nextCursor, boundedLimit);
|
|
26245
26363
|
}
|
|
26246
|
-
|
|
26364
|
+
writePageOutput(ctx, result.assertions, { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderAboutResult(ctx.out, ctx.colors, result, wref));
|
|
26247
26365
|
};
|
|
26248
|
-
function renderAboutResult(out, c, result, wref
|
|
26249
|
-
const resumeHint = `${c.dim}Next: --limit=${limit} --cursor=${result.nextCursor}${c.reset}`;
|
|
26366
|
+
function renderAboutResult(out, c, result, wref) {
|
|
26250
26367
|
out(`${c.bold}Assertions about${c.reset} ${pinnedWref(c, wref)} (${result.assertions.length}${result.nextCursor ? "+" : ""})`);
|
|
26251
26368
|
if (result.assertions.length === 0) {
|
|
26252
26369
|
out(` ${c.dim}(no assertions found)${c.reset}`);
|
|
26253
26370
|
if (result.nextCursor) {
|
|
26254
|
-
out(
|
|
26371
|
+
out(`${c.dim}More available. Use --all to fetch every page.${c.reset}`);
|
|
26255
26372
|
}
|
|
26256
26373
|
return;
|
|
26257
26374
|
}
|
|
@@ -26259,7 +26376,7 @@ function renderAboutResult(out, c, result, wref, limit) {
|
|
|
26259
26376
|
renderAboutAssertion(out, c, a, " ");
|
|
26260
26377
|
}
|
|
26261
26378
|
if (result.nextCursor) {
|
|
26262
|
-
out(
|
|
26379
|
+
out(`${c.dim}More available. Use --all to fetch every page.${c.reset}`);
|
|
26263
26380
|
}
|
|
26264
26381
|
}
|
|
26265
26382
|
function renderAboutAssertion(out, c, assertion, indent) {
|
|
@@ -26570,14 +26687,14 @@ function renderBatchView(out, c, result, wrefs, flagsVersion) {
|
|
|
26570
26687
|
// ../../packages/warmhub-cli/src/domains/thing/graph.ts
|
|
26571
26688
|
var graphFlags = {
|
|
26572
26689
|
depth: flag.number({
|
|
26573
|
-
description: "Resolve
|
|
26690
|
+
description: "Resolve outbound wref fields, assertion backlinks, and assertion about targets to this depth (default: 2, max: 5)"
|
|
26574
26691
|
}),
|
|
26575
26692
|
version: flag.number({ description: "Specific version number" })
|
|
26576
26693
|
};
|
|
26577
26694
|
var handleThingGraph = async (ctx, { flags, args }) => {
|
|
26578
26695
|
const wref = args[0];
|
|
26579
26696
|
if (!wref) {
|
|
26580
|
-
usageError("Usage: wh thing graph <wref> [--depth N]", "wh thing graph Game/base");
|
|
26697
|
+
usageError("Usage: wh thing graph <wref> [--depth N]", "wh thing graph Game/base", "wh thing refs Game/base --inbound");
|
|
26581
26698
|
}
|
|
26582
26699
|
const depth = flags.depth;
|
|
26583
26700
|
if (depth !== undefined && (depth < 1 || depth > 5)) {
|
|
@@ -26672,7 +26789,10 @@ var handleHistory = async (ctx, { flags, args }) => {
|
|
|
26672
26789
|
if (!all && result.nextCursor) {
|
|
26673
26790
|
emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, boundedLimit);
|
|
26674
26791
|
}
|
|
26675
|
-
|
|
26792
|
+
writePageOutput(ctx, result.versions ?? [], {
|
|
26793
|
+
limit: all ? pageLimit : boundedLimit,
|
|
26794
|
+
nextCursor: result.nextCursor ?? null
|
|
26795
|
+
}, () => renderHistory(ctx.out, ctx.colors, result));
|
|
26676
26796
|
};
|
|
26677
26797
|
async function fetchAllHistoryPages(ctx, org, repo, opts) {
|
|
26678
26798
|
const versions = [];
|
|
@@ -26758,8 +26878,8 @@ function validateKind(value, flagName = "--kind") {
|
|
|
26758
26878
|
function resolveRepoContext(ctx) {
|
|
26759
26879
|
return parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
26760
26880
|
}
|
|
26761
|
-
function validateComponentFilters(
|
|
26762
|
-
if (
|
|
26881
|
+
function validateComponentFilters(componentRef, excludeComponents, ...examples) {
|
|
26882
|
+
if (componentRef && excludeComponents) {
|
|
26763
26883
|
usageError("Cannot combine --component with --exclude-components.", ...examples);
|
|
26764
26884
|
}
|
|
26765
26885
|
}
|
|
@@ -26835,7 +26955,7 @@ var headFlags = {
|
|
|
26835
26955
|
description: "Include retracted things"
|
|
26836
26956
|
}),
|
|
26837
26957
|
component: flag.string({
|
|
26838
|
-
description: "Filter to things owned by this component
|
|
26958
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
26839
26959
|
}),
|
|
26840
26960
|
"exclude-components": flag.boolean({
|
|
26841
26961
|
description: "Exclude component-owned things from results"
|
|
@@ -26861,15 +26981,15 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26861
26981
|
if (cursor || all || limit || ctx.liveMode) {
|
|
26862
26982
|
usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN]", "wh thing list --shape Player --count");
|
|
26863
26983
|
}
|
|
26864
|
-
const
|
|
26984
|
+
const componentRef2 = flags.component;
|
|
26865
26985
|
const strictExclude2 = !!flags["exclude-components"];
|
|
26866
|
-
validateComponentFilters(
|
|
26986
|
+
validateComponentFilters(componentRef2, strictExclude2, "wh thing list --component acme/veritas");
|
|
26867
26987
|
return handleCount(ctx, org, repo, {
|
|
26868
26988
|
shape,
|
|
26869
26989
|
kind,
|
|
26870
26990
|
match,
|
|
26871
26991
|
includeRetracted,
|
|
26872
|
-
|
|
26992
|
+
componentRef: componentRef2,
|
|
26873
26993
|
excludeComponents: strictExclude2,
|
|
26874
26994
|
excludeInfraShapes: !strictExclude2 && !shape,
|
|
26875
26995
|
where: where.length > 0 ? where : undefined
|
|
@@ -26883,10 +27003,10 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26883
27003
|
}
|
|
26884
27004
|
const boundedLimit = Math.min(limit ?? DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);
|
|
26885
27005
|
const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
|
|
26886
|
-
const
|
|
27006
|
+
const componentRef = flags.component;
|
|
26887
27007
|
const hasShape = !!shape;
|
|
26888
27008
|
const strictExclude = !!flags["exclude-components"];
|
|
26889
|
-
validateComponentFilters(
|
|
27009
|
+
validateComponentFilters(componentRef, strictExclude, "wh thing list --component acme/veritas");
|
|
26890
27010
|
const excludeComponents = strictExclude;
|
|
26891
27011
|
const excludeInfraShapes = !strictExclude && !hasShape;
|
|
26892
27012
|
const headOpts = {
|
|
@@ -26896,7 +27016,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26896
27016
|
includeRetracted,
|
|
26897
27017
|
limit: pageLimit,
|
|
26898
27018
|
cursor,
|
|
26899
|
-
|
|
27019
|
+
componentRef,
|
|
26900
27020
|
excludeComponents,
|
|
26901
27021
|
excludeInfraShapes,
|
|
26902
27022
|
where: where.length > 0 ? where : undefined
|
|
@@ -26928,7 +27048,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26928
27048
|
includeRetracted,
|
|
26929
27049
|
limit: pageLimit,
|
|
26930
27050
|
cursor,
|
|
26931
|
-
|
|
27051
|
+
componentRef,
|
|
26932
27052
|
excludeComponents,
|
|
26933
27053
|
excludeInfraShapes,
|
|
26934
27054
|
where: where.length > 0 ? where : undefined
|
|
@@ -26939,7 +27059,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26939
27059
|
includeRetracted,
|
|
26940
27060
|
limit: boundedLimit,
|
|
26941
27061
|
cursor,
|
|
26942
|
-
|
|
27062
|
+
componentRef,
|
|
26943
27063
|
excludeComponents,
|
|
26944
27064
|
excludeInfraShapes,
|
|
26945
27065
|
where: where.length > 0 ? where : undefined
|
|
@@ -26947,7 +27067,10 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26947
27067
|
if (!all && result.nextCursor) {
|
|
26948
27068
|
emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
|
|
26949
27069
|
}
|
|
26950
|
-
|
|
27070
|
+
writePageOutput(ctx, result.items ?? [], {
|
|
27071
|
+
limit: all ? pageLimit : boundedLimit,
|
|
27072
|
+
nextCursor: result.nextCursor ?? null
|
|
27073
|
+
}, () => renderHead(ctx.out, ctx.colors, ctx.chars, result, org, repo, shape, kind));
|
|
26951
27074
|
};
|
|
26952
27075
|
async function fetchAllHeadPages(ctx, org, repo, opts) {
|
|
26953
27076
|
const items = [];
|
|
@@ -26960,7 +27083,7 @@ async function fetchAllHeadPages(ctx, org, repo, opts) {
|
|
|
26960
27083
|
includeRetracted: opts.includeRetracted,
|
|
26961
27084
|
limit: opts.limit,
|
|
26962
27085
|
cursor,
|
|
26963
|
-
|
|
27086
|
+
componentRef: opts.componentRef,
|
|
26964
27087
|
excludeComponents: opts.excludeComponents,
|
|
26965
27088
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
26966
27089
|
where: opts.where
|
|
@@ -26992,7 +27115,7 @@ var queryFlags = {
|
|
|
26992
27115
|
description: "Include assertions about collections (Pair/Triple/Set/List) containing the target. Only applies with --about."
|
|
26993
27116
|
}),
|
|
26994
27117
|
component: flag.string({
|
|
26995
|
-
description: "Filter to things owned by this component
|
|
27118
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
26996
27119
|
}),
|
|
26997
27120
|
"exclude-components": flag.boolean({
|
|
26998
27121
|
description: "Exclude component-owned things from results"
|
|
@@ -27014,10 +27137,10 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27014
27137
|
const count = flags.count;
|
|
27015
27138
|
const includeRetracted = flags["include-retracted"];
|
|
27016
27139
|
const resolveCollections = flags["resolve-collections"];
|
|
27017
|
-
const
|
|
27140
|
+
const componentRef = flags.component;
|
|
27018
27141
|
const hasShape = !!shape;
|
|
27019
27142
|
const strictExclude = !!flags["exclude-components"];
|
|
27020
|
-
validateComponentFilters(
|
|
27143
|
+
validateComponentFilters(componentRef, strictExclude, "wh thing query --component acme/veritas");
|
|
27021
27144
|
const excludeComponents = strictExclude;
|
|
27022
27145
|
const excludeInfraShapes = !strictExclude && !hasShape;
|
|
27023
27146
|
const c = ctx.colors;
|
|
@@ -27034,7 +27157,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27034
27157
|
about,
|
|
27035
27158
|
includeRetracted,
|
|
27036
27159
|
resolveCollections,
|
|
27037
|
-
|
|
27160
|
+
componentRef,
|
|
27038
27161
|
excludeComponents,
|
|
27039
27162
|
excludeInfraShapes,
|
|
27040
27163
|
where: where.length > 0 ? where : undefined
|
|
@@ -27057,7 +27180,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27057
27180
|
resolveCollections,
|
|
27058
27181
|
limit: pageLimit,
|
|
27059
27182
|
cursor,
|
|
27060
|
-
|
|
27183
|
+
componentRef,
|
|
27061
27184
|
excludeComponents,
|
|
27062
27185
|
excludeInfraShapes,
|
|
27063
27186
|
where: where.length > 0 ? where : undefined
|
|
@@ -27091,7 +27214,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27091
27214
|
resolveCollections,
|
|
27092
27215
|
limit: pageLimit,
|
|
27093
27216
|
cursor,
|
|
27094
|
-
|
|
27217
|
+
componentRef,
|
|
27095
27218
|
excludeComponents,
|
|
27096
27219
|
excludeInfraShapes,
|
|
27097
27220
|
where: where.length > 0 ? where : undefined
|
|
@@ -27104,7 +27227,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27104
27227
|
resolveCollections,
|
|
27105
27228
|
limit: boundedLimit,
|
|
27106
27229
|
cursor,
|
|
27107
|
-
|
|
27230
|
+
componentRef,
|
|
27108
27231
|
excludeComponents,
|
|
27109
27232
|
excludeInfraShapes,
|
|
27110
27233
|
where: where.length > 0 ? where : undefined
|
|
@@ -27112,7 +27235,10 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27112
27235
|
if (!all && result.nextCursor) {
|
|
27113
27236
|
emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
|
|
27114
27237
|
}
|
|
27115
|
-
|
|
27238
|
+
writePageOutput(ctx, result.items ?? [], {
|
|
27239
|
+
limit: all ? pageLimit : boundedLimit,
|
|
27240
|
+
nextCursor: result.nextCursor ?? null
|
|
27241
|
+
}, () => renderQueryResults(ctx.out, c, result));
|
|
27116
27242
|
};
|
|
27117
27243
|
async function fetchAllQueryPages(ctx, org, repo, opts) {
|
|
27118
27244
|
const items = [];
|
|
@@ -27127,7 +27253,7 @@ async function fetchAllQueryPages(ctx, org, repo, opts) {
|
|
|
27127
27253
|
resolveCollections: opts.resolveCollections,
|
|
27128
27254
|
limit: opts.limit,
|
|
27129
27255
|
cursor,
|
|
27130
|
-
|
|
27256
|
+
componentRef: opts.componentRef,
|
|
27131
27257
|
excludeComponents: opts.excludeComponents,
|
|
27132
27258
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
27133
27259
|
where: opts.where
|
|
@@ -27218,7 +27344,7 @@ var handleRefs = async (ctx, { flags, args }) => {
|
|
|
27218
27344
|
cur = page.nextCursor;
|
|
27219
27345
|
}
|
|
27220
27346
|
const result2 = { items, nextCursor: undefined };
|
|
27221
|
-
|
|
27347
|
+
writePageOutput(ctx, items, { limit: pageLimit, nextCursor: null }, () => renderRefs(ctx.out, ctx.colors, result2, wref, direction));
|
|
27222
27348
|
maybeEmitAboutHint(ctx, direction, items.length, refsQueryIsNarrowed);
|
|
27223
27349
|
return;
|
|
27224
27350
|
}
|
|
@@ -27226,7 +27352,7 @@ var handleRefs = async (ctx, { flags, args }) => {
|
|
|
27226
27352
|
if (result.nextCursor) {
|
|
27227
27353
|
emitPartialPageHint(ctx, (result.items ?? []).length, result.nextCursor, boundedLimit);
|
|
27228
27354
|
}
|
|
27229
|
-
|
|
27355
|
+
writePageOutput(ctx, result.items ?? [], { limit: boundedLimit, nextCursor: result.nextCursor ?? null }, () => renderRefs(ctx.out, ctx.colors, result, wref, direction));
|
|
27230
27356
|
maybeEmitAboutHint(ctx, direction, result.items?.length ?? 0, refsQueryIsNarrowed);
|
|
27231
27357
|
};
|
|
27232
27358
|
function maybeEmitAboutHint(ctx, direction, itemCount, refsQueryIsNarrowed) {
|
|
@@ -27405,7 +27531,7 @@ var searchFlags = {
|
|
|
27405
27531
|
cursor: flag.string({ description: "Opaque pagination cursor (text mode)" }),
|
|
27406
27532
|
all: flag.boolean({ description: "Fetch all pages (text mode)" }),
|
|
27407
27533
|
component: flag.string({
|
|
27408
|
-
description: "Filter to things owned by this component
|
|
27534
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
27409
27535
|
}),
|
|
27410
27536
|
"exclude-components": flag.boolean({
|
|
27411
27537
|
description: "Exclude component-owned things from results"
|
|
@@ -27442,10 +27568,10 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27442
27568
|
const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedTextLimit;
|
|
27443
27569
|
const resolveCollections = mode !== "hybrid" ? flags["resolve-collections"] : undefined;
|
|
27444
27570
|
const supportsComponentFilters = !mode || mode === "text";
|
|
27445
|
-
const
|
|
27571
|
+
const componentRef = supportsComponentFilters ? flags.component : undefined;
|
|
27446
27572
|
const hasShape = !!flags.shape;
|
|
27447
27573
|
const strictExclude = supportsComponentFilters ? !!flags["exclude-components"] : false;
|
|
27448
|
-
validateComponentFilters(
|
|
27574
|
+
validateComponentFilters(componentRef, strictExclude, 'wh thing search "policy" --component acme/veritas');
|
|
27449
27575
|
const excludeComponents = supportsComponentFilters && strictExclude ? true : undefined;
|
|
27450
27576
|
const excludeInfraShapes = supportsComponentFilters && !strictExclude && !hasShape ? true : undefined;
|
|
27451
27577
|
const rawResult = all ? await fetchAllSearchPages(ctx, org, repo, queryText, {
|
|
@@ -27456,7 +27582,7 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27456
27582
|
resolveCollections,
|
|
27457
27583
|
limit: pageLimit,
|
|
27458
27584
|
cursor,
|
|
27459
|
-
|
|
27585
|
+
componentRef,
|
|
27460
27586
|
excludeComponents,
|
|
27461
27587
|
excludeInfraShapes
|
|
27462
27588
|
}) : await ctx.client.thing.search(org, repo, queryText, {
|
|
@@ -27468,7 +27594,7 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27468
27594
|
limit: boundedTextLimit,
|
|
27469
27595
|
cursor,
|
|
27470
27596
|
mode,
|
|
27471
|
-
|
|
27597
|
+
componentRef,
|
|
27472
27598
|
excludeComponents,
|
|
27473
27599
|
excludeInfraShapes
|
|
27474
27600
|
});
|
|
@@ -27479,7 +27605,10 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27479
27605
|
if (!all && result.nextCursor) {
|
|
27480
27606
|
emitPartialPageHint(ctx, result.items.length, result.nextCursor, boundedTextLimit);
|
|
27481
27607
|
}
|
|
27482
|
-
|
|
27608
|
+
writePageOutput(ctx, result.items, {
|
|
27609
|
+
limit: all ? pageLimit : boundedTextLimit,
|
|
27610
|
+
nextCursor: result.nextCursor ?? null
|
|
27611
|
+
}, () => renderQueryResults(ctx.out, c, result));
|
|
27483
27612
|
};
|
|
27484
27613
|
async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
|
|
27485
27614
|
const items = [];
|
|
@@ -27494,7 +27623,7 @@ async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
|
|
|
27494
27623
|
limit: opts.limit,
|
|
27495
27624
|
cursor,
|
|
27496
27625
|
mode: "text",
|
|
27497
|
-
|
|
27626
|
+
componentRef: opts.componentRef,
|
|
27498
27627
|
excludeComponents: opts.excludeComponents,
|
|
27499
27628
|
excludeInfraShapes: opts.excludeInfraShapes
|
|
27500
27629
|
});
|
|
@@ -27847,13 +27976,16 @@ var THING_DOMAIN = defineDomain({
|
|
|
27847
27976
|
},
|
|
27848
27977
|
graph: {
|
|
27849
27978
|
prime: true,
|
|
27850
|
-
summary: "Fetch a thing's graph (
|
|
27979
|
+
summary: "Fetch a thing's graph (outbound wref fields, assertion backlinks, and assertion about targets)",
|
|
27851
27980
|
args: "<wref>",
|
|
27852
27981
|
flags: graphFlags,
|
|
27853
27982
|
examples: [
|
|
27854
27983
|
"wh thing graph Game/base",
|
|
27855
27984
|
"wh thing graph Game/base --depth 2"
|
|
27856
27985
|
],
|
|
27986
|
+
notes: [
|
|
27987
|
+
"`graph` does not traverse inbound wref-field references; use `wh thing refs <wref> --inbound` to find things whose fields point at this thing."
|
|
27988
|
+
],
|
|
27857
27989
|
handler: handleThingGraph
|
|
27858
27990
|
}
|
|
27859
27991
|
}
|
|
@@ -28161,7 +28293,10 @@ var handleHistory2 = async (ctx, { flags, args }) => {
|
|
|
28161
28293
|
versions,
|
|
28162
28294
|
nextCursor: flags.all ? undefined : nextCursor
|
|
28163
28295
|
};
|
|
28164
|
-
|
|
28296
|
+
if (!flags.all && result.nextCursor) {
|
|
28297
|
+
emitPartialPageHint(ctx, result.versions.length, result.nextCursor, limit);
|
|
28298
|
+
}
|
|
28299
|
+
writePageOutput(ctx, result.versions, { limit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
|
|
28165
28300
|
};
|
|
28166
28301
|
var handleCreate2 = async (ctx, { flags, args }) => {
|
|
28167
28302
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
|
|
@@ -28291,7 +28426,10 @@ var handleList = async (ctx, { flags, args }) => {
|
|
|
28291
28426
|
if (!all && result2.nextCursor) {
|
|
28292
28427
|
emitPartialPageHint(ctx, (result2.items ?? []).length, result2.nextCursor, boundedLimit);
|
|
28293
28428
|
}
|
|
28294
|
-
|
|
28429
|
+
writePageOutput(ctx, result2.items ?? [], {
|
|
28430
|
+
limit: all ? pageLimit : boundedLimit,
|
|
28431
|
+
nextCursor: result2.nextCursor ?? null
|
|
28432
|
+
}, () => renderHead(ctx.out, ctx.colors, ctx.chars, result2, org, repo, shape, "assertion"));
|
|
28295
28433
|
return;
|
|
28296
28434
|
}
|
|
28297
28435
|
const aboutOpts = {
|
|
@@ -28343,7 +28481,10 @@ var handleList = async (ctx, { flags, args }) => {
|
|
|
28343
28481
|
if (!all && result.nextCursor) {
|
|
28344
28482
|
emitPartialPageHint(ctx, (result.assertions ?? []).length, result.nextCursor, boundedLimit);
|
|
28345
28483
|
}
|
|
28346
|
-
|
|
28484
|
+
writePageOutput(ctx, result.assertions ?? [], {
|
|
28485
|
+
limit: all ? pageLimit : boundedLimit,
|
|
28486
|
+
nextCursor: result.nextCursor ?? null
|
|
28487
|
+
}, () => renderAbout(ctx.out, ctx.colors, result));
|
|
28347
28488
|
};
|
|
28348
28489
|
async function fetchAllAssertionAboutPages(ctx, org, repo, wref, opts) {
|
|
28349
28490
|
const assertions = [];
|
|
@@ -29417,7 +29558,7 @@ function ndjsonMessage(msg) {
|
|
|
29417
29558
|
return `${JSON.stringify(msg)}
|
|
29418
29559
|
`;
|
|
29419
29560
|
}
|
|
29420
|
-
function createMessageReader(input, onMessage) {
|
|
29561
|
+
function createMessageReader(input, onMessage, onError = () => {}) {
|
|
29421
29562
|
let buffer = "";
|
|
29422
29563
|
let mode = null;
|
|
29423
29564
|
function drain() {
|
|
@@ -29440,9 +29581,12 @@ function createMessageReader(input, onMessage) {
|
|
|
29440
29581
|
continue;
|
|
29441
29582
|
}
|
|
29442
29583
|
} else {
|
|
29443
|
-
const
|
|
29444
|
-
if (
|
|
29445
|
-
|
|
29584
|
+
const headerEnd = buffer.indexOf(HEADER_DELIMITER);
|
|
29585
|
+
if (headerEnd !== -1) {
|
|
29586
|
+
const resyncFrom = headerEnd + HEADER_DELIMITER.length;
|
|
29587
|
+
const nextHeaderMatch = /Content-Length:/i.exec(buffer.slice(resyncFrom));
|
|
29588
|
+
const nextHeader = nextHeaderMatch === null ? -1 : resyncFrom + nextHeaderMatch.index;
|
|
29589
|
+
buffer = nextHeader === -1 ? "" : buffer.slice(nextHeader);
|
|
29446
29590
|
continue;
|
|
29447
29591
|
}
|
|
29448
29592
|
}
|
|
@@ -29462,12 +29606,14 @@ function createMessageReader(input, onMessage) {
|
|
|
29462
29606
|
};
|
|
29463
29607
|
input.setEncoding("utf8");
|
|
29464
29608
|
input.on("data", onData);
|
|
29609
|
+
input.on("error", onError);
|
|
29465
29610
|
if ("resume" in input && typeof input.resume === "function") {
|
|
29466
29611
|
input.resume();
|
|
29467
29612
|
}
|
|
29468
29613
|
return {
|
|
29469
29614
|
close() {
|
|
29470
29615
|
input.removeListener("data", onData);
|
|
29616
|
+
input.removeListener("error", onError);
|
|
29471
29617
|
}
|
|
29472
29618
|
};
|
|
29473
29619
|
}
|
|
@@ -29477,9 +29623,25 @@ var MCP_PROTOCOL_VERSION2 = "2025-11-25";
|
|
|
29477
29623
|
function createChannelServer(opts) {
|
|
29478
29624
|
let reader = null;
|
|
29479
29625
|
let resolveReady;
|
|
29480
|
-
|
|
29626
|
+
let rejectReady;
|
|
29627
|
+
let readySettled = false;
|
|
29628
|
+
const onReady = new Promise((resolve, reject) => {
|
|
29481
29629
|
resolveReady = resolve;
|
|
29630
|
+
rejectReady = reject;
|
|
29482
29631
|
});
|
|
29632
|
+
function settleReady() {
|
|
29633
|
+
if (readySettled)
|
|
29634
|
+
return;
|
|
29635
|
+
readySettled = true;
|
|
29636
|
+
resolveReady();
|
|
29637
|
+
}
|
|
29638
|
+
function failReady(error) {
|
|
29639
|
+
if (readySettled)
|
|
29640
|
+
return;
|
|
29641
|
+
readySettled = true;
|
|
29642
|
+
reader?.close();
|
|
29643
|
+
rejectReady(error);
|
|
29644
|
+
}
|
|
29483
29645
|
function send(msg) {
|
|
29484
29646
|
opts.output.write(ndjsonMessage(msg));
|
|
29485
29647
|
}
|
|
@@ -29502,7 +29664,7 @@ function createChannelServer(opts) {
|
|
|
29502
29664
|
return;
|
|
29503
29665
|
}
|
|
29504
29666
|
if (method === "notifications/initialized") {
|
|
29505
|
-
|
|
29667
|
+
settleReady();
|
|
29506
29668
|
return;
|
|
29507
29669
|
}
|
|
29508
29670
|
if (method === "ping") {
|
|
@@ -29519,7 +29681,7 @@ function createChannelServer(opts) {
|
|
|
29519
29681
|
}
|
|
29520
29682
|
return {
|
|
29521
29683
|
start() {
|
|
29522
|
-
reader = createMessageReader(opts.input, handleMessage);
|
|
29684
|
+
reader = createMessageReader(opts.input, handleMessage, failReady);
|
|
29523
29685
|
},
|
|
29524
29686
|
notify(content, meta) {
|
|
29525
29687
|
send({
|
|
@@ -29531,6 +29693,7 @@ function createChannelServer(opts) {
|
|
|
29531
29693
|
onReady,
|
|
29532
29694
|
close() {
|
|
29533
29695
|
reader?.close();
|
|
29696
|
+
settleReady();
|
|
29534
29697
|
}
|
|
29535
29698
|
};
|
|
29536
29699
|
}
|
|
@@ -29593,7 +29756,16 @@ var handleChannel = async (ctx) => {
|
|
|
29593
29756
|
else
|
|
29594
29757
|
signal.addEventListener("abort", () => resolve("aborted"), { once: true });
|
|
29595
29758
|
});
|
|
29596
|
-
|
|
29759
|
+
let ready;
|
|
29760
|
+
try {
|
|
29761
|
+
ready = await Promise.race([server.onReady.then(() => {
|
|
29762
|
+
return;
|
|
29763
|
+
}), aborted]);
|
|
29764
|
+
} catch (err) {
|
|
29765
|
+
server.close();
|
|
29766
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29767
|
+
throw new CliError(4 /* Backend */, "BACKEND", `channel startup failed: ${msg}`);
|
|
29768
|
+
}
|
|
29597
29769
|
if (ready === "aborted") {
|
|
29598
29770
|
server.close();
|
|
29599
29771
|
return;
|
|
@@ -30969,13 +31141,16 @@ async function refreshFromSummaries(repoSlug, parsed, activeItems, client, now,
|
|
|
30969
31141
|
const components = {};
|
|
30970
31142
|
let detailReadFailures = 0;
|
|
30971
31143
|
for (const item of activeItems) {
|
|
31144
|
+
if (!item.ref)
|
|
31145
|
+
continue;
|
|
31146
|
+
const itemRef = item.ref;
|
|
30972
31147
|
let detail;
|
|
30973
31148
|
try {
|
|
30974
|
-
detail = await client.component.get(parsed.org, parsed.repo,
|
|
31149
|
+
detail = await client.component.get(parsed.org, parsed.repo, itemRef);
|
|
30975
31150
|
} catch {
|
|
30976
31151
|
detailReadFailures++;
|
|
30977
31152
|
const previousEntry = previousCache?.components[item.componentName];
|
|
30978
|
-
if (previousEntry?.
|
|
31153
|
+
if (previousEntry?.ref === itemRef) {
|
|
30979
31154
|
components[item.componentName] = previousEntry;
|
|
30980
31155
|
}
|
|
30981
31156
|
continue;
|
|
@@ -30990,7 +31165,7 @@ async function refreshFromSummaries(repoSlug, parsed, activeItems, client, now,
|
|
|
30990
31165
|
if (!ref)
|
|
30991
31166
|
continue;
|
|
30992
31167
|
components[item.componentName] = {
|
|
30993
|
-
|
|
31168
|
+
ref: itemRef,
|
|
30994
31169
|
ownerOrgName: ref.ownerOrgName,
|
|
30995
31170
|
registeredComponentName: ref.registeredComponentName,
|
|
30996
31171
|
version: manifest.component.version ?? item.version ?? "",
|
|
@@ -31350,7 +31525,7 @@ var handleComponentExec = async (ctx, { args, terminator }) => {
|
|
|
31350
31525
|
}
|
|
31351
31526
|
const method = entry.methods.find((m) => m.name === methodName);
|
|
31352
31527
|
if (!method) {
|
|
31353
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Method '${methodName}' not found on component '${componentName}'.`, undefined, `Available: ${entry.methods.map((m) => m.name).join(", ")}. Run wh component update ${
|
|
31528
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Method '${methodName}' not found on component '${componentName}'.`, undefined, `Available: ${entry.methods.map((m) => m.name).join(", ")}. Run wh component update ${entry.ref} --repo ${installRepo} if you expect a newer method.`);
|
|
31354
31529
|
}
|
|
31355
31530
|
if (helpRequested) {
|
|
31356
31531
|
renderMethodHelp(ctx, componentName, method);
|
|
@@ -31402,6 +31577,40 @@ function formatReservedNameWarning(name) {
|
|
|
31402
31577
|
return `warning: component name "${name}" shadows the builtin \`wh ${name}\` domain. Operators will need to invoke methods via \`wh component exec ${name} <method>\` — the shorthand \`wh ${name} <method>\` will route to the builtin instead.`;
|
|
31403
31578
|
}
|
|
31404
31579
|
|
|
31580
|
+
// ../../packages/warmhub-cli/src/global-search-command.ts
|
|
31581
|
+
var DEFAULT_LIMIT = 25;
|
|
31582
|
+
async function runGlobalSearchCommand(ctx, args) {
|
|
31583
|
+
const c = ctx.colors;
|
|
31584
|
+
const first = await args.fetch({ limit: args.limit, cursor: args.cursor });
|
|
31585
|
+
const items = [...first.items];
|
|
31586
|
+
let nextCursor = first.nextCursor;
|
|
31587
|
+
if (args.all) {
|
|
31588
|
+
while (nextCursor) {
|
|
31589
|
+
const page = await args.fetch({ limit: args.limit, cursor: nextCursor });
|
|
31590
|
+
items.push(...page.items);
|
|
31591
|
+
nextCursor = page.nextCursor;
|
|
31592
|
+
}
|
|
31593
|
+
}
|
|
31594
|
+
if (!args.all && nextCursor) {
|
|
31595
|
+
emitPartialPageHint(ctx, items.length, nextCursor, args.limit ?? DEFAULT_LIMIT);
|
|
31596
|
+
}
|
|
31597
|
+
writePageOutput(ctx, items, {
|
|
31598
|
+
limit: args.limit ?? DEFAULT_LIMIT,
|
|
31599
|
+
nextCursor: args.all ? null : nextCursor ?? null
|
|
31600
|
+
}, () => {
|
|
31601
|
+
if (items.length === 0) {
|
|
31602
|
+
ctx.status(`${c.dim}No ${args.emptyLabel} matching "${args.query}"${c.reset}`);
|
|
31603
|
+
return;
|
|
31604
|
+
}
|
|
31605
|
+
ctx.out(`${c.bold}${args.title}${c.reset} ${c.dim}"${args.query}"${c.reset}`);
|
|
31606
|
+
ctx.out("");
|
|
31607
|
+
for (const item of items) {
|
|
31608
|
+
const desc = item.description ? ` ${c.dim}${item.description}${c.reset}` : "";
|
|
31609
|
+
ctx.out(` ${c.cyan}${item.orgName}/${item.name}${c.reset}${desc}`);
|
|
31610
|
+
}
|
|
31611
|
+
});
|
|
31612
|
+
}
|
|
31613
|
+
|
|
31405
31614
|
// ../../packages/warmhub-cli/src/manifest/name-resolution.ts
|
|
31406
31615
|
function resolveManifestCredentialName(name, ctx) {
|
|
31407
31616
|
return resolveComponentTemplate(name, {
|
|
@@ -31459,7 +31668,7 @@ async function ensureSharedInfra(client, org, repo) {
|
|
|
31459
31668
|
name: shape.name,
|
|
31460
31669
|
data: { fields: shape.fields }
|
|
31461
31670
|
}
|
|
31462
|
-
], {
|
|
31671
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31463
31672
|
} catch (err) {
|
|
31464
31673
|
if (!isAlreadyExistsError(err)) {
|
|
31465
31674
|
throw err;
|
|
@@ -31472,7 +31681,7 @@ async function ensureSharedInfra(client, org, repo) {
|
|
|
31472
31681
|
name: shape.name,
|
|
31473
31682
|
data: { fields: shape.fields }
|
|
31474
31683
|
}
|
|
31475
|
-
], {
|
|
31684
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31476
31685
|
} catch {}
|
|
31477
31686
|
}
|
|
31478
31687
|
}
|
|
@@ -31505,6 +31714,15 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31505
31714
|
};
|
|
31506
31715
|
}
|
|
31507
31716
|
const componentName = typeof installData.name === "string" ? installData.name : componentId;
|
|
31717
|
+
const registeredComponentRef = typeof installData.registeredComponentRef === "string" && installData.registeredComponentRef.length > 0 ? installData.registeredComponentRef : undefined;
|
|
31718
|
+
if (!registeredComponentRef) {
|
|
31719
|
+
findings.push({
|
|
31720
|
+
resource: "ComponentInstall",
|
|
31721
|
+
status: "error",
|
|
31722
|
+
message: "Install record is missing registeredComponentRef"
|
|
31723
|
+
});
|
|
31724
|
+
return { componentId, componentName, state: "error", findings };
|
|
31725
|
+
}
|
|
31508
31726
|
const existingState = typeof installData.state === "string" ? installData.state : undefined;
|
|
31509
31727
|
if (existingState === "error") {
|
|
31510
31728
|
findings.push({
|
|
@@ -31543,12 +31761,12 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31543
31761
|
message: `Shape "${shape.name}" exists but is inactive`
|
|
31544
31762
|
});
|
|
31545
31763
|
} else {
|
|
31546
|
-
const
|
|
31547
|
-
if (
|
|
31764
|
+
const shapeComponentRef = s && typeof s === "object" && "componentRef" in s ? s.componentRef : undefined;
|
|
31765
|
+
if (shapeComponentRef !== undefined && shapeComponentRef !== registeredComponentRef) {
|
|
31548
31766
|
findings.push({
|
|
31549
31767
|
resource: `shape:${shape.name}`,
|
|
31550
31768
|
status: "warning",
|
|
31551
|
-
message: `Shape "${shape.name}" exists but is owned by "${
|
|
31769
|
+
message: `Shape "${shape.name}" exists but is owned by "${shapeComponentRef}"`
|
|
31552
31770
|
});
|
|
31553
31771
|
} else {
|
|
31554
31772
|
const expectedShapeData = manifestShapeData(shape);
|
|
@@ -31582,19 +31800,19 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31582
31800
|
hasSubs = true;
|
|
31583
31801
|
try {
|
|
31584
31802
|
const s = await client.subscription.get(org, repo, sub.name);
|
|
31585
|
-
const
|
|
31586
|
-
if (
|
|
31803
|
+
const subComponentRef = s && typeof s === "object" && "componentRef" in s ? s.componentRef : undefined;
|
|
31804
|
+
if (subComponentRef !== undefined && subComponentRef !== registeredComponentRef) {
|
|
31805
|
+
allSubsPaused = false;
|
|
31587
31806
|
findings.push({
|
|
31588
31807
|
resource: `sub:${sub.name}`,
|
|
31589
|
-
status: "
|
|
31590
|
-
message: `Subscription "${sub.name}" is
|
|
31808
|
+
status: "warning",
|
|
31809
|
+
message: `Subscription "${sub.name}" is owned by "${subComponentRef}"`
|
|
31591
31810
|
});
|
|
31592
|
-
} else if (
|
|
31593
|
-
allSubsPaused = false;
|
|
31811
|
+
} else if (!s.active) {
|
|
31594
31812
|
findings.push({
|
|
31595
31813
|
resource: `sub:${sub.name}`,
|
|
31596
|
-
status: "
|
|
31597
|
-
message: `Subscription "${sub.name}" is
|
|
31814
|
+
status: "inactive",
|
|
31815
|
+
message: `Subscription "${sub.name}" is paused`
|
|
31598
31816
|
});
|
|
31599
31817
|
} else {
|
|
31600
31818
|
allSubsPaused = false;
|
|
@@ -31664,10 +31882,11 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31664
31882
|
const hasMissing = findings.some((f) => f.status === "missing");
|
|
31665
31883
|
const hasInactive = findings.some((f) => f.status === "inactive" && !f.resource.startsWith("sub:"));
|
|
31666
31884
|
const hasShapeDrift = findings.some((f) => f.resource.startsWith("shape:") && f.status === "warning" && f.message.includes("differs from installed manifest"));
|
|
31885
|
+
const hasOwnershipConflict = findings.some((f) => (f.resource.startsWith("shape:") || f.resource.startsWith("sub:")) && f.status === "warning" && f.message.includes("owned by"));
|
|
31667
31886
|
let state;
|
|
31668
|
-
if (hasSubs && allSubsPaused && !hasMissing && !hasInactive && !hasShapeDrift) {
|
|
31887
|
+
if (hasSubs && allSubsPaused && !hasMissing && !hasInactive && !hasShapeDrift && !hasOwnershipConflict) {
|
|
31669
31888
|
state = "paused";
|
|
31670
|
-
} else if (hasMissing || hasInactive || hasShapeDrift) {
|
|
31889
|
+
} else if (hasMissing || hasInactive || hasShapeDrift || hasOwnershipConflict) {
|
|
31671
31890
|
state = "degraded";
|
|
31672
31891
|
} else {
|
|
31673
31892
|
state = "ready";
|
|
@@ -31680,7 +31899,7 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31680
31899
|
name: `ComponentInstall/${componentId}`,
|
|
31681
31900
|
data: { ...installData, state, checkedAt: new Date().toISOString() }
|
|
31682
31901
|
}
|
|
31683
|
-
], {
|
|
31902
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31684
31903
|
} catch {
|
|
31685
31904
|
findings.push({
|
|
31686
31905
|
resource: "state-update",
|
|
@@ -31774,6 +31993,22 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31774
31993
|
};
|
|
31775
31994
|
}
|
|
31776
31995
|
const componentName = typeof installData.name === "string" ? installData.name : componentId;
|
|
31996
|
+
const registeredComponentRef = typeof installData.registeredComponentRef === "string" && installData.registeredComponentRef.length > 0 ? installData.registeredComponentRef : undefined;
|
|
31997
|
+
if (!registeredComponentRef) {
|
|
31998
|
+
return {
|
|
31999
|
+
componentId,
|
|
32000
|
+
componentName,
|
|
32001
|
+
state: "error",
|
|
32002
|
+
steps: [
|
|
32003
|
+
{
|
|
32004
|
+
step: "load-install",
|
|
32005
|
+
status: "error",
|
|
32006
|
+
message: "Install record is missing registeredComponentRef"
|
|
32007
|
+
}
|
|
32008
|
+
],
|
|
32009
|
+
errors: ["Install record is missing registeredComponentRef"]
|
|
32010
|
+
};
|
|
32011
|
+
}
|
|
31777
32012
|
let subscriptionNames = [];
|
|
31778
32013
|
let teardownPolicy = {};
|
|
31779
32014
|
try {
|
|
@@ -31796,9 +32031,9 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31796
32031
|
for (const subName of subscriptionNames) {
|
|
31797
32032
|
try {
|
|
31798
32033
|
const sub = await client.subscription.get(org, repo, subName);
|
|
31799
|
-
const
|
|
31800
|
-
if (typeof
|
|
31801
|
-
const msg = `Subscription "${subName}" is owned by "${
|
|
32034
|
+
const ownerComponentRef = sub && typeof sub === "object" && "componentRef" in sub ? sub.componentRef : undefined;
|
|
32035
|
+
if (typeof ownerComponentRef === "string" && ownerComponentRef !== registeredComponentRef) {
|
|
32036
|
+
const msg = `Subscription "${subName}" is owned by "${ownerComponentRef}", not "${registeredComponentRef}"`;
|
|
31802
32037
|
errors.push(msg);
|
|
31803
32038
|
steps.push({
|
|
31804
32039
|
step: `pause-${subName}`,
|
|
@@ -31847,7 +32082,7 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31847
32082
|
updatedAt: new Date().toISOString()
|
|
31848
32083
|
}
|
|
31849
32084
|
}
|
|
31850
|
-
], {
|
|
32085
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31851
32086
|
steps.push({ step: "update-state", status: "ok" });
|
|
31852
32087
|
} catch (err) {
|
|
31853
32088
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -31920,6 +32155,12 @@ function resolveMintedTokensFlag(args) {
|
|
|
31920
32155
|
return false;
|
|
31921
32156
|
return;
|
|
31922
32157
|
}
|
|
32158
|
+
var showSecretsFlag = flag.boolean({
|
|
32159
|
+
description: "Reveal raw lifecycle URLs in command output"
|
|
32160
|
+
});
|
|
32161
|
+
var showSecretsStructuredOutputFlag = flag.boolean({
|
|
32162
|
+
description: "Reveal raw lifecycle URLs in JSON/JSONL output"
|
|
32163
|
+
});
|
|
31923
32164
|
var installFlags = {};
|
|
31924
32165
|
var updateFlags = {};
|
|
31925
32166
|
var validateFlags = {};
|
|
@@ -31932,13 +32173,15 @@ var listFlags2 = {
|
|
|
31932
32173
|
description: "Fetch all pages (auto-paginate until exhausted)"
|
|
31933
32174
|
})
|
|
31934
32175
|
};
|
|
32176
|
+
var DEFAULT_COMPONENT_LIST_LIMIT = 50;
|
|
32177
|
+
var MAX_COMPONENT_LIST_LIMIT = 500;
|
|
31935
32178
|
var viewFlags3 = {};
|
|
31936
32179
|
var teardownFlags = {};
|
|
31937
32180
|
var doctorFlags = {};
|
|
31938
32181
|
var initFlags = {};
|
|
31939
32182
|
var searchFlags2 = {
|
|
31940
32183
|
limit: flag.number({
|
|
31941
|
-
description: "Maximum
|
|
32184
|
+
description: "Maximum results per page"
|
|
31942
32185
|
}),
|
|
31943
32186
|
cursor: flag.string({ description: "Opaque pagination cursor" }),
|
|
31944
32187
|
all: flag.boolean({
|
|
@@ -31984,7 +32227,8 @@ var registerFlags = {
|
|
|
31984
32227
|
}),
|
|
31985
32228
|
"no-minted-tokens": flag.boolean({
|
|
31986
32229
|
description: "Disable minted tokens (default)"
|
|
31987
|
-
})
|
|
32230
|
+
}),
|
|
32231
|
+
"show-secrets": showSecretsFlag
|
|
31988
32232
|
};
|
|
31989
32233
|
function readManifestArg(path2) {
|
|
31990
32234
|
let raw;
|
|
@@ -32008,9 +32252,12 @@ var unregisterFlags = {};
|
|
|
32008
32252
|
var registryListFlags = {
|
|
32009
32253
|
org: flag.string({
|
|
32010
32254
|
description: "Owner org to list registrations for"
|
|
32011
|
-
})
|
|
32255
|
+
}),
|
|
32256
|
+
"show-secrets": showSecretsStructuredOutputFlag
|
|
32257
|
+
};
|
|
32258
|
+
var registryViewFlags = {
|
|
32259
|
+
"show-secrets": showSecretsFlag
|
|
32012
32260
|
};
|
|
32013
|
-
var registryViewFlags = {};
|
|
32014
32261
|
var registryUpdateFlags = {
|
|
32015
32262
|
manifest: flag.string({
|
|
32016
32263
|
description: "Path to a manifest.json to publish as a new version (optional; must have a strictly-greater semver)"
|
|
@@ -32049,7 +32296,8 @@ var registryUpdateFlags = {
|
|
|
32049
32296
|
}),
|
|
32050
32297
|
"no-minted-tokens": flag.boolean({
|
|
32051
32298
|
description: "Disable minted tokens"
|
|
32052
|
-
})
|
|
32299
|
+
}),
|
|
32300
|
+
"show-secrets": showSecretsFlag
|
|
32053
32301
|
};
|
|
32054
32302
|
function asRecord(value) {
|
|
32055
32303
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -32069,38 +32317,11 @@ function componentInstallCanonicalId(item) {
|
|
|
32069
32317
|
const data = asRecord(item.data);
|
|
32070
32318
|
return componentInstallIdFromWref(item.wref) ?? readString(data, "id") ?? readString(data, "componentId") ?? item.name;
|
|
32071
32319
|
}
|
|
32072
|
-
function
|
|
32073
|
-
return
|
|
32074
|
-
}
|
|
32075
|
-
function componentInstallIdentityIds(item) {
|
|
32076
|
-
const data = asRecord(item.data);
|
|
32077
|
-
return uniqueStrings([
|
|
32078
|
-
componentInstallCanonicalId(item),
|
|
32079
|
-
readString(data, "id"),
|
|
32080
|
-
readString(data, "componentId"),
|
|
32081
|
-
item.name
|
|
32082
|
-
]);
|
|
32083
|
-
}
|
|
32084
|
-
function componentInstallHasExactId(item, name) {
|
|
32085
|
-
return componentInstallIdentityIds(item).includes(name);
|
|
32320
|
+
function componentInstallHasRegisteredRef(item, ref) {
|
|
32321
|
+
return readString(asRecord(item.data), "registeredComponentRef") === ref;
|
|
32086
32322
|
}
|
|
32087
|
-
function
|
|
32088
|
-
return readString(asRecord(item.data), "name") === name;
|
|
32089
|
-
}
|
|
32090
|
-
function formatComponentInstallAmbiguity(name, matches) {
|
|
32091
|
-
const componentIds = uniqueStrings(matches.map((item) => componentInstallCanonicalId(item)));
|
|
32092
|
-
const listedIds = componentIds.map((id) => `- ${id}`).join(`
|
|
32093
|
-
`);
|
|
32094
|
-
const exampleId = componentIds[0] ?? name;
|
|
32095
|
-
return {
|
|
32096
|
-
message: `Component name "${name}" is ambiguous. It matches multiple installed components:
|
|
32097
|
-
${listedIds}`,
|
|
32098
|
-
hint: `Use a component id instead, for example: wh component doctor ${exampleId}`
|
|
32099
|
-
};
|
|
32100
|
-
}
|
|
32101
|
-
async function resolveComponentDoctorId(client, org, repo, name) {
|
|
32323
|
+
async function resolveInstalledComponentRefId(client, org, repo, ref) {
|
|
32102
32324
|
let cursor;
|
|
32103
|
-
const displayNameMatches = [];
|
|
32104
32325
|
do {
|
|
32105
32326
|
const result = await client.thing.head(org, repo, {
|
|
32106
32327
|
shape: "ComponentInstall",
|
|
@@ -32109,35 +32330,27 @@ async function resolveComponentDoctorId(client, org, repo, name) {
|
|
|
32109
32330
|
cursor
|
|
32110
32331
|
});
|
|
32111
32332
|
const items = result.items ?? [];
|
|
32112
|
-
const exactMatch = items.find((item) =>
|
|
32333
|
+
const exactMatch = items.find((item) => componentInstallHasRegisteredRef(item, ref));
|
|
32113
32334
|
const resolved = exactMatch ? componentInstallCanonicalId(exactMatch) : undefined;
|
|
32114
32335
|
if (resolved) {
|
|
32115
32336
|
return resolved;
|
|
32116
32337
|
}
|
|
32117
|
-
displayNameMatches.push(...items.filter((item) => componentInstallHasDisplayName(item, name)));
|
|
32118
32338
|
cursor = result.nextCursor;
|
|
32119
32339
|
} while (cursor);
|
|
32120
|
-
|
|
32121
|
-
return componentInstallCanonicalId(displayNameMatches[0]) ?? name;
|
|
32122
|
-
}
|
|
32123
|
-
if (displayNameMatches.length > 1) {
|
|
32124
|
-
const { message, hint } = formatComponentInstallAmbiguity(name, displayNameMatches);
|
|
32125
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", message, undefined, hint);
|
|
32126
|
-
}
|
|
32127
|
-
return name;
|
|
32340
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${ref}' is not installed. Run 'wh component install <org>/<name>' first.`);
|
|
32128
32341
|
}
|
|
32129
32342
|
var handleUpdate = async (ctx, { args }) => {
|
|
32130
|
-
const
|
|
32131
|
-
|
|
32132
|
-
|
|
32343
|
+
const ref = args[0];
|
|
32344
|
+
const usage = "Usage: wh component update <org/name> --repo org/repo";
|
|
32345
|
+
const example = "wh component update warmhub/research-knowledge --repo org/repo";
|
|
32346
|
+
if (!ref) {
|
|
32347
|
+
usageError(usage, example);
|
|
32133
32348
|
}
|
|
32134
|
-
|
|
32135
|
-
|
|
32136
|
-
|
|
32137
|
-
} catch {
|
|
32138
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${name}' is not installed. Run 'wh component install <org>/<name>' first.`);
|
|
32349
|
+
resolveRegisteredComponentRef(ref, usage, example);
|
|
32350
|
+
if (ctx.liveMode === false) {
|
|
32351
|
+
usageError("Dry-run is not supported for component update.", "wh component update warmhub/research-knowledge --repo org/repo");
|
|
32139
32352
|
}
|
|
32140
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${
|
|
32353
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${ref}' could not be updated through the component shell boundary.`, undefined, "Run `wh component update <org/name> --repo org/repo` without --dry-run.");
|
|
32141
32354
|
};
|
|
32142
32355
|
var handleRegister = async (ctx, { flags, args }) => {
|
|
32143
32356
|
const componentName = args[0];
|
|
@@ -32178,7 +32391,8 @@ var handleRegister = async (ctx, { flags, args }) => {
|
|
|
32178
32391
|
if (reservedWarning) {
|
|
32179
32392
|
ctx.err(reservedWarning);
|
|
32180
32393
|
}
|
|
32181
|
-
|
|
32394
|
+
const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
|
|
32395
|
+
writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
|
|
32182
32396
|
};
|
|
32183
32397
|
var handleUnregister = async (ctx, { args }) => {
|
|
32184
32398
|
const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component unregister <org/name>", "wh component unregister warmhub/veritas");
|
|
@@ -32193,12 +32407,14 @@ var handleRegistryList = async (ctx, { flags, args }) => {
|
|
|
32193
32407
|
usageError("Usage: wh component registry list --org <org>", "wh component registry list --org warmhub");
|
|
32194
32408
|
}
|
|
32195
32409
|
const result = await ctx.client.component.registry.list(orgName);
|
|
32196
|
-
|
|
32410
|
+
const items = redactRegistryEntryListLifecycleUrls(result.items, flags["show-secrets"]);
|
|
32411
|
+
writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => renderRegistryList(ctx, orgName, { ...result, items }));
|
|
32197
32412
|
};
|
|
32198
|
-
var handleRegistryView = async (ctx, { args }) => {
|
|
32413
|
+
var handleRegistryView = async (ctx, { flags, args }) => {
|
|
32199
32414
|
const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component registry view <org/name>", "wh component registry view warmhub/veritas");
|
|
32200
32415
|
const result = await ctx.client.component.registry.view(orgName, componentName);
|
|
32201
|
-
|
|
32416
|
+
const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
|
|
32417
|
+
writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
|
|
32202
32418
|
};
|
|
32203
32419
|
var handleRegistryUpdate = async (ctx, { flags, args }) => {
|
|
32204
32420
|
const { orgName, componentName } = resolveRegisteredComponentRef(args[0], "Usage: wh component registry update <org/name> [flags]", "wh component registry update warmhub/veritas --public");
|
|
@@ -32226,12 +32442,12 @@ var handleRegistryUpdate = async (ctx, { flags, args }) => {
|
|
|
32226
32442
|
description: flags.description,
|
|
32227
32443
|
mintedTokens
|
|
32228
32444
|
});
|
|
32229
|
-
|
|
32445
|
+
const output = redactRegistryEntryLifecycleUrls(result, flags["show-secrets"]);
|
|
32446
|
+
writeOutput(ctx, output, () => renderRegistryEntry(ctx, output));
|
|
32230
32447
|
};
|
|
32231
|
-
var handleInstall = async (
|
|
32448
|
+
var handleInstall = async (_ctx, { args }) => {
|
|
32232
32449
|
const source = args[0];
|
|
32233
|
-
const usage =
|
|
32234
|
-
source: <org>/<name> (registered component)`;
|
|
32450
|
+
const usage = "Usage: wh component install <org/name> --repo org/repo";
|
|
32235
32451
|
const example = "wh component install warmhub/veritas --repo myorg/myrepo";
|
|
32236
32452
|
if (!source) {
|
|
32237
32453
|
usageError(usage, example);
|
|
@@ -32262,9 +32478,12 @@ var handleList2 = async (ctx, { flags }) => {
|
|
|
32262
32478
|
const c = ctx.colors;
|
|
32263
32479
|
const { items, nextCursor } = await fetchComponentPages(ctx.client, org, repo, { all: flags.all, limit: flags.limit, cursor: flags.cursor });
|
|
32264
32480
|
if (!flags.all && nextCursor) {
|
|
32265
|
-
ctx
|
|
32481
|
+
emitPartialPageHint(ctx, items.length, nextCursor, Math.min(flags.limit ?? DEFAULT_COMPONENT_LIST_LIMIT, MAX_COMPONENT_LIST_LIMIT));
|
|
32266
32482
|
}
|
|
32267
|
-
|
|
32483
|
+
writePageOutput(ctx, items, {
|
|
32484
|
+
limit: Math.min(flags.limit ?? DEFAULT_COMPONENT_LIST_LIMIT, MAX_COMPONENT_LIST_LIMIT),
|
|
32485
|
+
nextCursor: flags.all ? null : nextCursor ?? null
|
|
32486
|
+
}, () => {
|
|
32268
32487
|
if (!items.length) {
|
|
32269
32488
|
ctx.status(`${c.dim}No components installed${c.reset}`);
|
|
32270
32489
|
return;
|
|
@@ -32276,51 +32495,41 @@ var handleList2 = async (ctx, { flags }) => {
|
|
|
32276
32495
|
const state = item.state ?? "unknown";
|
|
32277
32496
|
const source = item.source ?? "-";
|
|
32278
32497
|
const stateColor = stateToColor(c, state);
|
|
32279
|
-
ctx.out(` ${c.cyan}${item.
|
|
32498
|
+
ctx.out(` ${c.cyan}${item.ref ?? item.componentName}${c.reset} ${stateColor}${state}${c.reset} ${c.dim}v${version}${c.reset} ${source}`);
|
|
32280
32499
|
}
|
|
32281
32500
|
});
|
|
32282
32501
|
};
|
|
32283
32502
|
var handleSearch2 = async (ctx, { flags, args }) => {
|
|
32284
32503
|
const query = args[0]?.trim();
|
|
32285
32504
|
if (!query) {
|
|
32286
|
-
usageError("Usage: wh component search <query>
|
|
32505
|
+
usageError("Usage: wh component search <query>", 'wh component search "subjective logic"');
|
|
32287
32506
|
}
|
|
32288
|
-
|
|
32289
|
-
|
|
32290
|
-
|
|
32291
|
-
const needle = query.toLowerCase();
|
|
32292
|
-
const items = allItems.filter((item) => [item.componentId, item.componentName, item.source].filter((value) => typeof value === "string").some((value) => value.toLowerCase().includes(needle)));
|
|
32293
|
-
if (!flags.all && nextCursor) {
|
|
32294
|
-
ctx.status(`${c.yellow}${allItems.length} component(s) searched, more pages available${c.reset} — matches beyond this page were not searched. ` + `Use ${c.cyan}--all${c.reset} to search every page, ` + `or re-run the same command plus ${c.cyan}--cursor=${nextCursor}${c.reset} to continue from here.`);
|
|
32507
|
+
if (getRepoRef(ctx)) {
|
|
32508
|
+
const c = ctx.colors;
|
|
32509
|
+
ctx.status(`${c.dim}--repo is ignored: \`wh component search\` searches the cross-org registry. ` + `Use \`wh component list --repo <org/repo>\` to see installed components.${c.reset}`);
|
|
32295
32510
|
}
|
|
32296
|
-
|
|
32297
|
-
|
|
32298
|
-
|
|
32299
|
-
|
|
32300
|
-
|
|
32301
|
-
ctx.
|
|
32302
|
-
|
|
32303
|
-
|
|
32304
|
-
const version = item.version ?? "unknown";
|
|
32305
|
-
const state = item.state ?? "unknown";
|
|
32306
|
-
const source = item.source ?? "-";
|
|
32307
|
-
const stateColor = stateToColor(c, state);
|
|
32308
|
-
ctx.out(` ${c.cyan}${item.componentId}${c.reset} ${stateColor}${state}${c.reset} ${c.dim}v${version}${c.reset} ${source}`);
|
|
32309
|
-
}
|
|
32511
|
+
await runGlobalSearchCommand(ctx, {
|
|
32512
|
+
query,
|
|
32513
|
+
all: flags.all,
|
|
32514
|
+
limit: flags.limit,
|
|
32515
|
+
cursor: flags.cursor,
|
|
32516
|
+
fetch: (opts) => ctx.client.component.search(query, opts),
|
|
32517
|
+
title: "Component search",
|
|
32518
|
+
emptyLabel: "public components"
|
|
32310
32519
|
});
|
|
32311
32520
|
};
|
|
32312
32521
|
var handleView3 = async (ctx, { args }) => {
|
|
32313
|
-
const
|
|
32314
|
-
const usage = "Usage: wh component view <name> --repo org/repo";
|
|
32315
|
-
const example = "wh component view research-knowledge --repo myorg/myrepo";
|
|
32316
|
-
if (!
|
|
32522
|
+
const ref = args[0];
|
|
32523
|
+
const usage = "Usage: wh component view <org/name> --repo org/repo";
|
|
32524
|
+
const example = "wh component view myorg/research-knowledge --repo myorg/myrepo";
|
|
32525
|
+
if (!ref) {
|
|
32317
32526
|
usageError(usage, example);
|
|
32318
32527
|
}
|
|
32319
32528
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32320
|
-
const viewData = await ctx.client.component.get(org, repo,
|
|
32529
|
+
const viewData = await ctx.client.component.get(org, repo, ref);
|
|
32321
32530
|
writeOutput(ctx, viewData, () => {
|
|
32322
32531
|
const c = ctx.colors;
|
|
32323
|
-
ctx.out(`${c.bold}Component:${c.reset} ${c.cyan}${
|
|
32532
|
+
ctx.out(`${c.bold}Component:${c.reset} ${c.cyan}${viewData.ref ?? ref}${c.reset}`);
|
|
32324
32533
|
ctx.out(`${c.bold}Version:${c.reset} ${viewData.version ?? "unknown"}`);
|
|
32325
32534
|
ctx.out(`${c.bold}State:${c.reset} ${viewData.state ?? "-"}`);
|
|
32326
32535
|
ctx.out(`${c.bold}Source:${c.reset} ${viewData.source ?? "-"}`);
|
|
@@ -32396,23 +32605,24 @@ function renderValidationResult(ctx, result) {
|
|
|
32396
32605
|
var handleDoctor = async (ctx, { args }) => {
|
|
32397
32606
|
const name = args[0];
|
|
32398
32607
|
if (!name) {
|
|
32399
|
-
usageError("Usage: wh component doctor <name> --repo org/repo", "wh component doctor research-knowledge --repo myorg/myrepo");
|
|
32608
|
+
usageError("Usage: wh component doctor <org/name> --repo org/repo", "wh component doctor warmhub/research-knowledge --repo myorg/myrepo");
|
|
32400
32609
|
}
|
|
32401
32610
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32402
|
-
const componentId = await
|
|
32611
|
+
const componentId = await resolveInstalledComponentRefId(ctx.client, org, repo, name);
|
|
32403
32612
|
const result = await doctorComponent(ctx.client, org, repo, componentId);
|
|
32404
32613
|
writeOutput(ctx, result, () => renderDoctorResult(ctx, result));
|
|
32405
32614
|
};
|
|
32406
32615
|
var handleTeardown = async (ctx, { args }) => {
|
|
32407
32616
|
const name = args[0];
|
|
32408
32617
|
if (!name) {
|
|
32409
|
-
usageError("Usage: wh component teardown <name> --repo org/repo", "wh component teardown research-knowledge --repo myorg/myrepo");
|
|
32618
|
+
usageError("Usage: wh component teardown <org/name> --repo org/repo", "wh component teardown warmhub/research-knowledge --repo myorg/myrepo");
|
|
32410
32619
|
}
|
|
32411
32620
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32412
32621
|
const repoSlug = `${org}/${repo}`;
|
|
32622
|
+
const componentId = await resolveInstalledComponentRefId(ctx.client, org, repo, name);
|
|
32413
32623
|
let result;
|
|
32414
32624
|
try {
|
|
32415
|
-
result = await teardownComponent(ctx.client, org, repo,
|
|
32625
|
+
result = await teardownComponent(ctx.client, org, repo, componentId);
|
|
32416
32626
|
} catch (error) {
|
|
32417
32627
|
invalidateInstallSnapshotCache(repoSlug);
|
|
32418
32628
|
throw error;
|
|
@@ -32480,10 +32690,10 @@ function renderRegistryEntry(ctx, entry) {
|
|
|
32480
32690
|
ctx.out(` Source: ${c.dim}(not installable — no source URL)${c.reset}`);
|
|
32481
32691
|
}
|
|
32482
32692
|
if (entry.setupUrl) {
|
|
32483
|
-
ctx.out(` Setup: ${entry.setupUrl}`);
|
|
32693
|
+
ctx.out(` Setup: ${formatLifecycleUrl(entry.setupUrl, c)}`);
|
|
32484
32694
|
}
|
|
32485
32695
|
if (entry.uninstallUrl) {
|
|
32486
|
-
ctx.out(` Uninstall: ${entry.uninstallUrl}`);
|
|
32696
|
+
ctx.out(` Uninstall: ${formatLifecycleUrl(entry.uninstallUrl, c)}`);
|
|
32487
32697
|
}
|
|
32488
32698
|
if (entry.credentialSetName || entry.credentialSetId) {
|
|
32489
32699
|
ctx.out(` Credential set: ${entry.credentialSetName ?? entry.credentialSetId}`);
|
|
@@ -32493,6 +32703,43 @@ function renderRegistryEntry(ctx, entry) {
|
|
|
32493
32703
|
}
|
|
32494
32704
|
ctx.out(` ${c.dim}Updated: ${new Date(entry.updatedAt).toISOString().slice(0, 16)}${c.reset}`);
|
|
32495
32705
|
}
|
|
32706
|
+
function redactRegistryEntryLifecycleUrls(entry, showSecrets) {
|
|
32707
|
+
if (showSecrets)
|
|
32708
|
+
return entry;
|
|
32709
|
+
return {
|
|
32710
|
+
...entry,
|
|
32711
|
+
...entry.setupUrl ? { setupUrl: redactSecretBearingUrl(entry.setupUrl) } : {},
|
|
32712
|
+
...entry.uninstallUrl ? { uninstallUrl: redactSecretBearingUrl(entry.uninstallUrl) } : {}
|
|
32713
|
+
};
|
|
32714
|
+
}
|
|
32715
|
+
function redactRegistryEntryListLifecycleUrls(entries, showSecrets) {
|
|
32716
|
+
if (showSecrets)
|
|
32717
|
+
return entries;
|
|
32718
|
+
return entries.map((entry) => redactRegistryEntryLifecycleUrls(entry, showSecrets));
|
|
32719
|
+
}
|
|
32720
|
+
var REDACTED_LIFECYCLE_URL = "[redacted-url]";
|
|
32721
|
+
var REDACTED_LIFECYCLE_PATH_SUFFIX = "/***";
|
|
32722
|
+
function redactSecretBearingUrl(rawUrl) {
|
|
32723
|
+
try {
|
|
32724
|
+
const origin = new URL(rawUrl).origin;
|
|
32725
|
+
if (origin === "null") {
|
|
32726
|
+
return REDACTED_LIFECYCLE_URL;
|
|
32727
|
+
}
|
|
32728
|
+
return `${origin}${REDACTED_LIFECYCLE_PATH_SUFFIX}`;
|
|
32729
|
+
} catch {
|
|
32730
|
+
return REDACTED_LIFECYCLE_URL;
|
|
32731
|
+
}
|
|
32732
|
+
}
|
|
32733
|
+
function formatLifecycleUrl(url, colors) {
|
|
32734
|
+
if (url === REDACTED_LIFECYCLE_URL) {
|
|
32735
|
+
return `${colors.dim}${url}${colors.reset}`;
|
|
32736
|
+
}
|
|
32737
|
+
if (url.endsWith(REDACTED_LIFECYCLE_PATH_SUFFIX)) {
|
|
32738
|
+
const visiblePrefix = url.slice(0, -REDACTED_LIFECYCLE_PATH_SUFFIX.length);
|
|
32739
|
+
return `${visiblePrefix}${colors.dim}${REDACTED_LIFECYCLE_PATH_SUFFIX}${colors.reset}`;
|
|
32740
|
+
}
|
|
32741
|
+
return url;
|
|
32742
|
+
}
|
|
32496
32743
|
function renderRegistryList(ctx, orgName, result) {
|
|
32497
32744
|
const c = ctx.colors;
|
|
32498
32745
|
if (!result.items.length) {
|
|
@@ -32543,7 +32790,7 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32543
32790
|
install: {
|
|
32544
32791
|
prime: true,
|
|
32545
32792
|
summary: "Install a registered component by its <org>/<name> ref",
|
|
32546
|
-
args: "<
|
|
32793
|
+
args: "<org/name>",
|
|
32547
32794
|
flags: installFlags,
|
|
32548
32795
|
examples: [
|
|
32549
32796
|
"wh component install warmhub/identity --repo org/repo",
|
|
@@ -32553,9 +32800,9 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32553
32800
|
},
|
|
32554
32801
|
update: {
|
|
32555
32802
|
summary: "Update an installed registered component to the latest manifest",
|
|
32556
|
-
args: "<name>",
|
|
32803
|
+
args: "<org/name>",
|
|
32557
32804
|
flags: updateFlags,
|
|
32558
|
-
examples: ["wh component update
|
|
32805
|
+
examples: ["wh component update warmhub/identity --repo org/repo"],
|
|
32559
32806
|
handler: handleUpdate
|
|
32560
32807
|
},
|
|
32561
32808
|
list: {
|
|
@@ -32569,25 +32816,25 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32569
32816
|
view: {
|
|
32570
32817
|
prime: true,
|
|
32571
32818
|
summary: "Show component details",
|
|
32572
|
-
args: "<name>",
|
|
32819
|
+
args: "<org/name>",
|
|
32573
32820
|
flags: viewFlags3,
|
|
32574
|
-
examples: ["wh component view
|
|
32821
|
+
examples: ["wh component view warmhub/identity --repo org/repo"],
|
|
32575
32822
|
handler: handleView3
|
|
32576
32823
|
},
|
|
32577
32824
|
teardown: {
|
|
32578
32825
|
prime: true,
|
|
32579
32826
|
summary: "Pause component subscriptions",
|
|
32580
|
-
args: "<name>",
|
|
32827
|
+
args: "<org/name>",
|
|
32581
32828
|
flags: teardownFlags,
|
|
32582
|
-
examples: ["wh component teardown
|
|
32829
|
+
examples: ["wh component teardown warmhub/identity --repo org/repo"],
|
|
32583
32830
|
handler: handleTeardown
|
|
32584
32831
|
},
|
|
32585
32832
|
doctor: {
|
|
32586
32833
|
prime: true,
|
|
32587
32834
|
summary: "Run component health checks",
|
|
32588
|
-
args: "<name>",
|
|
32835
|
+
args: "<org/name>",
|
|
32589
32836
|
flags: doctorFlags,
|
|
32590
|
-
examples: ["wh component doctor
|
|
32837
|
+
examples: ["wh component doctor warmhub/identity --repo org/repo"],
|
|
32591
32838
|
handler: handleDoctor
|
|
32592
32839
|
},
|
|
32593
32840
|
init: {
|
|
@@ -32616,10 +32863,13 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32616
32863
|
handler: handleComponentExec
|
|
32617
32864
|
},
|
|
32618
32865
|
search: {
|
|
32619
|
-
summary: "Search
|
|
32866
|
+
summary: "Search public components across all orgs (the registry). To list components installed in a repo, use `wh component list --repo`.",
|
|
32620
32867
|
args: "<query>",
|
|
32621
32868
|
flags: searchFlags2,
|
|
32622
|
-
examples: [
|
|
32869
|
+
examples: [
|
|
32870
|
+
'wh component search "subjective logic"',
|
|
32871
|
+
"wh component search reputation"
|
|
32872
|
+
],
|
|
32623
32873
|
handler: handleSearch2
|
|
32624
32874
|
}
|
|
32625
32875
|
},
|
|
@@ -32742,7 +32992,7 @@ var handleCreate3 = async (ctx, { flags, args }) => {
|
|
|
32742
32992
|
var handleList3 = async (ctx, { flags }) => {
|
|
32743
32993
|
const context = resolveCredentialContext({ ctx, orgFlag: flags.org });
|
|
32744
32994
|
const items = await ctx.client.credential.listSets(context.org, context.repo);
|
|
32745
|
-
|
|
32995
|
+
writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
|
|
32746
32996
|
const c = ctx.colors;
|
|
32747
32997
|
if (!items.length) {
|
|
32748
32998
|
ctx.status(`${c.dim}No credential sets in ${formatCredentialContextTarget(context)}${c.reset}`);
|
|
@@ -32893,7 +33143,7 @@ var handleAudit = async (ctx, { flags, args }) => {
|
|
|
32893
33143
|
limit: flags.limit
|
|
32894
33144
|
})
|
|
32895
33145
|
});
|
|
32896
|
-
|
|
33146
|
+
writePageOutput(ctx, entries, { limit: flags.limit ?? entries.length, nextCursor: null }, () => {
|
|
32897
33147
|
const c = ctx.colors;
|
|
32898
33148
|
if (!entries.length) {
|
|
32899
33149
|
ctx.status(`${c.dim}No audit entries for ${setName}${c.reset}`);
|
|
@@ -33035,7 +33285,7 @@ import { basename } from "node:path";
|
|
|
33035
33285
|
// ../../packages/warmhub-cli/src/harness.ts
|
|
33036
33286
|
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
33037
33287
|
import { homedir as homedir4 } from "node:os";
|
|
33038
|
-
import { dirname as dirname6, join as
|
|
33288
|
+
import { dirname as dirname6, join as join5 } from "node:path";
|
|
33039
33289
|
var AGENTS_BEGIN_MARKER = "<!-- BEGIN WARMHUB CLI INTEGRATION -->";
|
|
33040
33290
|
var AGENTS_END_MARKER = "<!-- END WARMHUB CLI INTEGRATION -->";
|
|
33041
33291
|
var PRIME_COMMAND = "wh prime";
|
|
@@ -33055,10 +33305,10 @@ function getHarnessPaths(opts) {
|
|
|
33055
33305
|
const userHome = opts?.homeDir ?? homedir4();
|
|
33056
33306
|
return {
|
|
33057
33307
|
repoDir,
|
|
33058
|
-
agentsPath:
|
|
33059
|
-
projectSettingsPath:
|
|
33060
|
-
projectLocalSettingsPath:
|
|
33061
|
-
globalSettingsPath:
|
|
33308
|
+
agentsPath: join5(repoDir, "AGENTS.md"),
|
|
33309
|
+
projectSettingsPath: join5(repoDir, ".claude", "settings.json"),
|
|
33310
|
+
projectLocalSettingsPath: join5(repoDir, ".claude", "settings.local.json"),
|
|
33311
|
+
globalSettingsPath: join5(userHome, ".claude", "settings.json")
|
|
33062
33312
|
};
|
|
33063
33313
|
}
|
|
33064
33314
|
async function readJsonFile(path2) {
|
|
@@ -33302,7 +33552,7 @@ function comparePrereleaseIdentifiers2(a, b) {
|
|
|
33302
33552
|
return -1;
|
|
33303
33553
|
if (!aNum && bNum)
|
|
33304
33554
|
return 1;
|
|
33305
|
-
return a
|
|
33555
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
33306
33556
|
}
|
|
33307
33557
|
function compareVersions(candidate, current) {
|
|
33308
33558
|
if (candidate.major !== current.major)
|
|
@@ -33965,7 +34215,7 @@ var handleNotifications = async (ctx, { flags }) => {
|
|
|
33965
34215
|
since: parseSince(flags.since, usage, example),
|
|
33966
34216
|
limit: flags.limit
|
|
33967
34217
|
});
|
|
33968
|
-
|
|
34218
|
+
writePageOutput(ctx, result, { limit: flags.limit ?? result.length, nextCursor: null }, () => renderActionNotifications(ctx.out, ctx.status, ctx.colors, result));
|
|
33969
34219
|
};
|
|
33970
34220
|
var NOTIFICATIONS_DOMAIN = defineDomain({
|
|
33971
34221
|
kind: "flat",
|
|
@@ -34038,7 +34288,7 @@ var handleList4 = async (ctx, { flags }) => {
|
|
|
34038
34288
|
const result = await ctx.client.org.list({
|
|
34039
34289
|
includeArchived: flags["include-archived"]
|
|
34040
34290
|
});
|
|
34041
|
-
|
|
34291
|
+
writePageOutput(ctx, result.items, { limit: result.items.length, nextCursor: null }, () => {
|
|
34042
34292
|
if (!result.items.length) {
|
|
34043
34293
|
ctx.status(`${c.dim}No organizations${c.reset}`);
|
|
34044
34294
|
return;
|
|
@@ -34459,17 +34709,18 @@ cat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped
|
|
|
34459
34709
|
- \`wh credential revoke <setName> [--repo org/repo | --org org] [--reason]\` — Revoke a credential set (blocks new binds and strips auth from existing webhook deliveries)
|
|
34460
34710
|
|
|
34461
34711
|
### component — Component management
|
|
34462
|
-
- \`wh component validate <path>\` — Validate
|
|
34463
|
-
- \`wh component install <
|
|
34464
|
-
- \`wh component register <name> --org <org> --manifest <path> [flags]\` — Register
|
|
34712
|
+
- \`wh component validate <path>\` — Validate package
|
|
34713
|
+
- \`wh component install <org/name>\` — Install a registered component
|
|
34714
|
+
- \`wh component register <name> --org <org> --manifest <path> [flags]\` — Register component identity
|
|
34465
34715
|
- \`wh component unregister <org/name>\` — Remove a registered component identity
|
|
34466
34716
|
- \`wh component registry list --org <org>\` — List registered components
|
|
34467
34717
|
- \`wh component registry view <org/name>\` — View a registered component
|
|
34468
34718
|
- \`wh component registry update <org/name> [flags]\` — Update a registered component
|
|
34469
34719
|
- \`wh component list\` — List installed components
|
|
34470
|
-
- \`wh component
|
|
34471
|
-
- \`wh component
|
|
34472
|
-
- \`wh component
|
|
34720
|
+
- \`wh component update <org/name>\` — Update installed component
|
|
34721
|
+
- \`wh component view <org/name>\` — Show component details (alias: show)
|
|
34722
|
+
- \`wh component doctor <org/name>\` — Run component health checks
|
|
34723
|
+
- \`wh component teardown <org/name>\` — Pause component subscriptions
|
|
34473
34724
|
|
|
34474
34725
|
### Getting More Info
|
|
34475
34726
|
- \`wh help\` — full help overview
|
|
@@ -34799,6 +35050,8 @@ var repoListFlags = {
|
|
|
34799
35050
|
description: "Fetch all pages (auto-paginate until exhausted)"
|
|
34800
35051
|
})
|
|
34801
35052
|
};
|
|
35053
|
+
var DEFAULT_REPO_LIST_LIMIT = 50;
|
|
35054
|
+
var MAX_REPO_LIST_LIMIT = 200;
|
|
34802
35055
|
var handleList5 = async (ctx, { flags, args }) => {
|
|
34803
35056
|
const orgName = args[0] ?? ctx.config.defaultOrg;
|
|
34804
35057
|
if (!orgName) {
|
|
@@ -34826,9 +35079,12 @@ var handleList5 = async (ctx, { flags, args }) => {
|
|
|
34826
35079
|
}
|
|
34827
35080
|
}
|
|
34828
35081
|
if (!all && nextCursor) {
|
|
34829
|
-
ctx
|
|
35082
|
+
emitPartialPageHint(ctx, items.length, nextCursor, Math.min(flags.limit ?? DEFAULT_REPO_LIST_LIMIT, MAX_REPO_LIST_LIMIT));
|
|
34830
35083
|
}
|
|
34831
|
-
|
|
35084
|
+
writePageOutput(ctx, items, {
|
|
35085
|
+
limit: Math.min(flags.limit ?? DEFAULT_REPO_LIST_LIMIT, MAX_REPO_LIST_LIMIT),
|
|
35086
|
+
nextCursor: all ? null : nextCursor ?? null
|
|
35087
|
+
}, () => {
|
|
34832
35088
|
if (!items.length) {
|
|
34833
35089
|
ctx.status(`${c.dim}No repos in ${orgName}${c.reset}`);
|
|
34834
35090
|
return;
|
|
@@ -35349,6 +35605,30 @@ var CONTENT_SUBDOMAIN = defineDomain({
|
|
|
35349
35605
|
}
|
|
35350
35606
|
}
|
|
35351
35607
|
});
|
|
35608
|
+
var repoSearchFlags = {
|
|
35609
|
+
limit: flag.number({
|
|
35610
|
+
description: "Maximum results per page (default: 25, max: 100)"
|
|
35611
|
+
}),
|
|
35612
|
+
cursor: flag.string({ description: "Opaque pagination cursor" }),
|
|
35613
|
+
all: flag.boolean({
|
|
35614
|
+
description: "Fetch all pages (auto-paginate until exhausted)"
|
|
35615
|
+
})
|
|
35616
|
+
};
|
|
35617
|
+
var handleRepoSearch = async (ctx, { flags, args }) => {
|
|
35618
|
+
const query = args[0]?.trim();
|
|
35619
|
+
if (!query) {
|
|
35620
|
+
usageError("Usage: wh repo search <query>", 'wh repo search "payment processing"');
|
|
35621
|
+
}
|
|
35622
|
+
await runGlobalSearchCommand(ctx, {
|
|
35623
|
+
query,
|
|
35624
|
+
all: flags.all,
|
|
35625
|
+
limit: flags.limit,
|
|
35626
|
+
cursor: flags.cursor,
|
|
35627
|
+
fetch: (opts) => ctx.client.repo.search(query, opts),
|
|
35628
|
+
title: "Repo search",
|
|
35629
|
+
emptyLabel: "public repos"
|
|
35630
|
+
});
|
|
35631
|
+
};
|
|
35352
35632
|
var REPO_DOMAIN = defineDomain({
|
|
35353
35633
|
name: "repo",
|
|
35354
35634
|
summary: "Repository management",
|
|
@@ -35379,6 +35659,14 @@ var REPO_DOMAIN = defineDomain({
|
|
|
35379
35659
|
],
|
|
35380
35660
|
handler: handleList5
|
|
35381
35661
|
},
|
|
35662
|
+
search: {
|
|
35663
|
+
prime: true,
|
|
35664
|
+
summary: "Search public repos across all orgs",
|
|
35665
|
+
args: "<query>",
|
|
35666
|
+
flags: repoSearchFlags,
|
|
35667
|
+
examples: ["wh repo search users", "wh repo search users --limit 10"],
|
|
35668
|
+
handler: handleRepoSearch
|
|
35669
|
+
},
|
|
35382
35670
|
view: {
|
|
35383
35671
|
prime: true,
|
|
35384
35672
|
summary: "Show repo details",
|
|
@@ -35481,7 +35769,7 @@ var FIELD_CONSTRAINTS_NOTES = [
|
|
|
35481
35769
|
var listFlags4 = {
|
|
35482
35770
|
match: flag.string({ description: "Filter by name glob pattern" }),
|
|
35483
35771
|
component: flag.string({
|
|
35484
|
-
description: "Filter to shapes owned by this component
|
|
35772
|
+
description: "Filter to shapes owned by this component (Org/Name ref)"
|
|
35485
35773
|
}),
|
|
35486
35774
|
"exclude-components": flag.boolean({
|
|
35487
35775
|
description: "Exclude component-owned shapes from results"
|
|
@@ -35494,18 +35782,18 @@ var handleList6 = async (ctx, { flags }) => {
|
|
|
35494
35782
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
35495
35783
|
const c = ctx.colors;
|
|
35496
35784
|
const match = flags.match;
|
|
35497
|
-
const
|
|
35785
|
+
const componentRef = flags.component;
|
|
35498
35786
|
const excludeComponents = !!flags["exclude-components"];
|
|
35499
35787
|
const includeRetracted = flags["include-retracted"];
|
|
35500
|
-
validateComponentFilters(
|
|
35788
|
+
validateComponentFilters(componentRef, excludeComponents, "wh shape list --component acme/veritas", "wh shape list --exclude-components");
|
|
35501
35789
|
const result = await ctx.client.shape.list(org, repo, {
|
|
35502
35790
|
match,
|
|
35503
|
-
|
|
35791
|
+
componentRef,
|
|
35504
35792
|
excludeComponents,
|
|
35505
35793
|
includeRetracted
|
|
35506
35794
|
});
|
|
35507
35795
|
const items = result.items;
|
|
35508
|
-
|
|
35796
|
+
writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
|
|
35509
35797
|
if (!items.length) {
|
|
35510
35798
|
ctx.status(`${c.dim}No shapes registered${c.reset}`);
|
|
35511
35799
|
return;
|
|
@@ -35567,9 +35855,9 @@ var handleView7 = async (ctx, { flags, args }) => {
|
|
|
35567
35855
|
if (typeof shapeDescription === "string" && shapeDescription) {
|
|
35568
35856
|
ctx.out(` ${c.dim}${shapeDescription}${c.reset}`);
|
|
35569
35857
|
}
|
|
35570
|
-
const
|
|
35571
|
-
if (
|
|
35572
|
-
ctx.out(` ${c.dim}owner:${c.reset} ${c.yellow}${
|
|
35858
|
+
const componentRef = result.componentRef;
|
|
35859
|
+
if (componentRef) {
|
|
35860
|
+
ctx.out(` ${c.dim}owner:${c.reset} ${c.yellow}${componentRef}${c.reset}`);
|
|
35573
35861
|
}
|
|
35574
35862
|
const fields = shapeData?.fields;
|
|
35575
35863
|
if (fields) {
|
|
@@ -35742,7 +36030,7 @@ var handleHistory3 = async (ctx, { flags, args }) => {
|
|
|
35742
36030
|
if (!all && result.nextCursor) {
|
|
35743
36031
|
emitPartialPageHint(ctx, (result.versions ?? []).length, result.nextCursor, pageLimit);
|
|
35744
36032
|
}
|
|
35745
|
-
|
|
36033
|
+
writePageOutput(ctx, result.versions ?? [], { limit: pageLimit, nextCursor: result.nextCursor ?? null }, () => renderHistory(ctx.out, ctx.colors, result));
|
|
35746
36034
|
};
|
|
35747
36035
|
var handleShapeRename = async (ctx, { args }) => {
|
|
35748
36036
|
const oldName = args[0];
|
|
@@ -36184,7 +36472,7 @@ var handleList7 = async (ctx, { flags }) => {
|
|
|
36184
36472
|
const { org, repo } = resolveRepoContext(ctx);
|
|
36185
36473
|
const all = await ctx.client.subscription.list(org, repo);
|
|
36186
36474
|
const items = all.slice(0, flags.limit ?? all.length);
|
|
36187
|
-
|
|
36475
|
+
writePageOutput(ctx, items, { limit: flags.limit ?? all.length, nextCursor: null }, () => {
|
|
36188
36476
|
const c = ctx.colors;
|
|
36189
36477
|
if (!items.length) {
|
|
36190
36478
|
ctx.status(`${c.dim}No subscriptions in ${org}/${repo}${c.reset}`);
|
|
@@ -36651,7 +36939,7 @@ var handleCreate8 = async (ctx, { flags }) => {
|
|
|
36651
36939
|
var handleList8 = async (ctx, { flags }) => {
|
|
36652
36940
|
const c = ctx.colors;
|
|
36653
36941
|
const items = await ctx.client.token.list({ includeInactive: flags.all });
|
|
36654
|
-
|
|
36942
|
+
writePageOutput(ctx, items, { limit: items.length, nextCursor: null }, () => {
|
|
36655
36943
|
if (!items.length) {
|
|
36656
36944
|
ctx.status(`${c.dim}No tokens${c.reset}`);
|
|
36657
36945
|
return;
|
|
@@ -37869,10 +38157,6 @@ async function dispatch(ctx) {
|
|
|
37869
38157
|
const { command } = ctx.invocation;
|
|
37870
38158
|
if (!command || command === "help") {
|
|
37871
38159
|
const helpTarget = command === "help" ? ctx.invocation.positional[0] : undefined;
|
|
37872
|
-
if (ctx.format === "json") {
|
|
37873
|
-
printJson(ctx.out, buildCliSpec());
|
|
37874
|
-
return;
|
|
37875
|
-
}
|
|
37876
38160
|
if (helpTarget) {
|
|
37877
38161
|
const domain = registry.getDomain(helpTarget);
|
|
37878
38162
|
if (domain) {
|
|
@@ -37881,6 +38165,10 @@ async function dispatch(ctx) {
|
|
|
37881
38165
|
throw new CliError(2 /* UserInput */, "USER_INPUT", `Unknown command: ${helpTarget}`, undefined, "Run 'wh help' for available commands.");
|
|
37882
38166
|
}
|
|
37883
38167
|
} else {
|
|
38168
|
+
if (ctx.format === "json") {
|
|
38169
|
+
printJson(ctx.out, buildCliSpec());
|
|
38170
|
+
return;
|
|
38171
|
+
}
|
|
37884
38172
|
let repoSlug;
|
|
37885
38173
|
try {
|
|
37886
38174
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
@@ -37932,6 +38220,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37932
38220
|
const errors = [];
|
|
37933
38221
|
const { meta, manifest } = pkg;
|
|
37934
38222
|
const componentId = meta.id;
|
|
38223
|
+
const componentRef = source.registeredComponentRef;
|
|
37935
38224
|
const validation = validateComponentPackage(pkg);
|
|
37936
38225
|
if (!validation.valid) {
|
|
37937
38226
|
const validationErrors = validation.findings.filter((f) => f.level === "error").map((f) => f.message);
|
|
@@ -37982,7 +38271,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37982
38271
|
const oldCredNames = wasIncomplete ? new Set : new Set(oldManifest?.credentials?.map((c) => c.name) ?? []);
|
|
37983
38272
|
const liveShapeNames = new Set;
|
|
37984
38273
|
const liveShapeDataByName = new Map;
|
|
37985
|
-
const
|
|
38274
|
+
const liveShapeComponentRefByName = new Map;
|
|
37986
38275
|
for (const shape of reconcileShapes) {
|
|
37987
38276
|
if (isFailedInstallState || previousState !== "degraded" && !oldShapeNames.has(shape.name)) {
|
|
37988
38277
|
continue;
|
|
@@ -37999,7 +38288,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37999
38288
|
includeRetracted: true
|
|
38000
38289
|
});
|
|
38001
38290
|
liveShapeDataByName.set(shape.name, liveShape.version?.data);
|
|
38002
|
-
|
|
38291
|
+
liveShapeComponentRefByName.set(shape.name, liveShape.componentRef);
|
|
38003
38292
|
} catch {}
|
|
38004
38293
|
} catch {}
|
|
38005
38294
|
}
|
|
@@ -38034,7 +38323,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38034
38323
|
data: manifestShapeData(shape)
|
|
38035
38324
|
}));
|
|
38036
38325
|
try {
|
|
38037
|
-
await client.commit.apply(org, repo, `Add new shapes for ${meta.name}`, shapeOps, {
|
|
38326
|
+
await client.commit.apply(org, repo, `Add new shapes for ${meta.name}`, shapeOps, { componentRef });
|
|
38038
38327
|
steps.push({ step: "add-new-shapes", status: "ok" });
|
|
38039
38328
|
} catch (err) {
|
|
38040
38329
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38050,8 +38339,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38050
38339
|
if (!liveShapeNames.has(shape.name))
|
|
38051
38340
|
return false;
|
|
38052
38341
|
const liveData = liveShapeDataByName.get(shape.name);
|
|
38053
|
-
const
|
|
38054
|
-
return
|
|
38342
|
+
const liveComponentRef = liveShapeComponentRefByName.get(shape.name);
|
|
38343
|
+
return liveComponentRef !== componentRef || !shapeDataEquals(manifestShapeData(shape), liveData);
|
|
38055
38344
|
});
|
|
38056
38345
|
if (changedShapes.length > 0) {
|
|
38057
38346
|
const shapeOps = changedShapes.map((shape) => ({
|
|
@@ -38061,7 +38350,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38061
38350
|
data: manifestShapeData(shape)
|
|
38062
38351
|
}));
|
|
38063
38352
|
try {
|
|
38064
|
-
await client.commit.apply(org, repo, `Reconcile shapes for ${meta.name}`, shapeOps, {
|
|
38353
|
+
await client.commit.apply(org, repo, `Reconcile shapes for ${meta.name}`, shapeOps, { componentRef });
|
|
38065
38354
|
steps.push({ step: "claim-existing-shapes", status: "ok" });
|
|
38066
38355
|
} catch (err) {
|
|
38067
38356
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38127,7 +38416,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38127
38416
|
filterJson: compiled.filterJson,
|
|
38128
38417
|
webhookUrl: compiled.webhookUrl,
|
|
38129
38418
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38130
|
-
|
|
38419
|
+
componentRef
|
|
38131
38420
|
});
|
|
38132
38421
|
steps.push({ step: `add-sub-${sub.name}`, status: "ok" });
|
|
38133
38422
|
} catch (err) {
|
|
@@ -38166,8 +38455,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38166
38455
|
}
|
|
38167
38456
|
try {
|
|
38168
38457
|
const liveSub = await client.subscription.get(org, repo, sub.name);
|
|
38169
|
-
if (liveSub.
|
|
38170
|
-
const msg = `Subscription "${sub.name}" is owned by component "${liveSub.
|
|
38458
|
+
if (liveSub.componentRef && liveSub.componentRef !== componentRef) {
|
|
38459
|
+
const msg = `Subscription "${sub.name}" is owned by component "${liveSub.componentRef}"`;
|
|
38171
38460
|
errors.push(msg);
|
|
38172
38461
|
steps.push({ step: stepName, status: "error", message: msg });
|
|
38173
38462
|
continue;
|
|
@@ -38185,7 +38474,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38185
38474
|
filterJson: compiled.filterJson,
|
|
38186
38475
|
webhookUrl: compiled.webhookUrl,
|
|
38187
38476
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38188
|
-
|
|
38477
|
+
componentRef
|
|
38189
38478
|
});
|
|
38190
38479
|
} catch (createErr) {
|
|
38191
38480
|
const createMsg = createErr instanceof Error ? createErr.message : String(createErr);
|
|
@@ -38242,7 +38531,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38242
38531
|
name: `${seed.shape}/${seed.name}`,
|
|
38243
38532
|
data: seed.data
|
|
38244
38533
|
}
|
|
38245
|
-
], {
|
|
38534
|
+
], { componentRef });
|
|
38246
38535
|
} catch (reviseErr) {
|
|
38247
38536
|
const reviseMsg = reviseErr instanceof Error ? reviseErr.message : String(reviseErr);
|
|
38248
38537
|
const reviseLooksMissing = reviseMsg.includes("not found") || reviseMsg.includes("NOT_FOUND");
|
|
@@ -38258,7 +38547,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38258
38547
|
name: `${seed.shape}/${seed.name}`,
|
|
38259
38548
|
data: seed.data
|
|
38260
38549
|
}
|
|
38261
|
-
], {
|
|
38550
|
+
], { componentRef });
|
|
38262
38551
|
} catch (addErr) {
|
|
38263
38552
|
const msg = addErr instanceof Error ? addErr.message : String(addErr);
|
|
38264
38553
|
if (!isAlreadyExistsError(addErr)) {
|
|
@@ -38283,8 +38572,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38283
38572
|
componentId,
|
|
38284
38573
|
name: meta.name,
|
|
38285
38574
|
version: meta.version,
|
|
38286
|
-
source:
|
|
38287
|
-
sourceKind:
|
|
38575
|
+
source: "registry",
|
|
38576
|
+
sourceKind: "registered",
|
|
38288
38577
|
sourceRef: source.ref ?? "",
|
|
38289
38578
|
resolvedSha: source.resolvedSha ?? "",
|
|
38290
38579
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38296,7 +38585,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38296
38585
|
...source.installId ?? persistedInstallId ? { installId: source.installId ?? persistedInstallId } : {}
|
|
38297
38586
|
}
|
|
38298
38587
|
}
|
|
38299
|
-
], {
|
|
38588
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38300
38589
|
steps.push({ step: "update-install-record", status: "ok" });
|
|
38301
38590
|
} catch (err) {
|
|
38302
38591
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38411,8 +38700,8 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38411
38700
|
componentId,
|
|
38412
38701
|
name: meta.name,
|
|
38413
38702
|
version: meta.version,
|
|
38414
|
-
source:
|
|
38415
|
-
sourceKind:
|
|
38703
|
+
source: "registry",
|
|
38704
|
+
sourceKind: "registered",
|
|
38416
38705
|
sourceRef: source.ref ?? "",
|
|
38417
38706
|
resolvedSha: source.resolvedSha ?? "",
|
|
38418
38707
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38423,7 +38712,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38423
38712
|
...source.installId ? { installId: source.installId } : {}
|
|
38424
38713
|
}
|
|
38425
38714
|
}
|
|
38426
|
-
], {
|
|
38715
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38427
38716
|
steps.push({ step: "create-install-record", status: "ok" });
|
|
38428
38717
|
} catch (err) {
|
|
38429
38718
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38439,13 +38728,13 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38439
38728
|
data: manifestShapeData(shape)
|
|
38440
38729
|
}));
|
|
38441
38730
|
try {
|
|
38442
|
-
await client.commit.apply(org, repo, `Add shapes for ${meta.name}`, shapeOps, {
|
|
38731
|
+
await client.commit.apply(org, repo, `Add shapes for ${meta.name}`, shapeOps, { componentRef: source.registeredComponentRef });
|
|
38443
38732
|
steps.push({ step: "create-shapes", status: "ok" });
|
|
38444
38733
|
} catch (err) {
|
|
38445
38734
|
const msg = err instanceof Error ? err.message : String(err);
|
|
38446
38735
|
if (isAlreadyExistsError(err)) {
|
|
38447
38736
|
try {
|
|
38448
|
-
await reconcileShapesAfterCreateConflict(client, org, repo, pkg);
|
|
38737
|
+
await reconcileShapesAfterCreateConflict(client, org, repo, pkg, source);
|
|
38449
38738
|
steps.push({
|
|
38450
38739
|
step: "create-shapes",
|
|
38451
38740
|
status: "ok",
|
|
@@ -38522,7 +38811,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38522
38811
|
filterJson: compiled.filterJson,
|
|
38523
38812
|
webhookUrl: compiled.webhookUrl,
|
|
38524
38813
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38525
|
-
|
|
38814
|
+
componentRef: source.registeredComponentRef
|
|
38526
38815
|
});
|
|
38527
38816
|
steps.push({ step: `create-sub-${sub.name}`, status: "ok" });
|
|
38528
38817
|
} catch (err) {
|
|
@@ -38561,7 +38850,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38561
38850
|
name: seedName,
|
|
38562
38851
|
data: seed.data
|
|
38563
38852
|
}
|
|
38564
|
-
], {
|
|
38853
|
+
], { componentRef: source.registeredComponentRef });
|
|
38565
38854
|
steps.push({ step: `seed-${seedName}`, status: "ok" });
|
|
38566
38855
|
} catch (err) {
|
|
38567
38856
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38588,8 +38877,8 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38588
38877
|
componentId,
|
|
38589
38878
|
name: meta.name,
|
|
38590
38879
|
version: meta.version,
|
|
38591
|
-
source:
|
|
38592
|
-
sourceKind:
|
|
38880
|
+
source: "registry",
|
|
38881
|
+
sourceKind: "registered",
|
|
38593
38882
|
sourceRef: source.ref ?? "",
|
|
38594
38883
|
resolvedSha: source.resolvedSha ?? "",
|
|
38595
38884
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38601,7 +38890,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38601
38890
|
...source.installId ? { installId: source.installId } : {}
|
|
38602
38891
|
}
|
|
38603
38892
|
}
|
|
38604
|
-
], {
|
|
38893
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38605
38894
|
steps.push({ step: "finalize", status: "ok" });
|
|
38606
38895
|
} catch (err) {
|
|
38607
38896
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38619,12 +38908,12 @@ function assertCliMethodsAllowedForSource(pkg, source) {
|
|
|
38619
38908
|
const hasCliMethods = (pkg.manifest.cli?.methods?.length ?? 0) > 0;
|
|
38620
38909
|
if (!hasCliMethods)
|
|
38621
38910
|
return;
|
|
38622
|
-
if (
|
|
38911
|
+
if (typeof source.registeredComponentRef === "string" && source.registeredComponentRef.length > 0) {
|
|
38623
38912
|
return;
|
|
38624
38913
|
}
|
|
38625
38914
|
throw new CliError(2 /* UserInput */, "USER_INPUT", "Components that declare manifest.cli.methods must be installed from the registry.", undefined, "Register the component, then install it as <org>/<name>. Local path and GitHub URL installs cannot expose CLI methods.");
|
|
38626
38915
|
}
|
|
38627
|
-
async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
38916
|
+
async function reconcileShapesAfterCreateConflict(client, org, repo, pkg, source) {
|
|
38628
38917
|
const { meta, manifest } = pkg;
|
|
38629
38918
|
const existingShapes = new Map;
|
|
38630
38919
|
for (const shape of manifest.shapes) {
|
|
@@ -38632,8 +38921,8 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38632
38921
|
const existingShape = await client.shape.get(org, repo, shape.name, {
|
|
38633
38922
|
includeRetracted: true
|
|
38634
38923
|
});
|
|
38635
|
-
if (existingShape.
|
|
38636
|
-
const owner = existingShape.
|
|
38924
|
+
if (existingShape.componentRef !== source.registeredComponentRef) {
|
|
38925
|
+
const owner = existingShape.componentRef ? `owned by component "${existingShape.componentRef}"` : "not owned by this component";
|
|
38637
38926
|
throw new Error(`Shape "${shape.name}" already exists and is ${owner}; cannot reconcile during fresh install`);
|
|
38638
38927
|
}
|
|
38639
38928
|
existingShapes.set(shape.name, existingShape);
|
|
@@ -38655,7 +38944,7 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38655
38944
|
name: shape.name,
|
|
38656
38945
|
data
|
|
38657
38946
|
}
|
|
38658
|
-
], {
|
|
38947
|
+
], { componentRef: source.registeredComponentRef });
|
|
38659
38948
|
continue;
|
|
38660
38949
|
}
|
|
38661
38950
|
try {
|
|
@@ -38666,7 +38955,7 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38666
38955
|
name: shape.name,
|
|
38667
38956
|
data
|
|
38668
38957
|
}
|
|
38669
|
-
], {
|
|
38958
|
+
], { componentRef: source.registeredComponentRef });
|
|
38670
38959
|
} catch (err) {
|
|
38671
38960
|
if (isAlreadyExistsError(err)) {
|
|
38672
38961
|
throw new Error(`Shape "${shape.name}" already exists but ownership could not be verified; cannot reconcile during fresh install`);
|
|
@@ -38888,14 +39177,16 @@ async function runCli(argv, opts) {
|
|
|
38888
39177
|
teeStderr: debugMode,
|
|
38889
39178
|
whVersion: version
|
|
38890
39179
|
});
|
|
38891
|
-
|
|
39180
|
+
const handleUncaughtException = (e) => {
|
|
38892
39181
|
logger.crash(e, "uncaughtException");
|
|
38893
39182
|
process.exit(1);
|
|
38894
|
-
}
|
|
38895
|
-
|
|
39183
|
+
};
|
|
39184
|
+
const handleUnhandledRejection = (reason) => {
|
|
38896
39185
|
logger.crash(reason, "unhandledRejection");
|
|
38897
39186
|
process.exit(1);
|
|
38898
|
-
}
|
|
39187
|
+
};
|
|
39188
|
+
process.once("uncaughtException", handleUncaughtException);
|
|
39189
|
+
process.once("unhandledRejection", handleUnhandledRejection);
|
|
38899
39190
|
logger.info("cli.start", {
|
|
38900
39191
|
argv: redactArgv(argv),
|
|
38901
39192
|
version,
|
|
@@ -38905,6 +39196,7 @@ async function runCli(argv, opts) {
|
|
|
38905
39196
|
profile: getStringFlag(invocation.flags, "profile", "P") ?? undefined
|
|
38906
39197
|
});
|
|
38907
39198
|
let exitCode = 0 /* Ok */;
|
|
39199
|
+
let removeSignalListeners;
|
|
38908
39200
|
try {
|
|
38909
39201
|
canonicalizeGlobalFlags({ invocation });
|
|
38910
39202
|
const retirementHint = lookupInvocationRenameHint(invocation);
|
|
@@ -38957,17 +39249,23 @@ async function runCli(argv, opts) {
|
|
|
38957
39249
|
const chars = makeChars();
|
|
38958
39250
|
const ac = new AbortController;
|
|
38959
39251
|
const liveMode = getBoolFlag(invocation.flags, "live");
|
|
38960
|
-
|
|
39252
|
+
const handleSigint = () => {
|
|
38961
39253
|
ac.abort();
|
|
38962
39254
|
logger.info("cli.cancelled", { signal: "SIGINT" });
|
|
38963
39255
|
if (!liveMode)
|
|
38964
39256
|
process.exitCode = 130 /* Cancelled */;
|
|
38965
|
-
}
|
|
38966
|
-
|
|
39257
|
+
};
|
|
39258
|
+
const handleSigterm = () => {
|
|
38967
39259
|
ac.abort();
|
|
38968
39260
|
logger.info("cli.cancelled", { signal: "SIGTERM" });
|
|
38969
39261
|
process.exitCode = 143;
|
|
38970
|
-
}
|
|
39262
|
+
};
|
|
39263
|
+
process.on("SIGINT", handleSigint);
|
|
39264
|
+
process.on("SIGTERM", handleSigterm);
|
|
39265
|
+
removeSignalListeners = () => {
|
|
39266
|
+
process.removeListener("SIGINT", handleSigint);
|
|
39267
|
+
process.removeListener("SIGTERM", handleSigterm);
|
|
39268
|
+
};
|
|
38971
39269
|
await dispatch({
|
|
38972
39270
|
client,
|
|
38973
39271
|
config,
|
|
@@ -39026,6 +39324,9 @@ async function runCli(argv, opts) {
|
|
|
39026
39324
|
});
|
|
39027
39325
|
return exitCode;
|
|
39028
39326
|
} finally {
|
|
39327
|
+
process.removeListener("uncaughtException", handleUncaughtException);
|
|
39328
|
+
process.removeListener("unhandledRejection", handleUnhandledRejection);
|
|
39329
|
+
removeSignalListeners?.();
|
|
39029
39330
|
logger.info("cli.end", {
|
|
39030
39331
|
exit_code: exitCode,
|
|
39031
39332
|
duration_ms: Date.now() - startedAt
|
|
@@ -39081,7 +39382,7 @@ function resolveLogLevel(flags, env) {
|
|
|
39081
39382
|
// package.json
|
|
39082
39383
|
var package_default3 = {
|
|
39083
39384
|
name: "@warmhub/cli",
|
|
39084
|
-
version: "0.
|
|
39385
|
+
version: "0.54.0",
|
|
39085
39386
|
private: false,
|
|
39086
39387
|
type: "module",
|
|
39087
39388
|
description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -39228,14 +39529,17 @@ async function maybeHandleComponentShellBoundary(argv, deps = {}) {
|
|
|
39228
39529
|
callRegisteredSetup: callRegisteredSetupImpl
|
|
39229
39530
|
});
|
|
39230
39531
|
}
|
|
39231
|
-
const
|
|
39232
|
-
if (!
|
|
39532
|
+
const componentRef = invocation.positional[1];
|
|
39533
|
+
if (!componentRef) {
|
|
39233
39534
|
return;
|
|
39234
39535
|
}
|
|
39536
|
+
if (!isRegisteredComponentSource(componentRef)) {
|
|
39537
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Invalid component reference '${componentRef}'. Expected '<org>/<name>' with no extra slashes and no empty parts.`, undefined, "Usage: wh component update <org/name> --repo org/repo");
|
|
39538
|
+
}
|
|
39235
39539
|
const repoFlag = getStringFlag(invocation.flags, "repo") ?? config.defaultRepo;
|
|
39236
39540
|
const refOverride = getStringFlag(invocation.flags, "ref");
|
|
39237
39541
|
return await handleComponentUpdate({
|
|
39238
|
-
|
|
39542
|
+
componentRef,
|
|
39239
39543
|
repoFlag,
|
|
39240
39544
|
refOverride,
|
|
39241
39545
|
client,
|
|
@@ -39306,7 +39610,6 @@ async function performRegisteredInstall(args) {
|
|
|
39306
39610
|
invalidateInstallSnapshotCache(installRepo);
|
|
39307
39611
|
const result = await args.installFromManifest(args.client, args.parsedRepo.org, args.parsedRepo.repo, resolved.manifest, {
|
|
39308
39612
|
installId,
|
|
39309
|
-
sourceKind: "registered",
|
|
39310
39613
|
registeredComponentRef: args.componentRef
|
|
39311
39614
|
});
|
|
39312
39615
|
if (!result.ok) {
|
|
@@ -39371,11 +39674,15 @@ function warmHubErrorBackendCode(error) {
|
|
|
39371
39674
|
async function handleComponentUpdate(args) {
|
|
39372
39675
|
const parsedRepo = parseOrgRepo(args.repoFlag, args.config);
|
|
39373
39676
|
const installRepo = `${parsedRepo.org}/${parsedRepo.repo}`;
|
|
39374
|
-
const
|
|
39677
|
+
const componentId = await resolveInstalledComponentRefId(args.client, parsedRepo.org, parsedRepo.repo, args.componentRef);
|
|
39678
|
+
const installThing = await args.client.thing.get(parsedRepo.org, parsedRepo.repo, `ComponentInstall/${componentId}`);
|
|
39375
39679
|
const installData = installThing.data && typeof installThing.data === "object" ? installThing.data : {};
|
|
39376
39680
|
const source = resolveComponentUpdateSource(installData);
|
|
39377
39681
|
if (source.kind === "registered") {
|
|
39378
39682
|
rejectRefForRegistered(source.componentRef, args.refOverride);
|
|
39683
|
+
if (source.componentRef !== args.componentRef) {
|
|
39684
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.componentRef}' resolved to an install for '${source.componentRef}', which is inconsistent with the install record.`);
|
|
39685
|
+
}
|
|
39379
39686
|
return performRegisteredInstall({
|
|
39380
39687
|
componentRef: source.componentRef,
|
|
39381
39688
|
persistedInstallData: installData,
|
|
@@ -39391,9 +39698,9 @@ async function handleComponentUpdate(args) {
|
|
|
39391
39698
|
});
|
|
39392
39699
|
}
|
|
39393
39700
|
if (source.kind === "system") {
|
|
39394
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.
|
|
39701
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.componentRef}' is a platform-managed system install and cannot be updated via the CLI; it is reconciled automatically by the WarmHub backend.`);
|
|
39395
39702
|
}
|
|
39396
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.
|
|
39703
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.componentRef}' was not installed from a registered component and can no longer be updated in place.`, undefined, "Register the component (`wh component register <name> --org <org> --manifest <path>`) and reinstall it with `wh component install <org>/<name>`.");
|
|
39397
39704
|
}
|
|
39398
39705
|
async function writeInstallResult(writeOut, writeErr, format, verb, result, installRepo, client) {
|
|
39399
39706
|
if (result.ok) {
|
|
@@ -39866,4 +40173,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
|
|
|
39866
40173
|
var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
|
|
39867
40174
|
process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
|
|
39868
40175
|
|
|
39869
|
-
//# debugId=
|
|
40176
|
+
//# debugId=194B08F51AA9569F64756E2164756E21
|