hivenet 0.4.1 → 0.6.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/README.md +75 -4
- package/dist/chunk-AK23JXBN.js +32 -0
- package/dist/{chunk-K4DIOYVH.js → chunk-DNR6HNJD.js} +607 -166
- package/dist/cli.js +358 -57
- package/dist/doctor-EA2GJRUS.js +210 -0
- package/dist/index.cjs +16771 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1053 -0
- package/dist/index.d.ts +1053 -0
- package/dist/index.js +16709 -0
- package/dist/index.js.map +1 -0
- package/dist/owner-ZWROA7AU.js +539 -0
- package/package.json +14 -1
- package/dist/owner-LAL5WKKW.js +0 -235
|
@@ -1389,10 +1389,10 @@ function mergeDefs(...defs) {
|
|
|
1389
1389
|
function cloneDef(schema) {
|
|
1390
1390
|
return mergeDefs(schema._zod.def);
|
|
1391
1391
|
}
|
|
1392
|
-
function getElementAtPath(obj,
|
|
1393
|
-
if (!
|
|
1392
|
+
function getElementAtPath(obj, path6) {
|
|
1393
|
+
if (!path6)
|
|
1394
1394
|
return obj;
|
|
1395
|
-
return
|
|
1395
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
1396
1396
|
}
|
|
1397
1397
|
function promiseAllObject(promisesObj) {
|
|
1398
1398
|
const keys = Object.keys(promisesObj);
|
|
@@ -1801,11 +1801,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1801
1801
|
}
|
|
1802
1802
|
return false;
|
|
1803
1803
|
}
|
|
1804
|
-
function prefixIssues(
|
|
1804
|
+
function prefixIssues(path6, issues) {
|
|
1805
1805
|
return issues.map((iss) => {
|
|
1806
1806
|
var _a3;
|
|
1807
1807
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1808
|
-
iss.path.unshift(
|
|
1808
|
+
iss.path.unshift(path6);
|
|
1809
1809
|
return iss;
|
|
1810
1810
|
});
|
|
1811
1811
|
}
|
|
@@ -1952,16 +1952,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1952
1952
|
}
|
|
1953
1953
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1954
1954
|
const fieldErrors = { _errors: [] };
|
|
1955
|
-
const processError = (error52,
|
|
1955
|
+
const processError = (error52, path6 = []) => {
|
|
1956
1956
|
for (const issue2 of error52.issues) {
|
|
1957
1957
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1958
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1958
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
1959
1959
|
} else if (issue2.code === "invalid_key") {
|
|
1960
|
-
processError({ issues: issue2.issues }, [...
|
|
1960
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1961
1961
|
} else if (issue2.code === "invalid_element") {
|
|
1962
|
-
processError({ issues: issue2.issues }, [...
|
|
1962
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1963
1963
|
} else {
|
|
1964
|
-
const fullpath = [...
|
|
1964
|
+
const fullpath = [...path6, ...issue2.path];
|
|
1965
1965
|
if (fullpath.length === 0) {
|
|
1966
1966
|
fieldErrors._errors.push(mapper(issue2));
|
|
1967
1967
|
} else {
|
|
@@ -1988,17 +1988,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1988
1988
|
}
|
|
1989
1989
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1990
1990
|
const result = { errors: [] };
|
|
1991
|
-
const processError = (error52,
|
|
1991
|
+
const processError = (error52, path6 = []) => {
|
|
1992
1992
|
var _a3, _b;
|
|
1993
1993
|
for (const issue2 of error52.issues) {
|
|
1994
1994
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1995
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1995
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
1996
1996
|
} else if (issue2.code === "invalid_key") {
|
|
1997
|
-
processError({ issues: issue2.issues }, [...
|
|
1997
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1998
1998
|
} else if (issue2.code === "invalid_element") {
|
|
1999
|
-
processError({ issues: issue2.issues }, [...
|
|
1999
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
2000
2000
|
} else {
|
|
2001
|
-
const fullpath = [...
|
|
2001
|
+
const fullpath = [...path6, ...issue2.path];
|
|
2002
2002
|
if (fullpath.length === 0) {
|
|
2003
2003
|
result.errors.push(mapper(issue2));
|
|
2004
2004
|
continue;
|
|
@@ -2030,8 +2030,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2030
2030
|
}
|
|
2031
2031
|
function toDotPath(_path) {
|
|
2032
2032
|
const segs = [];
|
|
2033
|
-
const
|
|
2034
|
-
for (const seg of
|
|
2033
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2034
|
+
for (const seg of path6) {
|
|
2035
2035
|
if (typeof seg === "number")
|
|
2036
2036
|
segs.push(`[${seg}]`);
|
|
2037
2037
|
else if (typeof seg === "symbol")
|
|
@@ -14723,13 +14723,13 @@ function resolveRef(ref, ctx) {
|
|
|
14723
14723
|
if (!ref.startsWith("#")) {
|
|
14724
14724
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14725
14725
|
}
|
|
14726
|
-
const
|
|
14727
|
-
if (
|
|
14726
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
14727
|
+
if (path6.length === 0) {
|
|
14728
14728
|
return ctx.rootSchema;
|
|
14729
14729
|
}
|
|
14730
14730
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14731
|
-
if (
|
|
14732
|
-
const key =
|
|
14731
|
+
if (path6[0] === defsKey) {
|
|
14732
|
+
const key = path6[1];
|
|
14733
14733
|
if (!key || !ctx.defs[key]) {
|
|
14734
14734
|
throw new Error(`Reference not found: ${ref}`);
|
|
14735
14735
|
}
|
|
@@ -15138,6 +15138,102 @@ function date4(params) {
|
|
|
15138
15138
|
config(en_default());
|
|
15139
15139
|
|
|
15140
15140
|
// ../spec/dist/index.js
|
|
15141
|
+
var MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
15142
|
+
var MAX_ATTACHMENTS = 10;
|
|
15143
|
+
var MAX_ATTACHMENT_DESCRIPTION_LENGTH = 1e3;
|
|
15144
|
+
var ATTACHMENT_UPLOAD_PATH = "/v1/attachments";
|
|
15145
|
+
var attachmentDescriptionSchema = external_exports.string().trim().min(1).max(MAX_ATTACHMENT_DESCRIPTION_LENGTH).describe("Optional plain text: what this file shows and why it matters.");
|
|
15146
|
+
var attachmentIdSchema = external_exports.string().regex(/^att_[a-f0-9]{32}$/);
|
|
15147
|
+
var ATTACHMENT_TARGET_TYPES = [
|
|
15148
|
+
"event",
|
|
15149
|
+
"issue",
|
|
15150
|
+
"question",
|
|
15151
|
+
"eval",
|
|
15152
|
+
"investigation",
|
|
15153
|
+
"investigation_question",
|
|
15154
|
+
"investigation_reply"
|
|
15155
|
+
];
|
|
15156
|
+
var attachmentTargetSchema = external_exports.object({
|
|
15157
|
+
type: external_exports.enum(ATTACHMENT_TARGET_TYPES),
|
|
15158
|
+
id: external_exports.string().min(1).max(64)
|
|
15159
|
+
});
|
|
15160
|
+
var attachmentManifestSchema = external_exports.object({
|
|
15161
|
+
filename: external_exports.string().min(1).max(180).refine(
|
|
15162
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: Reject control characters in filenames and HTTP headers.
|
|
15163
|
+
(name) => !/[\\/\u0000-\u001f\u007f]/.test(name) && name !== "." && name !== "..",
|
|
15164
|
+
"Use a filename without directories or control characters."
|
|
15165
|
+
),
|
|
15166
|
+
mediaType: external_exports.string().max(127).regex(/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/),
|
|
15167
|
+
size: external_exports.number().int().min(1).max(MAX_ATTACHMENT_BYTES),
|
|
15168
|
+
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/)
|
|
15169
|
+
});
|
|
15170
|
+
var prepareAttachmentSchema = attachmentManifestSchema.extend({
|
|
15171
|
+
to: external_exports.string().min(1).max(253).optional(),
|
|
15172
|
+
scope: external_exports.enum(["reporter", "owner"]).default("reporter"),
|
|
15173
|
+
/** Self-reported agent name for reporter uploads. */
|
|
15174
|
+
uploader: external_exports.string().min(1).max(128).optional()
|
|
15175
|
+
});
|
|
15176
|
+
var preparedAttachmentSchema = external_exports.object({
|
|
15177
|
+
reference: external_exports.object({
|
|
15178
|
+
id: attachmentIdSchema,
|
|
15179
|
+
token: external_exports.string().regex(/^hva_[a-f0-9]{64}$/)
|
|
15180
|
+
}),
|
|
15181
|
+
uploadUrl: external_exports.url(),
|
|
15182
|
+
expiresAt: external_exports.string()
|
|
15183
|
+
});
|
|
15184
|
+
var attachmentReferenceSchema = preparedAttachmentSchema.shape.reference.extend({
|
|
15185
|
+
description: attachmentDescriptionSchema.optional()
|
|
15186
|
+
});
|
|
15187
|
+
var attachmentReferencesSchema = external_exports.array(attachmentReferenceSchema).max(MAX_ATTACHMENTS).refine(
|
|
15188
|
+
(refs) => new Set(refs.map((ref) => ref.id)).size === refs.length,
|
|
15189
|
+
"Each file can be attached once."
|
|
15190
|
+
);
|
|
15191
|
+
var attachFilesSchema = external_exports.object({
|
|
15192
|
+
target: attachmentTargetSchema,
|
|
15193
|
+
attachments: attachmentReferencesSchema.min(1)
|
|
15194
|
+
});
|
|
15195
|
+
var attachmentSchema = attachmentManifestSchema.extend({
|
|
15196
|
+
id: attachmentIdSchema,
|
|
15197
|
+
createdAt: external_exports.string(),
|
|
15198
|
+
source: external_exports.enum(["reporter", "owner"]),
|
|
15199
|
+
/** Reporter names are self-reported; owner uploads are authenticated. */
|
|
15200
|
+
uploader: external_exports.string().nullable(),
|
|
15201
|
+
/** The record the file belongs to — a report when shown on its issue or eval. */
|
|
15202
|
+
target: attachmentTargetSchema,
|
|
15203
|
+
description: attachmentDescriptionSchema.optional()
|
|
15204
|
+
});
|
|
15205
|
+
var deliveredAttachmentSchema = attachmentSchema.extend({
|
|
15206
|
+
url: external_exports.url(),
|
|
15207
|
+
expiresAt: external_exports.string()
|
|
15208
|
+
});
|
|
15209
|
+
var MEDIA_TYPES = {
|
|
15210
|
+
png: "image/png",
|
|
15211
|
+
jpg: "image/jpeg",
|
|
15212
|
+
jpeg: "image/jpeg",
|
|
15213
|
+
gif: "image/gif",
|
|
15214
|
+
webp: "image/webp",
|
|
15215
|
+
svg: "image/svg+xml",
|
|
15216
|
+
mp4: "video/mp4",
|
|
15217
|
+
webm: "video/webm",
|
|
15218
|
+
mp3: "audio/mpeg",
|
|
15219
|
+
m4a: "audio/mp4",
|
|
15220
|
+
wav: "audio/wav",
|
|
15221
|
+
ogg: "audio/ogg",
|
|
15222
|
+
pdf: "application/pdf",
|
|
15223
|
+
json: "application/json",
|
|
15224
|
+
jsonl: "application/x-ndjson",
|
|
15225
|
+
ndjson: "application/x-ndjson",
|
|
15226
|
+
txt: "text/plain",
|
|
15227
|
+
log: "text/plain",
|
|
15228
|
+
md: "text/markdown",
|
|
15229
|
+
csv: "text/csv",
|
|
15230
|
+
zip: "application/zip",
|
|
15231
|
+
html: "text/html"
|
|
15232
|
+
};
|
|
15233
|
+
function mediaTypeForFilename(filename) {
|
|
15234
|
+
const extension = /\.([^./\\]+)$/.exec(filename)?.[1]?.toLowerCase();
|
|
15235
|
+
return extension && MEDIA_TYPES[extension] || "application/octet-stream";
|
|
15236
|
+
}
|
|
15141
15237
|
var PROTOCOL_VERSION = 1;
|
|
15142
15238
|
var MAX_FEEDBACK_LENGTH = 5e3;
|
|
15143
15239
|
var MAX_SUBJECT_LENGTH = 500;
|
|
@@ -15157,15 +15253,40 @@ var FEEDBACK_CATEGORIES = [
|
|
|
15157
15253
|
"cli",
|
|
15158
15254
|
"api",
|
|
15159
15255
|
"model",
|
|
15160
|
-
"eval",
|
|
15161
15256
|
"ux",
|
|
15162
15257
|
"other"
|
|
15163
15258
|
];
|
|
15164
|
-
var
|
|
15165
|
-
|
|
15259
|
+
var createQuestionInputSchema = external_exports.object({
|
|
15260
|
+
prompt: external_exports.string().trim().min(8).max(500).describe('The question, e.g. "If you used <feature>: what broke or was missing?"'),
|
|
15261
|
+
category: external_exports.enum(FEEDBACK_CATEGORIES).optional().describe("Only ask agents whose submission carries this category."),
|
|
15262
|
+
attachments: attachmentReferencesSchema.optional().describe("Uploaded files, each {id, token, description?}; every agent asked can open them."),
|
|
15263
|
+
idempotencyKey: external_exports.string().regex(/^[A-Za-z0-9_-]{8,64}$/).optional().describe(
|
|
15264
|
+
"Same key + same project = the same question, so a retried publish never duplicates."
|
|
15265
|
+
)
|
|
15266
|
+
});
|
|
15267
|
+
var LEGACY_CATEGORIES = ["eval"];
|
|
15268
|
+
var EVENT_STATUSES = [
|
|
15269
|
+
"new",
|
|
15270
|
+
"seen",
|
|
15271
|
+
"in_progress",
|
|
15272
|
+
"resolved",
|
|
15273
|
+
"wont_fix",
|
|
15274
|
+
"spam"
|
|
15275
|
+
];
|
|
15276
|
+
var ISSUE_STATUSES = [
|
|
15277
|
+
"open",
|
|
15278
|
+
"in_progress",
|
|
15279
|
+
"needs_review",
|
|
15280
|
+
"resolved",
|
|
15281
|
+
"wont_fix",
|
|
15282
|
+
"spam"
|
|
15283
|
+
];
|
|
15284
|
+
var issueStatusSchema = external_exports.enum(ISSUE_STATUSES);
|
|
15285
|
+
var EVAL_STATUSES = ["proposed", "accepted", "archived"];
|
|
15166
15286
|
var VENDOR_CATEGORY_PATTERN = /^x-[a-z0-9][a-z0-9-]{0,38}$/;
|
|
15167
15287
|
var categorySchema = external_exports.union([
|
|
15168
15288
|
external_exports.enum(FEEDBACK_CATEGORIES),
|
|
15289
|
+
external_exports.enum(LEGACY_CATEGORIES),
|
|
15169
15290
|
external_exports.string().regex(VENDOR_CATEGORY_PATTERN, "vendor categories must match x-<kebab-case>")
|
|
15170
15291
|
]);
|
|
15171
15292
|
var sentimentSchema = external_exports.enum(["positive", "negative", "neutral"]);
|
|
@@ -15212,7 +15333,10 @@ var feedbackContextSchema = external_exports.object({
|
|
|
15212
15333
|
/** Only populated via vendor identity paths (signed grants / pass-through). */
|
|
15213
15334
|
user: userContextSchema.optional()
|
|
15214
15335
|
});
|
|
15215
|
-
var metadataSchema = external_exports.record(
|
|
15336
|
+
var metadataSchema = external_exports.record(
|
|
15337
|
+
external_exports.string().min(1).max(40),
|
|
15338
|
+
external_exports.union([external_exports.string().max(200), external_exports.number().finite(), external_exports.boolean()])
|
|
15339
|
+
).refine((value) => Object.keys(value).length <= 20, { message: "at most 20 metadata keys" });
|
|
15216
15340
|
var feedbackEventSchema = external_exports.object({
|
|
15217
15341
|
v: external_exports.literal(PROTOCOL_VERSION),
|
|
15218
15342
|
/** Tenant slug or domain this feedback is addressed to. Optional when the write key implies it. */
|
|
@@ -15224,6 +15348,10 @@ var feedbackEventSchema = external_exports.object({
|
|
|
15224
15348
|
author: authorSchema.optional(),
|
|
15225
15349
|
thread: external_exports.object({ id: external_exports.string().regex(THREAD_ID_PATTERN) }),
|
|
15226
15350
|
eval: evalReportSchema.optional(),
|
|
15351
|
+
/** Id of an owner/system question this submission answers (from a prior response's `ask`). */
|
|
15352
|
+
question: external_exports.string().max(64).optional(),
|
|
15353
|
+
/** Uploaded files, committed with the event or not at all. Bytes never travel in feedback JSON. */
|
|
15354
|
+
attachments: attachmentReferencesSchema.optional(),
|
|
15227
15355
|
context: feedbackContextSchema.optional(),
|
|
15228
15356
|
metadata: metadataSchema.optional(),
|
|
15229
15357
|
/** Client-minted retry key: same key + same project = same stored event. */
|
|
@@ -15234,6 +15362,31 @@ var feedbackEventSchema = external_exports.object({
|
|
|
15234
15362
|
}),
|
|
15235
15363
|
consent: external_exports.object({ telemetry: external_exports.boolean() })
|
|
15236
15364
|
});
|
|
15365
|
+
var knownIssueSchema = external_exports.object({
|
|
15366
|
+
title: external_exports.string().max(120),
|
|
15367
|
+
/** wont_fix is disclosed only when the owner attached a closing note. */
|
|
15368
|
+
status: external_exports.enum(["open", "wont_fix"]),
|
|
15369
|
+
/** This very report flipped a resolved issue back open — already recorded. */
|
|
15370
|
+
reopened: external_exports.boolean().optional(),
|
|
15371
|
+
/** Total reports on this issue, including this one. */
|
|
15372
|
+
reports: external_exports.number().int().positive(),
|
|
15373
|
+
/** The owner's closing note, verbatim — their explanation of the decision. */
|
|
15374
|
+
note: external_exports.string().max(MAX_GUIDANCE_LENGTH).optional(),
|
|
15375
|
+
/** Server-composed next step for the submitting agent. */
|
|
15376
|
+
hint: external_exports.string().max(300)
|
|
15377
|
+
});
|
|
15378
|
+
var ownerIssueSchema = external_exports.object({
|
|
15379
|
+
id: external_exports.string(),
|
|
15380
|
+
title: external_exports.string(),
|
|
15381
|
+
summary: external_exports.string().nullable(),
|
|
15382
|
+
status: issueStatusSchema,
|
|
15383
|
+
fingerprint: external_exports.string().nullable(),
|
|
15384
|
+
event_count: external_exports.number(),
|
|
15385
|
+
reopened_count: external_exports.number(),
|
|
15386
|
+
first_seen: external_exports.string(),
|
|
15387
|
+
last_seen: external_exports.string(),
|
|
15388
|
+
links_json: external_exports.string()
|
|
15389
|
+
});
|
|
15237
15390
|
var ingestResponseSchema = external_exports.object({
|
|
15238
15391
|
id: external_exports.string().max(64),
|
|
15239
15392
|
thread: external_exports.string().regex(THREAD_ID_PATTERN),
|
|
@@ -15241,6 +15394,19 @@ var ingestResponseSchema = external_exports.object({
|
|
|
15241
15394
|
resume: external_exports.string().max(512).optional(),
|
|
15242
15395
|
/** Vendor-configured answer back to the submitting agent (known issues, workarounds). */
|
|
15243
15396
|
guidance: external_exports.string().max(MAX_GUIDANCE_LENGTH).optional(),
|
|
15397
|
+
/** The report matched an already-tracked issue; recorded — don't file variants. */
|
|
15398
|
+
known_issue: knownIssueSchema.optional(),
|
|
15399
|
+
/**
|
|
15400
|
+
* A question from the project's team, delivered at most one per response.
|
|
15401
|
+
* Answering is optional and must be grounded in what the agent actually did;
|
|
15402
|
+
* `command` is ready to run and files the answer on this thread.
|
|
15403
|
+
*/
|
|
15404
|
+
ask: external_exports.object({
|
|
15405
|
+
id: external_exports.string().max(64),
|
|
15406
|
+
prompt: external_exports.string().max(500),
|
|
15407
|
+
command: external_exports.string().max(512),
|
|
15408
|
+
attachments: external_exports.array(deliveredAttachmentSchema).optional()
|
|
15409
|
+
}).optional(),
|
|
15244
15410
|
/** True when idempotencyKey matched an already-stored event; id/thread are the original's. */
|
|
15245
15411
|
duplicate: external_exports.boolean().optional()
|
|
15246
15412
|
});
|
|
@@ -15269,8 +15435,8 @@ var repoEntrySchema = external_exports.object({
|
|
|
15269
15435
|
var repoListSchema = external_exports.array(repoEntrySchema).max(20);
|
|
15270
15436
|
function formatIssues(error51) {
|
|
15271
15437
|
return error51.issues.map((issue2) => {
|
|
15272
|
-
const
|
|
15273
|
-
return
|
|
15438
|
+
const path6 = issue2.path.join(".");
|
|
15439
|
+
return path6 ? `${path6}: ${issue2.message}` : issue2.message;
|
|
15274
15440
|
});
|
|
15275
15441
|
}
|
|
15276
15442
|
function validateFeedbackEvent(input) {
|
|
@@ -15286,6 +15452,13 @@ function validateIngestResponse(input) {
|
|
|
15286
15452
|
return result.success ? { ok: true, data: result.data } : { ok: false, errors: formatIssues(result.error) };
|
|
15287
15453
|
}
|
|
15288
15454
|
|
|
15455
|
+
// ../core/dist/index.js
|
|
15456
|
+
import { createHash } from "crypto";
|
|
15457
|
+
import { readFile, stat } from "fs/promises";
|
|
15458
|
+
import path2 from "path";
|
|
15459
|
+
import { readFileSync } from "fs";
|
|
15460
|
+
import path3 from "path";
|
|
15461
|
+
|
|
15289
15462
|
// ../../node_modules/.pnpm/agent-cli-detector@0.1.5/node_modules/agent-cli-detector/dist/index.js
|
|
15290
15463
|
import { execFileSync } from "child_process";
|
|
15291
15464
|
import path from "path";
|
|
@@ -15580,8 +15753,6 @@ function sessionIdProperties(agent, env) {
|
|
|
15580
15753
|
|
|
15581
15754
|
// ../core/dist/index.js
|
|
15582
15755
|
var import_ci_info = __toESM(require_ci_info(), 1);
|
|
15583
|
-
import { readFileSync } from "fs";
|
|
15584
|
-
import path2 from "path";
|
|
15585
15756
|
|
|
15586
15757
|
// ../../node_modules/.pnpm/sandbox-cli-detector@0.2.0/node_modules/sandbox-cli-detector/dist/chunk-HZH3SATY.js
|
|
15587
15758
|
var defaultSandboxes = [
|
|
@@ -15650,28 +15821,152 @@ function matchesEnvSignal(signal, env) {
|
|
|
15650
15821
|
|
|
15651
15822
|
// ../core/dist/index.js
|
|
15652
15823
|
import { homedir } from "os";
|
|
15653
|
-
import
|
|
15824
|
+
import path22 from "path";
|
|
15654
15825
|
import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
15655
|
-
import path32 from "path";
|
|
15656
|
-
import { appendFileSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
15657
15826
|
import path4 from "path";
|
|
15827
|
+
import { randomUUID } from "crypto";
|
|
15828
|
+
import { appendFileSync, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, renameSync, rmSync } from "fs";
|
|
15829
|
+
import path5 from "path";
|
|
15658
15830
|
import { randomBytes } from "crypto";
|
|
15831
|
+
import { createRequire } from "module";
|
|
15832
|
+
var FeedbackError = class extends Error {
|
|
15833
|
+
constructor(message) {
|
|
15834
|
+
super(message);
|
|
15835
|
+
this.name = "FeedbackError";
|
|
15836
|
+
}
|
|
15837
|
+
};
|
|
15838
|
+
async function readLocalAttachments(inputs, cwd = process.cwd()) {
|
|
15839
|
+
if (inputs.length > MAX_ATTACHMENTS)
|
|
15840
|
+
throw new FeedbackError(`At most ${MAX_ATTACHMENTS} files can be attached.`);
|
|
15841
|
+
const files = [];
|
|
15842
|
+
for (const input of inputs) {
|
|
15843
|
+
const selected = typeof input === "string" ? input : input.path;
|
|
15844
|
+
const filename = path2.basename(selected);
|
|
15845
|
+
const description = attachmentDescriptionSchema.optional().safeParse(typeof input === "string" ? void 0 : input.description);
|
|
15846
|
+
if (!description.success)
|
|
15847
|
+
throw new FeedbackError(
|
|
15848
|
+
`Invalid description for "${filename}": ${description.error.issues.map((issue2) => issue2.message).join("; ")}`
|
|
15849
|
+
);
|
|
15850
|
+
const file2 = path2.resolve(cwd, selected);
|
|
15851
|
+
const info = await stat(file2).catch(() => null);
|
|
15852
|
+
if (!info?.isFile())
|
|
15853
|
+
throw new FeedbackError(`Cannot attach "${selected}": choose an existing, readable file.`);
|
|
15854
|
+
if (info.size < 1 || info.size > MAX_ATTACHMENT_BYTES)
|
|
15855
|
+
throw new FeedbackError(`"${filename}" must be between 1 byte and 20 MiB.`);
|
|
15856
|
+
const bytes = new Uint8Array(
|
|
15857
|
+
await readFile(file2).catch(() => {
|
|
15858
|
+
throw new FeedbackError(`Cannot read "${selected}".`);
|
|
15859
|
+
})
|
|
15860
|
+
);
|
|
15861
|
+
const manifest = attachmentManifestSchema.safeParse({
|
|
15862
|
+
filename,
|
|
15863
|
+
mediaType: mediaTypeForFilename(filename),
|
|
15864
|
+
size: bytes.length,
|
|
15865
|
+
sha256: createHash("sha256").update(bytes).digest("hex")
|
|
15866
|
+
});
|
|
15867
|
+
if (!manifest.success)
|
|
15868
|
+
throw new FeedbackError(
|
|
15869
|
+
`Cannot attach "${filename}": ${manifest.error.issues.map((issue2) => issue2.message).join("; ")}`
|
|
15870
|
+
);
|
|
15871
|
+
files.push({
|
|
15872
|
+
manifest: manifest.data,
|
|
15873
|
+
bytes,
|
|
15874
|
+
...description.data ? { description: description.data } : {}
|
|
15875
|
+
});
|
|
15876
|
+
}
|
|
15877
|
+
return files;
|
|
15878
|
+
}
|
|
15879
|
+
var AttachmentUploadError = class extends FeedbackError {
|
|
15880
|
+
constructor(message, rejected) {
|
|
15881
|
+
super(message);
|
|
15882
|
+
this.rejected = rejected;
|
|
15883
|
+
this.name = "AttachmentUploadError";
|
|
15884
|
+
}
|
|
15885
|
+
rejected;
|
|
15886
|
+
};
|
|
15887
|
+
async function send(fetchImpl, url2, init, timeoutMs) {
|
|
15888
|
+
let response;
|
|
15889
|
+
try {
|
|
15890
|
+
response = await fetchImpl(url2, {
|
|
15891
|
+
...init,
|
|
15892
|
+
redirect: "error",
|
|
15893
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
15894
|
+
});
|
|
15895
|
+
} catch {
|
|
15896
|
+
throw new AttachmentUploadError("Could not reach the server to upload files.", false);
|
|
15897
|
+
}
|
|
15898
|
+
if (response.ok) return response;
|
|
15899
|
+
const body = await response.json().catch(() => null);
|
|
15900
|
+
const errors = Array.isArray(body?.errors) ? body.errors.map(String).join("; ") : void 0;
|
|
15901
|
+
if (response.status === 404 && !errors)
|
|
15902
|
+
throw new AttachmentUploadError("This server does not accept files.", false);
|
|
15903
|
+
throw new AttachmentUploadError(
|
|
15904
|
+
errors ?? `File upload failed (${response.status}).`,
|
|
15905
|
+
!(response.status >= 500 || response.status === 429 || response.status === 408)
|
|
15906
|
+
);
|
|
15907
|
+
}
|
|
15908
|
+
async function uploadFiles(options) {
|
|
15909
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
15910
|
+
const timeoutMs = options.timeoutMs ?? 6e4;
|
|
15911
|
+
const origin = new URL(options.endpoint).origin;
|
|
15912
|
+
const references = [];
|
|
15913
|
+
for (const file2 of options.files) {
|
|
15914
|
+
const response = await send(
|
|
15915
|
+
fetchImpl,
|
|
15916
|
+
`${origin}${ATTACHMENT_UPLOAD_PATH}`,
|
|
15917
|
+
{
|
|
15918
|
+
method: "POST",
|
|
15919
|
+
headers: {
|
|
15920
|
+
"content-type": "application/json",
|
|
15921
|
+
...options.secretKey ? { authorization: `Bearer ${options.secretKey}` } : {},
|
|
15922
|
+
...options.writeKey ? { [WRITE_KEY_HEADER]: options.writeKey } : {}
|
|
15923
|
+
},
|
|
15924
|
+
body: JSON.stringify({
|
|
15925
|
+
...file2.manifest,
|
|
15926
|
+
to: options.to,
|
|
15927
|
+
scope: options.secretKey ? "owner" : "reporter",
|
|
15928
|
+
uploader: options.uploader
|
|
15929
|
+
})
|
|
15930
|
+
},
|
|
15931
|
+
timeoutMs
|
|
15932
|
+
);
|
|
15933
|
+
const prepared = preparedAttachmentSchema.safeParse(await response.json().catch(() => null));
|
|
15934
|
+
if (!prepared.success || new URL(prepared.data.uploadUrl).origin !== origin)
|
|
15935
|
+
throw new AttachmentUploadError("The server returned an invalid upload response.", true);
|
|
15936
|
+
await send(
|
|
15937
|
+
fetchImpl,
|
|
15938
|
+
prepared.data.uploadUrl,
|
|
15939
|
+
{
|
|
15940
|
+
method: "PUT",
|
|
15941
|
+
headers: { authorization: `Bearer ${prepared.data.reference.token}` },
|
|
15942
|
+
body: file2.bytes
|
|
15943
|
+
},
|
|
15944
|
+
// At least 100 KB/s: a 20 MiB file on a slow link still gets about 3.5 minutes.
|
|
15945
|
+
Math.max(timeoutMs, file2.bytes.length / 100)
|
|
15946
|
+
);
|
|
15947
|
+
references.push({
|
|
15948
|
+
...prepared.data.reference,
|
|
15949
|
+
...file2.description ? { description: file2.description } : {}
|
|
15950
|
+
});
|
|
15951
|
+
}
|
|
15952
|
+
return references;
|
|
15953
|
+
}
|
|
15659
15954
|
var DSN_ENV_VAR = "HIVENET_DSN";
|
|
15660
15955
|
var REGISTRY_ENV_VAR = "HIVENET_REGISTRY";
|
|
15661
15956
|
var HOME_ENV_VAR = "HIVENET_HOME";
|
|
15662
15957
|
var NO_TELEMETRY_ENV_VAR = "HIVENET_NO_TELEMETRY";
|
|
15663
15958
|
function feedbackHomeDir(env = process.env) {
|
|
15664
15959
|
const override = env[HOME_ENV_VAR];
|
|
15665
|
-
return override
|
|
15960
|
+
return override?.trim() ? override : path22.join(homedir(), ".hivenet");
|
|
15666
15961
|
}
|
|
15667
15962
|
function isTelemetryDisabled(extraOptOutEnvVars = [], env = process.env) {
|
|
15668
15963
|
const vars = ["DO_NOT_TRACK", NO_TELEMETRY_ENV_VAR, ...extraOptOutEnvVars];
|
|
15669
15964
|
return vars.some((name) => env[name] === "1" || env[name] === "true");
|
|
15670
15965
|
}
|
|
15671
15966
|
var MAX_SESSION_ID_LENGTH = 256;
|
|
15672
|
-
function detectAgentSafe() {
|
|
15967
|
+
function detectAgentSafe(env) {
|
|
15673
15968
|
try {
|
|
15674
|
-
const result = detectAgent();
|
|
15969
|
+
const result = detectAgent({ env });
|
|
15675
15970
|
if (result.detected && result.agent) {
|
|
15676
15971
|
return {
|
|
15677
15972
|
id: result.agent.id,
|
|
@@ -15683,9 +15978,9 @@ function detectAgentSafe() {
|
|
|
15683
15978
|
}
|
|
15684
15979
|
return void 0;
|
|
15685
15980
|
}
|
|
15686
|
-
function detectSandboxSafe() {
|
|
15981
|
+
function detectSandboxSafe(env) {
|
|
15687
15982
|
try {
|
|
15688
|
-
const result = detectSandbox();
|
|
15983
|
+
const result = detectSandbox({ env });
|
|
15689
15984
|
if (result.detected && result.sandbox) {
|
|
15690
15985
|
return {
|
|
15691
15986
|
id: result.sandbox.id,
|
|
@@ -15750,7 +16045,7 @@ function resolveSessions(sources, projectRoot, env) {
|
|
|
15750
16045
|
}
|
|
15751
16046
|
const value = "envVar" in source ? normalizeSessionId(env[source.envVar]) : normalizeSessionId(
|
|
15752
16047
|
readDotenvKey(
|
|
15753
|
-
|
|
16048
|
+
path3.resolve(projectRoot, source.dotenvFile),
|
|
15754
16049
|
source.dotenvKey ?? source.key
|
|
15755
16050
|
)
|
|
15756
16051
|
);
|
|
@@ -15766,8 +16061,8 @@ async function collectContext(options = {}) {
|
|
|
15766
16061
|
return void 0;
|
|
15767
16062
|
}
|
|
15768
16063
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
15769
|
-
const agent = detectAgentSafe();
|
|
15770
|
-
const sandbox = detectSandboxSafe();
|
|
16064
|
+
const agent = detectAgentSafe(env);
|
|
16065
|
+
const sandbox = detectSandboxSafe(env);
|
|
15771
16066
|
const ci = detectCi();
|
|
15772
16067
|
const session = resolveSessions(options.sessions ?? [], projectRoot, env);
|
|
15773
16068
|
let project;
|
|
@@ -15790,12 +16085,6 @@ async function collectContext(options = {}) {
|
|
|
15790
16085
|
function inferAuthor(context) {
|
|
15791
16086
|
return context?.agent ? "agent" : void 0;
|
|
15792
16087
|
}
|
|
15793
|
-
var FeedbackError = class extends Error {
|
|
15794
|
-
constructor(message) {
|
|
15795
|
-
super(message);
|
|
15796
|
-
this.name = "FeedbackError";
|
|
15797
|
-
}
|
|
15798
|
-
};
|
|
15799
16088
|
var CONFIG_FILE_NAME = "feedback.config.json";
|
|
15800
16089
|
var DESCRIPTOR_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
15801
16090
|
var RESOLVE_TIMEOUT_MS = 5e3;
|
|
@@ -15820,9 +16109,9 @@ function parseDsn(dsn) {
|
|
|
15820
16109
|
};
|
|
15821
16110
|
}
|
|
15822
16111
|
function findConfigFile(startDir) {
|
|
15823
|
-
let current =
|
|
16112
|
+
let current = path4.resolve(startDir);
|
|
15824
16113
|
while (true) {
|
|
15825
|
-
const candidate =
|
|
16114
|
+
const candidate = path4.join(current, CONFIG_FILE_NAME);
|
|
15826
16115
|
try {
|
|
15827
16116
|
const raw = readFileSync2(candidate, "utf8");
|
|
15828
16117
|
const parsed = JSON.parse(raw);
|
|
@@ -15831,7 +16120,7 @@ function findConfigFile(startDir) {
|
|
|
15831
16120
|
}
|
|
15832
16121
|
} catch {
|
|
15833
16122
|
}
|
|
15834
|
-
const parent =
|
|
16123
|
+
const parent = path4.dirname(current);
|
|
15835
16124
|
if (parent === current) {
|
|
15836
16125
|
return void 0;
|
|
15837
16126
|
}
|
|
@@ -15839,7 +16128,7 @@ function findConfigFile(startDir) {
|
|
|
15839
16128
|
}
|
|
15840
16129
|
}
|
|
15841
16130
|
function cacheFilePath(cacheDir) {
|
|
15842
|
-
return
|
|
16131
|
+
return path4.join(cacheDir, "descriptors.json");
|
|
15843
16132
|
}
|
|
15844
16133
|
function readCache(cacheDir) {
|
|
15845
16134
|
try {
|
|
@@ -15964,7 +16253,7 @@ async function postEvent(options) {
|
|
|
15964
16253
|
error: error51 instanceof Error ? error51.message : String(error51)
|
|
15965
16254
|
};
|
|
15966
16255
|
}
|
|
15967
|
-
if (response.status >= 500) {
|
|
16256
|
+
if (response.status >= 500 || response.status === 429 || response.status === 408) {
|
|
15968
16257
|
return { kind: "unreachable", error: `server error (${response.status})` };
|
|
15969
16258
|
}
|
|
15970
16259
|
if (!response.ok) {
|
|
@@ -15992,13 +16281,14 @@ async function postEvent(options) {
|
|
|
15992
16281
|
}
|
|
15993
16282
|
var OUTBOX_FILE = "outbox.jsonl";
|
|
15994
16283
|
var MAX_OUTBOX_ENTRIES = 100;
|
|
16284
|
+
var STALE_CLAIM_MS = 30 * 60 * 1e3;
|
|
15995
16285
|
function outboxPath(env = process.env) {
|
|
15996
|
-
return
|
|
16286
|
+
return path5.join(feedbackHomeDir(env), OUTBOX_FILE);
|
|
15997
16287
|
}
|
|
15998
16288
|
function appendToOutbox(entry, env = process.env) {
|
|
15999
16289
|
try {
|
|
16000
16290
|
const file2 = outboxPath(env);
|
|
16001
|
-
mkdirSync2(
|
|
16291
|
+
mkdirSync2(path5.dirname(file2), { recursive: true });
|
|
16002
16292
|
appendFileSync(file2, `${JSON.stringify(entry)}
|
|
16003
16293
|
`);
|
|
16004
16294
|
return true;
|
|
@@ -16006,19 +16296,43 @@ function appendToOutbox(entry, env = process.env) {
|
|
|
16006
16296
|
return false;
|
|
16007
16297
|
}
|
|
16008
16298
|
}
|
|
16009
|
-
function
|
|
16299
|
+
function readEntries(file2) {
|
|
16010
16300
|
try {
|
|
16011
|
-
return readFileSync3(
|
|
16301
|
+
return readFileSync3(file2, "utf8").split("\n").filter((line) => line.trim()).flatMap((line) => {
|
|
16302
|
+
try {
|
|
16303
|
+
return [JSON.parse(line)];
|
|
16304
|
+
} catch {
|
|
16305
|
+
return [];
|
|
16306
|
+
}
|
|
16307
|
+
});
|
|
16012
16308
|
} catch {
|
|
16013
16309
|
return [];
|
|
16014
16310
|
}
|
|
16015
16311
|
}
|
|
16312
|
+
function claimQueue(env) {
|
|
16313
|
+
const file2 = outboxPath(env);
|
|
16314
|
+
let names;
|
|
16315
|
+
try {
|
|
16316
|
+
names = readdirSync(path5.dirname(file2));
|
|
16317
|
+
} catch {
|
|
16318
|
+
return [];
|
|
16319
|
+
}
|
|
16320
|
+
const claims = names.filter((name) => {
|
|
16321
|
+
const claimedAt = Number(/\.flushing-(\d+)-/.exec(name)?.[1]);
|
|
16322
|
+
return name.startsWith(OUTBOX_FILE) && Date.now() - claimedAt > STALE_CLAIM_MS;
|
|
16323
|
+
}).map((name) => path5.join(path5.dirname(file2), name));
|
|
16324
|
+
const fresh = `${file2}.flushing-${Date.now()}-${randomUUID()}`;
|
|
16325
|
+
try {
|
|
16326
|
+
renameSync(file2, fresh);
|
|
16327
|
+
claims.push(fresh);
|
|
16328
|
+
} catch {
|
|
16329
|
+
}
|
|
16330
|
+
return claims;
|
|
16331
|
+
}
|
|
16016
16332
|
async function flushOutbox(options = {}) {
|
|
16017
16333
|
const env = options.env ?? process.env;
|
|
16018
|
-
const
|
|
16019
|
-
|
|
16020
|
-
return { delivered: 0, remaining: 0 };
|
|
16021
|
-
}
|
|
16334
|
+
const claims = claimQueue(env);
|
|
16335
|
+
const entries = claims.flatMap(readEntries).slice(-MAX_OUTBOX_ENTRIES);
|
|
16022
16336
|
const failures = [];
|
|
16023
16337
|
let delivered = 0;
|
|
16024
16338
|
for (const entry of entries) {
|
|
@@ -16035,23 +16349,194 @@ async function flushOutbox(options = {}) {
|
|
|
16035
16349
|
failures.push(entry);
|
|
16036
16350
|
}
|
|
16037
16351
|
}
|
|
16038
|
-
|
|
16039
|
-
|
|
16040
|
-
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
16352
|
+
if (failures.every((entry) => appendToOutbox(entry, env))) {
|
|
16353
|
+
for (const claim of claims) {
|
|
16354
|
+
try {
|
|
16355
|
+
rmSync(claim, { force: true });
|
|
16356
|
+
} catch {
|
|
16357
|
+
}
|
|
16358
|
+
}
|
|
16044
16359
|
}
|
|
16045
16360
|
return { delivered, remaining: failures.length };
|
|
16046
16361
|
}
|
|
16362
|
+
async function resolveApiOrigin(options) {
|
|
16363
|
+
if (!options.to && !options.dsn) {
|
|
16364
|
+
return new URL(DEFAULT_REGISTRY_URL).origin;
|
|
16365
|
+
}
|
|
16366
|
+
const destination = await resolveDestination({
|
|
16367
|
+
...options.to !== void 0 ? { to: options.to } : {},
|
|
16368
|
+
...options.dsn !== void 0 ? { dsn: options.dsn } : {},
|
|
16369
|
+
...options.env ? { env: options.env } : {},
|
|
16370
|
+
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}
|
|
16371
|
+
});
|
|
16372
|
+
return new URL(destination.endpoint).origin;
|
|
16373
|
+
}
|
|
16374
|
+
function ownerApi(options) {
|
|
16375
|
+
const origin = (options.apiOrigin ?? new URL(DEFAULT_REGISTRY_URL).origin).replace(/\/$/, "");
|
|
16376
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
16377
|
+
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
16378
|
+
async function request(path6, init) {
|
|
16379
|
+
let response;
|
|
16380
|
+
try {
|
|
16381
|
+
response = await fetchImpl(`${origin}${path6}`, {
|
|
16382
|
+
...init,
|
|
16383
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
16384
|
+
headers: {
|
|
16385
|
+
authorization: `Bearer ${options.secretKey}`,
|
|
16386
|
+
...init?.body ? { "content-type": "application/json" } : {},
|
|
16387
|
+
...init?.headers
|
|
16388
|
+
}
|
|
16389
|
+
});
|
|
16390
|
+
} catch (error51) {
|
|
16391
|
+
throw new FeedbackError(
|
|
16392
|
+
`Could not reach ${origin} (${error51 instanceof Error ? error51.message : String(error51)}).`
|
|
16393
|
+
);
|
|
16394
|
+
}
|
|
16395
|
+
let body;
|
|
16396
|
+
try {
|
|
16397
|
+
body = await response.json();
|
|
16398
|
+
} catch {
|
|
16399
|
+
body = void 0;
|
|
16400
|
+
}
|
|
16401
|
+
if (!response.ok) {
|
|
16402
|
+
const errors = body?.errors;
|
|
16403
|
+
throw new FeedbackError(
|
|
16404
|
+
Array.isArray(errors) ? errors.map(String).join("; ") : `Request failed (${response.status}).`
|
|
16405
|
+
);
|
|
16406
|
+
}
|
|
16407
|
+
return body;
|
|
16408
|
+
}
|
|
16409
|
+
async function upload(paths, cwd) {
|
|
16410
|
+
return uploadFiles({
|
|
16411
|
+
endpoint: origin,
|
|
16412
|
+
files: await readLocalAttachments(paths, cwd),
|
|
16413
|
+
secretKey: options.secretKey,
|
|
16414
|
+
fetchImpl,
|
|
16415
|
+
timeoutMs: Math.max(timeoutMs, 6e4)
|
|
16416
|
+
});
|
|
16417
|
+
}
|
|
16418
|
+
return {
|
|
16419
|
+
/** Upload local files and attach them to a record (at most 10 files per record). */
|
|
16420
|
+
async attachFiles(target, paths, cwd) {
|
|
16421
|
+
if (!paths.length) throw new FeedbackError("Select at least one file.");
|
|
16422
|
+
const attachments = await upload(paths, cwd);
|
|
16423
|
+
return request("/v1/attachments/attach", {
|
|
16424
|
+
method: "POST",
|
|
16425
|
+
body: JSON.stringify({ target, attachments })
|
|
16426
|
+
});
|
|
16427
|
+
},
|
|
16428
|
+
/** A record's files; issues and evals include their reports' files. */
|
|
16429
|
+
async listAttachments(target, offset = 0) {
|
|
16430
|
+
return request(
|
|
16431
|
+
`/v1/attachments?${new URLSearchParams({ type: target.type, id: target.id, offset: String(offset) })}`
|
|
16432
|
+
);
|
|
16433
|
+
},
|
|
16434
|
+
async deleteAttachment(id) {
|
|
16435
|
+
return request(`/v1/attachments/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
16436
|
+
},
|
|
16437
|
+
async listFeedback(filters = {}) {
|
|
16438
|
+
const params = new URLSearchParams();
|
|
16439
|
+
if (filters.status) params.set("status", filters.status);
|
|
16440
|
+
if (filters.category) params.set("category", filters.category);
|
|
16441
|
+
if (filters.thread) params.set("thread", filters.thread);
|
|
16442
|
+
if (filters.since) params.set("since", filters.since);
|
|
16443
|
+
if (filters.limit) params.set("limit", String(filters.limit));
|
|
16444
|
+
const query = params.toString();
|
|
16445
|
+
return request(`/v1/events${query ? `?${query}` : ""}`);
|
|
16446
|
+
},
|
|
16447
|
+
async getFeedback(id) {
|
|
16448
|
+
return request(`/v1/events/${encodeURIComponent(id)}`);
|
|
16449
|
+
},
|
|
16450
|
+
async setFeedbackStatus(id, status, note) {
|
|
16451
|
+
return request(`/v1/events/${encodeURIComponent(id)}`, {
|
|
16452
|
+
method: "PATCH",
|
|
16453
|
+
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16454
|
+
});
|
|
16455
|
+
},
|
|
16456
|
+
async listIssues(filters = {}) {
|
|
16457
|
+
const params = new URLSearchParams();
|
|
16458
|
+
if (filters.status) params.set("status", filters.status);
|
|
16459
|
+
if (filters.since) params.set("since", filters.since);
|
|
16460
|
+
if (filters.limit) params.set("limit", String(filters.limit));
|
|
16461
|
+
const query = params.toString();
|
|
16462
|
+
return request(`/v1/issues${query ? `?${query}` : ""}`);
|
|
16463
|
+
},
|
|
16464
|
+
async getIssue(id) {
|
|
16465
|
+
return request(`/v1/issues/${encodeURIComponent(id)}`);
|
|
16466
|
+
},
|
|
16467
|
+
async setIssueStatus(id, status, note) {
|
|
16468
|
+
return request(`/v1/issues/${encodeURIComponent(id)}`, {
|
|
16469
|
+
method: "PATCH",
|
|
16470
|
+
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16471
|
+
});
|
|
16472
|
+
},
|
|
16473
|
+
async listQuestions(filters = {}) {
|
|
16474
|
+
const query = filters.status ? `?status=${filters.status}` : "";
|
|
16475
|
+
return request(`/v1/questions${query}`);
|
|
16476
|
+
},
|
|
16477
|
+
/** Files are shared with every agent that receives the question. */
|
|
16478
|
+
async createQuestion(prompt, category, options2 = {}) {
|
|
16479
|
+
const attachments = options2.files?.length ? await upload(options2.files, options2.cwd) : [];
|
|
16480
|
+
return request("/v1/questions", {
|
|
16481
|
+
method: "POST",
|
|
16482
|
+
body: JSON.stringify({
|
|
16483
|
+
prompt,
|
|
16484
|
+
...category ? { category } : {},
|
|
16485
|
+
...attachments.length ? { attachments } : {},
|
|
16486
|
+
...options2.idempotencyKey ? { idempotencyKey: options2.idempotencyKey } : {}
|
|
16487
|
+
})
|
|
16488
|
+
});
|
|
16489
|
+
},
|
|
16490
|
+
async closeQuestion(id) {
|
|
16491
|
+
return request(`/v1/questions/${encodeURIComponent(id)}`, {
|
|
16492
|
+
method: "PATCH",
|
|
16493
|
+
body: JSON.stringify({ status: "closed" })
|
|
16494
|
+
});
|
|
16495
|
+
},
|
|
16496
|
+
async listEvals(filters = {}) {
|
|
16497
|
+
const query = filters.status ? `?status=${filters.status}` : "";
|
|
16498
|
+
return request(`/v1/evals${query}`);
|
|
16499
|
+
},
|
|
16500
|
+
async getEval(id) {
|
|
16501
|
+
return request(`/v1/evals/${encodeURIComponent(id)}`);
|
|
16502
|
+
},
|
|
16503
|
+
/** Promote a failed-task report (category=eval event) into the eval corpus. */
|
|
16504
|
+
async promoteEval(eventId) {
|
|
16505
|
+
return request("/v1/evals", {
|
|
16506
|
+
method: "POST",
|
|
16507
|
+
body: JSON.stringify({ event_id: eventId })
|
|
16508
|
+
});
|
|
16509
|
+
},
|
|
16510
|
+
async setEvalStatus(id, status, note) {
|
|
16511
|
+
return request(`/v1/evals/${encodeURIComponent(id)}`, {
|
|
16512
|
+
method: "PATCH",
|
|
16513
|
+
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16514
|
+
});
|
|
16515
|
+
},
|
|
16516
|
+
/** Attach an external link (Slack message, Linear/GitHub issue, PR) to evt_… or iss_…. */
|
|
16517
|
+
async addLink(id, url2, label) {
|
|
16518
|
+
const path6 = id.startsWith("iss_") ? `/v1/issues/${id}` : `/v1/events/${id}`;
|
|
16519
|
+
return request(path6, {
|
|
16520
|
+
method: "PATCH",
|
|
16521
|
+
body: JSON.stringify({ addLink: { url: url2, ...label !== void 0 ? { label } : {} } })
|
|
16522
|
+
});
|
|
16523
|
+
}
|
|
16524
|
+
};
|
|
16525
|
+
}
|
|
16047
16526
|
function mintIdempotencyKey() {
|
|
16048
16527
|
return randomBytes(16).toString("hex");
|
|
16049
16528
|
}
|
|
16050
16529
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
16051
16530
|
var DEFAULT_CLIENT_NAME = "hivenet";
|
|
16052
|
-
var DEFAULT_CLIENT_VERSION =
|
|
16531
|
+
var DEFAULT_CLIENT_VERSION = (() => {
|
|
16532
|
+
try {
|
|
16533
|
+
return createRequire(import.meta.url)("../package.json").version ?? "0";
|
|
16534
|
+
} catch {
|
|
16535
|
+
return "0";
|
|
16536
|
+
}
|
|
16537
|
+
})();
|
|
16053
16538
|
function generateThreadId() {
|
|
16054
|
-
return randomBytes(
|
|
16539
|
+
return randomBytes(16).toString("hex");
|
|
16055
16540
|
}
|
|
16056
16541
|
function resolveThreadId(resume) {
|
|
16057
16542
|
if (resume !== void 0 && THREAD_ID_PATTERN.test(resume)) {
|
|
@@ -16059,9 +16544,10 @@ function resolveThreadId(resume) {
|
|
|
16059
16544
|
}
|
|
16060
16545
|
return { id: generateThreadId(), resumed: false };
|
|
16061
16546
|
}
|
|
16062
|
-
async function
|
|
16547
|
+
async function prepareFeedback(options) {
|
|
16063
16548
|
const env = options.env ?? process.env;
|
|
16064
16549
|
const cwd = options.cwd ?? process.cwd();
|
|
16550
|
+
const files = await readLocalAttachments(options.attachments ?? [], cwd);
|
|
16065
16551
|
const config2 = findConfigFile(cwd)?.config;
|
|
16066
16552
|
const resolveOptions = {
|
|
16067
16553
|
...options.to !== void 0 ? { to: options.to } : {},
|
|
@@ -16097,6 +16583,7 @@ async function sendFeedback(options) {
|
|
|
16097
16583
|
...author ? { author } : {},
|
|
16098
16584
|
thread: { id: thread.id },
|
|
16099
16585
|
...options.eval ? { eval: options.eval } : {},
|
|
16586
|
+
...options.question ? { question: options.question } : {},
|
|
16100
16587
|
...context ? { context } : {},
|
|
16101
16588
|
...options.metadata && Object.keys(options.metadata).length > 0 ? { metadata: options.metadata } : {},
|
|
16102
16589
|
// Minted before the first attempt so outbox retries replay the SAME event
|
|
@@ -16112,7 +16599,32 @@ async function sendFeedback(options) {
|
|
|
16112
16599
|
if (!validated.ok) {
|
|
16113
16600
|
throw new FeedbackError(`Invalid feedback event: ${validated.errors.join("; ")}`);
|
|
16114
16601
|
}
|
|
16115
|
-
|
|
16602
|
+
return { event: validated.data, destination, resumed: thread.resumed, files };
|
|
16603
|
+
}
|
|
16604
|
+
async function sendFeedback(options) {
|
|
16605
|
+
const env = options.env ?? process.env;
|
|
16606
|
+
const { event, destination, resumed, files } = await prepareFeedback(options);
|
|
16607
|
+
const names = files.map((file2) => file2.manifest.filename);
|
|
16608
|
+
let filesNotAttached;
|
|
16609
|
+
if (files.length) {
|
|
16610
|
+
try {
|
|
16611
|
+
event.attachments = await uploadFiles({
|
|
16612
|
+
endpoint: destination.endpoint,
|
|
16613
|
+
files,
|
|
16614
|
+
...destination.to ? { to: destination.to } : {},
|
|
16615
|
+
...destination.writeKey ? { writeKey: destination.writeKey } : {},
|
|
16616
|
+
...event.context?.agent?.id ? { uploader: event.context.agent.id } : {},
|
|
16617
|
+
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}
|
|
16618
|
+
});
|
|
16619
|
+
} catch (error51) {
|
|
16620
|
+
if (!(error51 instanceof AttachmentUploadError) || error51.rejected) {
|
|
16621
|
+
throw new FeedbackError(
|
|
16622
|
+
`${error51 instanceof Error ? error51.message : String(error51)} Nothing was sent.`
|
|
16623
|
+
);
|
|
16624
|
+
}
|
|
16625
|
+
filesNotAttached = { files: names, reason: error51.message };
|
|
16626
|
+
}
|
|
16627
|
+
}
|
|
16116
16628
|
const result = await postEvent({
|
|
16117
16629
|
endpoint: destination.endpoint,
|
|
16118
16630
|
...destination.writeKey ? { writeKey: destination.writeKey } : {},
|
|
@@ -16126,12 +16638,17 @@ async function sendFeedback(options) {
|
|
|
16126
16638
|
response: result.response,
|
|
16127
16639
|
event,
|
|
16128
16640
|
destination,
|
|
16129
|
-
resumed
|
|
16641
|
+
resumed,
|
|
16642
|
+
...filesNotAttached ? { filesNotAttached } : {}
|
|
16130
16643
|
};
|
|
16131
16644
|
}
|
|
16132
16645
|
if (result.kind === "rejected") {
|
|
16133
16646
|
throw new FeedbackError(`Feedback rejected: ${result.errors.join("; ")}`);
|
|
16134
16647
|
}
|
|
16648
|
+
if (event.attachments) {
|
|
16649
|
+
delete event.attachments;
|
|
16650
|
+
filesNotAttached = { files: names, reason: result.error };
|
|
16651
|
+
}
|
|
16135
16652
|
const queued = options.outbox !== false && appendToOutbox(
|
|
16136
16653
|
{
|
|
16137
16654
|
endpoint: destination.endpoint,
|
|
@@ -16147,116 +16664,40 @@ async function sendFeedback(options) {
|
|
|
16147
16664
|
error: result.error,
|
|
16148
16665
|
event,
|
|
16149
16666
|
destination,
|
|
16150
|
-
resumed
|
|
16151
|
-
|
|
16152
|
-
}
|
|
16153
|
-
async function resolveApiOrigin(options) {
|
|
16154
|
-
if (!options.to && !options.dsn) {
|
|
16155
|
-
return new URL(DEFAULT_REGISTRY_URL).origin;
|
|
16156
|
-
}
|
|
16157
|
-
const destination = await resolveDestination({
|
|
16158
|
-
...options.to !== void 0 ? { to: options.to } : {},
|
|
16159
|
-
...options.dsn !== void 0 ? { dsn: options.dsn } : {},
|
|
16160
|
-
...options.env ? { env: options.env } : {},
|
|
16161
|
-
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}
|
|
16162
|
-
});
|
|
16163
|
-
return new URL(destination.endpoint).origin;
|
|
16164
|
-
}
|
|
16165
|
-
function ownerApi(options) {
|
|
16166
|
-
const origin = (options.apiOrigin ?? new URL(DEFAULT_REGISTRY_URL).origin).replace(/\/$/, "");
|
|
16167
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
16168
|
-
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
16169
|
-
async function request(path5, init) {
|
|
16170
|
-
let response;
|
|
16171
|
-
try {
|
|
16172
|
-
response = await fetchImpl(`${origin}${path5}`, {
|
|
16173
|
-
...init,
|
|
16174
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
16175
|
-
headers: {
|
|
16176
|
-
authorization: `Bearer ${options.secretKey}`,
|
|
16177
|
-
...init?.body ? { "content-type": "application/json" } : {},
|
|
16178
|
-
...init?.headers
|
|
16179
|
-
}
|
|
16180
|
-
});
|
|
16181
|
-
} catch (error51) {
|
|
16182
|
-
throw new FeedbackError(
|
|
16183
|
-
`Could not reach ${origin} (${error51 instanceof Error ? error51.message : String(error51)}).`
|
|
16184
|
-
);
|
|
16185
|
-
}
|
|
16186
|
-
let body;
|
|
16187
|
-
try {
|
|
16188
|
-
body = await response.json();
|
|
16189
|
-
} catch {
|
|
16190
|
-
body = void 0;
|
|
16191
|
-
}
|
|
16192
|
-
if (!response.ok) {
|
|
16193
|
-
const errors = body?.errors;
|
|
16194
|
-
throw new FeedbackError(
|
|
16195
|
-
Array.isArray(errors) ? errors.map(String).join("; ") : `Request failed (${response.status}).`
|
|
16196
|
-
);
|
|
16197
|
-
}
|
|
16198
|
-
return body;
|
|
16199
|
-
}
|
|
16200
|
-
return {
|
|
16201
|
-
async listFeedback(filters = {}) {
|
|
16202
|
-
const params = new URLSearchParams();
|
|
16203
|
-
if (filters.status) params.set("status", filters.status);
|
|
16204
|
-
if (filters.category) params.set("category", filters.category);
|
|
16205
|
-
if (filters.thread) params.set("thread", filters.thread);
|
|
16206
|
-
if (filters.since) params.set("since", filters.since);
|
|
16207
|
-
if (filters.limit) params.set("limit", String(filters.limit));
|
|
16208
|
-
const query = params.toString();
|
|
16209
|
-
return request(`/v1/events${query ? `?${query}` : ""}`);
|
|
16210
|
-
},
|
|
16211
|
-
async getFeedback(id) {
|
|
16212
|
-
return request(`/v1/events/${encodeURIComponent(id)}`);
|
|
16213
|
-
},
|
|
16214
|
-
async setFeedbackStatus(id, status, note) {
|
|
16215
|
-
return request(`/v1/events/${encodeURIComponent(id)}`, {
|
|
16216
|
-
method: "PATCH",
|
|
16217
|
-
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16218
|
-
});
|
|
16219
|
-
},
|
|
16220
|
-
async listIssues(filters = {}) {
|
|
16221
|
-
const params = new URLSearchParams();
|
|
16222
|
-
if (filters.status) params.set("status", filters.status);
|
|
16223
|
-
if (filters.since) params.set("since", filters.since);
|
|
16224
|
-
if (filters.limit) params.set("limit", String(filters.limit));
|
|
16225
|
-
const query = params.toString();
|
|
16226
|
-
return request(`/v1/issues${query ? `?${query}` : ""}`);
|
|
16227
|
-
},
|
|
16228
|
-
async getIssue(id) {
|
|
16229
|
-
return request(`/v1/issues/${encodeURIComponent(id)}`);
|
|
16230
|
-
},
|
|
16231
|
-
async setIssueStatus(id, status, note) {
|
|
16232
|
-
return request(`/v1/issues/${encodeURIComponent(id)}`, {
|
|
16233
|
-
method: "PATCH",
|
|
16234
|
-
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16235
|
-
});
|
|
16236
|
-
},
|
|
16237
|
-
/** Attach an external link (Slack message, Linear/GitHub issue, PR) to evt_… or iss_…. */
|
|
16238
|
-
async addLink(id, url2, label) {
|
|
16239
|
-
const path5 = id.startsWith("iss_") ? `/v1/issues/${id}` : `/v1/events/${id}`;
|
|
16240
|
-
return request(path5, {
|
|
16241
|
-
method: "PATCH",
|
|
16242
|
-
body: JSON.stringify({ addLink: { url: url2, ...label !== void 0 ? { label } : {} } })
|
|
16243
|
-
});
|
|
16244
|
-
}
|
|
16667
|
+
resumed,
|
|
16668
|
+
...filesNotAttached ? { filesNotAttached } : {}
|
|
16245
16669
|
};
|
|
16246
16670
|
}
|
|
16247
16671
|
|
|
16248
16672
|
export {
|
|
16249
16673
|
__toESM,
|
|
16674
|
+
external_exports,
|
|
16675
|
+
MAX_ATTACHMENTS,
|
|
16676
|
+
attachmentDescriptionSchema,
|
|
16677
|
+
ATTACHMENT_TARGET_TYPES,
|
|
16678
|
+
attachmentTargetSchema,
|
|
16679
|
+
PROTOCOL_VERSION,
|
|
16250
16680
|
MAX_FEEDBACK_LENGTH,
|
|
16681
|
+
WELL_KNOWN_PATH,
|
|
16251
16682
|
FEEDBACK_CATEGORIES,
|
|
16252
16683
|
EVENT_STATUSES,
|
|
16253
16684
|
ISSUE_STATUSES,
|
|
16685
|
+
EVAL_STATUSES,
|
|
16254
16686
|
sentimentSchema,
|
|
16255
16687
|
authorSchema,
|
|
16688
|
+
evalReportSchema,
|
|
16689
|
+
feedbackEventSchema,
|
|
16690
|
+
validateFeedbackEvent,
|
|
16691
|
+
validateDescriptor,
|
|
16256
16692
|
FeedbackError,
|
|
16693
|
+
parseDsn,
|
|
16694
|
+
registryUrl,
|
|
16695
|
+
postEvent,
|
|
16257
16696
|
flushOutbox,
|
|
16258
|
-
sendFeedback,
|
|
16259
16697
|
resolveApiOrigin,
|
|
16260
16698
|
ownerApi,
|
|
16699
|
+
generateThreadId,
|
|
16700
|
+
prepareFeedback,
|
|
16701
|
+
sendFeedback,
|
|
16261
16702
|
require_arg
|
|
16262
16703
|
};
|