@warmhub/cli 0.52.0 → 0.53.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 +369 -248
- 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.52.1",
|
|
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,12 @@ class WarmHubClient {
|
|
|
22177
22184
|
throw toWarmHubError(error);
|
|
22178
22185
|
}
|
|
22179
22186
|
},
|
|
22180
|
-
get: async (orgName, repoName,
|
|
22187
|
+
get: async (orgName, repoName, componentRef) => {
|
|
22181
22188
|
try {
|
|
22182
22189
|
return await this.trpc.component.get.query({
|
|
22183
22190
|
orgName,
|
|
22184
22191
|
repoName,
|
|
22185
|
-
|
|
22192
|
+
componentRef
|
|
22186
22193
|
});
|
|
22187
22194
|
} catch (error) {
|
|
22188
22195
|
throw toWarmHubError(error);
|
|
@@ -22277,7 +22284,7 @@ class WarmHubClient {
|
|
|
22277
22284
|
repoName,
|
|
22278
22285
|
committer: opts?.committer,
|
|
22279
22286
|
message,
|
|
22280
|
-
|
|
22287
|
+
componentRef: opts?.componentRef,
|
|
22281
22288
|
chunkSize: opts?.chunkSize,
|
|
22282
22289
|
skipExisting: opts?.skipExisting,
|
|
22283
22290
|
streamId: opts?.streamId,
|
|
@@ -22715,7 +22722,7 @@ class WarmHubClient {
|
|
|
22715
22722
|
orgName,
|
|
22716
22723
|
repoName,
|
|
22717
22724
|
match: opts?.match,
|
|
22718
|
-
|
|
22725
|
+
componentRef: opts?.componentRef,
|
|
22719
22726
|
excludeComponents: opts?.excludeComponents,
|
|
22720
22727
|
includeRetracted: opts?.includeRetracted
|
|
22721
22728
|
});
|
|
@@ -22832,6 +22839,17 @@ class WarmHubClient {
|
|
|
22832
22839
|
throw toWarmHubError(error);
|
|
22833
22840
|
}
|
|
22834
22841
|
},
|
|
22842
|
+
reveal: async (orgName, repoName, name) => {
|
|
22843
|
+
try {
|
|
22844
|
+
return await this.trpc.subscription.reveal.query({
|
|
22845
|
+
orgName,
|
|
22846
|
+
repoName,
|
|
22847
|
+
name
|
|
22848
|
+
});
|
|
22849
|
+
} catch (error) {
|
|
22850
|
+
throw toWarmHubError(error);
|
|
22851
|
+
}
|
|
22852
|
+
},
|
|
22835
22853
|
list: async (orgName, repoName) => {
|
|
22836
22854
|
try {
|
|
22837
22855
|
const result = await this.trpc.subscription.list.query({
|
|
@@ -23050,7 +23068,7 @@ class WarmHubClient {
|
|
|
23050
23068
|
includeRetracted: opts?.includeRetracted,
|
|
23051
23069
|
limit: opts?.limit,
|
|
23052
23070
|
cursor: opts?.cursor,
|
|
23053
|
-
|
|
23071
|
+
componentRef: opts?.componentRef,
|
|
23054
23072
|
excludeComponents: opts?.excludeComponents,
|
|
23055
23073
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23056
23074
|
where: opts?.where
|
|
@@ -23271,7 +23289,7 @@ class WarmHubClient {
|
|
|
23271
23289
|
resolveCollections: opts?.resolveCollections,
|
|
23272
23290
|
limit: opts?.limit,
|
|
23273
23291
|
cursor: opts?.cursor,
|
|
23274
|
-
|
|
23292
|
+
componentRef: opts?.componentRef,
|
|
23275
23293
|
excludeComponents: opts?.excludeComponents,
|
|
23276
23294
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23277
23295
|
where: opts?.where
|
|
@@ -23302,7 +23320,7 @@ class WarmHubClient {
|
|
|
23302
23320
|
resolveCollections: opts?.resolveCollections,
|
|
23303
23321
|
limit: opts?.limit,
|
|
23304
23322
|
cursor: opts?.cursor,
|
|
23305
|
-
|
|
23323
|
+
componentRef: opts?.componentRef,
|
|
23306
23324
|
excludeComponents: opts?.excludeComponents,
|
|
23307
23325
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23308
23326
|
mode: opts?.mode
|
|
@@ -23323,7 +23341,7 @@ class WarmHubClient {
|
|
|
23323
23341
|
match: opts?.match,
|
|
23324
23342
|
includeRetracted: opts?.includeRetracted,
|
|
23325
23343
|
resolveCollections: opts?.resolveCollections,
|
|
23326
|
-
|
|
23344
|
+
componentRef: opts?.componentRef,
|
|
23327
23345
|
excludeComponents: opts?.excludeComponents,
|
|
23328
23346
|
excludeInfraShapes: opts?.excludeInfraShapes,
|
|
23329
23347
|
where: opts?.where
|
|
@@ -25165,7 +25183,7 @@ function loadProfileStore(path) {
|
|
|
25165
25183
|
} catch (cause) {
|
|
25166
25184
|
throw corruptedAuthError(p, cause);
|
|
25167
25185
|
}
|
|
25168
|
-
if (parsed === null || typeof parsed !== "object" || parsed.version !== 1 || parsed.profiles === null || typeof parsed.profiles !== "object") {
|
|
25186
|
+
if (parsed === null || typeof parsed !== "object" || parsed.version !== 1 || parsed.profiles === null || typeof parsed.profiles !== "object" || Array.isArray(parsed.profiles)) {
|
|
25169
25187
|
throw corruptedAuthError(p);
|
|
25170
25188
|
}
|
|
25171
25189
|
return parsed;
|
|
@@ -25470,20 +25488,34 @@ function recordBenchmarkResponse(response, benchmarkId) {
|
|
|
25470
25488
|
benchmarkTelemetry.requestDbQueryCountSum += requestDbQueryCount;
|
|
25471
25489
|
}
|
|
25472
25490
|
}
|
|
25473
|
-
function createBenchmarkAwareFetch(benchmarkId) {
|
|
25474
|
-
if (!benchmarkId)
|
|
25491
|
+
function createBenchmarkAwareFetch(benchmarkId, signal) {
|
|
25492
|
+
if (!benchmarkId && !signal)
|
|
25475
25493
|
return;
|
|
25476
25494
|
return async (input, init) => {
|
|
25477
25495
|
const headers = new Headers(init?.headers);
|
|
25478
|
-
|
|
25496
|
+
if (benchmarkId)
|
|
25497
|
+
headers.set(BENCHMARK_HEADER, benchmarkId);
|
|
25479
25498
|
const response = await fetch(input, {
|
|
25480
25499
|
...init,
|
|
25481
|
-
headers
|
|
25500
|
+
headers,
|
|
25501
|
+
signal: mergeAbortSignals(init?.signal, signal)
|
|
25482
25502
|
});
|
|
25483
|
-
|
|
25503
|
+
if (benchmarkId)
|
|
25504
|
+
recordBenchmarkResponse(response, benchmarkId);
|
|
25484
25505
|
return response;
|
|
25485
25506
|
};
|
|
25486
25507
|
}
|
|
25508
|
+
function mergeAbortSignals(requestSignal, liveSignal) {
|
|
25509
|
+
if (!requestSignal)
|
|
25510
|
+
return liveSignal;
|
|
25511
|
+
if (!liveSignal)
|
|
25512
|
+
return requestSignal;
|
|
25513
|
+
if (requestSignal.aborted)
|
|
25514
|
+
return requestSignal;
|
|
25515
|
+
if (liveSignal.aborted)
|
|
25516
|
+
return liveSignal;
|
|
25517
|
+
return AbortSignal.any([requestSignal, liveSignal]);
|
|
25518
|
+
}
|
|
25487
25519
|
function resetBenchmarkTelemetry() {
|
|
25488
25520
|
benchmarkTelemetry = emptyBenchmarkTelemetry();
|
|
25489
25521
|
}
|
|
@@ -25511,18 +25543,34 @@ function createClient(config, opts = {}) {
|
|
|
25511
25543
|
function wantsStructuredLiveOutput(format) {
|
|
25512
25544
|
return format === "json" || format === "jsonl";
|
|
25513
25545
|
}
|
|
25546
|
+
var LIVE_ABORTED = Symbol("live-aborted");
|
|
25547
|
+
function pollUntilAbort(poll, signal) {
|
|
25548
|
+
if (signal.aborted)
|
|
25549
|
+
return Promise.resolve(LIVE_ABORTED);
|
|
25550
|
+
return new Promise((resolve, reject) => {
|
|
25551
|
+
const onAbort = () => resolve(LIVE_ABORTED);
|
|
25552
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
25553
|
+
poll.then((result) => {
|
|
25554
|
+
signal.removeEventListener("abort", onAbort);
|
|
25555
|
+
resolve(result);
|
|
25556
|
+
}, (error) => {
|
|
25557
|
+
signal.removeEventListener("abort", onAbort);
|
|
25558
|
+
reject(error);
|
|
25559
|
+
});
|
|
25560
|
+
});
|
|
25561
|
+
}
|
|
25514
25562
|
async function runLive(opts) {
|
|
25515
25563
|
const auth = opts.auth ?? {
|
|
25516
|
-
getToken: async () => await getValidToken() ?? undefined
|
|
25564
|
+
getToken: async () => await getValidToken(opts.profile) ?? undefined
|
|
25517
25565
|
};
|
|
25518
25566
|
const benchmarkId = process.env.WH_BENCHMARK_ID?.trim();
|
|
25567
|
+
const controller = new AbortController;
|
|
25519
25568
|
const client = new WarmHubClient({
|
|
25520
25569
|
apiUrl: opts.apiUrl,
|
|
25521
25570
|
auth,
|
|
25522
|
-
fetch: createBenchmarkAwareFetch(benchmarkId),
|
|
25571
|
+
fetch: createBenchmarkAwareFetch(benchmarkId, controller.signal),
|
|
25523
25572
|
functionLogs: opts.functionLogs
|
|
25524
25573
|
});
|
|
25525
|
-
const controller = new AbortController;
|
|
25526
25574
|
if (opts.signal) {
|
|
25527
25575
|
if (opts.signal.aborted)
|
|
25528
25576
|
controller.abort();
|
|
@@ -25546,7 +25594,12 @@ async function runLive(opts) {
|
|
|
25546
25594
|
startTimer = setTimeout(() => controller.abort(), opts.startTimeoutMs);
|
|
25547
25595
|
}
|
|
25548
25596
|
while (!controller.signal.aborted) {
|
|
25549
|
-
const
|
|
25597
|
+
const poll = opts.poll(client, controller.signal);
|
|
25598
|
+
const result = await pollUntilAbort(poll, controller.signal);
|
|
25599
|
+
if (result === LIVE_ABORTED) {
|
|
25600
|
+
poll.catch(() => {});
|
|
25601
|
+
break;
|
|
25602
|
+
}
|
|
25550
25603
|
updates += 1;
|
|
25551
25604
|
if (startTimer) {
|
|
25552
25605
|
clearTimeout(startTimer);
|
|
@@ -26207,6 +26260,7 @@ var handleAbout = async (ctx, { flags, args }) => {
|
|
|
26207
26260
|
maxUpdates: ctx.maxUpdates,
|
|
26208
26261
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
26209
26262
|
functionLogs: ctx.functionLogMode,
|
|
26263
|
+
profile: ctx.profile,
|
|
26210
26264
|
signal: ctx.signal
|
|
26211
26265
|
});
|
|
26212
26266
|
return;
|
|
@@ -26558,14 +26612,14 @@ function renderBatchView(out, c, result, wrefs, flagsVersion) {
|
|
|
26558
26612
|
// ../../packages/warmhub-cli/src/domains/thing/graph.ts
|
|
26559
26613
|
var graphFlags = {
|
|
26560
26614
|
depth: flag.number({
|
|
26561
|
-
description: "Resolve
|
|
26615
|
+
description: "Resolve outbound wref fields, assertion backlinks, and assertion about targets to this depth (default: 2, max: 5)"
|
|
26562
26616
|
}),
|
|
26563
26617
|
version: flag.number({ description: "Specific version number" })
|
|
26564
26618
|
};
|
|
26565
26619
|
var handleThingGraph = async (ctx, { flags, args }) => {
|
|
26566
26620
|
const wref = args[0];
|
|
26567
26621
|
if (!wref) {
|
|
26568
|
-
usageError("Usage: wh thing graph <wref> [--depth N]", "wh thing graph Game/base");
|
|
26622
|
+
usageError("Usage: wh thing graph <wref> [--depth N]", "wh thing graph Game/base", "wh thing refs Game/base --inbound");
|
|
26569
26623
|
}
|
|
26570
26624
|
const depth = flags.depth;
|
|
26571
26625
|
if (depth !== undefined && (depth < 1 || depth > 5)) {
|
|
@@ -26635,6 +26689,7 @@ var handleHistory = async (ctx, { flags, args }) => {
|
|
|
26635
26689
|
maxUpdates: ctx.maxUpdates,
|
|
26636
26690
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
26637
26691
|
functionLogs: ctx.functionLogMode,
|
|
26692
|
+
profile: ctx.profile,
|
|
26638
26693
|
signal: ctx.signal
|
|
26639
26694
|
});
|
|
26640
26695
|
return;
|
|
@@ -26745,8 +26800,8 @@ function validateKind(value, flagName = "--kind") {
|
|
|
26745
26800
|
function resolveRepoContext(ctx) {
|
|
26746
26801
|
return parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
26747
26802
|
}
|
|
26748
|
-
function validateComponentFilters(
|
|
26749
|
-
if (
|
|
26803
|
+
function validateComponentFilters(componentRef, excludeComponents, ...examples) {
|
|
26804
|
+
if (componentRef && excludeComponents) {
|
|
26750
26805
|
usageError("Cannot combine --component with --exclude-components.", ...examples);
|
|
26751
26806
|
}
|
|
26752
26807
|
}
|
|
@@ -26822,7 +26877,7 @@ var headFlags = {
|
|
|
26822
26877
|
description: "Include retracted things"
|
|
26823
26878
|
}),
|
|
26824
26879
|
component: flag.string({
|
|
26825
|
-
description: "Filter to things owned by this component
|
|
26880
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
26826
26881
|
}),
|
|
26827
26882
|
"exclude-components": flag.boolean({
|
|
26828
26883
|
description: "Exclude component-owned things from results"
|
|
@@ -26848,15 +26903,15 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26848
26903
|
if (cursor || all || limit || ctx.liveMode) {
|
|
26849
26904
|
usageError("Usage: wh thing list --count [--shape SHAPE] [--kind KIND] [--match PATTERN]", "wh thing list --shape Player --count");
|
|
26850
26905
|
}
|
|
26851
|
-
const
|
|
26906
|
+
const componentRef2 = flags.component;
|
|
26852
26907
|
const strictExclude2 = !!flags["exclude-components"];
|
|
26853
|
-
validateComponentFilters(
|
|
26908
|
+
validateComponentFilters(componentRef2, strictExclude2, "wh thing list --component acme/veritas");
|
|
26854
26909
|
return handleCount(ctx, org, repo, {
|
|
26855
26910
|
shape,
|
|
26856
26911
|
kind,
|
|
26857
26912
|
match,
|
|
26858
26913
|
includeRetracted,
|
|
26859
|
-
|
|
26914
|
+
componentRef: componentRef2,
|
|
26860
26915
|
excludeComponents: strictExclude2,
|
|
26861
26916
|
excludeInfraShapes: !strictExclude2 && !shape,
|
|
26862
26917
|
where: where.length > 0 ? where : undefined
|
|
@@ -26870,10 +26925,10 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26870
26925
|
}
|
|
26871
26926
|
const boundedLimit = Math.min(limit ?? DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT);
|
|
26872
26927
|
const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedLimit;
|
|
26873
|
-
const
|
|
26928
|
+
const componentRef = flags.component;
|
|
26874
26929
|
const hasShape = !!shape;
|
|
26875
26930
|
const strictExclude = !!flags["exclude-components"];
|
|
26876
|
-
validateComponentFilters(
|
|
26931
|
+
validateComponentFilters(componentRef, strictExclude, "wh thing list --component acme/veritas");
|
|
26877
26932
|
const excludeComponents = strictExclude;
|
|
26878
26933
|
const excludeInfraShapes = !strictExclude && !hasShape;
|
|
26879
26934
|
const headOpts = {
|
|
@@ -26883,7 +26938,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26883
26938
|
includeRetracted,
|
|
26884
26939
|
limit: pageLimit,
|
|
26885
26940
|
cursor,
|
|
26886
|
-
|
|
26941
|
+
componentRef,
|
|
26887
26942
|
excludeComponents,
|
|
26888
26943
|
excludeInfraShapes,
|
|
26889
26944
|
where: where.length > 0 ? where : undefined
|
|
@@ -26903,6 +26958,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26903
26958
|
maxUpdates: ctx.maxUpdates,
|
|
26904
26959
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
26905
26960
|
functionLogs: ctx.functionLogMode,
|
|
26961
|
+
profile: ctx.profile,
|
|
26906
26962
|
signal: ctx.signal
|
|
26907
26963
|
});
|
|
26908
26964
|
return;
|
|
@@ -26914,7 +26970,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26914
26970
|
includeRetracted,
|
|
26915
26971
|
limit: pageLimit,
|
|
26916
26972
|
cursor,
|
|
26917
|
-
|
|
26973
|
+
componentRef,
|
|
26918
26974
|
excludeComponents,
|
|
26919
26975
|
excludeInfraShapes,
|
|
26920
26976
|
where: where.length > 0 ? where : undefined
|
|
@@ -26925,7 +26981,7 @@ var handleHead = async (ctx, { flags, args }) => {
|
|
|
26925
26981
|
includeRetracted,
|
|
26926
26982
|
limit: boundedLimit,
|
|
26927
26983
|
cursor,
|
|
26928
|
-
|
|
26984
|
+
componentRef,
|
|
26929
26985
|
excludeComponents,
|
|
26930
26986
|
excludeInfraShapes,
|
|
26931
26987
|
where: where.length > 0 ? where : undefined
|
|
@@ -26946,7 +27002,7 @@ async function fetchAllHeadPages(ctx, org, repo, opts) {
|
|
|
26946
27002
|
includeRetracted: opts.includeRetracted,
|
|
26947
27003
|
limit: opts.limit,
|
|
26948
27004
|
cursor,
|
|
26949
|
-
|
|
27005
|
+
componentRef: opts.componentRef,
|
|
26950
27006
|
excludeComponents: opts.excludeComponents,
|
|
26951
27007
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
26952
27008
|
where: opts.where
|
|
@@ -26978,7 +27034,7 @@ var queryFlags = {
|
|
|
26978
27034
|
description: "Include assertions about collections (Pair/Triple/Set/List) containing the target. Only applies with --about."
|
|
26979
27035
|
}),
|
|
26980
27036
|
component: flag.string({
|
|
26981
|
-
description: "Filter to things owned by this component
|
|
27037
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
26982
27038
|
}),
|
|
26983
27039
|
"exclude-components": flag.boolean({
|
|
26984
27040
|
description: "Exclude component-owned things from results"
|
|
@@ -27000,10 +27056,10 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27000
27056
|
const count = flags.count;
|
|
27001
27057
|
const includeRetracted = flags["include-retracted"];
|
|
27002
27058
|
const resolveCollections = flags["resolve-collections"];
|
|
27003
|
-
const
|
|
27059
|
+
const componentRef = flags.component;
|
|
27004
27060
|
const hasShape = !!shape;
|
|
27005
27061
|
const strictExclude = !!flags["exclude-components"];
|
|
27006
|
-
validateComponentFilters(
|
|
27062
|
+
validateComponentFilters(componentRef, strictExclude, "wh thing query --component acme/veritas");
|
|
27007
27063
|
const excludeComponents = strictExclude;
|
|
27008
27064
|
const excludeInfraShapes = !strictExclude && !hasShape;
|
|
27009
27065
|
const c = ctx.colors;
|
|
@@ -27020,7 +27076,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27020
27076
|
about,
|
|
27021
27077
|
includeRetracted,
|
|
27022
27078
|
resolveCollections,
|
|
27023
|
-
|
|
27079
|
+
componentRef,
|
|
27024
27080
|
excludeComponents,
|
|
27025
27081
|
excludeInfraShapes,
|
|
27026
27082
|
where: where.length > 0 ? where : undefined
|
|
@@ -27043,7 +27099,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27043
27099
|
resolveCollections,
|
|
27044
27100
|
limit: pageLimit,
|
|
27045
27101
|
cursor,
|
|
27046
|
-
|
|
27102
|
+
componentRef,
|
|
27047
27103
|
excludeComponents,
|
|
27048
27104
|
excludeInfraShapes,
|
|
27049
27105
|
where: where.length > 0 ? where : undefined
|
|
@@ -27063,6 +27119,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27063
27119
|
maxUpdates: ctx.maxUpdates,
|
|
27064
27120
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
27065
27121
|
functionLogs: ctx.functionLogMode,
|
|
27122
|
+
profile: ctx.profile,
|
|
27066
27123
|
signal: ctx.signal
|
|
27067
27124
|
});
|
|
27068
27125
|
return;
|
|
@@ -27076,7 +27133,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27076
27133
|
resolveCollections,
|
|
27077
27134
|
limit: pageLimit,
|
|
27078
27135
|
cursor,
|
|
27079
|
-
|
|
27136
|
+
componentRef,
|
|
27080
27137
|
excludeComponents,
|
|
27081
27138
|
excludeInfraShapes,
|
|
27082
27139
|
where: where.length > 0 ? where : undefined
|
|
@@ -27089,7 +27146,7 @@ var handleQuery = async (ctx, { flags }) => {
|
|
|
27089
27146
|
resolveCollections,
|
|
27090
27147
|
limit: boundedLimit,
|
|
27091
27148
|
cursor,
|
|
27092
|
-
|
|
27149
|
+
componentRef,
|
|
27093
27150
|
excludeComponents,
|
|
27094
27151
|
excludeInfraShapes,
|
|
27095
27152
|
where: where.length > 0 ? where : undefined
|
|
@@ -27112,7 +27169,7 @@ async function fetchAllQueryPages(ctx, org, repo, opts) {
|
|
|
27112
27169
|
resolveCollections: opts.resolveCollections,
|
|
27113
27170
|
limit: opts.limit,
|
|
27114
27171
|
cursor,
|
|
27115
|
-
|
|
27172
|
+
componentRef: opts.componentRef,
|
|
27116
27173
|
excludeComponents: opts.excludeComponents,
|
|
27117
27174
|
excludeInfraShapes: opts.excludeInfraShapes,
|
|
27118
27175
|
where: opts.where
|
|
@@ -27390,7 +27447,7 @@ var searchFlags = {
|
|
|
27390
27447
|
cursor: flag.string({ description: "Opaque pagination cursor (text mode)" }),
|
|
27391
27448
|
all: flag.boolean({ description: "Fetch all pages (text mode)" }),
|
|
27392
27449
|
component: flag.string({
|
|
27393
|
-
description: "Filter to things owned by this component
|
|
27450
|
+
description: "Filter to things owned by this component (Org/Name ref)"
|
|
27394
27451
|
}),
|
|
27395
27452
|
"exclude-components": flag.boolean({
|
|
27396
27453
|
description: "Exclude component-owned things from results"
|
|
@@ -27427,10 +27484,10 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27427
27484
|
const pageLimit = all ? Math.min(limit ?? AUTO_PAGE_LIMIT, MAX_PAGE_LIMIT) : boundedTextLimit;
|
|
27428
27485
|
const resolveCollections = mode !== "hybrid" ? flags["resolve-collections"] : undefined;
|
|
27429
27486
|
const supportsComponentFilters = !mode || mode === "text";
|
|
27430
|
-
const
|
|
27487
|
+
const componentRef = supportsComponentFilters ? flags.component : undefined;
|
|
27431
27488
|
const hasShape = !!flags.shape;
|
|
27432
27489
|
const strictExclude = supportsComponentFilters ? !!flags["exclude-components"] : false;
|
|
27433
|
-
validateComponentFilters(
|
|
27490
|
+
validateComponentFilters(componentRef, strictExclude, 'wh thing search "policy" --component acme/veritas');
|
|
27434
27491
|
const excludeComponents = supportsComponentFilters && strictExclude ? true : undefined;
|
|
27435
27492
|
const excludeInfraShapes = supportsComponentFilters && !strictExclude && !hasShape ? true : undefined;
|
|
27436
27493
|
const rawResult = all ? await fetchAllSearchPages(ctx, org, repo, queryText, {
|
|
@@ -27441,7 +27498,7 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27441
27498
|
resolveCollections,
|
|
27442
27499
|
limit: pageLimit,
|
|
27443
27500
|
cursor,
|
|
27444
|
-
|
|
27501
|
+
componentRef,
|
|
27445
27502
|
excludeComponents,
|
|
27446
27503
|
excludeInfraShapes
|
|
27447
27504
|
}) : await ctx.client.thing.search(org, repo, queryText, {
|
|
@@ -27453,7 +27510,7 @@ var handleSearch = async (ctx, { flags, args }) => {
|
|
|
27453
27510
|
limit: boundedTextLimit,
|
|
27454
27511
|
cursor,
|
|
27455
27512
|
mode,
|
|
27456
|
-
|
|
27513
|
+
componentRef,
|
|
27457
27514
|
excludeComponents,
|
|
27458
27515
|
excludeInfraShapes
|
|
27459
27516
|
});
|
|
@@ -27479,7 +27536,7 @@ async function fetchAllSearchPages(ctx, org, repo, queryText, opts) {
|
|
|
27479
27536
|
limit: opts.limit,
|
|
27480
27537
|
cursor,
|
|
27481
27538
|
mode: "text",
|
|
27482
|
-
|
|
27539
|
+
componentRef: opts.componentRef,
|
|
27483
27540
|
excludeComponents: opts.excludeComponents,
|
|
27484
27541
|
excludeInfraShapes: opts.excludeInfraShapes
|
|
27485
27542
|
});
|
|
@@ -27616,6 +27673,7 @@ async function runSingleView(ctx, wref, flags) {
|
|
|
27616
27673
|
maxUpdates: ctx.maxUpdates,
|
|
27617
27674
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
27618
27675
|
functionLogs: ctx.functionLogMode,
|
|
27676
|
+
profile: ctx.profile,
|
|
27619
27677
|
signal: ctx.signal
|
|
27620
27678
|
});
|
|
27621
27679
|
return;
|
|
@@ -27831,13 +27889,16 @@ var THING_DOMAIN = defineDomain({
|
|
|
27831
27889
|
},
|
|
27832
27890
|
graph: {
|
|
27833
27891
|
prime: true,
|
|
27834
|
-
summary: "Fetch a thing's graph (
|
|
27892
|
+
summary: "Fetch a thing's graph (outbound wref fields, assertion backlinks, and assertion about targets)",
|
|
27835
27893
|
args: "<wref>",
|
|
27836
27894
|
flags: graphFlags,
|
|
27837
27895
|
examples: [
|
|
27838
27896
|
"wh thing graph Game/base",
|
|
27839
27897
|
"wh thing graph Game/base --depth 2"
|
|
27840
27898
|
],
|
|
27899
|
+
notes: [
|
|
27900
|
+
"`graph` does not traverse inbound wref-field references; use `wh thing refs <wref> --inbound` to find things whose fields point at this thing."
|
|
27901
|
+
],
|
|
27841
27902
|
handler: handleThingGraph
|
|
27842
27903
|
}
|
|
27843
27904
|
}
|
|
@@ -27990,6 +28051,7 @@ var handleView2 = async (ctx, { flags, args }) => {
|
|
|
27990
28051
|
maxUpdates: ctx.maxUpdates,
|
|
27991
28052
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
27992
28053
|
functionLogs: ctx.functionLogMode,
|
|
28054
|
+
profile: ctx.profile,
|
|
27993
28055
|
signal: ctx.signal
|
|
27994
28056
|
});
|
|
27995
28057
|
return;
|
|
@@ -28118,6 +28180,7 @@ var handleHistory2 = async (ctx, { flags, args }) => {
|
|
|
28118
28180
|
maxUpdates: ctx.maxUpdates,
|
|
28119
28181
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
28120
28182
|
functionLogs: ctx.functionLogMode,
|
|
28183
|
+
profile: ctx.profile,
|
|
28121
28184
|
signal: ctx.signal
|
|
28122
28185
|
});
|
|
28123
28186
|
return;
|
|
@@ -28261,6 +28324,7 @@ var handleList = async (ctx, { flags, args }) => {
|
|
|
28261
28324
|
maxUpdates: ctx.maxUpdates,
|
|
28262
28325
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
28263
28326
|
functionLogs: ctx.functionLogMode,
|
|
28327
|
+
profile: ctx.profile,
|
|
28264
28328
|
signal: ctx.signal
|
|
28265
28329
|
});
|
|
28266
28330
|
return;
|
|
@@ -28299,6 +28363,7 @@ var handleList = async (ctx, { flags, args }) => {
|
|
|
28299
28363
|
maxUpdates: ctx.maxUpdates,
|
|
28300
28364
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
28301
28365
|
functionLogs: ctx.functionLogMode,
|
|
28366
|
+
profile: ctx.profile,
|
|
28302
28367
|
signal: ctx.signal
|
|
28303
28368
|
});
|
|
28304
28369
|
return;
|
|
@@ -29397,7 +29462,7 @@ function ndjsonMessage(msg) {
|
|
|
29397
29462
|
return `${JSON.stringify(msg)}
|
|
29398
29463
|
`;
|
|
29399
29464
|
}
|
|
29400
|
-
function createMessageReader(input, onMessage) {
|
|
29465
|
+
function createMessageReader(input, onMessage, onError = () => {}) {
|
|
29401
29466
|
let buffer = "";
|
|
29402
29467
|
let mode = null;
|
|
29403
29468
|
function drain() {
|
|
@@ -29420,9 +29485,12 @@ function createMessageReader(input, onMessage) {
|
|
|
29420
29485
|
continue;
|
|
29421
29486
|
}
|
|
29422
29487
|
} else {
|
|
29423
|
-
const
|
|
29424
|
-
if (
|
|
29425
|
-
|
|
29488
|
+
const headerEnd = buffer.indexOf(HEADER_DELIMITER);
|
|
29489
|
+
if (headerEnd !== -1) {
|
|
29490
|
+
const resyncFrom = headerEnd + HEADER_DELIMITER.length;
|
|
29491
|
+
const nextHeaderMatch = /Content-Length:/i.exec(buffer.slice(resyncFrom));
|
|
29492
|
+
const nextHeader = nextHeaderMatch === null ? -1 : resyncFrom + nextHeaderMatch.index;
|
|
29493
|
+
buffer = nextHeader === -1 ? "" : buffer.slice(nextHeader);
|
|
29426
29494
|
continue;
|
|
29427
29495
|
}
|
|
29428
29496
|
}
|
|
@@ -29442,12 +29510,14 @@ function createMessageReader(input, onMessage) {
|
|
|
29442
29510
|
};
|
|
29443
29511
|
input.setEncoding("utf8");
|
|
29444
29512
|
input.on("data", onData);
|
|
29513
|
+
input.on("error", onError);
|
|
29445
29514
|
if ("resume" in input && typeof input.resume === "function") {
|
|
29446
29515
|
input.resume();
|
|
29447
29516
|
}
|
|
29448
29517
|
return {
|
|
29449
29518
|
close() {
|
|
29450
29519
|
input.removeListener("data", onData);
|
|
29520
|
+
input.removeListener("error", onError);
|
|
29451
29521
|
}
|
|
29452
29522
|
};
|
|
29453
29523
|
}
|
|
@@ -29457,9 +29527,25 @@ var MCP_PROTOCOL_VERSION2 = "2025-11-25";
|
|
|
29457
29527
|
function createChannelServer(opts) {
|
|
29458
29528
|
let reader = null;
|
|
29459
29529
|
let resolveReady;
|
|
29460
|
-
|
|
29530
|
+
let rejectReady;
|
|
29531
|
+
let readySettled = false;
|
|
29532
|
+
const onReady = new Promise((resolve, reject) => {
|
|
29461
29533
|
resolveReady = resolve;
|
|
29534
|
+
rejectReady = reject;
|
|
29462
29535
|
});
|
|
29536
|
+
function settleReady() {
|
|
29537
|
+
if (readySettled)
|
|
29538
|
+
return;
|
|
29539
|
+
readySettled = true;
|
|
29540
|
+
resolveReady();
|
|
29541
|
+
}
|
|
29542
|
+
function failReady(error) {
|
|
29543
|
+
if (readySettled)
|
|
29544
|
+
return;
|
|
29545
|
+
readySettled = true;
|
|
29546
|
+
reader?.close();
|
|
29547
|
+
rejectReady(error);
|
|
29548
|
+
}
|
|
29463
29549
|
function send(msg) {
|
|
29464
29550
|
opts.output.write(ndjsonMessage(msg));
|
|
29465
29551
|
}
|
|
@@ -29482,7 +29568,7 @@ function createChannelServer(opts) {
|
|
|
29482
29568
|
return;
|
|
29483
29569
|
}
|
|
29484
29570
|
if (method === "notifications/initialized") {
|
|
29485
|
-
|
|
29571
|
+
settleReady();
|
|
29486
29572
|
return;
|
|
29487
29573
|
}
|
|
29488
29574
|
if (method === "ping") {
|
|
@@ -29499,7 +29585,7 @@ function createChannelServer(opts) {
|
|
|
29499
29585
|
}
|
|
29500
29586
|
return {
|
|
29501
29587
|
start() {
|
|
29502
|
-
reader = createMessageReader(opts.input, handleMessage);
|
|
29588
|
+
reader = createMessageReader(opts.input, handleMessage, failReady);
|
|
29503
29589
|
},
|
|
29504
29590
|
notify(content, meta) {
|
|
29505
29591
|
send({
|
|
@@ -29511,6 +29597,7 @@ function createChannelServer(opts) {
|
|
|
29511
29597
|
onReady,
|
|
29512
29598
|
close() {
|
|
29513
29599
|
reader?.close();
|
|
29600
|
+
settleReady();
|
|
29514
29601
|
}
|
|
29515
29602
|
};
|
|
29516
29603
|
}
|
|
@@ -29573,7 +29660,16 @@ var handleChannel = async (ctx) => {
|
|
|
29573
29660
|
else
|
|
29574
29661
|
signal.addEventListener("abort", () => resolve("aborted"), { once: true });
|
|
29575
29662
|
});
|
|
29576
|
-
|
|
29663
|
+
let ready;
|
|
29664
|
+
try {
|
|
29665
|
+
ready = await Promise.race([server.onReady.then(() => {
|
|
29666
|
+
return;
|
|
29667
|
+
}), aborted]);
|
|
29668
|
+
} catch (err) {
|
|
29669
|
+
server.close();
|
|
29670
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29671
|
+
throw new CliError(4 /* Backend */, "BACKEND", `channel startup failed: ${msg}`);
|
|
29672
|
+
}
|
|
29577
29673
|
if (ready === "aborted") {
|
|
29578
29674
|
server.close();
|
|
29579
29675
|
return;
|
|
@@ -30949,13 +31045,16 @@ async function refreshFromSummaries(repoSlug, parsed, activeItems, client, now,
|
|
|
30949
31045
|
const components = {};
|
|
30950
31046
|
let detailReadFailures = 0;
|
|
30951
31047
|
for (const item of activeItems) {
|
|
31048
|
+
if (!item.ref)
|
|
31049
|
+
continue;
|
|
31050
|
+
const itemRef = item.ref;
|
|
30952
31051
|
let detail;
|
|
30953
31052
|
try {
|
|
30954
|
-
detail = await client.component.get(parsed.org, parsed.repo,
|
|
31053
|
+
detail = await client.component.get(parsed.org, parsed.repo, itemRef);
|
|
30955
31054
|
} catch {
|
|
30956
31055
|
detailReadFailures++;
|
|
30957
31056
|
const previousEntry = previousCache?.components[item.componentName];
|
|
30958
|
-
if (previousEntry?.
|
|
31057
|
+
if (previousEntry?.ref === itemRef) {
|
|
30959
31058
|
components[item.componentName] = previousEntry;
|
|
30960
31059
|
}
|
|
30961
31060
|
continue;
|
|
@@ -30970,7 +31069,7 @@ async function refreshFromSummaries(repoSlug, parsed, activeItems, client, now,
|
|
|
30970
31069
|
if (!ref)
|
|
30971
31070
|
continue;
|
|
30972
31071
|
components[item.componentName] = {
|
|
30973
|
-
|
|
31072
|
+
ref: itemRef,
|
|
30974
31073
|
ownerOrgName: ref.ownerOrgName,
|
|
30975
31074
|
registeredComponentName: ref.registeredComponentName,
|
|
30976
31075
|
version: manifest.component.version ?? item.version ?? "",
|
|
@@ -31330,7 +31429,7 @@ var handleComponentExec = async (ctx, { args, terminator }) => {
|
|
|
31330
31429
|
}
|
|
31331
31430
|
const method = entry.methods.find((m) => m.name === methodName);
|
|
31332
31431
|
if (!method) {
|
|
31333
|
-
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 ${
|
|
31432
|
+
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.`);
|
|
31334
31433
|
}
|
|
31335
31434
|
if (helpRequested) {
|
|
31336
31435
|
renderMethodHelp(ctx, componentName, method);
|
|
@@ -31439,7 +31538,7 @@ async function ensureSharedInfra(client, org, repo) {
|
|
|
31439
31538
|
name: shape.name,
|
|
31440
31539
|
data: { fields: shape.fields }
|
|
31441
31540
|
}
|
|
31442
|
-
], {
|
|
31541
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31443
31542
|
} catch (err) {
|
|
31444
31543
|
if (!isAlreadyExistsError(err)) {
|
|
31445
31544
|
throw err;
|
|
@@ -31452,7 +31551,7 @@ async function ensureSharedInfra(client, org, repo) {
|
|
|
31452
31551
|
name: shape.name,
|
|
31453
31552
|
data: { fields: shape.fields }
|
|
31454
31553
|
}
|
|
31455
|
-
], {
|
|
31554
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31456
31555
|
} catch {}
|
|
31457
31556
|
}
|
|
31458
31557
|
}
|
|
@@ -31485,6 +31584,15 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31485
31584
|
};
|
|
31486
31585
|
}
|
|
31487
31586
|
const componentName = typeof installData.name === "string" ? installData.name : componentId;
|
|
31587
|
+
const registeredComponentRef = typeof installData.registeredComponentRef === "string" && installData.registeredComponentRef.length > 0 ? installData.registeredComponentRef : undefined;
|
|
31588
|
+
if (!registeredComponentRef) {
|
|
31589
|
+
findings.push({
|
|
31590
|
+
resource: "ComponentInstall",
|
|
31591
|
+
status: "error",
|
|
31592
|
+
message: "Install record is missing registeredComponentRef"
|
|
31593
|
+
});
|
|
31594
|
+
return { componentId, componentName, state: "error", findings };
|
|
31595
|
+
}
|
|
31488
31596
|
const existingState = typeof installData.state === "string" ? installData.state : undefined;
|
|
31489
31597
|
if (existingState === "error") {
|
|
31490
31598
|
findings.push({
|
|
@@ -31523,12 +31631,12 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31523
31631
|
message: `Shape "${shape.name}" exists but is inactive`
|
|
31524
31632
|
});
|
|
31525
31633
|
} else {
|
|
31526
|
-
const
|
|
31527
|
-
if (
|
|
31634
|
+
const shapeComponentRef = s && typeof s === "object" && "componentRef" in s ? s.componentRef : undefined;
|
|
31635
|
+
if (shapeComponentRef !== undefined && shapeComponentRef !== registeredComponentRef) {
|
|
31528
31636
|
findings.push({
|
|
31529
31637
|
resource: `shape:${shape.name}`,
|
|
31530
31638
|
status: "warning",
|
|
31531
|
-
message: `Shape "${shape.name}" exists but is owned by "${
|
|
31639
|
+
message: `Shape "${shape.name}" exists but is owned by "${shapeComponentRef}"`
|
|
31532
31640
|
});
|
|
31533
31641
|
} else {
|
|
31534
31642
|
const expectedShapeData = manifestShapeData(shape);
|
|
@@ -31562,19 +31670,19 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31562
31670
|
hasSubs = true;
|
|
31563
31671
|
try {
|
|
31564
31672
|
const s = await client.subscription.get(org, repo, sub.name);
|
|
31565
|
-
const
|
|
31566
|
-
if (
|
|
31673
|
+
const subComponentRef = s && typeof s === "object" && "componentRef" in s ? s.componentRef : undefined;
|
|
31674
|
+
if (subComponentRef !== undefined && subComponentRef !== registeredComponentRef) {
|
|
31675
|
+
allSubsPaused = false;
|
|
31567
31676
|
findings.push({
|
|
31568
31677
|
resource: `sub:${sub.name}`,
|
|
31569
|
-
status: "
|
|
31570
|
-
message: `Subscription "${sub.name}" is
|
|
31678
|
+
status: "warning",
|
|
31679
|
+
message: `Subscription "${sub.name}" is owned by "${subComponentRef}"`
|
|
31571
31680
|
});
|
|
31572
|
-
} else if (
|
|
31573
|
-
allSubsPaused = false;
|
|
31681
|
+
} else if (!s.active) {
|
|
31574
31682
|
findings.push({
|
|
31575
31683
|
resource: `sub:${sub.name}`,
|
|
31576
|
-
status: "
|
|
31577
|
-
message: `Subscription "${sub.name}" is
|
|
31684
|
+
status: "inactive",
|
|
31685
|
+
message: `Subscription "${sub.name}" is paused`
|
|
31578
31686
|
});
|
|
31579
31687
|
} else {
|
|
31580
31688
|
allSubsPaused = false;
|
|
@@ -31644,10 +31752,11 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31644
31752
|
const hasMissing = findings.some((f) => f.status === "missing");
|
|
31645
31753
|
const hasInactive = findings.some((f) => f.status === "inactive" && !f.resource.startsWith("sub:"));
|
|
31646
31754
|
const hasShapeDrift = findings.some((f) => f.resource.startsWith("shape:") && f.status === "warning" && f.message.includes("differs from installed manifest"));
|
|
31755
|
+
const hasOwnershipConflict = findings.some((f) => (f.resource.startsWith("shape:") || f.resource.startsWith("sub:")) && f.status === "warning" && f.message.includes("owned by"));
|
|
31647
31756
|
let state;
|
|
31648
|
-
if (hasSubs && allSubsPaused && !hasMissing && !hasInactive && !hasShapeDrift) {
|
|
31757
|
+
if (hasSubs && allSubsPaused && !hasMissing && !hasInactive && !hasShapeDrift && !hasOwnershipConflict) {
|
|
31649
31758
|
state = "paused";
|
|
31650
|
-
} else if (hasMissing || hasInactive || hasShapeDrift) {
|
|
31759
|
+
} else if (hasMissing || hasInactive || hasShapeDrift || hasOwnershipConflict) {
|
|
31651
31760
|
state = "degraded";
|
|
31652
31761
|
} else {
|
|
31653
31762
|
state = "ready";
|
|
@@ -31660,7 +31769,7 @@ async function doctorComponent(client, org, repo, componentId) {
|
|
|
31660
31769
|
name: `ComponentInstall/${componentId}`,
|
|
31661
31770
|
data: { ...installData, state, checkedAt: new Date().toISOString() }
|
|
31662
31771
|
}
|
|
31663
|
-
], {
|
|
31772
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31664
31773
|
} catch {
|
|
31665
31774
|
findings.push({
|
|
31666
31775
|
resource: "state-update",
|
|
@@ -31754,6 +31863,22 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31754
31863
|
};
|
|
31755
31864
|
}
|
|
31756
31865
|
const componentName = typeof installData.name === "string" ? installData.name : componentId;
|
|
31866
|
+
const registeredComponentRef = typeof installData.registeredComponentRef === "string" && installData.registeredComponentRef.length > 0 ? installData.registeredComponentRef : undefined;
|
|
31867
|
+
if (!registeredComponentRef) {
|
|
31868
|
+
return {
|
|
31869
|
+
componentId,
|
|
31870
|
+
componentName,
|
|
31871
|
+
state: "error",
|
|
31872
|
+
steps: [
|
|
31873
|
+
{
|
|
31874
|
+
step: "load-install",
|
|
31875
|
+
status: "error",
|
|
31876
|
+
message: "Install record is missing registeredComponentRef"
|
|
31877
|
+
}
|
|
31878
|
+
],
|
|
31879
|
+
errors: ["Install record is missing registeredComponentRef"]
|
|
31880
|
+
};
|
|
31881
|
+
}
|
|
31757
31882
|
let subscriptionNames = [];
|
|
31758
31883
|
let teardownPolicy = {};
|
|
31759
31884
|
try {
|
|
@@ -31776,9 +31901,9 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31776
31901
|
for (const subName of subscriptionNames) {
|
|
31777
31902
|
try {
|
|
31778
31903
|
const sub = await client.subscription.get(org, repo, subName);
|
|
31779
|
-
const
|
|
31780
|
-
if (typeof
|
|
31781
|
-
const msg = `Subscription "${subName}" is owned by "${
|
|
31904
|
+
const ownerComponentRef = sub && typeof sub === "object" && "componentRef" in sub ? sub.componentRef : undefined;
|
|
31905
|
+
if (typeof ownerComponentRef === "string" && ownerComponentRef !== registeredComponentRef) {
|
|
31906
|
+
const msg = `Subscription "${subName}" is owned by "${ownerComponentRef}", not "${registeredComponentRef}"`;
|
|
31782
31907
|
errors.push(msg);
|
|
31783
31908
|
steps.push({
|
|
31784
31909
|
step: `pause-${subName}`,
|
|
@@ -31827,7 +31952,7 @@ async function teardownComponent(client, org, repo, componentId) {
|
|
|
31827
31952
|
updatedAt: new Date().toISOString()
|
|
31828
31953
|
}
|
|
31829
31954
|
}
|
|
31830
|
-
], {
|
|
31955
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
31831
31956
|
steps.push({ step: "update-state", status: "ok" });
|
|
31832
31957
|
} catch (err) {
|
|
31833
31958
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -32049,38 +32174,11 @@ function componentInstallCanonicalId(item) {
|
|
|
32049
32174
|
const data = asRecord(item.data);
|
|
32050
32175
|
return componentInstallIdFromWref(item.wref) ?? readString(data, "id") ?? readString(data, "componentId") ?? item.name;
|
|
32051
32176
|
}
|
|
32052
|
-
function
|
|
32053
|
-
return
|
|
32177
|
+
function componentInstallHasRegisteredRef(item, ref) {
|
|
32178
|
+
return readString(asRecord(item.data), "registeredComponentRef") === ref;
|
|
32054
32179
|
}
|
|
32055
|
-
function
|
|
32056
|
-
const data = asRecord(item.data);
|
|
32057
|
-
return uniqueStrings([
|
|
32058
|
-
componentInstallCanonicalId(item),
|
|
32059
|
-
readString(data, "id"),
|
|
32060
|
-
readString(data, "componentId"),
|
|
32061
|
-
item.name
|
|
32062
|
-
]);
|
|
32063
|
-
}
|
|
32064
|
-
function componentInstallHasExactId(item, name) {
|
|
32065
|
-
return componentInstallIdentityIds(item).includes(name);
|
|
32066
|
-
}
|
|
32067
|
-
function componentInstallHasDisplayName(item, name) {
|
|
32068
|
-
return readString(asRecord(item.data), "name") === name;
|
|
32069
|
-
}
|
|
32070
|
-
function formatComponentInstallAmbiguity(name, matches) {
|
|
32071
|
-
const componentIds = uniqueStrings(matches.map((item) => componentInstallCanonicalId(item)));
|
|
32072
|
-
const listedIds = componentIds.map((id) => `- ${id}`).join(`
|
|
32073
|
-
`);
|
|
32074
|
-
const exampleId = componentIds[0] ?? name;
|
|
32075
|
-
return {
|
|
32076
|
-
message: `Component name "${name}" is ambiguous. It matches multiple installed components:
|
|
32077
|
-
${listedIds}`,
|
|
32078
|
-
hint: `Use a component id instead, for example: wh component doctor ${exampleId}`
|
|
32079
|
-
};
|
|
32080
|
-
}
|
|
32081
|
-
async function resolveComponentDoctorId(client, org, repo, name) {
|
|
32180
|
+
async function resolveInstalledComponentRefId(client, org, repo, ref) {
|
|
32082
32181
|
let cursor;
|
|
32083
|
-
const displayNameMatches = [];
|
|
32084
32182
|
do {
|
|
32085
32183
|
const result = await client.thing.head(org, repo, {
|
|
32086
32184
|
shape: "ComponentInstall",
|
|
@@ -32089,35 +32187,27 @@ async function resolveComponentDoctorId(client, org, repo, name) {
|
|
|
32089
32187
|
cursor
|
|
32090
32188
|
});
|
|
32091
32189
|
const items = result.items ?? [];
|
|
32092
|
-
const exactMatch = items.find((item) =>
|
|
32190
|
+
const exactMatch = items.find((item) => componentInstallHasRegisteredRef(item, ref));
|
|
32093
32191
|
const resolved = exactMatch ? componentInstallCanonicalId(exactMatch) : undefined;
|
|
32094
32192
|
if (resolved) {
|
|
32095
32193
|
return resolved;
|
|
32096
32194
|
}
|
|
32097
|
-
displayNameMatches.push(...items.filter((item) => componentInstallHasDisplayName(item, name)));
|
|
32098
32195
|
cursor = result.nextCursor;
|
|
32099
32196
|
} while (cursor);
|
|
32100
|
-
|
|
32101
|
-
return componentInstallCanonicalId(displayNameMatches[0]) ?? name;
|
|
32102
|
-
}
|
|
32103
|
-
if (displayNameMatches.length > 1) {
|
|
32104
|
-
const { message, hint } = formatComponentInstallAmbiguity(name, displayNameMatches);
|
|
32105
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", message, undefined, hint);
|
|
32106
|
-
}
|
|
32107
|
-
return name;
|
|
32197
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${ref}' is not installed. Run 'wh component install <org>/<name>' first.`);
|
|
32108
32198
|
}
|
|
32109
32199
|
var handleUpdate = async (ctx, { args }) => {
|
|
32110
|
-
const
|
|
32111
|
-
|
|
32112
|
-
|
|
32200
|
+
const ref = args[0];
|
|
32201
|
+
const usage = "Usage: wh component update <org/name> --repo org/repo";
|
|
32202
|
+
const example = "wh component update warmhub/research-knowledge --repo org/repo";
|
|
32203
|
+
if (!ref) {
|
|
32204
|
+
usageError(usage, example);
|
|
32113
32205
|
}
|
|
32114
|
-
|
|
32115
|
-
|
|
32116
|
-
|
|
32117
|
-
} catch {
|
|
32118
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${name}' is not installed. Run 'wh component install <org>/<name>' first.`);
|
|
32206
|
+
resolveRegisteredComponentRef(ref, usage, example);
|
|
32207
|
+
if (ctx.liveMode === false) {
|
|
32208
|
+
usageError("Dry-run is not supported for component update.", "wh component update warmhub/research-knowledge --repo org/repo");
|
|
32119
32209
|
}
|
|
32120
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${
|
|
32210
|
+
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.");
|
|
32121
32211
|
};
|
|
32122
32212
|
var handleRegister = async (ctx, { flags, args }) => {
|
|
32123
32213
|
const componentName = args[0];
|
|
@@ -32210,8 +32300,7 @@ var handleRegistryUpdate = async (ctx, { flags, args }) => {
|
|
|
32210
32300
|
};
|
|
32211
32301
|
var handleInstall = async (ctx, { args }) => {
|
|
32212
32302
|
const source = args[0];
|
|
32213
|
-
const usage =
|
|
32214
|
-
source: <org>/<name> (registered component)`;
|
|
32303
|
+
const usage = "Usage: wh component install <org/name> --repo org/repo";
|
|
32215
32304
|
const example = "wh component install warmhub/veritas --repo myorg/myrepo";
|
|
32216
32305
|
if (!source) {
|
|
32217
32306
|
usageError(usage, example);
|
|
@@ -32256,7 +32345,7 @@ var handleList2 = async (ctx, { flags }) => {
|
|
|
32256
32345
|
const state = item.state ?? "unknown";
|
|
32257
32346
|
const source = item.source ?? "-";
|
|
32258
32347
|
const stateColor = stateToColor(c, state);
|
|
32259
|
-
ctx.out(` ${c.cyan}${item.
|
|
32348
|
+
ctx.out(` ${c.cyan}${item.ref ?? item.componentName}${c.reset} ${stateColor}${state}${c.reset} ${c.dim}v${version}${c.reset} ${source}`);
|
|
32260
32349
|
}
|
|
32261
32350
|
});
|
|
32262
32351
|
};
|
|
@@ -32269,7 +32358,7 @@ var handleSearch2 = async (ctx, { flags, args }) => {
|
|
|
32269
32358
|
const c = ctx.colors;
|
|
32270
32359
|
const { items: allItems, nextCursor } = await fetchComponentPages(ctx.client, org, repo, { all: flags.all, limit: flags.limit, cursor: flags.cursor });
|
|
32271
32360
|
const needle = query.toLowerCase();
|
|
32272
|
-
const items = allItems.filter((item) => [item.
|
|
32361
|
+
const items = allItems.filter((item) => [item.ref, item.componentName, item.source].filter((value) => typeof value === "string").some((value) => value.toLowerCase().includes(needle)));
|
|
32273
32362
|
if (!flags.all && nextCursor) {
|
|
32274
32363
|
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.`);
|
|
32275
32364
|
}
|
|
@@ -32285,22 +32374,22 @@ var handleSearch2 = async (ctx, { flags, args }) => {
|
|
|
32285
32374
|
const state = item.state ?? "unknown";
|
|
32286
32375
|
const source = item.source ?? "-";
|
|
32287
32376
|
const stateColor = stateToColor(c, state);
|
|
32288
|
-
ctx.out(` ${c.cyan}${item.
|
|
32377
|
+
ctx.out(` ${c.cyan}${item.ref ?? item.componentName}${c.reset} ${stateColor}${state}${c.reset} ${c.dim}v${version}${c.reset} ${source}`);
|
|
32289
32378
|
}
|
|
32290
32379
|
});
|
|
32291
32380
|
};
|
|
32292
32381
|
var handleView3 = async (ctx, { args }) => {
|
|
32293
|
-
const
|
|
32294
|
-
const usage = "Usage: wh component view <name> --repo org/repo";
|
|
32295
|
-
const example = "wh component view research-knowledge --repo myorg/myrepo";
|
|
32296
|
-
if (!
|
|
32382
|
+
const ref = args[0];
|
|
32383
|
+
const usage = "Usage: wh component view <org/name> --repo org/repo";
|
|
32384
|
+
const example = "wh component view myorg/research-knowledge --repo myorg/myrepo";
|
|
32385
|
+
if (!ref) {
|
|
32297
32386
|
usageError(usage, example);
|
|
32298
32387
|
}
|
|
32299
32388
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32300
|
-
const viewData = await ctx.client.component.get(org, repo,
|
|
32389
|
+
const viewData = await ctx.client.component.get(org, repo, ref);
|
|
32301
32390
|
writeOutput(ctx, viewData, () => {
|
|
32302
32391
|
const c = ctx.colors;
|
|
32303
|
-
ctx.out(`${c.bold}Component:${c.reset} ${c.cyan}${
|
|
32392
|
+
ctx.out(`${c.bold}Component:${c.reset} ${c.cyan}${viewData.ref ?? ref}${c.reset}`);
|
|
32304
32393
|
ctx.out(`${c.bold}Version:${c.reset} ${viewData.version ?? "unknown"}`);
|
|
32305
32394
|
ctx.out(`${c.bold}State:${c.reset} ${viewData.state ?? "-"}`);
|
|
32306
32395
|
ctx.out(`${c.bold}Source:${c.reset} ${viewData.source ?? "-"}`);
|
|
@@ -32376,23 +32465,24 @@ function renderValidationResult(ctx, result) {
|
|
|
32376
32465
|
var handleDoctor = async (ctx, { args }) => {
|
|
32377
32466
|
const name = args[0];
|
|
32378
32467
|
if (!name) {
|
|
32379
|
-
usageError("Usage: wh component doctor <name> --repo org/repo", "wh component doctor research-knowledge --repo myorg/myrepo");
|
|
32468
|
+
usageError("Usage: wh component doctor <org/name> --repo org/repo", "wh component doctor warmhub/research-knowledge --repo myorg/myrepo");
|
|
32380
32469
|
}
|
|
32381
32470
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32382
|
-
const componentId = await
|
|
32471
|
+
const componentId = await resolveInstalledComponentRefId(ctx.client, org, repo, name);
|
|
32383
32472
|
const result = await doctorComponent(ctx.client, org, repo, componentId);
|
|
32384
32473
|
writeOutput(ctx, result, () => renderDoctorResult(ctx, result));
|
|
32385
32474
|
};
|
|
32386
32475
|
var handleTeardown = async (ctx, { args }) => {
|
|
32387
32476
|
const name = args[0];
|
|
32388
32477
|
if (!name) {
|
|
32389
|
-
usageError("Usage: wh component teardown <name> --repo org/repo", "wh component teardown research-knowledge --repo myorg/myrepo");
|
|
32478
|
+
usageError("Usage: wh component teardown <org/name> --repo org/repo", "wh component teardown warmhub/research-knowledge --repo myorg/myrepo");
|
|
32390
32479
|
}
|
|
32391
32480
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
32392
32481
|
const repoSlug = `${org}/${repo}`;
|
|
32482
|
+
const componentId = await resolveInstalledComponentRefId(ctx.client, org, repo, name);
|
|
32393
32483
|
let result;
|
|
32394
32484
|
try {
|
|
32395
|
-
result = await teardownComponent(ctx.client, org, repo,
|
|
32485
|
+
result = await teardownComponent(ctx.client, org, repo, componentId);
|
|
32396
32486
|
} catch (error) {
|
|
32397
32487
|
invalidateInstallSnapshotCache(repoSlug);
|
|
32398
32488
|
throw error;
|
|
@@ -32523,7 +32613,7 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32523
32613
|
install: {
|
|
32524
32614
|
prime: true,
|
|
32525
32615
|
summary: "Install a registered component by its <org>/<name> ref",
|
|
32526
|
-
args: "<
|
|
32616
|
+
args: "<org/name>",
|
|
32527
32617
|
flags: installFlags,
|
|
32528
32618
|
examples: [
|
|
32529
32619
|
"wh component install warmhub/identity --repo org/repo",
|
|
@@ -32533,9 +32623,9 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32533
32623
|
},
|
|
32534
32624
|
update: {
|
|
32535
32625
|
summary: "Update an installed registered component to the latest manifest",
|
|
32536
|
-
args: "<name>",
|
|
32626
|
+
args: "<org/name>",
|
|
32537
32627
|
flags: updateFlags,
|
|
32538
|
-
examples: ["wh component update
|
|
32628
|
+
examples: ["wh component update warmhub/identity --repo org/repo"],
|
|
32539
32629
|
handler: handleUpdate
|
|
32540
32630
|
},
|
|
32541
32631
|
list: {
|
|
@@ -32549,25 +32639,25 @@ var COMPONENT_DOMAIN = defineDomain({
|
|
|
32549
32639
|
view: {
|
|
32550
32640
|
prime: true,
|
|
32551
32641
|
summary: "Show component details",
|
|
32552
|
-
args: "<name>",
|
|
32642
|
+
args: "<org/name>",
|
|
32553
32643
|
flags: viewFlags3,
|
|
32554
|
-
examples: ["wh component view
|
|
32644
|
+
examples: ["wh component view warmhub/identity --repo org/repo"],
|
|
32555
32645
|
handler: handleView3
|
|
32556
32646
|
},
|
|
32557
32647
|
teardown: {
|
|
32558
32648
|
prime: true,
|
|
32559
32649
|
summary: "Pause component subscriptions",
|
|
32560
|
-
args: "<name>",
|
|
32650
|
+
args: "<org/name>",
|
|
32561
32651
|
flags: teardownFlags,
|
|
32562
|
-
examples: ["wh component teardown
|
|
32652
|
+
examples: ["wh component teardown warmhub/identity --repo org/repo"],
|
|
32563
32653
|
handler: handleTeardown
|
|
32564
32654
|
},
|
|
32565
32655
|
doctor: {
|
|
32566
32656
|
prime: true,
|
|
32567
32657
|
summary: "Run component health checks",
|
|
32568
|
-
args: "<name>",
|
|
32658
|
+
args: "<org/name>",
|
|
32569
32659
|
flags: doctorFlags,
|
|
32570
|
-
examples: ["wh component doctor
|
|
32660
|
+
examples: ["wh component doctor warmhub/identity --repo org/repo"],
|
|
32571
32661
|
handler: handleDoctor
|
|
32572
32662
|
},
|
|
32573
32663
|
init: {
|
|
@@ -33015,7 +33105,7 @@ import { basename } from "node:path";
|
|
|
33015
33105
|
// ../../packages/warmhub-cli/src/harness.ts
|
|
33016
33106
|
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
33017
33107
|
import { homedir as homedir4 } from "node:os";
|
|
33018
|
-
import { dirname as dirname6, join as
|
|
33108
|
+
import { dirname as dirname6, join as join5 } from "node:path";
|
|
33019
33109
|
var AGENTS_BEGIN_MARKER = "<!-- BEGIN WARMHUB CLI INTEGRATION -->";
|
|
33020
33110
|
var AGENTS_END_MARKER = "<!-- END WARMHUB CLI INTEGRATION -->";
|
|
33021
33111
|
var PRIME_COMMAND = "wh prime";
|
|
@@ -33035,10 +33125,10 @@ function getHarnessPaths(opts) {
|
|
|
33035
33125
|
const userHome = opts?.homeDir ?? homedir4();
|
|
33036
33126
|
return {
|
|
33037
33127
|
repoDir,
|
|
33038
|
-
agentsPath:
|
|
33039
|
-
projectSettingsPath:
|
|
33040
|
-
projectLocalSettingsPath:
|
|
33041
|
-
globalSettingsPath:
|
|
33128
|
+
agentsPath: join5(repoDir, "AGENTS.md"),
|
|
33129
|
+
projectSettingsPath: join5(repoDir, ".claude", "settings.json"),
|
|
33130
|
+
projectLocalSettingsPath: join5(repoDir, ".claude", "settings.local.json"),
|
|
33131
|
+
globalSettingsPath: join5(userHome, ".claude", "settings.json")
|
|
33042
33132
|
};
|
|
33043
33133
|
}
|
|
33044
33134
|
async function readJsonFile(path2) {
|
|
@@ -34439,17 +34529,18 @@ cat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped
|
|
|
34439
34529
|
- \`wh credential revoke <setName> [--repo org/repo | --org org] [--reason]\` — Revoke a credential set (blocks new binds and strips auth from existing webhook deliveries)
|
|
34440
34530
|
|
|
34441
34531
|
### component — Component management
|
|
34442
|
-
- \`wh component validate <path>\` — Validate
|
|
34443
|
-
- \`wh component install <
|
|
34444
|
-
- \`wh component register <name> --org <org> --manifest <path> [flags]\` — Register
|
|
34532
|
+
- \`wh component validate <path>\` — Validate package
|
|
34533
|
+
- \`wh component install <org/name>\` — Install a registered component
|
|
34534
|
+
- \`wh component register <name> --org <org> --manifest <path> [flags]\` — Register component identity
|
|
34445
34535
|
- \`wh component unregister <org/name>\` — Remove a registered component identity
|
|
34446
34536
|
- \`wh component registry list --org <org>\` — List registered components
|
|
34447
34537
|
- \`wh component registry view <org/name>\` — View a registered component
|
|
34448
34538
|
- \`wh component registry update <org/name> [flags]\` — Update a registered component
|
|
34449
34539
|
- \`wh component list\` — List installed components
|
|
34450
|
-
- \`wh component
|
|
34451
|
-
- \`wh component
|
|
34452
|
-
- \`wh component
|
|
34540
|
+
- \`wh component update <org/name>\` — Update installed component
|
|
34541
|
+
- \`wh component view <org/name>\` — Show component details (alias: show)
|
|
34542
|
+
- \`wh component doctor <org/name>\` — Run component health checks
|
|
34543
|
+
- \`wh component teardown <org/name>\` — Pause component subscriptions
|
|
34453
34544
|
|
|
34454
34545
|
### Getting More Info
|
|
34455
34546
|
- \`wh help\` — full help overview
|
|
@@ -35461,7 +35552,7 @@ var FIELD_CONSTRAINTS_NOTES = [
|
|
|
35461
35552
|
var listFlags4 = {
|
|
35462
35553
|
match: flag.string({ description: "Filter by name glob pattern" }),
|
|
35463
35554
|
component: flag.string({
|
|
35464
|
-
description: "Filter to shapes owned by this component
|
|
35555
|
+
description: "Filter to shapes owned by this component (Org/Name ref)"
|
|
35465
35556
|
}),
|
|
35466
35557
|
"exclude-components": flag.boolean({
|
|
35467
35558
|
description: "Exclude component-owned shapes from results"
|
|
@@ -35474,13 +35565,13 @@ var handleList6 = async (ctx, { flags }) => {
|
|
|
35474
35565
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
35475
35566
|
const c = ctx.colors;
|
|
35476
35567
|
const match = flags.match;
|
|
35477
|
-
const
|
|
35568
|
+
const componentRef = flags.component;
|
|
35478
35569
|
const excludeComponents = !!flags["exclude-components"];
|
|
35479
35570
|
const includeRetracted = flags["include-retracted"];
|
|
35480
|
-
validateComponentFilters(
|
|
35571
|
+
validateComponentFilters(componentRef, excludeComponents, "wh shape list --component acme/veritas", "wh shape list --exclude-components");
|
|
35481
35572
|
const result = await ctx.client.shape.list(org, repo, {
|
|
35482
35573
|
match,
|
|
35483
|
-
|
|
35574
|
+
componentRef,
|
|
35484
35575
|
excludeComponents,
|
|
35485
35576
|
includeRetracted
|
|
35486
35577
|
});
|
|
@@ -35547,9 +35638,9 @@ var handleView7 = async (ctx, { flags, args }) => {
|
|
|
35547
35638
|
if (typeof shapeDescription === "string" && shapeDescription) {
|
|
35548
35639
|
ctx.out(` ${c.dim}${shapeDescription}${c.reset}`);
|
|
35549
35640
|
}
|
|
35550
|
-
const
|
|
35551
|
-
if (
|
|
35552
|
-
ctx.out(` ${c.dim}owner:${c.reset} ${c.yellow}${
|
|
35641
|
+
const componentRef = result.componentRef;
|
|
35642
|
+
if (componentRef) {
|
|
35643
|
+
ctx.out(` ${c.dim}owner:${c.reset} ${c.yellow}${componentRef}${c.reset}`);
|
|
35553
35644
|
}
|
|
35554
35645
|
const fields = shapeData?.fields;
|
|
35555
35646
|
if (fields) {
|
|
@@ -35694,6 +35785,7 @@ var handleHistory3 = async (ctx, { flags, args }) => {
|
|
|
35694
35785
|
maxUpdates: ctx.maxUpdates,
|
|
35695
35786
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
35696
35787
|
functionLogs: ctx.functionLogMode,
|
|
35788
|
+
profile: ctx.profile,
|
|
35697
35789
|
signal: ctx.signal
|
|
35698
35790
|
});
|
|
35699
35791
|
return;
|
|
@@ -36008,6 +36100,11 @@ var logFlags = {
|
|
|
36008
36100
|
var listFlags5 = {
|
|
36009
36101
|
limit: flag.number({ description: "Max subscriptions to return" })
|
|
36010
36102
|
};
|
|
36103
|
+
var viewFlags5 = {
|
|
36104
|
+
"show-secrets": flag.boolean({
|
|
36105
|
+
description: "Reveal the raw webhook URL(s) instead of the redacted origin (audit-logged)"
|
|
36106
|
+
})
|
|
36107
|
+
};
|
|
36011
36108
|
function buildSubscriptionPatchArgs(flags, usage, example) {
|
|
36012
36109
|
const args = {};
|
|
36013
36110
|
if (typeof flags.on === "string" && flags.on) {
|
|
@@ -36121,14 +36218,15 @@ var handleUpdate4 = async (ctx, { flags, args }) => {
|
|
|
36121
36218
|
ctx.status(`${c.green}Updated subscription${c.reset} ${c.cyan}${name}${c.reset} on ${c.cyan}${org}/${repo}${c.reset}`);
|
|
36122
36219
|
});
|
|
36123
36220
|
};
|
|
36124
|
-
var handleView8 = async (ctx, { args }) => {
|
|
36221
|
+
var handleView8 = async (ctx, { args, flags }) => {
|
|
36125
36222
|
const name = args[0];
|
|
36126
36223
|
if (!name) {
|
|
36127
|
-
usageError("Usage: wh sub view <name> [--repo org/repo]", "wh sub view signal-hook --repo myorg/myrepo");
|
|
36224
|
+
usageError("Usage: wh sub view <name> [--show-secrets] [--repo org/repo]", "wh sub view signal-hook --repo myorg/myrepo");
|
|
36128
36225
|
}
|
|
36129
36226
|
const { org, repo } = resolveRepoContext(ctx);
|
|
36130
36227
|
const sub = await ctx.client.subscription.get(org, repo, name);
|
|
36131
|
-
|
|
36228
|
+
const revealed = flags["show-secrets"] ? await ctx.client.subscription.reveal(org, repo, name) : undefined;
|
|
36229
|
+
writeOutput(ctx, revealed ? { ...sub, ...revealed } : sub, () => {
|
|
36132
36230
|
const c = ctx.colors;
|
|
36133
36231
|
ctx.out(`${c.bold}${sub.name}${c.reset}`);
|
|
36134
36232
|
ctx.out(` kind: ${c.cyan}${sub.kind}${c.reset}`);
|
|
@@ -36139,12 +36237,15 @@ var handleView8 = async (ctx, { args }) => {
|
|
|
36139
36237
|
if (sub.allowTraceReentry) {
|
|
36140
36238
|
ctx.out(` allowTraceReentry: ${c.green}${sub.allowTraceReentry}${c.reset}`);
|
|
36141
36239
|
}
|
|
36142
|
-
|
|
36143
|
-
|
|
36144
|
-
|
|
36145
|
-
|
|
36146
|
-
|
|
36147
|
-
|
|
36240
|
+
const renderHook = (rawLabel, originLabel, raw, origin) => {
|
|
36241
|
+
if (raw) {
|
|
36242
|
+
ctx.out(` ${rawLabel}: ${raw}`);
|
|
36243
|
+
} else if (origin) {
|
|
36244
|
+
ctx.out(` ${originLabel}: ${origin}${c.dim}/***${c.reset}`);
|
|
36245
|
+
}
|
|
36246
|
+
};
|
|
36247
|
+
renderHook("webhookUrl", "webhookOrigin", revealed?.webhookUrl, sub.webhookOrigin);
|
|
36248
|
+
renderHook("fallbackWebhookUrl", "fallbackWebhookOrigin", revealed?.fallbackWebhookUrl, sub.fallbackWebhookOrigin);
|
|
36148
36249
|
if (sub.actionContainer) {
|
|
36149
36250
|
ctx.out(` action container: ${c.cyan}${sub.actionContainer}${c.reset}`);
|
|
36150
36251
|
}
|
|
@@ -36256,6 +36357,7 @@ var handleLog = async (ctx, { flags, args }) => {
|
|
|
36256
36357
|
maxUpdates: ctx.maxUpdates,
|
|
36257
36358
|
inactivityTimeoutMs: ctx.inactivityTimeoutMs,
|
|
36258
36359
|
functionLogs: ctx.functionLogMode,
|
|
36360
|
+
profile: ctx.profile,
|
|
36259
36361
|
signal: ctx.signal
|
|
36260
36362
|
});
|
|
36261
36363
|
return;
|
|
@@ -36340,7 +36442,11 @@ var SUB_DOMAIN = defineDomain({
|
|
|
36340
36442
|
prime: true,
|
|
36341
36443
|
summary: "View subscription details",
|
|
36342
36444
|
args: "<name>",
|
|
36343
|
-
|
|
36445
|
+
flags: viewFlags5,
|
|
36446
|
+
examples: [
|
|
36447
|
+
"wh sub view signal-hook --repo myorg/myrepo",
|
|
36448
|
+
"wh sub view signal-hook --show-secrets --repo myorg/myrepo"
|
|
36449
|
+
],
|
|
36344
36450
|
handler: handleView8
|
|
36345
36451
|
},
|
|
36346
36452
|
list: {
|
|
@@ -37834,10 +37940,6 @@ async function dispatch(ctx) {
|
|
|
37834
37940
|
const { command } = ctx.invocation;
|
|
37835
37941
|
if (!command || command === "help") {
|
|
37836
37942
|
const helpTarget = command === "help" ? ctx.invocation.positional[0] : undefined;
|
|
37837
|
-
if (ctx.format === "json") {
|
|
37838
|
-
printJson(ctx.out, buildCliSpec());
|
|
37839
|
-
return;
|
|
37840
|
-
}
|
|
37841
37943
|
if (helpTarget) {
|
|
37842
37944
|
const domain = registry.getDomain(helpTarget);
|
|
37843
37945
|
if (domain) {
|
|
@@ -37846,6 +37948,10 @@ async function dispatch(ctx) {
|
|
|
37846
37948
|
throw new CliError(2 /* UserInput */, "USER_INPUT", `Unknown command: ${helpTarget}`, undefined, "Run 'wh help' for available commands.");
|
|
37847
37949
|
}
|
|
37848
37950
|
} else {
|
|
37951
|
+
if (ctx.format === "json") {
|
|
37952
|
+
printJson(ctx.out, buildCliSpec());
|
|
37953
|
+
return;
|
|
37954
|
+
}
|
|
37849
37955
|
let repoSlug;
|
|
37850
37956
|
try {
|
|
37851
37957
|
const { org, repo } = parseOrgRepo(getRepoRef(ctx), ctx.config);
|
|
@@ -37897,6 +38003,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37897
38003
|
const errors = [];
|
|
37898
38004
|
const { meta, manifest } = pkg;
|
|
37899
38005
|
const componentId = meta.id;
|
|
38006
|
+
const componentRef = source.registeredComponentRef;
|
|
37900
38007
|
const validation = validateComponentPackage(pkg);
|
|
37901
38008
|
if (!validation.valid) {
|
|
37902
38009
|
const validationErrors = validation.findings.filter((f) => f.level === "error").map((f) => f.message);
|
|
@@ -37947,7 +38054,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37947
38054
|
const oldCredNames = wasIncomplete ? new Set : new Set(oldManifest?.credentials?.map((c) => c.name) ?? []);
|
|
37948
38055
|
const liveShapeNames = new Set;
|
|
37949
38056
|
const liveShapeDataByName = new Map;
|
|
37950
|
-
const
|
|
38057
|
+
const liveShapeComponentRefByName = new Map;
|
|
37951
38058
|
for (const shape of reconcileShapes) {
|
|
37952
38059
|
if (isFailedInstallState || previousState !== "degraded" && !oldShapeNames.has(shape.name)) {
|
|
37953
38060
|
continue;
|
|
@@ -37964,7 +38071,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37964
38071
|
includeRetracted: true
|
|
37965
38072
|
});
|
|
37966
38073
|
liveShapeDataByName.set(shape.name, liveShape.version?.data);
|
|
37967
|
-
|
|
38074
|
+
liveShapeComponentRefByName.set(shape.name, liveShape.componentRef);
|
|
37968
38075
|
} catch {}
|
|
37969
38076
|
} catch {}
|
|
37970
38077
|
}
|
|
@@ -37999,7 +38106,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
37999
38106
|
data: manifestShapeData(shape)
|
|
38000
38107
|
}));
|
|
38001
38108
|
try {
|
|
38002
|
-
await client.commit.apply(org, repo, `Add new shapes for ${meta.name}`, shapeOps, {
|
|
38109
|
+
await client.commit.apply(org, repo, `Add new shapes for ${meta.name}`, shapeOps, { componentRef });
|
|
38003
38110
|
steps.push({ step: "add-new-shapes", status: "ok" });
|
|
38004
38111
|
} catch (err) {
|
|
38005
38112
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38015,8 +38122,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38015
38122
|
if (!liveShapeNames.has(shape.name))
|
|
38016
38123
|
return false;
|
|
38017
38124
|
const liveData = liveShapeDataByName.get(shape.name);
|
|
38018
|
-
const
|
|
38019
|
-
return
|
|
38125
|
+
const liveComponentRef = liveShapeComponentRefByName.get(shape.name);
|
|
38126
|
+
return liveComponentRef !== componentRef || !shapeDataEquals(manifestShapeData(shape), liveData);
|
|
38020
38127
|
});
|
|
38021
38128
|
if (changedShapes.length > 0) {
|
|
38022
38129
|
const shapeOps = changedShapes.map((shape) => ({
|
|
@@ -38026,7 +38133,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38026
38133
|
data: manifestShapeData(shape)
|
|
38027
38134
|
}));
|
|
38028
38135
|
try {
|
|
38029
|
-
await client.commit.apply(org, repo, `Reconcile shapes for ${meta.name}`, shapeOps, {
|
|
38136
|
+
await client.commit.apply(org, repo, `Reconcile shapes for ${meta.name}`, shapeOps, { componentRef });
|
|
38030
38137
|
steps.push({ step: "claim-existing-shapes", status: "ok" });
|
|
38031
38138
|
} catch (err) {
|
|
38032
38139
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38092,7 +38199,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38092
38199
|
filterJson: compiled.filterJson,
|
|
38093
38200
|
webhookUrl: compiled.webhookUrl,
|
|
38094
38201
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38095
|
-
|
|
38202
|
+
componentRef
|
|
38096
38203
|
});
|
|
38097
38204
|
steps.push({ step: `add-sub-${sub.name}`, status: "ok" });
|
|
38098
38205
|
} catch (err) {
|
|
@@ -38131,8 +38238,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38131
38238
|
}
|
|
38132
38239
|
try {
|
|
38133
38240
|
const liveSub = await client.subscription.get(org, repo, sub.name);
|
|
38134
|
-
if (liveSub.
|
|
38135
|
-
const msg = `Subscription "${sub.name}" is owned by component "${liveSub.
|
|
38241
|
+
if (liveSub.componentRef && liveSub.componentRef !== componentRef) {
|
|
38242
|
+
const msg = `Subscription "${sub.name}" is owned by component "${liveSub.componentRef}"`;
|
|
38136
38243
|
errors.push(msg);
|
|
38137
38244
|
steps.push({ step: stepName, status: "error", message: msg });
|
|
38138
38245
|
continue;
|
|
@@ -38150,7 +38257,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38150
38257
|
filterJson: compiled.filterJson,
|
|
38151
38258
|
webhookUrl: compiled.webhookUrl,
|
|
38152
38259
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38153
|
-
|
|
38260
|
+
componentRef
|
|
38154
38261
|
});
|
|
38155
38262
|
} catch (createErr) {
|
|
38156
38263
|
const createMsg = createErr instanceof Error ? createErr.message : String(createErr);
|
|
@@ -38207,7 +38314,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38207
38314
|
name: `${seed.shape}/${seed.name}`,
|
|
38208
38315
|
data: seed.data
|
|
38209
38316
|
}
|
|
38210
|
-
], {
|
|
38317
|
+
], { componentRef });
|
|
38211
38318
|
} catch (reviseErr) {
|
|
38212
38319
|
const reviseMsg = reviseErr instanceof Error ? reviseErr.message : String(reviseErr);
|
|
38213
38320
|
const reviseLooksMissing = reviseMsg.includes("not found") || reviseMsg.includes("NOT_FOUND");
|
|
@@ -38223,7 +38330,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38223
38330
|
name: `${seed.shape}/${seed.name}`,
|
|
38224
38331
|
data: seed.data
|
|
38225
38332
|
}
|
|
38226
|
-
], {
|
|
38333
|
+
], { componentRef });
|
|
38227
38334
|
} catch (addErr) {
|
|
38228
38335
|
const msg = addErr instanceof Error ? addErr.message : String(addErr);
|
|
38229
38336
|
if (!isAlreadyExistsError(addErr)) {
|
|
@@ -38248,8 +38355,8 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38248
38355
|
componentId,
|
|
38249
38356
|
name: meta.name,
|
|
38250
38357
|
version: meta.version,
|
|
38251
|
-
source:
|
|
38252
|
-
sourceKind:
|
|
38358
|
+
source: "registry",
|
|
38359
|
+
sourceKind: "registered",
|
|
38253
38360
|
sourceRef: source.ref ?? "",
|
|
38254
38361
|
resolvedSha: source.resolvedSha ?? "",
|
|
38255
38362
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38261,7 +38368,7 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
38261
38368
|
...source.installId ?? persistedInstallId ? { installId: source.installId ?? persistedInstallId } : {}
|
|
38262
38369
|
}
|
|
38263
38370
|
}
|
|
38264
|
-
], {
|
|
38371
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38265
38372
|
steps.push({ step: "update-install-record", status: "ok" });
|
|
38266
38373
|
} catch (err) {
|
|
38267
38374
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38376,8 +38483,8 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38376
38483
|
componentId,
|
|
38377
38484
|
name: meta.name,
|
|
38378
38485
|
version: meta.version,
|
|
38379
|
-
source:
|
|
38380
|
-
sourceKind:
|
|
38486
|
+
source: "registry",
|
|
38487
|
+
sourceKind: "registered",
|
|
38381
38488
|
sourceRef: source.ref ?? "",
|
|
38382
38489
|
resolvedSha: source.resolvedSha ?? "",
|
|
38383
38490
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38388,7 +38495,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38388
38495
|
...source.installId ? { installId: source.installId } : {}
|
|
38389
38496
|
}
|
|
38390
38497
|
}
|
|
38391
|
-
], {
|
|
38498
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38392
38499
|
steps.push({ step: "create-install-record", status: "ok" });
|
|
38393
38500
|
} catch (err) {
|
|
38394
38501
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38404,13 +38511,13 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38404
38511
|
data: manifestShapeData(shape)
|
|
38405
38512
|
}));
|
|
38406
38513
|
try {
|
|
38407
|
-
await client.commit.apply(org, repo, `Add shapes for ${meta.name}`, shapeOps, {
|
|
38514
|
+
await client.commit.apply(org, repo, `Add shapes for ${meta.name}`, shapeOps, { componentRef: source.registeredComponentRef });
|
|
38408
38515
|
steps.push({ step: "create-shapes", status: "ok" });
|
|
38409
38516
|
} catch (err) {
|
|
38410
38517
|
const msg = err instanceof Error ? err.message : String(err);
|
|
38411
38518
|
if (isAlreadyExistsError(err)) {
|
|
38412
38519
|
try {
|
|
38413
|
-
await reconcileShapesAfterCreateConflict(client, org, repo, pkg);
|
|
38520
|
+
await reconcileShapesAfterCreateConflict(client, org, repo, pkg, source);
|
|
38414
38521
|
steps.push({
|
|
38415
38522
|
step: "create-shapes",
|
|
38416
38523
|
status: "ok",
|
|
@@ -38487,7 +38594,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38487
38594
|
filterJson: compiled.filterJson,
|
|
38488
38595
|
webhookUrl: compiled.webhookUrl,
|
|
38489
38596
|
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
38490
|
-
|
|
38597
|
+
componentRef: source.registeredComponentRef
|
|
38491
38598
|
});
|
|
38492
38599
|
steps.push({ step: `create-sub-${sub.name}`, status: "ok" });
|
|
38493
38600
|
} catch (err) {
|
|
@@ -38526,7 +38633,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38526
38633
|
name: seedName,
|
|
38527
38634
|
data: seed.data
|
|
38528
38635
|
}
|
|
38529
|
-
], {
|
|
38636
|
+
], { componentRef: source.registeredComponentRef });
|
|
38530
38637
|
steps.push({ step: `seed-${seedName}`, status: "ok" });
|
|
38531
38638
|
} catch (err) {
|
|
38532
38639
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38553,8 +38660,8 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38553
38660
|
componentId,
|
|
38554
38661
|
name: meta.name,
|
|
38555
38662
|
version: meta.version,
|
|
38556
|
-
source:
|
|
38557
|
-
sourceKind:
|
|
38663
|
+
source: "registry",
|
|
38664
|
+
sourceKind: "registered",
|
|
38558
38665
|
sourceRef: source.ref ?? "",
|
|
38559
38666
|
resolvedSha: source.resolvedSha ?? "",
|
|
38560
38667
|
...source.registeredComponentRef ? { registeredComponentRef: source.registeredComponentRef } : {},
|
|
@@ -38566,7 +38673,7 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
38566
38673
|
...source.installId ? { installId: source.installId } : {}
|
|
38567
38674
|
}
|
|
38568
38675
|
}
|
|
38569
|
-
], {
|
|
38676
|
+
], { componentRef: SYSTEM_REGISTERED_COMPONENT_REF });
|
|
38570
38677
|
steps.push({ step: "finalize", status: "ok" });
|
|
38571
38678
|
} catch (err) {
|
|
38572
38679
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -38584,12 +38691,12 @@ function assertCliMethodsAllowedForSource(pkg, source) {
|
|
|
38584
38691
|
const hasCliMethods = (pkg.manifest.cli?.methods?.length ?? 0) > 0;
|
|
38585
38692
|
if (!hasCliMethods)
|
|
38586
38693
|
return;
|
|
38587
|
-
if (
|
|
38694
|
+
if (typeof source.registeredComponentRef === "string" && source.registeredComponentRef.length > 0) {
|
|
38588
38695
|
return;
|
|
38589
38696
|
}
|
|
38590
38697
|
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.");
|
|
38591
38698
|
}
|
|
38592
|
-
async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
38699
|
+
async function reconcileShapesAfterCreateConflict(client, org, repo, pkg, source) {
|
|
38593
38700
|
const { meta, manifest } = pkg;
|
|
38594
38701
|
const existingShapes = new Map;
|
|
38595
38702
|
for (const shape of manifest.shapes) {
|
|
@@ -38597,8 +38704,8 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38597
38704
|
const existingShape = await client.shape.get(org, repo, shape.name, {
|
|
38598
38705
|
includeRetracted: true
|
|
38599
38706
|
});
|
|
38600
|
-
if (existingShape.
|
|
38601
|
-
const owner = existingShape.
|
|
38707
|
+
if (existingShape.componentRef !== source.registeredComponentRef) {
|
|
38708
|
+
const owner = existingShape.componentRef ? `owned by component "${existingShape.componentRef}"` : "not owned by this component";
|
|
38602
38709
|
throw new Error(`Shape "${shape.name}" already exists and is ${owner}; cannot reconcile during fresh install`);
|
|
38603
38710
|
}
|
|
38604
38711
|
existingShapes.set(shape.name, existingShape);
|
|
@@ -38620,7 +38727,7 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38620
38727
|
name: shape.name,
|
|
38621
38728
|
data
|
|
38622
38729
|
}
|
|
38623
|
-
], {
|
|
38730
|
+
], { componentRef: source.registeredComponentRef });
|
|
38624
38731
|
continue;
|
|
38625
38732
|
}
|
|
38626
38733
|
try {
|
|
@@ -38631,7 +38738,7 @@ async function reconcileShapesAfterCreateConflict(client, org, repo, pkg) {
|
|
|
38631
38738
|
name: shape.name,
|
|
38632
38739
|
data
|
|
38633
38740
|
}
|
|
38634
|
-
], {
|
|
38741
|
+
], { componentRef: source.registeredComponentRef });
|
|
38635
38742
|
} catch (err) {
|
|
38636
38743
|
if (isAlreadyExistsError(err)) {
|
|
38637
38744
|
throw new Error(`Shape "${shape.name}" already exists but ownership could not be verified; cannot reconcile during fresh install`);
|
|
@@ -38906,9 +39013,10 @@ async function runCli(argv, opts) {
|
|
|
38906
39013
|
requestedMode: requestedFunctionLogs
|
|
38907
39014
|
});
|
|
38908
39015
|
const localOnlyCommand = isLocalOnlyInvocation(invocation);
|
|
38909
|
-
const { config, client } = localOnlyCommand ? {
|
|
39016
|
+
const { config, client, profile } = localOnlyCommand ? {
|
|
38910
39017
|
config: loadConfig(),
|
|
38911
|
-
client: createLocalOnlyClient()
|
|
39018
|
+
client: createLocalOnlyClient(),
|
|
39019
|
+
profile: "default"
|
|
38912
39020
|
} : resolveCliContext({
|
|
38913
39021
|
invocation,
|
|
38914
39022
|
format,
|
|
@@ -38936,6 +39044,7 @@ async function runCli(argv, opts) {
|
|
|
38936
39044
|
client,
|
|
38937
39045
|
config,
|
|
38938
39046
|
invocation,
|
|
39047
|
+
profile,
|
|
38939
39048
|
colors,
|
|
38940
39049
|
chars,
|
|
38941
39050
|
format,
|
|
@@ -39044,7 +39153,7 @@ function resolveLogLevel(flags, env) {
|
|
|
39044
39153
|
// package.json
|
|
39045
39154
|
var package_default3 = {
|
|
39046
39155
|
name: "@warmhub/cli",
|
|
39047
|
-
version: "0.
|
|
39156
|
+
version: "0.53.0",
|
|
39048
39157
|
private: false,
|
|
39049
39158
|
type: "module",
|
|
39050
39159
|
description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -39149,12 +39258,18 @@ async function maybeHandleComponentShellBoundary(argv, deps = {}) {
|
|
|
39149
39258
|
const writeOut = deps.out ?? out;
|
|
39150
39259
|
const writeErr = deps.err ?? err;
|
|
39151
39260
|
const debug = getBoolFlag(invocation.flags, "debug") || process.env.WARMHUB_DEBUG === "1";
|
|
39152
|
-
|
|
39153
|
-
const format = formatFlag === "json" || formatFlag === "jsonl" ? formatFlag : getBoolFlag(invocation.flags, "json") ? "json" : "pretty";
|
|
39261
|
+
let format = "pretty";
|
|
39154
39262
|
const installFromManifestImpl = deps.installFromManifest ?? installFromManifest;
|
|
39155
39263
|
const resolveRegisteredInstallImpl = deps.resolveRegisteredInstall ?? resolveRegisteredInstall;
|
|
39156
39264
|
const callRegisteredSetupImpl = deps.callRegisteredSetup ?? callRegisteredSetup;
|
|
39157
39265
|
try {
|
|
39266
|
+
canonicalizeGlobalFlags({ invocation });
|
|
39267
|
+
const formatFlag = getStringFlag(invocation.flags, "format");
|
|
39268
|
+
format = formatFlag === "json" || formatFlag === "jsonl" ? formatFlag : "pretty";
|
|
39269
|
+
applyGlobalFlags({ invocation });
|
|
39270
|
+
if (getBoolFlag(invocation.flags, "dry-run")) {
|
|
39271
|
+
return;
|
|
39272
|
+
}
|
|
39158
39273
|
const { config, client } = resolveCliContext({
|
|
39159
39274
|
invocation,
|
|
39160
39275
|
format,
|
|
@@ -39185,14 +39300,17 @@ async function maybeHandleComponentShellBoundary(argv, deps = {}) {
|
|
|
39185
39300
|
callRegisteredSetup: callRegisteredSetupImpl
|
|
39186
39301
|
});
|
|
39187
39302
|
}
|
|
39188
|
-
const
|
|
39189
|
-
if (!
|
|
39303
|
+
const componentRef = invocation.positional[1];
|
|
39304
|
+
if (!componentRef) {
|
|
39190
39305
|
return;
|
|
39191
39306
|
}
|
|
39307
|
+
if (!isRegisteredComponentSource(componentRef)) {
|
|
39308
|
+
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");
|
|
39309
|
+
}
|
|
39192
39310
|
const repoFlag = getStringFlag(invocation.flags, "repo") ?? config.defaultRepo;
|
|
39193
39311
|
const refOverride = getStringFlag(invocation.flags, "ref");
|
|
39194
39312
|
return await handleComponentUpdate({
|
|
39195
|
-
|
|
39313
|
+
componentRef,
|
|
39196
39314
|
repoFlag,
|
|
39197
39315
|
refOverride,
|
|
39198
39316
|
client,
|
|
@@ -39263,7 +39381,6 @@ async function performRegisteredInstall(args) {
|
|
|
39263
39381
|
invalidateInstallSnapshotCache(installRepo);
|
|
39264
39382
|
const result = await args.installFromManifest(args.client, args.parsedRepo.org, args.parsedRepo.repo, resolved.manifest, {
|
|
39265
39383
|
installId,
|
|
39266
|
-
sourceKind: "registered",
|
|
39267
39384
|
registeredComponentRef: args.componentRef
|
|
39268
39385
|
});
|
|
39269
39386
|
if (!result.ok) {
|
|
@@ -39328,11 +39445,15 @@ function warmHubErrorBackendCode(error) {
|
|
|
39328
39445
|
async function handleComponentUpdate(args) {
|
|
39329
39446
|
const parsedRepo = parseOrgRepo(args.repoFlag, args.config);
|
|
39330
39447
|
const installRepo = `${parsedRepo.org}/${parsedRepo.repo}`;
|
|
39331
|
-
const
|
|
39448
|
+
const componentId = await resolveInstalledComponentRefId(args.client, parsedRepo.org, parsedRepo.repo, args.componentRef);
|
|
39449
|
+
const installThing = await args.client.thing.get(parsedRepo.org, parsedRepo.repo, `ComponentInstall/${componentId}`);
|
|
39332
39450
|
const installData = installThing.data && typeof installThing.data === "object" ? installThing.data : {};
|
|
39333
39451
|
const source = resolveComponentUpdateSource(installData);
|
|
39334
39452
|
if (source.kind === "registered") {
|
|
39335
39453
|
rejectRefForRegistered(source.componentRef, args.refOverride);
|
|
39454
|
+
if (source.componentRef !== args.componentRef) {
|
|
39455
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.componentRef}' resolved to an install for '${source.componentRef}', which is inconsistent with the install record.`);
|
|
39456
|
+
}
|
|
39336
39457
|
return performRegisteredInstall({
|
|
39337
39458
|
componentRef: source.componentRef,
|
|
39338
39459
|
persistedInstallData: installData,
|
|
@@ -39348,9 +39469,9 @@ async function handleComponentUpdate(args) {
|
|
|
39348
39469
|
});
|
|
39349
39470
|
}
|
|
39350
39471
|
if (source.kind === "system") {
|
|
39351
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.
|
|
39472
|
+
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.`);
|
|
39352
39473
|
}
|
|
39353
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `Component '${args.
|
|
39474
|
+
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>`.");
|
|
39354
39475
|
}
|
|
39355
39476
|
async function writeInstallResult(writeOut, writeErr, format, verb, result, installRepo, client) {
|
|
39356
39477
|
if (result.ok) {
|
|
@@ -39823,4 +39944,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
|
|
|
39823
39944
|
var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
|
|
39824
39945
|
process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
|
|
39825
39946
|
|
|
39826
|
-
//# debugId=
|
|
39947
|
+
//# debugId=E69740B781D6D4C864756E2164756E21
|