@warmhub/cli 0.49.0 → 0.50.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 +380 -247
- package/package.json +1 -1
package/dist/wh.js
CHANGED
|
@@ -19527,7 +19527,7 @@ function findSystemComponent(componentId) {
|
|
|
19527
19527
|
// ../../packages/sdk-ts/package.json
|
|
19528
19528
|
var package_default = {
|
|
19529
19529
|
name: "@warmhub/sdk-ts",
|
|
19530
|
-
version: "0.
|
|
19530
|
+
version: "0.50.0",
|
|
19531
19531
|
private: false,
|
|
19532
19532
|
type: "module",
|
|
19533
19533
|
description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -19825,9 +19825,6 @@ async function submitOperationsViaStream(client, args) {
|
|
|
19825
19825
|
if (args.operations.length === 0) {
|
|
19826
19826
|
throw new StreamValidationError("At least one operation is required for stream submission.");
|
|
19827
19827
|
}
|
|
19828
|
-
if ((args.allocatedTokens?.length ?? 0) > 0 && args.streamId === undefined) {
|
|
19829
|
-
throw new StreamValidationError("Manual stream resume with allocatedTokens requires the original streamId.");
|
|
19830
|
-
}
|
|
19831
19828
|
const operations = args.operations.map((operation, index) => {
|
|
19832
19829
|
let streamOperation;
|
|
19833
19830
|
try {
|
|
@@ -19843,9 +19840,8 @@ async function submitOperationsViaStream(client, args) {
|
|
|
19843
19840
|
});
|
|
19844
19841
|
const chunkSize = normalizeChunkSize(args.chunkSize);
|
|
19845
19842
|
let streamId = args.streamId ?? createStreamId();
|
|
19846
|
-
const
|
|
19847
|
-
|
|
19848
|
-
let allocatedTokens = args.allocatedTokens ?? [];
|
|
19843
|
+
const policy = args.streamId !== undefined ? false : resolveRetryPolicy(args.retry);
|
|
19844
|
+
let allocatedTokenRanges = [];
|
|
19849
19845
|
let createdByEmail;
|
|
19850
19846
|
const chunkResults = [];
|
|
19851
19847
|
let sawAmbiguousAttempt = false;
|
|
@@ -19857,7 +19853,7 @@ async function submitOperationsViaStream(client, args) {
|
|
|
19857
19853
|
while (true) {
|
|
19858
19854
|
try {
|
|
19859
19855
|
const appendResult = await client.stream.append({
|
|
19860
|
-
|
|
19856
|
+
allocatedTokenRanges,
|
|
19861
19857
|
orgName: args.orgName,
|
|
19862
19858
|
repoName: args.repoName,
|
|
19863
19859
|
streamId,
|
|
@@ -19866,7 +19862,7 @@ async function submitOperationsViaStream(client, args) {
|
|
|
19866
19862
|
message: args.message,
|
|
19867
19863
|
operations: chunk
|
|
19868
19864
|
});
|
|
19869
|
-
|
|
19865
|
+
allocatedTokenRanges = appendResult.allocatedTokenRanges;
|
|
19870
19866
|
if (appendResult.createdByEmail !== undefined) {
|
|
19871
19867
|
createdByEmail = appendResult.createdByEmail;
|
|
19872
19868
|
}
|
|
@@ -19882,7 +19878,7 @@ async function submitOperationsViaStream(client, args) {
|
|
|
19882
19878
|
priorAttemptAmbiguous = true;
|
|
19883
19879
|
sawAmbiguousAttempt = true;
|
|
19884
19880
|
streamId = createStreamId();
|
|
19885
|
-
|
|
19881
|
+
allocatedTokenRanges = [];
|
|
19886
19882
|
continue;
|
|
19887
19883
|
}
|
|
19888
19884
|
const completedOperations = completedOperationsFrom(toSubmittedStreamResult({
|
|
@@ -20059,6 +20055,27 @@ function toSubmittedStreamResult(writeResult, committer, createdByEmail, message
|
|
|
20059
20055
|
};
|
|
20060
20056
|
}
|
|
20061
20057
|
// ../../packages/sdk-ts/src/index.ts
|
|
20058
|
+
var WARMHUB_CLIENT_OPTION_NAMES = [
|
|
20059
|
+
"apiUrl",
|
|
20060
|
+
"fetch",
|
|
20061
|
+
"accessToken",
|
|
20062
|
+
"auth",
|
|
20063
|
+
"functionLogs"
|
|
20064
|
+
];
|
|
20065
|
+
var WARMHUB_CLIENT_OPTION_NAME_SET = new Set(WARMHUB_CLIENT_OPTION_NAMES);
|
|
20066
|
+
var ACCESS_TOKEN_OPTION_ALIASES = new Set(["token", "apiKey", "bearer"]);
|
|
20067
|
+
function validateWarmHubClientOptions(options) {
|
|
20068
|
+
if (!options) {
|
|
20069
|
+
return;
|
|
20070
|
+
}
|
|
20071
|
+
for (const key of Object.keys(options)) {
|
|
20072
|
+
if (WARMHUB_CLIENT_OPTION_NAME_SET.has(key)) {
|
|
20073
|
+
continue;
|
|
20074
|
+
}
|
|
20075
|
+
const hint = ACCESS_TOKEN_OPTION_ALIASES.has(key) ? '; did you mean "accessToken"?' : `. Valid options are: ${WARMHUB_CLIENT_OPTION_NAMES.join(", ")}.`;
|
|
20076
|
+
throw new TypeError(`Unknown WarmHubClient option "${key}"${hint}`);
|
|
20077
|
+
}
|
|
20078
|
+
}
|
|
20062
20079
|
var SDK_VERSION = typeof __SDK_VERSION__ !== "undefined" ? __SDK_VERSION__ : package_default.version;
|
|
20063
20080
|
var DEFAULT_API_URL = "https://api.warmhub.ai";
|
|
20064
20081
|
var UNBATCHED_TRPC_PATHS = new Set([
|
|
@@ -20162,16 +20179,18 @@ class WarmHubError extends Error {
|
|
|
20162
20179
|
status;
|
|
20163
20180
|
hint;
|
|
20164
20181
|
retryAfter;
|
|
20182
|
+
errorCode;
|
|
20165
20183
|
backendCode;
|
|
20166
20184
|
details;
|
|
20167
|
-
constructor(code, message, status, hint, retryAfter,
|
|
20185
|
+
constructor(code, message, status, hint, retryAfter, errorCode, details) {
|
|
20168
20186
|
super(message);
|
|
20169
20187
|
this.name = "WarmHubError";
|
|
20170
20188
|
this.code = code;
|
|
20171
20189
|
this.status = status;
|
|
20172
20190
|
this.hint = hint;
|
|
20173
20191
|
this.retryAfter = retryAfter;
|
|
20174
|
-
this.
|
|
20192
|
+
this.errorCode = errorCode;
|
|
20193
|
+
this.backendCode = errorCode;
|
|
20175
20194
|
this.details = details;
|
|
20176
20195
|
}
|
|
20177
20196
|
get kind() {
|
|
@@ -20202,7 +20221,7 @@ function toWarmHubError(error) {
|
|
|
20202
20221
|
if (error instanceof Error) {
|
|
20203
20222
|
const warmhubLike = error;
|
|
20204
20223
|
if (error.name === "WarmHubError" && typeof warmhubLike.code === "string") {
|
|
20205
|
-
return new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined, typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : undefined, warmhubLike.details);
|
|
20224
|
+
return new WarmHubError(warmhubLike.code, sanitizeErrorMessage(error.message), typeof warmhubLike.status === "number" ? warmhubLike.status : undefined, typeof warmhubLike.hint === "string" ? warmhubLike.hint : undefined, typeof warmhubLike.retryAfter === "number" ? warmhubLike.retryAfter : undefined, typeof warmhubLike.errorCode === "string" ? warmhubLike.errorCode : typeof warmhubLike.backendCode === "string" ? warmhubLike.backendCode : undefined, warmhubLike.details);
|
|
20206
20225
|
}
|
|
20207
20226
|
if (error.name === "AbortError") {
|
|
20208
20227
|
return new WarmHubError("CANCELLED", error.message);
|
|
@@ -20545,7 +20564,6 @@ class WarmHubClient {
|
|
|
20545
20564
|
chunkSize: opts?.chunkSize,
|
|
20546
20565
|
skipExisting: opts?.skipExisting,
|
|
20547
20566
|
streamId: opts?.streamId,
|
|
20548
|
-
allocatedTokens: opts?.allocatedTokens,
|
|
20549
20567
|
retry: opts?.retry,
|
|
20550
20568
|
operations
|
|
20551
20569
|
});
|
|
@@ -20896,19 +20914,19 @@ class WarmHubClient {
|
|
|
20896
20914
|
throw toWarmHubError(error);
|
|
20897
20915
|
}
|
|
20898
20916
|
},
|
|
20899
|
-
|
|
20917
|
+
listForCaller: async (opts) => {
|
|
20900
20918
|
try {
|
|
20901
|
-
return await this.trpc.repo.
|
|
20902
|
-
|
|
20903
|
-
|
|
20919
|
+
return await this.trpc.repo.listForCaller.query({
|
|
20920
|
+
limit: opts?.limit,
|
|
20921
|
+
sort: opts?.sort
|
|
20904
20922
|
});
|
|
20905
20923
|
} catch (error) {
|
|
20906
20924
|
throw toWarmHubError(error);
|
|
20907
20925
|
}
|
|
20908
20926
|
},
|
|
20909
|
-
|
|
20927
|
+
getReadme: async (orgName, repoName) => {
|
|
20910
20928
|
try {
|
|
20911
|
-
return await this.trpc.repo.
|
|
20929
|
+
return await this.trpc.repo.getReadme.query({
|
|
20912
20930
|
orgName,
|
|
20913
20931
|
repoName
|
|
20914
20932
|
});
|
|
@@ -20950,16 +20968,6 @@ class WarmHubClient {
|
|
|
20950
20968
|
throw toWarmHubError(error);
|
|
20951
20969
|
}
|
|
20952
20970
|
},
|
|
20953
|
-
generateAgents: async (orgName, repoName) => {
|
|
20954
|
-
try {
|
|
20955
|
-
return await this.trpc.repo.generateAgents.mutate({
|
|
20956
|
-
orgName,
|
|
20957
|
-
repoName
|
|
20958
|
-
});
|
|
20959
|
-
} catch (error) {
|
|
20960
|
-
throw toWarmHubError(error);
|
|
20961
|
-
}
|
|
20962
|
-
},
|
|
20963
20971
|
getLlmsTxt: async (orgName, repoName) => {
|
|
20964
20972
|
try {
|
|
20965
20973
|
return await this.trpc.repo.getLlmsTxt.query({
|
|
@@ -21263,6 +21271,18 @@ class WarmHubClient {
|
|
|
21263
21271
|
throw toWarmHubError(error);
|
|
21264
21272
|
}
|
|
21265
21273
|
},
|
|
21274
|
+
runStats: async (orgName, repoName, opts) => {
|
|
21275
|
+
try {
|
|
21276
|
+
return await this.trpc.action.runStats.query({
|
|
21277
|
+
orgName,
|
|
21278
|
+
repoName,
|
|
21279
|
+
subscriptionName: opts?.subscriptionName,
|
|
21280
|
+
since: opts?.since
|
|
21281
|
+
});
|
|
21282
|
+
} catch (error) {
|
|
21283
|
+
throw toWarmHubError(error);
|
|
21284
|
+
}
|
|
21285
|
+
},
|
|
21266
21286
|
getRunAttempts: async (orgName, repoName, runId) => {
|
|
21267
21287
|
try {
|
|
21268
21288
|
return await this.trpc.action.getRunAttempts.query({
|
|
@@ -21785,6 +21805,7 @@ class WarmHubClient {
|
|
|
21785
21805
|
credentials = this.credential;
|
|
21786
21806
|
constructor(apiUrlOrOptions, maybeOptions) {
|
|
21787
21807
|
const options = typeof apiUrlOrOptions === "string" ? maybeOptions : apiUrlOrOptions;
|
|
21808
|
+
validateWarmHubClientOptions(options);
|
|
21788
21809
|
const apiUrl = typeof apiUrlOrOptions === "string" ? apiUrlOrOptions : apiUrlOrOptions?.apiUrl ?? DEFAULT_API_URL;
|
|
21789
21810
|
this.apiUrl = apiUrl;
|
|
21790
21811
|
this.fetchImpl = options?.fetch;
|
|
@@ -21920,7 +21941,7 @@ class WarmHubClient {
|
|
|
21920
21941
|
if (!response.ok) {
|
|
21921
21942
|
let message = `Request failed with status ${response.status}`;
|
|
21922
21943
|
let code = httpStatusToWarmHubCode(response.status);
|
|
21923
|
-
let
|
|
21944
|
+
let errorCode;
|
|
21924
21945
|
let hint;
|
|
21925
21946
|
let retryAfter;
|
|
21926
21947
|
try {
|
|
@@ -21930,7 +21951,7 @@ class WarmHubClient {
|
|
|
21930
21951
|
}
|
|
21931
21952
|
if (typeof body.error?.code === "string") {
|
|
21932
21953
|
code = body.error.code;
|
|
21933
|
-
|
|
21954
|
+
errorCode = body.error.code;
|
|
21934
21955
|
}
|
|
21935
21956
|
if (typeof body.error?.hint === "string") {
|
|
21936
21957
|
hint = body.error.hint;
|
|
@@ -21939,7 +21960,7 @@ class WarmHubClient {
|
|
|
21939
21960
|
retryAfter = body.error.retryAfter;
|
|
21940
21961
|
}
|
|
21941
21962
|
} catch {}
|
|
21942
|
-
throw new WarmHubError(code, message, response.status, hint, retryAfter,
|
|
21963
|
+
throw new WarmHubError(code, message, response.status, hint, retryAfter, errorCode);
|
|
21943
21964
|
}
|
|
21944
21965
|
return response;
|
|
21945
21966
|
}
|
|
@@ -22068,6 +22089,9 @@ class CliError extends Error {
|
|
|
22068
22089
|
this.backendCode = backendCode;
|
|
22069
22090
|
this.context = context;
|
|
22070
22091
|
}
|
|
22092
|
+
get errorCode() {
|
|
22093
|
+
return this.backendCode;
|
|
22094
|
+
}
|
|
22071
22095
|
}
|
|
22072
22096
|
function unauthenticatedHint(message) {
|
|
22073
22097
|
if (message.includes("Authentication required")) {
|
|
@@ -22153,7 +22177,7 @@ var CONFLICT_SHAPED_CODES = new Set([
|
|
|
22153
22177
|
"LEASE_UNAVAILABLE"
|
|
22154
22178
|
]);
|
|
22155
22179
|
function fromWh(exit, kind, err, hint = err.hint) {
|
|
22156
|
-
return new CliError(exit, kind, err.message, err, hint, undefined, err.
|
|
22180
|
+
return new CliError(exit, kind, err.message, err, hint, undefined, err.errorCode);
|
|
22157
22181
|
}
|
|
22158
22182
|
function usageError(usage, example) {
|
|
22159
22183
|
throw new CliError(2 /* UserInput */, "USER_INPUT", usage, undefined, `Example: ${example}`);
|
|
@@ -22180,7 +22204,7 @@ function toCliError(err) {
|
|
|
22180
22204
|
return fromWh(exit, err.code, err);
|
|
22181
22205
|
}
|
|
22182
22206
|
if (CONFLICT_SHAPED_CODES.has(err.code)) {
|
|
22183
|
-
return fromWh(2 /* UserInput */, "CONFLICT", err, err.hint ?? conflictHint(err.message, err.
|
|
22207
|
+
return fromWh(2 /* UserInput */, "CONFLICT", err, err.hint ?? conflictHint(err.message, err.errorCode ?? err.code));
|
|
22184
22208
|
}
|
|
22185
22209
|
if (err.code === "RATE_LIMITED") {
|
|
22186
22210
|
const retryAfter = err.retryAfter;
|
|
@@ -22224,7 +22248,7 @@ function isAlreadyExistsError(err, seen = new WeakSet) {
|
|
|
22224
22248
|
}
|
|
22225
22249
|
return isAlreadyExistsError(err.cause, seen);
|
|
22226
22250
|
}
|
|
22227
|
-
function generateSuggestions(code, message, context,
|
|
22251
|
+
function generateSuggestions(code, message, context, errorCode) {
|
|
22228
22252
|
const suggestions = [];
|
|
22229
22253
|
if (code === "CONFIG" && (message.includes("repo") || message.includes("WARMHUB_REPO"))) {
|
|
22230
22254
|
suggestions.push({
|
|
@@ -22281,7 +22305,7 @@ function generateSuggestions(code, message, context, backendCode) {
|
|
|
22281
22305
|
}
|
|
22282
22306
|
}
|
|
22283
22307
|
if (code === "CONFLICT") {
|
|
22284
|
-
switch (classifyConflict(message,
|
|
22308
|
+
switch (classifyConflict(message, errorCode)) {
|
|
22285
22309
|
case "already-exists":
|
|
22286
22310
|
suggestions.push({
|
|
22287
22311
|
action: "Update the existing item instead of creating a new one"
|
|
@@ -22436,8 +22460,8 @@ var OP_USER_INPUT_CODES = new Set([
|
|
|
22436
22460
|
function cliErrorFromOpFailure(failure) {
|
|
22437
22461
|
const code = failure.error?.code ?? "BACKEND";
|
|
22438
22462
|
const message = failure.error?.message ?? `Operation on "${failure.name}" failed`;
|
|
22439
|
-
const
|
|
22440
|
-
const make = (exit, kind, hint) => new CliError(exit, kind, message, undefined, hint, undefined,
|
|
22463
|
+
const errorCode = failure.error?.code;
|
|
22464
|
+
const make = (exit, kind, hint) => new CliError(exit, kind, message, undefined, hint, undefined, errorCode);
|
|
22441
22465
|
if (code === "FORBIDDEN" || code === "UNAUTHENTICATED") {
|
|
22442
22466
|
return make(5 /* Auth */, "AUTH");
|
|
22443
22467
|
}
|
|
@@ -22491,11 +22515,11 @@ function assertSingleOpSuccess(result) {
|
|
|
22491
22515
|
function printCliError(err, errWriter, opts = {}) {
|
|
22492
22516
|
const debugEnabled = opts.debug || process.env.WARMHUB_DEBUG === "1";
|
|
22493
22517
|
if (opts.format === "json" || opts.format === "jsonl") {
|
|
22494
|
-
const suggestions = generateSuggestions(err.kind, err.message, err.context, err.
|
|
22518
|
+
const suggestions = generateSuggestions(err.kind, err.message, err.context, err.errorCode);
|
|
22495
22519
|
const envelope = {
|
|
22496
22520
|
error: {
|
|
22497
22521
|
code: err.kind,
|
|
22498
|
-
...err.
|
|
22522
|
+
...err.errorCode ? { errorCode: err.errorCode, backendCode: err.errorCode } : {},
|
|
22499
22523
|
message: err.message,
|
|
22500
22524
|
...err.hint ? { hint: err.hint } : {},
|
|
22501
22525
|
...suggestions.length > 0 ? { suggestions } : {},
|
|
@@ -23647,25 +23671,11 @@ function accessTokenExpiry(accessToken) {
|
|
|
23647
23671
|
var BENCHMARK_HEADER = "x-warmhub-benchmark-id";
|
|
23648
23672
|
var REQUEST_TOTAL_MS_HEADER = "x-warmhub-request-total-ms";
|
|
23649
23673
|
var REQUEST_DB_QUERY_COUNT_HEADER = "x-warmhub-request-db-query-count";
|
|
23650
|
-
var REQUEST_PEAK_HEAP_USED_HEADER = "x-warmhub-request-peak-heap-used-bytes";
|
|
23651
|
-
var REQUEST_PEAK_RSS_HEADER = "x-warmhub-request-peak-rss-bytes";
|
|
23652
|
-
var REQUEST_PEAK_EXTERNAL_HEADER = "x-warmhub-request-peak-external-bytes";
|
|
23653
|
-
var REQUEST_RETAINED_CAPTURE_MS_HEADER = "x-warmhub-request-retained-capture-ms";
|
|
23654
|
-
var REQUEST_RETAINED_HEAP_USED_HEADER = "x-warmhub-request-retained-heap-used-bytes";
|
|
23655
|
-
var REQUEST_RETAINED_RSS_HEADER = "x-warmhub-request-retained-rss-bytes";
|
|
23656
|
-
var REQUEST_RETAINED_EXTERNAL_HEADER = "x-warmhub-request-retained-external-bytes";
|
|
23657
23674
|
var benchmarkTelemetry = emptyBenchmarkTelemetry();
|
|
23658
23675
|
function emptyBenchmarkTelemetry() {
|
|
23659
23676
|
return {
|
|
23660
23677
|
requestCount: 0,
|
|
23661
23678
|
requestDbQueryCountSum: 0,
|
|
23662
|
-
requestRetainedCaptureMsMax: 0,
|
|
23663
|
-
requestRetainedExternalBytesMax: 0,
|
|
23664
|
-
requestRetainedHeapUsedBytesMax: 0,
|
|
23665
|
-
requestRetainedRssBytesMax: 0,
|
|
23666
|
-
requestPeakExternalBytesMax: 0,
|
|
23667
|
-
requestPeakHeapUsedBytesMax: 0,
|
|
23668
|
-
requestPeakRssBytesMax: 0,
|
|
23669
23679
|
requestTotalMsMax: 0,
|
|
23670
23680
|
requestTotalMsSum: 0
|
|
23671
23681
|
};
|
|
@@ -23683,14 +23693,7 @@ function recordBenchmarkResponse(response, benchmarkId) {
|
|
|
23683
23693
|
return;
|
|
23684
23694
|
const requestTotalMs = parseHeaderNumber(response.headers.get(REQUEST_TOTAL_MS_HEADER));
|
|
23685
23695
|
const requestDbQueryCount = parseHeaderNumber(response.headers.get(REQUEST_DB_QUERY_COUNT_HEADER));
|
|
23686
|
-
|
|
23687
|
-
const requestPeakRssBytes = parseHeaderNumber(response.headers.get(REQUEST_PEAK_RSS_HEADER));
|
|
23688
|
-
const requestPeakExternalBytes = parseHeaderNumber(response.headers.get(REQUEST_PEAK_EXTERNAL_HEADER));
|
|
23689
|
-
const requestRetainedCaptureMs = parseHeaderNumber(response.headers.get(REQUEST_RETAINED_CAPTURE_MS_HEADER));
|
|
23690
|
-
const requestRetainedHeapUsedBytes = parseHeaderNumber(response.headers.get(REQUEST_RETAINED_HEAP_USED_HEADER));
|
|
23691
|
-
const requestRetainedRssBytes = parseHeaderNumber(response.headers.get(REQUEST_RETAINED_RSS_HEADER));
|
|
23692
|
-
const requestRetainedExternalBytes = parseHeaderNumber(response.headers.get(REQUEST_RETAINED_EXTERNAL_HEADER));
|
|
23693
|
-
if (requestTotalMs === null && requestDbQueryCount === null && requestPeakHeapUsedBytes === null && requestPeakRssBytes === null && requestPeakExternalBytes === null && requestRetainedCaptureMs === null && requestRetainedHeapUsedBytes === null && requestRetainedRssBytes === null && requestRetainedExternalBytes === null) {
|
|
23696
|
+
if (requestTotalMs === null && requestDbQueryCount === null) {
|
|
23694
23697
|
return;
|
|
23695
23698
|
}
|
|
23696
23699
|
benchmarkTelemetry.requestCount += 1;
|
|
@@ -23701,27 +23704,6 @@ function recordBenchmarkResponse(response, benchmarkId) {
|
|
|
23701
23704
|
if (requestDbQueryCount !== null) {
|
|
23702
23705
|
benchmarkTelemetry.requestDbQueryCountSum += requestDbQueryCount;
|
|
23703
23706
|
}
|
|
23704
|
-
if (requestPeakHeapUsedBytes !== null) {
|
|
23705
|
-
benchmarkTelemetry.requestPeakHeapUsedBytesMax = Math.max(benchmarkTelemetry.requestPeakHeapUsedBytesMax, requestPeakHeapUsedBytes);
|
|
23706
|
-
}
|
|
23707
|
-
if (requestPeakRssBytes !== null) {
|
|
23708
|
-
benchmarkTelemetry.requestPeakRssBytesMax = Math.max(benchmarkTelemetry.requestPeakRssBytesMax, requestPeakRssBytes);
|
|
23709
|
-
}
|
|
23710
|
-
if (requestPeakExternalBytes !== null) {
|
|
23711
|
-
benchmarkTelemetry.requestPeakExternalBytesMax = Math.max(benchmarkTelemetry.requestPeakExternalBytesMax, requestPeakExternalBytes);
|
|
23712
|
-
}
|
|
23713
|
-
if (requestRetainedCaptureMs !== null) {
|
|
23714
|
-
benchmarkTelemetry.requestRetainedCaptureMsMax = Math.max(benchmarkTelemetry.requestRetainedCaptureMsMax, requestRetainedCaptureMs);
|
|
23715
|
-
}
|
|
23716
|
-
if (requestRetainedHeapUsedBytes !== null) {
|
|
23717
|
-
benchmarkTelemetry.requestRetainedHeapUsedBytesMax = Math.max(benchmarkTelemetry.requestRetainedHeapUsedBytesMax, requestRetainedHeapUsedBytes);
|
|
23718
|
-
}
|
|
23719
|
-
if (requestRetainedRssBytes !== null) {
|
|
23720
|
-
benchmarkTelemetry.requestRetainedRssBytesMax = Math.max(benchmarkTelemetry.requestRetainedRssBytesMax, requestRetainedRssBytes);
|
|
23721
|
-
}
|
|
23722
|
-
if (requestRetainedExternalBytes !== null) {
|
|
23723
|
-
benchmarkTelemetry.requestRetainedExternalBytesMax = Math.max(benchmarkTelemetry.requestRetainedExternalBytesMax, requestRetainedExternalBytes);
|
|
23724
|
-
}
|
|
23725
23707
|
}
|
|
23726
23708
|
function createBenchmarkAwareFetch(benchmarkId) {
|
|
23727
23709
|
if (!benchmarkId)
|
|
@@ -27866,6 +27848,7 @@ import { createInterface } from "node:readline";
|
|
|
27866
27848
|
class StreamProgressReporter {
|
|
27867
27849
|
ctx;
|
|
27868
27850
|
active;
|
|
27851
|
+
jsonl;
|
|
27869
27852
|
requested;
|
|
27870
27853
|
sourceKind;
|
|
27871
27854
|
totalOps;
|
|
@@ -27874,10 +27857,12 @@ class StreamProgressReporter {
|
|
|
27874
27857
|
startedAtMs = 0;
|
|
27875
27858
|
opsAppended = 0;
|
|
27876
27859
|
chunksAppended = 0;
|
|
27860
|
+
summaryEmitted = false;
|
|
27877
27861
|
constructor(ctx, opts) {
|
|
27878
27862
|
this.ctx = ctx;
|
|
27879
27863
|
this.requested = opts.requested;
|
|
27880
27864
|
this.active = opts.requested && ctx.stderrIsTTY === true;
|
|
27865
|
+
this.jsonl = opts.requested && ctx.stderrIsTTY !== true;
|
|
27881
27866
|
this.sourceKind = opts.sourceKind;
|
|
27882
27867
|
this.totalOps = opts.totalOps;
|
|
27883
27868
|
}
|
|
@@ -27885,7 +27870,7 @@ class StreamProgressReporter {
|
|
|
27885
27870
|
return this.requested;
|
|
27886
27871
|
}
|
|
27887
27872
|
get enabled() {
|
|
27888
|
-
return this.
|
|
27873
|
+
return this.requested;
|
|
27889
27874
|
}
|
|
27890
27875
|
start(startedAtMs) {
|
|
27891
27876
|
this.startedAtMs = startedAtMs;
|
|
@@ -27896,11 +27881,32 @@ class StreamProgressReporter {
|
|
|
27896
27881
|
onChunkAppended(args) {
|
|
27897
27882
|
this.opsAppended = args.opsAppended;
|
|
27898
27883
|
this.chunksAppended = args.chunksAppended;
|
|
27884
|
+
if (this.jsonl) {
|
|
27885
|
+
this.writeJsonl({
|
|
27886
|
+
type: "stream.progress",
|
|
27887
|
+
chunksAppended: this.chunksAppended,
|
|
27888
|
+
elapsedMs: Math.round(args.nowMs - this.startedAtMs),
|
|
27889
|
+
opsAppended: this.opsAppended,
|
|
27890
|
+
sourceKind: this.sourceKind,
|
|
27891
|
+
...this.totalOps === undefined ? {} : { totalOps: this.totalOps }
|
|
27892
|
+
});
|
|
27893
|
+
return;
|
|
27894
|
+
}
|
|
27899
27895
|
if (!this.active)
|
|
27900
27896
|
return;
|
|
27901
27897
|
this.renderLine(this.renderReading(args.nowMs));
|
|
27902
27898
|
}
|
|
27903
27899
|
onComplete(args) {
|
|
27900
|
+
if (this.jsonl) {
|
|
27901
|
+
this.emitSummary({
|
|
27902
|
+
appendMs: args.appendMs,
|
|
27903
|
+
chunkCount: args.chunkCount,
|
|
27904
|
+
nowMs: args.nowMs,
|
|
27905
|
+
opCount: args.opCount,
|
|
27906
|
+
status: "success"
|
|
27907
|
+
});
|
|
27908
|
+
return;
|
|
27909
|
+
}
|
|
27904
27910
|
if (!this.active)
|
|
27905
27911
|
return;
|
|
27906
27912
|
this.clearLine();
|
|
@@ -27909,10 +27915,37 @@ class StreamProgressReporter {
|
|
|
27909
27915
|
this.ctx.err(`progress: ${args.opCount} ops, ${args.chunkCount} chunks, ${elapsedSeconds}s, ${appendThroughput} ops/s append`);
|
|
27910
27916
|
}
|
|
27911
27917
|
onError() {
|
|
27918
|
+
if (this.jsonl) {
|
|
27919
|
+
this.emitSummary({
|
|
27920
|
+
chunkCount: this.chunksAppended,
|
|
27921
|
+
nowMs: performance.now(),
|
|
27922
|
+
opCount: this.opsAppended,
|
|
27923
|
+
status: "error"
|
|
27924
|
+
});
|
|
27925
|
+
return;
|
|
27926
|
+
}
|
|
27912
27927
|
if (!this.active)
|
|
27913
27928
|
return;
|
|
27914
27929
|
this.clearLine();
|
|
27915
27930
|
}
|
|
27931
|
+
emitSummary(args) {
|
|
27932
|
+
if (this.summaryEmitted)
|
|
27933
|
+
return;
|
|
27934
|
+
this.summaryEmitted = true;
|
|
27935
|
+
const elapsedMs = Math.round(args.nowMs - this.startedAtMs);
|
|
27936
|
+
const appendThroughput = args.appendMs === undefined ? undefined : Math.round(args.opCount / Math.max(args.appendMs / 1000, 0.001));
|
|
27937
|
+
this.writeJsonl({
|
|
27938
|
+
type: "stream.summary",
|
|
27939
|
+
chunkCount: args.chunkCount,
|
|
27940
|
+
elapsedMs,
|
|
27941
|
+
opCount: args.opCount,
|
|
27942
|
+
sourceKind: this.sourceKind,
|
|
27943
|
+
status: args.status,
|
|
27944
|
+
...appendThroughput === undefined ? {} : { appendThroughput },
|
|
27945
|
+
...args.appendMs === undefined ? {} : { appendMs: Math.round(args.appendMs) },
|
|
27946
|
+
...this.totalOps === undefined ? {} : { totalOps: this.totalOps }
|
|
27947
|
+
});
|
|
27948
|
+
}
|
|
27916
27949
|
renderReading(nowMs) {
|
|
27917
27950
|
const elapsed = formatElapsed(nowMs - this.startedAtMs);
|
|
27918
27951
|
if (this.sourceKind === "file" && this.totalOps != null) {
|
|
@@ -27940,6 +27973,9 @@ class StreamProgressReporter {
|
|
|
27940
27973
|
writeRaw(chunk) {
|
|
27941
27974
|
(this.ctx.stderrWrite ?? ((value) => process.stderr.write(value)))(chunk);
|
|
27942
27975
|
}
|
|
27976
|
+
writeJsonl(payload) {
|
|
27977
|
+
this.ctx.err(JSON.stringify(payload));
|
|
27978
|
+
}
|
|
27943
27979
|
}
|
|
27944
27980
|
async function countNonEmptyJsonlLines(path2) {
|
|
27945
27981
|
const lines = createInterface({
|
|
@@ -28022,8 +28058,7 @@ function toCommitSubmitResult(args) {
|
|
|
28022
28058
|
const status = streamAppendResultStatus(operation);
|
|
28023
28059
|
if (status === "error") {
|
|
28024
28060
|
statusCounts.error++;
|
|
28025
|
-
const
|
|
28026
|
-
const submittedOperation = submittedIndex >= 0 ? args.submittedOperations?.[submittedIndex] : undefined;
|
|
28061
|
+
const submittedOperation = args.submittedOperations?.[opIndex];
|
|
28027
28062
|
return {
|
|
28028
28063
|
opIndex,
|
|
28029
28064
|
name: operation.name ?? "",
|
|
@@ -28056,25 +28091,6 @@ function toCommitSubmitResult(args) {
|
|
|
28056
28091
|
operations
|
|
28057
28092
|
};
|
|
28058
28093
|
}
|
|
28059
|
-
function createStreamId2() {
|
|
28060
|
-
return globalThis.crypto.randomUUID();
|
|
28061
|
-
}
|
|
28062
|
-
function parseAllocatedTokensFlag(raw) {
|
|
28063
|
-
if (raw === undefined)
|
|
28064
|
-
return;
|
|
28065
|
-
const parsed = safeParseJson(raw, "--allocated-tokens");
|
|
28066
|
-
if (!Array.isArray(parsed) || !parsed.every((entry) => {
|
|
28067
|
-
if (!isPlainObject(entry))
|
|
28068
|
-
return false;
|
|
28069
|
-
const tokenNumber = entry.tokenNumber;
|
|
28070
|
-
return Number.isInteger(tokenNumber) && Number(tokenNumber) > 0;
|
|
28071
|
-
})) {
|
|
28072
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", '--allocated-tokens must be a JSON array like [{"tokenNumber":1}].');
|
|
28073
|
-
}
|
|
28074
|
-
return parsed.map((entry) => ({
|
|
28075
|
-
tokenNumber: entry.tokenNumber
|
|
28076
|
-
}));
|
|
28077
|
-
}
|
|
28078
28094
|
function backendErrorCode(error) {
|
|
28079
28095
|
if (typeof error !== "object" || error === null) {
|
|
28080
28096
|
return;
|
|
@@ -28128,14 +28144,13 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28128
28144
|
});
|
|
28129
28145
|
resetBenchmarkTelemetry();
|
|
28130
28146
|
const t0 = performance.now();
|
|
28131
|
-
const streamId = args.streamId
|
|
28132
|
-
const operationOffset = Math.max(0, Math.trunc(args.operationOffset ?? 0));
|
|
28147
|
+
const streamId = args.streamId;
|
|
28133
28148
|
const tAppendStart = performance.now();
|
|
28134
28149
|
progress.start(t0);
|
|
28135
28150
|
try {
|
|
28136
28151
|
const operations = [];
|
|
28137
28152
|
const submittedOperations = [];
|
|
28138
|
-
let
|
|
28153
|
+
let allocatedTokenRanges = [];
|
|
28139
28154
|
let createdByEmail;
|
|
28140
28155
|
let opCount = 0;
|
|
28141
28156
|
let parsedOpCount = 0;
|
|
@@ -28149,7 +28164,7 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28149
28164
|
let appendResult;
|
|
28150
28165
|
try {
|
|
28151
28166
|
appendResult = await ctx.client.stream.append({
|
|
28152
|
-
|
|
28167
|
+
allocatedTokenRanges,
|
|
28153
28168
|
orgName: args.org,
|
|
28154
28169
|
repoName: args.repo,
|
|
28155
28170
|
streamId,
|
|
@@ -28158,7 +28173,7 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28158
28173
|
operations: operationsChunk
|
|
28159
28174
|
});
|
|
28160
28175
|
} catch (cause) {
|
|
28161
|
-
const completed =
|
|
28176
|
+
const completed = opCount;
|
|
28162
28177
|
if (opCount > 0 || firstJsonlAppendErrorMayHaveCommitted(cause)) {
|
|
28163
28178
|
const backendCode = toWarmHubError(cause).backendCode;
|
|
28164
28179
|
const suffix = backendCode ? ` (backend: ${backendCode})` : "";
|
|
@@ -28166,7 +28181,7 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28166
28181
|
}
|
|
28167
28182
|
throw cause;
|
|
28168
28183
|
}
|
|
28169
|
-
|
|
28184
|
+
allocatedTokenRanges = appendResult.allocatedTokenRanges;
|
|
28170
28185
|
if (appendResult.createdByEmail !== undefined) {
|
|
28171
28186
|
createdByEmail = appendResult.createdByEmail;
|
|
28172
28187
|
}
|
|
@@ -28198,7 +28213,7 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28198
28213
|
refInsertMs: subphases?.refInsertMs,
|
|
28199
28214
|
refSourceCount: subphases?.refSourceCount
|
|
28200
28215
|
});
|
|
28201
|
-
operations.push(...offsetChunkResultIndexes2(appendResult.results,
|
|
28216
|
+
operations.push(...offsetChunkResultIndexes2(appendResult.results, opCount));
|
|
28202
28217
|
submittedOperations.push(...operationsChunk);
|
|
28203
28218
|
opCount += operationsChunk.length;
|
|
28204
28219
|
chunkCount++;
|
|
@@ -28226,13 +28241,8 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28226
28241
|
} catch (cause) {
|
|
28227
28242
|
if (cause instanceof CliError) {
|
|
28228
28243
|
if (opCount > 0) {
|
|
28229
|
-
const completed = operationOffset + opCount;
|
|
28230
|
-
const baseHint = cause.hint && cause.hint.length > 0 ? `${cause.hint} ` : "";
|
|
28231
|
-
throw new CliError(4 /* Backend */, "BACKEND", `${cause.message} (${completed} earlier operation(s) already acknowledged by the server before this NUL-byte rejection).`, undefined, `${baseHint}The earlier chunks have landed; inspect repository state before submitting any remaining JSONL operations.`);
|
|
28232
|
-
}
|
|
28233
|
-
if (operationOffset > 0) {
|
|
28234
28244
|
const baseHint = cause.hint && cause.hint.length > 0 ? `${cause.hint} ` : "";
|
|
28235
|
-
throw new CliError(
|
|
28245
|
+
throw new CliError(4 /* Backend */, "BACKEND", `${cause.message} (${opCount} earlier operation(s) already acknowledged by the server before this NUL-byte rejection).`, undefined, `${baseHint}The earlier chunks have landed; inspect repository state before submitting any remaining JSONL operations.`);
|
|
28236
28246
|
}
|
|
28237
28247
|
}
|
|
28238
28248
|
throw cause;
|
|
@@ -28342,13 +28352,6 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28342
28352
|
requestTotalMsSum: benchmarkTelemetry2.requestTotalMsSum,
|
|
28343
28353
|
requestTotalMsMax: benchmarkTelemetry2.requestTotalMsMax,
|
|
28344
28354
|
requestDbQueryCountSum: benchmarkTelemetry2.requestDbQueryCountSum,
|
|
28345
|
-
requestRetainedCaptureMsMax: benchmarkTelemetry2.requestRetainedCaptureMsMax,
|
|
28346
|
-
requestRetainedHeapUsedBytesMax: benchmarkTelemetry2.requestRetainedHeapUsedBytesMax,
|
|
28347
|
-
requestRetainedRssBytesMax: benchmarkTelemetry2.requestRetainedRssBytesMax,
|
|
28348
|
-
requestRetainedExternalBytesMax: benchmarkTelemetry2.requestRetainedExternalBytesMax,
|
|
28349
|
-
requestPeakHeapUsedBytesMax: benchmarkTelemetry2.requestPeakHeapUsedBytesMax,
|
|
28350
|
-
requestPeakRssBytesMax: benchmarkTelemetry2.requestPeakRssBytesMax,
|
|
28351
|
-
requestPeakExternalBytesMax: benchmarkTelemetry2.requestPeakExternalBytesMax,
|
|
28352
28355
|
appendServerSamples,
|
|
28353
28356
|
appendServerTotals
|
|
28354
28357
|
};
|
|
@@ -28364,8 +28367,7 @@ async function applyJsonlCommit(ctx, args) {
|
|
|
28364
28367
|
message: args.message,
|
|
28365
28368
|
operationCount: operations.length,
|
|
28366
28369
|
operations,
|
|
28367
|
-
submittedOperations
|
|
28368
|
-
submittedOperationOffset: operationOffset
|
|
28370
|
+
submittedOperations
|
|
28369
28371
|
});
|
|
28370
28372
|
} catch (error) {
|
|
28371
28373
|
progress.onError();
|
|
@@ -28376,7 +28378,7 @@ async function applyJsonlFileCommit(ctx, args) {
|
|
|
28376
28378
|
try {
|
|
28377
28379
|
const countedOps = await countNonEmptyJsonlLines(args.opsFile);
|
|
28378
28380
|
assertWithinStreamOpLimit(countedOps);
|
|
28379
|
-
const totalOps = args.progressRequested
|
|
28381
|
+
const totalOps = args.progressRequested ? countedOps : undefined;
|
|
28380
28382
|
return await applyJsonlCommit(ctx, {
|
|
28381
28383
|
...args,
|
|
28382
28384
|
input: createReadStream2(args.opsFile, { encoding: "utf-8" }),
|
|
@@ -28395,14 +28397,14 @@ async function applyJsonlFileCommit(ctx, args) {
|
|
|
28395
28397
|
async function applyJsonlStdinCommit(ctx, args) {
|
|
28396
28398
|
const input = ctx.stdin ?? process.stdin;
|
|
28397
28399
|
if (isTTY(input)) {
|
|
28398
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", "No JSONL operations provided on stdin.", undefined, 'Pipe JSONL operations via stdin: producer | wh commit submit --stream -m "message"');
|
|
28400
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "No JSONL operations provided on stdin.", undefined, 'Pipe JSONL operations via stdin: producer | wh commit submit --stream --stream-id bulk-2026-06-04 --skip-existing -m "message"');
|
|
28399
28401
|
}
|
|
28400
28402
|
return applyJsonlCommit(ctx, {
|
|
28401
28403
|
...args,
|
|
28402
28404
|
input,
|
|
28403
28405
|
lineLabel: "--stream",
|
|
28404
28406
|
emptyInputMessage: "No JSONL operations provided on stdin.",
|
|
28405
|
-
emptyInputHint: 'Pipe JSONL operations via stdin: producer | wh commit submit --stream -m "message"',
|
|
28407
|
+
emptyInputHint: 'Pipe JSONL operations via stdin: producer | wh commit submit --stream --stream-id bulk-2026-06-04 --skip-existing -m "message"',
|
|
28406
28408
|
progressSourceKind: "stream"
|
|
28407
28409
|
});
|
|
28408
28410
|
}
|
|
@@ -28531,7 +28533,7 @@ var createFlags3 = {
|
|
|
28531
28533
|
description: "Read newline-delimited operations from stdin"
|
|
28532
28534
|
}),
|
|
28533
28535
|
progress: flag.boolean({
|
|
28534
|
-
description: "Show
|
|
28536
|
+
description: "Show stream-append progress on stderr (TTY status or JSONL events)."
|
|
28535
28537
|
}),
|
|
28536
28538
|
"skip-existing": flag.boolean({
|
|
28537
28539
|
description: "Skip add operations when the target shape, thing, assertion, or collection already exists."
|
|
@@ -28548,12 +28550,6 @@ var createFlags3 = {
|
|
|
28548
28550
|
"stream-id": flag.string({
|
|
28549
28551
|
description: "Use a caller-managed stream id for JSONL token continuity."
|
|
28550
28552
|
}),
|
|
28551
|
-
"allocated-tokens": flag.string({
|
|
28552
|
-
description: `Continue JSONL $N/#N token state as JSON, e.g. '[{"tokenNumber":1}]'.`
|
|
28553
|
-
}),
|
|
28554
|
-
"operation-offset": flag.number({
|
|
28555
|
-
description: "Zero-based original operation index for the first JSONL operation in this input."
|
|
28556
|
-
}),
|
|
28557
28553
|
message: flag.string({ short: "m", description: "Commit message" }),
|
|
28558
28554
|
committer: flag.string({
|
|
28559
28555
|
description: "Committer thing wref (e.g. Agent/bot-1)"
|
|
@@ -28612,9 +28608,7 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
28612
28608
|
const chunkSize = flags["chunk-size"];
|
|
28613
28609
|
const allowNulBytes = flags["allow-nul-bytes"] === true;
|
|
28614
28610
|
const timingOut = flags["timing-out"];
|
|
28615
|
-
const
|
|
28616
|
-
const resumeAllocatedTokens = parseAllocatedTokensFlag(flags["allocated-tokens"]);
|
|
28617
|
-
const resumeOperationOffset = flags["operation-offset"] === undefined ? undefined : Math.max(0, Math.trunc(flags["operation-offset"]));
|
|
28611
|
+
const streamId = flags["stream-id"];
|
|
28618
28612
|
const c = ctx.colors;
|
|
28619
28613
|
const addNames = flags.add ?? [];
|
|
28620
28614
|
const reviseName = flags.revise;
|
|
@@ -28658,11 +28652,14 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
28658
28652
|
if (progressRequested && !streamInput && !jsonlFile) {
|
|
28659
28653
|
throw new CliError(2 /* UserInput */, "USER_INPUT", "--progress requires --stream or a .jsonl --file.");
|
|
28660
28654
|
}
|
|
28661
|
-
if (
|
|
28662
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", "--stream-id
|
|
28655
|
+
if (streamId !== undefined && !streamInput && !jsonlFile) {
|
|
28656
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "--stream-id requires --stream or a .jsonl --file.");
|
|
28657
|
+
}
|
|
28658
|
+
if ((streamInput || jsonlFile) && streamId === undefined) {
|
|
28659
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "JSONL streaming requires --stream-id.", undefined, "Choose a stable id up front so add streams can rebuild token state on full rerun: --stream-id bulk-2026-06-04.");
|
|
28663
28660
|
}
|
|
28664
|
-
if (
|
|
28665
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", "--
|
|
28661
|
+
if ((streamInput || jsonlFile) && !skipExisting) {
|
|
28662
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "JSONL streaming requires --skip-existing.", undefined, "Full-input rerun recovery depends on idempotent add operations; pass --skip-existing with --stream-id.");
|
|
28666
28663
|
}
|
|
28667
28664
|
const shorthandModeCount = (addNames.length > 0 ? 1 : 0) + (reviseName !== undefined ? 1 : 0) + (retractNames.length > 0 ? 1 : 0) + (collectionType !== undefined ? 1 : 0);
|
|
28668
28665
|
if (!streamInput && !opsJson && !opsFile && shorthandModeCount > 1) {
|
|
@@ -28773,9 +28770,7 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
28773
28770
|
chunkSize,
|
|
28774
28771
|
progressRequested,
|
|
28775
28772
|
skipExisting,
|
|
28776
|
-
streamId
|
|
28777
|
-
allocatedTokens: resumeAllocatedTokens,
|
|
28778
|
-
operationOffset: resumeOperationOffset,
|
|
28773
|
+
streamId,
|
|
28779
28774
|
allowNulBytes
|
|
28780
28775
|
}) : jsonlFile ? await applyJsonlFileCommit(ctx, {
|
|
28781
28776
|
org,
|
|
@@ -28787,9 +28782,7 @@ var handleSubmit = async (ctx, { flags, args }) => {
|
|
|
28787
28782
|
progressRequested,
|
|
28788
28783
|
timingOut,
|
|
28789
28784
|
skipExisting,
|
|
28790
|
-
streamId
|
|
28791
|
-
allocatedTokens: resumeAllocatedTokens,
|
|
28792
|
-
operationOffset: resumeOperationOffset,
|
|
28785
|
+
streamId,
|
|
28793
28786
|
allowNulBytes
|
|
28794
28787
|
}) : await ctx.client.commit.apply(org, repo, message, operations, {
|
|
28795
28788
|
committer,
|
|
@@ -28981,8 +28974,8 @@ var COMMIT_DOMAIN = defineDomain({
|
|
|
28981
28974
|
`wh commit submit --add alice --data '{"score":1}' --add bob --data '{"score":2}' --shape Player -m "seed players"`,
|
|
28982
28975
|
'wh commit submit -f operations.json -m "Batch update"',
|
|
28983
28976
|
`wh commit submit --ops '[{"operation":"add","kind":"thing","name":"Session/run-001","data":{}},{"operation":"add","kind":"assertion","name":"HypothesisCandidate/run-001-claim","about":"Session/run-001","data":{}}]' -m "Create session + assertion"`,
|
|
28984
|
-
`printf '%s\\n' '{"operation":"add","kind":"thing","name":"Player/alice","data":{"score":1}}' | wh commit submit --stream --repo acme/world -m "stdin stream"`,
|
|
28985
|
-
'wh commit submit --file dataset.jsonl --progress -m "bulk stream"',
|
|
28977
|
+
`printf '%s\\n' '{"operation":"add","kind":"thing","name":"Player/alice","data":{"score":1}}' | wh commit submit --stream --stream-id bulk-2026-06-04 --skip-existing --repo acme/world -m "stdin stream"`,
|
|
28978
|
+
'wh commit submit --file dataset.jsonl --stream-id bulk-2026-06-04 --skip-existing --progress -m "bulk stream"',
|
|
28986
28979
|
"wh shape template Session HypothesisCandidate -o ops.json",
|
|
28987
28980
|
"wh commit submit --type pair --members Location/a,Location/b",
|
|
28988
28981
|
'wh commit submit --type set --members Location/a,Location/b,Location/c -m "Create location set"'
|
|
@@ -30364,7 +30357,7 @@ function crossValidate(pkg) {
|
|
|
30364
30357
|
findings.push({
|
|
30365
30358
|
level: "warning",
|
|
30366
30359
|
code: "MISSING_SCHEMA",
|
|
30367
|
-
message: 'manifest.json is missing "$schema". Add "$schema": "https://warmhub.
|
|
30360
|
+
message: 'manifest.json is missing "$schema". Add "$schema": "https://docs.warmhub.ai/schema/component-manifest.v1.json" for IDE autocomplete and validation.'
|
|
30368
30361
|
});
|
|
30369
30362
|
}
|
|
30370
30363
|
const hasErrors = findings.some((f) => f.level === "error");
|
|
@@ -30582,18 +30575,36 @@ async function reconcileComponent(client, org, repo, pkg, source, existingInstal
|
|
|
30582
30575
|
continue;
|
|
30583
30576
|
}
|
|
30584
30577
|
try {
|
|
30585
|
-
|
|
30586
|
-
|
|
30587
|
-
|
|
30588
|
-
|
|
30589
|
-
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30596
|
-
|
|
30578
|
+
if (compiled.kind === "cron") {
|
|
30579
|
+
const cronConfig = compiled.cronConfig;
|
|
30580
|
+
if (!cronConfig) {
|
|
30581
|
+
throw new Error(`Compiled cron subscription "${compiled.name}" is missing cronConfig`);
|
|
30582
|
+
}
|
|
30583
|
+
await client.subscription.create({
|
|
30584
|
+
orgName: org,
|
|
30585
|
+
repoName: repo,
|
|
30586
|
+
name: compiled.name,
|
|
30587
|
+
kind: compiled.kind,
|
|
30588
|
+
shapeName: compiled.shapeName,
|
|
30589
|
+
filterJson: compiled.filterJson,
|
|
30590
|
+
cronConfig,
|
|
30591
|
+
webhookUrl: compiled.webhookUrl,
|
|
30592
|
+
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
30593
|
+
componentId
|
|
30594
|
+
});
|
|
30595
|
+
} else {
|
|
30596
|
+
await client.subscription.create({
|
|
30597
|
+
orgName: org,
|
|
30598
|
+
repoName: repo,
|
|
30599
|
+
name: compiled.name,
|
|
30600
|
+
kind: compiled.kind,
|
|
30601
|
+
shapeName: compiled.shapeName,
|
|
30602
|
+
filterJson: compiled.filterJson,
|
|
30603
|
+
webhookUrl: compiled.webhookUrl,
|
|
30604
|
+
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
30605
|
+
componentId
|
|
30606
|
+
});
|
|
30607
|
+
}
|
|
30597
30608
|
steps.push({ step: `add-sub-${sub.name}`, status: "ok" });
|
|
30598
30609
|
} catch (err) {
|
|
30599
30610
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -30949,18 +30960,36 @@ async function installComponent(client, org, repo, pkg, source) {
|
|
|
30949
30960
|
continue;
|
|
30950
30961
|
}
|
|
30951
30962
|
try {
|
|
30952
|
-
|
|
30953
|
-
|
|
30954
|
-
|
|
30955
|
-
|
|
30956
|
-
|
|
30957
|
-
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
30961
|
-
|
|
30962
|
-
|
|
30963
|
-
|
|
30963
|
+
if (compiled.kind === "cron") {
|
|
30964
|
+
const cronConfig = compiled.cronConfig;
|
|
30965
|
+
if (!cronConfig) {
|
|
30966
|
+
throw new Error(`Compiled cron subscription "${compiled.name}" is missing cronConfig`);
|
|
30967
|
+
}
|
|
30968
|
+
await client.subscription.create({
|
|
30969
|
+
orgName: org,
|
|
30970
|
+
repoName: repo,
|
|
30971
|
+
name: compiled.name,
|
|
30972
|
+
kind: compiled.kind,
|
|
30973
|
+
shapeName: compiled.shapeName,
|
|
30974
|
+
filterJson: compiled.filterJson,
|
|
30975
|
+
cronConfig,
|
|
30976
|
+
webhookUrl: compiled.webhookUrl,
|
|
30977
|
+
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
30978
|
+
componentId
|
|
30979
|
+
});
|
|
30980
|
+
} else {
|
|
30981
|
+
await client.subscription.create({
|
|
30982
|
+
orgName: org,
|
|
30983
|
+
repoName: repo,
|
|
30984
|
+
name: compiled.name,
|
|
30985
|
+
kind: compiled.kind,
|
|
30986
|
+
shapeName: compiled.shapeName,
|
|
30987
|
+
filterJson: compiled.filterJson,
|
|
30988
|
+
webhookUrl: compiled.webhookUrl,
|
|
30989
|
+
fallbackWebhookUrl: compiled.fallbackWebhookUrl,
|
|
30990
|
+
componentId
|
|
30991
|
+
});
|
|
30992
|
+
}
|
|
30964
30993
|
steps.push({ step: `create-sub-${sub.name}`, status: "ok" });
|
|
30965
30994
|
} catch (err) {
|
|
30966
30995
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -31923,7 +31952,7 @@ function renderValidationResult(ctx, result) {
|
|
|
31923
31952
|
}
|
|
31924
31953
|
if (result.valid && result.errors.length === 0) {
|
|
31925
31954
|
ctx.out(`${c.green}Valid component package${c.reset}`);
|
|
31926
|
-
ctx.out(`${c.dim}Schema: https://warmhub.
|
|
31955
|
+
ctx.out(`${c.dim}Schema: https://docs.warmhub.ai/schema/component-manifest.v1.json${c.reset}`);
|
|
31927
31956
|
}
|
|
31928
31957
|
}
|
|
31929
31958
|
var handleDoctor = async (ctx, { args }) => {
|
|
@@ -33965,7 +33994,7 @@ cat wrefs.txt | wh thing view --format jsonl # one JSON line per *deduped
|
|
|
33965
33994
|
- \`wh thing about <wref> [--shape] [--match] [--depth] [--resolve-collections] [--limit] [--include-retracted]\` — Show assertions about the target identity; \`--resolve-collections\` expands collection members for bare/@HEAD/@ALL inputs, not pinned @vN
|
|
33966
33995
|
|
|
33967
33996
|
### commit — Write operations
|
|
33968
|
-
- \`wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]
|
|
33997
|
+
- \`wh commit submit [--ops|--file|--add|--revise|--retract] [--kind] [--data] [--reason] [--expected-version] [--chunk-size] [--skip-existing] [--progress] [--stream-id]\` — Submit operations (bare \`wh commit\` is equivalent). Use \`--file ops.jsonl --stream-id <id> --chunk-size 5000 --skip-existing\` for bulk ingest.
|
|
33969
33998
|
- \`wh shape template <shape> [shape2 ...] [--kind] [--operation add|revise|retract] [-o file]\` — Generate sample ops
|
|
33970
33999
|
|
|
33971
34000
|
### assertion — Assertion operations
|
|
@@ -34079,11 +34108,12 @@ wh commit submit --file ops.jsonl --stream-id "$ID" --chunk-size 5000 \\
|
|
|
34079
34108
|
--skip-existing --progress -m "bulk ingest" --repo org/repo
|
|
34080
34109
|
# --chunk-size: ops per append chunk (default 1000, max 10000); chunk≈1 is ~60× slower
|
|
34081
34110
|
# --skip-existing: skips already-written add ops (drops per-row read-before-write)
|
|
34082
|
-
#
|
|
34083
|
-
# Fixed-name
|
|
34084
|
-
#
|
|
34085
|
-
#
|
|
34086
|
-
#
|
|
34111
|
+
# Add-stream restart: rerun the WHOLE file with the SAME --stream-id.
|
|
34112
|
+
# Fixed-name adds are idempotent via --skip-existing; tokenized ($N/#N) names
|
|
34113
|
+
# derive from streamId, so rerun rebuilds token state. Omitting --stream-id is
|
|
34114
|
+
# rejected because reruns must reuse the same token namespace. Mid-stream resume
|
|
34115
|
+
# is not a CLI mode. Mixed revise/retract JSONL streams are not full-rerun safe
|
|
34116
|
+
# after an ambiguous append; inspect repo state and reconcile explicitly.
|
|
34087
34117
|
\`\`\`
|
|
34088
34118
|
|
|
34089
34119
|
**Create collections:**
|
|
@@ -34205,6 +34235,73 @@ var PRIME_DOMAIN = defineDomain({
|
|
|
34205
34235
|
handler: handlePrime
|
|
34206
34236
|
});
|
|
34207
34237
|
|
|
34238
|
+
// ../../packages/warmhub-cli/src/domains/content-prompt.ts
|
|
34239
|
+
var PROMPT_BUDGET = {
|
|
34240
|
+
maxChars: 14000,
|
|
34241
|
+
maxLines: 260
|
|
34242
|
+
};
|
|
34243
|
+
var TARGET_FILE = {
|
|
34244
|
+
readme: "README.md",
|
|
34245
|
+
agents: "AGENTS.md"
|
|
34246
|
+
};
|
|
34247
|
+
var GUIDANCE = {
|
|
34248
|
+
readme: "Write a 100–200 word Markdown README. Start with a `#` heading using the " + "repo name. Cover the purpose, the key shapes, and how to get started.",
|
|
34249
|
+
agents: "Write 100–250 words of Markdown AGENTS.md guidance for an AI agent working " + "with this WarmHub repo. Cover how to navigate the repo, the most important " + "shapes, common workflows, and any gotchas."
|
|
34250
|
+
};
|
|
34251
|
+
function buildContextLines(ctx) {
|
|
34252
|
+
const sampled = ctx.sampleThingNames.slice(0, 20);
|
|
34253
|
+
const moreThings = ctx.sampleThingNames.length - sampled.length;
|
|
34254
|
+
const byShapeEntries = Object.entries(ctx.byShape).filter(([, count]) => count > 0);
|
|
34255
|
+
return [
|
|
34256
|
+
`Repository: ${ctx.org}/${ctx.repo}`,
|
|
34257
|
+
ctx.description ? `Description: ${ctx.description}` : null,
|
|
34258
|
+
`Total items: ${ctx.byKind.thing} things, ${ctx.byKind.assertion} assertions, ${ctx.byKind.shape} shapes`,
|
|
34259
|
+
ctx.shapeNames.length > 0 ? `Shapes (data schemas): ${ctx.shapeNames.join(", ")}` : null,
|
|
34260
|
+
sampled.length > 0 ? `Sample things: ${sampled.join(", ")}${moreThings > 0 ? ` ... and ${moreThings} more` : ""}` : null,
|
|
34261
|
+
byShapeEntries.length > 0 ? `Things by shape: ${byShapeEntries.map(([name, count]) => `${name} (${count})`).join(", ")}` : null
|
|
34262
|
+
].filter((line) => line !== null);
|
|
34263
|
+
}
|
|
34264
|
+
function applyBudget(text, reservedChars, reservedLines) {
|
|
34265
|
+
const maxChars = Math.max(0, PROMPT_BUDGET.maxChars - reservedChars);
|
|
34266
|
+
const maxLines = Math.max(0, PROMPT_BUDGET.maxLines - reservedLines);
|
|
34267
|
+
let lines = text.split(`
|
|
34268
|
+
`);
|
|
34269
|
+
let truncated = false;
|
|
34270
|
+
if (lines.length > maxLines) {
|
|
34271
|
+
lines = lines.slice(0, maxLines);
|
|
34272
|
+
truncated = true;
|
|
34273
|
+
}
|
|
34274
|
+
let out = lines.join(`
|
|
34275
|
+
`);
|
|
34276
|
+
if (out.length > maxChars) {
|
|
34277
|
+
out = out.slice(0, maxChars);
|
|
34278
|
+
truncated = true;
|
|
34279
|
+
}
|
|
34280
|
+
return truncated ? `${out}
|
|
34281
|
+
[context truncated to fit the prompt budget]` : out;
|
|
34282
|
+
}
|
|
34283
|
+
function buildContentPrompt(ctx) {
|
|
34284
|
+
const file = TARGET_FILE[ctx.kind];
|
|
34285
|
+
const saveCommand = `wh repo content set ${ctx.org}/${ctx.repo} --kind ${ctx.kind} --file ${file}`;
|
|
34286
|
+
const head = [GUIDANCE[ctx.kind], "", "Repository context:"].join(`
|
|
34287
|
+
`);
|
|
34288
|
+
const tail = [
|
|
34289
|
+
"",
|
|
34290
|
+
"Write only the content markdown, nothing else. Then save it with:",
|
|
34291
|
+
` ${saveCommand}`,
|
|
34292
|
+
`(or pipe it: cat ${file} | wh repo content set ${ctx.org}/${ctx.repo} --kind ${ctx.kind})`
|
|
34293
|
+
].join(`
|
|
34294
|
+
`);
|
|
34295
|
+
const reservedChars = head.length + tail.length + 2;
|
|
34296
|
+
const reservedLines = head.split(`
|
|
34297
|
+
`).length + tail.split(`
|
|
34298
|
+
`).length;
|
|
34299
|
+
const context = applyBudget(buildContextLines(ctx).join(`
|
|
34300
|
+
`), reservedChars, reservedLines);
|
|
34301
|
+
return { prompt: [head, context, tail].join(`
|
|
34302
|
+
`), saveCommand };
|
|
34303
|
+
}
|
|
34304
|
+
|
|
34208
34305
|
// ../../packages/warmhub-cli/src/domains/repo.ts
|
|
34209
34306
|
function usageError8(usage, example) {
|
|
34210
34307
|
throw new CliError(2 /* UserInput */, "USER_INPUT", usage, undefined, `Example: ${example}`);
|
|
@@ -34454,6 +34551,9 @@ var handleUpdate3 = async (ctx, { args, flags }) => {
|
|
|
34454
34551
|
ctx.out(`${c.green}Updated${c.reset} ${c.cyan}${orgName}/${repoName}${c.reset} description`);
|
|
34455
34552
|
});
|
|
34456
34553
|
};
|
|
34554
|
+
function nameStrings(items) {
|
|
34555
|
+
return items.map((item) => item.name).filter((name) => typeof name === "string");
|
|
34556
|
+
}
|
|
34457
34557
|
var describeFlags = {
|
|
34458
34558
|
"indexed-fields": flag.boolean({
|
|
34459
34559
|
description: "Show typed field index state (building, ready, failed) for each shape"
|
|
@@ -34472,7 +34572,7 @@ var handleDescribe = async (ctx, { args, flags }) => {
|
|
|
34472
34572
|
]);
|
|
34473
34573
|
const shapes = shapesPage.items;
|
|
34474
34574
|
const byShape = Object.fromEntries([
|
|
34475
|
-
...shapes
|
|
34575
|
+
...nameStrings(shapes).map((name) => [name, 0]),
|
|
34476
34576
|
...Object.entries(stats.byShape)
|
|
34477
34577
|
]);
|
|
34478
34578
|
function stripShapeThingId(bucket) {
|
|
@@ -34693,11 +34793,8 @@ var contentSetFlags = {
|
|
|
34693
34793
|
description: "Inline markdown content"
|
|
34694
34794
|
})
|
|
34695
34795
|
};
|
|
34696
|
-
var
|
|
34697
|
-
kind: kindFlagDef
|
|
34698
|
-
save: flag.boolean({
|
|
34699
|
-
description: "Commit the generated content after generation"
|
|
34700
|
-
})
|
|
34796
|
+
var promptFlags = {
|
|
34797
|
+
kind: kindFlagDef
|
|
34701
34798
|
};
|
|
34702
34799
|
function requireKind(kind) {
|
|
34703
34800
|
if (!kind) {
|
|
@@ -34710,7 +34807,7 @@ function requireKind(kind) {
|
|
|
34710
34807
|
}
|
|
34711
34808
|
var handleContentGet = async (ctx, { args, flags }) => {
|
|
34712
34809
|
const kind = requireKind(flags.kind);
|
|
34713
|
-
const { org, repo } = parseOrgRepo(args[0], ctx.config);
|
|
34810
|
+
const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
|
|
34714
34811
|
switch (kind) {
|
|
34715
34812
|
case "readme": {
|
|
34716
34813
|
const result = await ctx.client.repo.getReadme(org, repo);
|
|
@@ -34742,9 +34839,9 @@ var handleContentGet = async (ctx, { args, flags }) => {
|
|
|
34742
34839
|
var handleContentSet = async (ctx, { args, flags }) => {
|
|
34743
34840
|
const kind = requireKind(flags.kind);
|
|
34744
34841
|
if (READ_ONLY_KINDS.has(kind)) {
|
|
34745
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} is read-only; \`set\` is rejected.`, undefined, `Use \`wh repo content get
|
|
34842
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} is read-only; \`set\` is rejected.`, undefined, `Use \`wh repo content get [org/repo] --kind ${kind}\` (or set --repo)`);
|
|
34746
34843
|
}
|
|
34747
|
-
const { org, repo } = parseOrgRepo(args[0], ctx.config);
|
|
34844
|
+
const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
|
|
34748
34845
|
const inputContent = await readContentInput(flags.file, flags.content, ctx.stdin);
|
|
34749
34846
|
switch (kind) {
|
|
34750
34847
|
case "readme": {
|
|
@@ -34765,36 +34862,37 @@ var handleContentSet = async (ctx, { args, flags }) => {
|
|
|
34765
34862
|
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} does not support \`set\`.`);
|
|
34766
34863
|
}
|
|
34767
34864
|
};
|
|
34768
|
-
var
|
|
34865
|
+
var handleContentPrompt = async (ctx, { args, flags }) => {
|
|
34769
34866
|
const kind = requireKind(flags.kind);
|
|
34770
34867
|
if (READ_ONLY_KINDS.has(kind)) {
|
|
34771
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} is read-only; \`
|
|
34772
|
-
}
|
|
34773
|
-
const { org, repo } = parseOrgRepo(args[0], ctx.config);
|
|
34774
|
-
switch (kind) {
|
|
34775
|
-
case "readme": {
|
|
34776
|
-
const generated = await ctx.client.repo.generateReadme(org, repo);
|
|
34777
|
-
if (flags.save) {
|
|
34778
|
-
await ctx.client.repo.setReadme(org, repo, generated.content);
|
|
34779
|
-
}
|
|
34780
|
-
writeOutput(ctx, generated, () => {
|
|
34781
|
-
ctx.out(generated.content);
|
|
34782
|
-
});
|
|
34783
|
-
break;
|
|
34784
|
-
}
|
|
34785
|
-
case "agents": {
|
|
34786
|
-
const generated = await ctx.client.repo.generateAgents(org, repo);
|
|
34787
|
-
if (flags.save) {
|
|
34788
|
-
await ctx.client.repo.setAgents(org, repo, generated.content);
|
|
34789
|
-
}
|
|
34790
|
-
writeOutput(ctx, generated, () => {
|
|
34791
|
-
ctx.out(generated.content);
|
|
34792
|
-
});
|
|
34793
|
-
break;
|
|
34794
|
-
}
|
|
34795
|
-
default:
|
|
34796
|
-
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} does not support \`generate\`.`);
|
|
34868
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `--kind ${kind} is read-only; \`prompt\` is rejected.`, undefined, `Use \`wh repo content get [org/repo] --kind ${kind}\` (or set --repo)`);
|
|
34797
34869
|
}
|
|
34870
|
+
const promptKind = kind;
|
|
34871
|
+
const { org, repo } = parseOrgRepo(getRepoRef(ctx) ?? args[0], ctx.config);
|
|
34872
|
+
const [repoInfo, shapesPage, stats, thingsPage] = await Promise.all([
|
|
34873
|
+
ctx.client.repo.get(org, repo),
|
|
34874
|
+
ctx.client.shape.list(org, repo),
|
|
34875
|
+
ctx.client.repo.getStats(org, repo),
|
|
34876
|
+
ctx.client.thing.query(org, repo, { limit: 30 })
|
|
34877
|
+
]);
|
|
34878
|
+
const { prompt, saveCommand } = buildContentPrompt({
|
|
34879
|
+
kind: promptKind,
|
|
34880
|
+
org,
|
|
34881
|
+
repo,
|
|
34882
|
+
description: repoInfo.description ?? null,
|
|
34883
|
+
byKind: stats.byKind,
|
|
34884
|
+
byShape: stats.byShape,
|
|
34885
|
+
shapeNames: nameStrings(shapesPage.items),
|
|
34886
|
+
sampleThingNames: nameStrings(thingsPage.items)
|
|
34887
|
+
});
|
|
34888
|
+
writeOutput(ctx, { kind: promptKind, org, repo, prompt, saveCommand }, () => {
|
|
34889
|
+
ctx.out(prompt);
|
|
34890
|
+
});
|
|
34891
|
+
ctx.status(`Next: draft the content, then run:
|
|
34892
|
+
${saveCommand}`);
|
|
34893
|
+
};
|
|
34894
|
+
var handleContentGenerate = async () => {
|
|
34895
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "wh repo content generate is no longer supported — WarmHub no longer hosts README/AGENTS generation.", undefined, "Draft locally with your own agent: wh repo content prompt [org/repo] --kind readme");
|
|
34798
34896
|
};
|
|
34799
34897
|
var CONTENT_SUBDOMAIN = defineDomain({
|
|
34800
34898
|
name: "content",
|
|
@@ -34802,7 +34900,7 @@ var CONTENT_SUBDOMAIN = defineDomain({
|
|
|
34802
34900
|
verbs: {
|
|
34803
34901
|
get: {
|
|
34804
34902
|
summary: "Fetch repo content by kind",
|
|
34805
|
-
args: "
|
|
34903
|
+
args: "[org/repo]",
|
|
34806
34904
|
flags: contentGetFlags,
|
|
34807
34905
|
examples: [
|
|
34808
34906
|
"wh repo content get myorg/myrepo --kind readme",
|
|
@@ -34813,7 +34911,7 @@ var CONTENT_SUBDOMAIN = defineDomain({
|
|
|
34813
34911
|
},
|
|
34814
34912
|
set: {
|
|
34815
34913
|
summary: "Set repo content by kind",
|
|
34816
|
-
args: "
|
|
34914
|
+
args: "[org/repo]",
|
|
34817
34915
|
flags: contentSetFlags,
|
|
34818
34916
|
examples: [
|
|
34819
34917
|
'wh repo content set myorg/myrepo --kind readme --content "# Hello"',
|
|
@@ -34822,14 +34920,21 @@ var CONTENT_SUBDOMAIN = defineDomain({
|
|
|
34822
34920
|
],
|
|
34823
34921
|
handler: handleContentSet
|
|
34824
34922
|
},
|
|
34825
|
-
|
|
34826
|
-
summary: "
|
|
34827
|
-
args: "
|
|
34828
|
-
flags:
|
|
34923
|
+
prompt: {
|
|
34924
|
+
summary: "Print an agent-ready prompt to draft repo content locally (no hosted LLM)",
|
|
34925
|
+
args: "[org/repo]",
|
|
34926
|
+
flags: promptFlags,
|
|
34829
34927
|
examples: [
|
|
34830
|
-
"wh repo content
|
|
34831
|
-
"wh repo content
|
|
34928
|
+
"wh repo content prompt myorg/myrepo --kind readme",
|
|
34929
|
+
"wh repo content prompt myorg/myrepo --kind agents"
|
|
34832
34930
|
],
|
|
34931
|
+
handler: handleContentPrompt
|
|
34932
|
+
},
|
|
34933
|
+
generate: {
|
|
34934
|
+
summary: "Deprecated — use `wh repo content prompt` (no hosted LLM)",
|
|
34935
|
+
args: "<org/repo>",
|
|
34936
|
+
flags: promptFlags,
|
|
34937
|
+
examples: ["wh repo content prompt myorg/myrepo --kind readme"],
|
|
34833
34938
|
handler: handleContentGenerate
|
|
34834
34939
|
}
|
|
34835
34940
|
}
|
|
@@ -35466,7 +35571,9 @@ var createFlags8 = {
|
|
|
35466
35571
|
timezone: flag.string({
|
|
35467
35572
|
description: "IANA timezone (e.g., America/New_York). Default: UTC"
|
|
35468
35573
|
}),
|
|
35469
|
-
"webhook-url": flag.string({
|
|
35574
|
+
"webhook-url": flag.string({
|
|
35575
|
+
description: "Webhook destination URL (required for webhook and cron)"
|
|
35576
|
+
}),
|
|
35470
35577
|
url: flag.string({ description: "Alias for --webhook-url" }),
|
|
35471
35578
|
"fallback-webhook-url": flag.string({
|
|
35472
35579
|
description: "Optional fallback webhook URL for terminal action failures"
|
|
@@ -35478,7 +35585,7 @@ var createFlags8 = {
|
|
|
35478
35585
|
description: "Subscription name (deprecated; use positional <name>)"
|
|
35479
35586
|
}),
|
|
35480
35587
|
source: flag.string({
|
|
35481
|
-
description: 'Source repo to watch (same-org shorthand "repoName" or "orgName/repoName")'
|
|
35588
|
+
description: 'Source repo to watch for webhook subscriptions (same-org shorthand "repoName" or "orgName/repoName")'
|
|
35482
35589
|
})
|
|
35483
35590
|
};
|
|
35484
35591
|
var updateFlags4 = {
|
|
@@ -35487,7 +35594,9 @@ var updateFlags4 = {
|
|
|
35487
35594
|
filter: createFlags8.filter,
|
|
35488
35595
|
cronspec: createFlags8.cronspec,
|
|
35489
35596
|
timezone: createFlags8.timezone,
|
|
35490
|
-
"webhook-url":
|
|
35597
|
+
"webhook-url": flag.string({
|
|
35598
|
+
description: "Webhook destination URL"
|
|
35599
|
+
}),
|
|
35491
35600
|
url: createFlags8.url,
|
|
35492
35601
|
"fallback-webhook-url": createFlags8["fallback-webhook-url"],
|
|
35493
35602
|
"clear-fallback-webhook-url": flag.boolean({
|
|
@@ -35584,19 +35693,42 @@ var handleCreate7 = async (ctx, { flags, args }) => {
|
|
|
35584
35693
|
const kind = parseKind(flags.kind, usage, example);
|
|
35585
35694
|
const { org, repo } = resolveRepoContext2(ctx);
|
|
35586
35695
|
const createArgs = buildSubscriptionMutationArgs(kind, flags, usage, example);
|
|
35587
|
-
const
|
|
35696
|
+
const sourceRepoRef = typeof flags.source === "string" ? flags.source : undefined;
|
|
35697
|
+
if (kind === "cron" && sourceRepoRef) {
|
|
35698
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", "--source is only supported for webhook subscriptions", undefined, `Example: wh sub create signal-hook --repo myorg/myrepo --on Signal --kind webhook --filter '{"shape":"Signal"}' --webhook-url https://example.com/hook --source myorg/source-repo`);
|
|
35699
|
+
}
|
|
35700
|
+
const webhookUrl = createArgs.webhookUrl;
|
|
35701
|
+
if (!webhookUrl) {
|
|
35702
|
+
usageError10(usage, example);
|
|
35703
|
+
}
|
|
35704
|
+
const commonArgs = {
|
|
35588
35705
|
orgName: org,
|
|
35589
35706
|
repoName: repo,
|
|
35590
|
-
shapeName: createArgs.shapeName,
|
|
35591
35707
|
name,
|
|
35592
|
-
|
|
35593
|
-
kind,
|
|
35594
|
-
webhookUrl: createArgs.webhookUrl,
|
|
35708
|
+
webhookUrl,
|
|
35595
35709
|
fallbackWebhookUrl: createArgs.fallbackWebhookUrl,
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35710
|
+
...createArgs.allowTraceReentry === true ? { allowTraceReentry: true } : {}
|
|
35711
|
+
};
|
|
35712
|
+
let result;
|
|
35713
|
+
if (kind === "cron") {
|
|
35714
|
+
const cronConfig = createArgs.cronConfig;
|
|
35715
|
+
if (!cronConfig) {
|
|
35716
|
+
usageError10("Usage: wh sub create <name> --repo org/repo --kind cron --cronspec <expr> --webhook-url <url>", 'wh sub create health-check --repo org/repo --kind cron --cronspec "*/15 * * * *" --webhook-url https://example.com/health');
|
|
35717
|
+
}
|
|
35718
|
+
result = await ctx.client.subscription.create({
|
|
35719
|
+
...commonArgs,
|
|
35720
|
+
kind,
|
|
35721
|
+
cronConfig
|
|
35722
|
+
});
|
|
35723
|
+
} else {
|
|
35724
|
+
result = await ctx.client.subscription.create({
|
|
35725
|
+
...commonArgs,
|
|
35726
|
+
kind,
|
|
35727
|
+
shapeName: createArgs.shapeName,
|
|
35728
|
+
filterJson: createArgs.filterJson,
|
|
35729
|
+
sourceRepoRef
|
|
35730
|
+
});
|
|
35731
|
+
}
|
|
35600
35732
|
writeOutput(ctx, result, () => {
|
|
35601
35733
|
const c = ctx.colors;
|
|
35602
35734
|
ctx.status(`${c.green}Created subscription${c.reset} ${c.cyan}${name}${c.reset} on ${c.cyan}${org}/${repo}${c.reset}`);
|
|
@@ -36044,7 +36176,7 @@ var createFlags9 = {
|
|
|
36044
36176
|
name: flag.string({ short: "n", description: "Token name" }),
|
|
36045
36177
|
scope: flag.string({
|
|
36046
36178
|
short: "s",
|
|
36047
|
-
description: "Scope entry: org/repo=perms, org=perms, or perms for global scope. Repeatable.",
|
|
36179
|
+
description: "Scope entry: org/repo=perms, org=perms, or perms for global scope. " + "A role: shorthand (role:owner|admin|editor|viewer, e.g. org/repo=role:editor) " + "expands to that role's scopes. Repeatable.",
|
|
36048
36180
|
multiple: true
|
|
36049
36181
|
}),
|
|
36050
36182
|
"scopes-json": flag.string({
|
|
@@ -36095,7 +36227,7 @@ function formatScopes(scopes) {
|
|
|
36095
36227
|
}
|
|
36096
36228
|
var handleCreate8 = async (ctx, { flags }) => {
|
|
36097
36229
|
if (!flags.name) {
|
|
36098
|
-
usageError11("Usage: wh token create --name <name> [flags]", "wh token create --name ci-bot --scope myorg/myrepo=
|
|
36230
|
+
usageError11("Usage: wh token create --name <name> [flags]", "wh token create --name ci-bot --scope myorg/myrepo=role:editor --expires 90d");
|
|
36099
36231
|
}
|
|
36100
36232
|
const hasScopesJson = flags["scopes-json"] !== undefined;
|
|
36101
36233
|
if (flags.scope && hasScopesJson) {
|
|
@@ -36207,6 +36339,7 @@ var TOKEN_DOMAIN = defineDomain({
|
|
|
36207
36339
|
flags: createFlags9,
|
|
36208
36340
|
examples: [
|
|
36209
36341
|
"wh token create --name ci-bot --scope myorg/myrepo=repo:read,repo:write",
|
|
36342
|
+
"wh token create --name ci-bot --scope myorg/myrepo=role:editor",
|
|
36210
36343
|
'wh token create -n deploy -s myorg=repo:write -d "Deploy pipeline" --expires 90d',
|
|
36211
36344
|
"wh token create --name reader --scope repo:read",
|
|
36212
36345
|
`wh token create --name scoped --scopes-json '[{"resource":"myorg/myrepo","permissions":["repo:read"],"allowedMatches":["Signal/*"]}]'`,
|
|
@@ -37419,8 +37552,8 @@ var package_default2 = {
|
|
|
37419
37552
|
scripts: {
|
|
37420
37553
|
"check:contract": "node ../../scripts/lint/external-identity-contracts.mjs cli",
|
|
37421
37554
|
"check:boundary": "node ../../scripts/lint/boundary-imports.mjs src tests",
|
|
37422
|
-
test: "vitest run",
|
|
37423
|
-
"test:watch": "vitest",
|
|
37555
|
+
test: "bun run --filter @warmhub/sdk-ts build && vitest run",
|
|
37556
|
+
"test:watch": "bun run --filter @warmhub/sdk-ts build && vitest",
|
|
37424
37557
|
typecheck: "bun run check:boundary && bun run check:contract && tsc --noEmit"
|
|
37425
37558
|
},
|
|
37426
37559
|
dependencies: {
|
|
@@ -37733,7 +37866,7 @@ function resolveLogLevel(flags, env) {
|
|
|
37733
37866
|
// package.json
|
|
37734
37867
|
var package_default3 = {
|
|
37735
37868
|
name: "@warmhub/cli",
|
|
37736
|
-
version: "0.
|
|
37869
|
+
version: "0.50.0",
|
|
37737
37870
|
private: false,
|
|
37738
37871
|
type: "module",
|
|
37739
37872
|
description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -38760,4 +38893,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
|
|
|
38760
38893
|
var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
|
|
38761
38894
|
process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
|
|
38762
38895
|
|
|
38763
|
-
//# debugId=
|
|
38896
|
+
//# debugId=C77C7A7F52472BC464756E2164756E21
|
package/package.json
CHANGED