hivenet 0.4.2 → 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 +55 -0
- package/dist/chunk-AK23JXBN.js +32 -0
- package/dist/{chunk-WWPF6V2Y.js → chunk-DNR6HNJD.js} +484 -70
- package/dist/cli.js +323 -66
- package/dist/{doctor-CVWF7J3P.js → doctor-EA2GJRUS.js} +1 -1
- package/dist/index.cjs +868 -460
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +384 -31
- package/dist/index.d.ts +384 -31
- package/dist/index.js +863 -457
- package/dist/index.js.map +1 -1
- package/dist/owner-ZWROA7AU.js +539 -0
- package/package.json +1 -1
- package/dist/owner-N2MSYLV7.js +0 -257
package/dist/owner-N2MSYLV7.js
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EVENT_STATUSES,
|
|
3
|
-
FeedbackError,
|
|
4
|
-
ISSUE_STATUSES,
|
|
5
|
-
__toESM,
|
|
6
|
-
ownerApi,
|
|
7
|
-
require_arg,
|
|
8
|
-
resolveApiOrigin
|
|
9
|
-
} from "./chunk-WWPF6V2Y.js";
|
|
10
|
-
|
|
11
|
-
// src/owner.ts
|
|
12
|
-
var import_arg = __toESM(require_arg(), 1);
|
|
13
|
-
var SECRET_ENV_VAR = "HIVENET_SECRET_KEY";
|
|
14
|
-
var OWNER_FLAGS = {
|
|
15
|
-
"--to": String,
|
|
16
|
-
"--dsn": String,
|
|
17
|
-
"--api": String,
|
|
18
|
-
"--secret": String,
|
|
19
|
-
"--json": Boolean,
|
|
20
|
-
"--help": Boolean,
|
|
21
|
-
"-h": "--help"
|
|
22
|
-
};
|
|
23
|
-
async function buildApi(args) {
|
|
24
|
-
const secretKey = args["--secret"] ?? process.env[SECRET_ENV_VAR];
|
|
25
|
-
if (!secretKey?.startsWith("hv_sec_")) {
|
|
26
|
-
throw new FeedbackError(
|
|
27
|
-
`An owner secret key is required (hv_sec_\u2026, from your project's Settings).
|
|
28
|
-
Pass --secret <key> or set ${SECRET_ENV_VAR}.`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
const apiOrigin = args["--api"] ?? await resolveApiOrigin({
|
|
32
|
-
...args["--to"] !== void 0 ? { to: args["--to"] } : {},
|
|
33
|
-
...args["--dsn"] !== void 0 ? { dsn: args["--dsn"] } : {}
|
|
34
|
-
});
|
|
35
|
-
return ownerApi({ secretKey, apiOrigin });
|
|
36
|
-
}
|
|
37
|
-
function statusIcon(status) {
|
|
38
|
-
return { new: "\u25CF", seen: "\u25D0", in_progress: "\u25D2", resolved: "\u2713", wont_fix: "\u2717", spam: "\u2298" }[status];
|
|
39
|
-
}
|
|
40
|
-
function printEvent(event, verbose = false) {
|
|
41
|
-
const subject = event.subject ? ` \xB7 ${event.subject}` : "";
|
|
42
|
-
console.log(
|
|
43
|
-
`${statusIcon(event.status)} ${event.id} [${event.status}] ${event.category}${subject} (${event.agent_id ?? event.author ?? "unknown"}, ${event.received_at.slice(0, 16).replace("T", " ")})`
|
|
44
|
-
);
|
|
45
|
-
console.log(` ${event.feedback}`);
|
|
46
|
-
if (event.triage_note) {
|
|
47
|
-
console.log(` \u21B3 note: ${event.triage_note}`);
|
|
48
|
-
}
|
|
49
|
-
if (verbose) {
|
|
50
|
-
console.log(
|
|
51
|
-
` thread ${event.thread_id} \xB7 telemetry ${event.consent_telemetry ? "on" : "off"}`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
async function runInbox(argv) {
|
|
56
|
-
const args = (0, import_arg.default)(
|
|
57
|
-
{
|
|
58
|
-
...OWNER_FLAGS,
|
|
59
|
-
"--status": String,
|
|
60
|
-
"--category": String,
|
|
61
|
-
"--thread": String,
|
|
62
|
-
"--limit": Number
|
|
63
|
-
},
|
|
64
|
-
{ argv }
|
|
65
|
-
);
|
|
66
|
-
if (args["--help"]) {
|
|
67
|
-
console.log(`
|
|
68
|
-
Usage
|
|
69
|
-
$ npx hivenet inbox [--status new] [--category mcp] [--thread <id>] [--limit 50]
|
|
70
|
-
|
|
71
|
-
List feedback for your project (owners only). Auth: --secret <hv_sec_\u2026> or
|
|
72
|
-
${SECRET_ENV_VAR}. Destination: --to <slug|domain>, --dsn, or --api <origin>
|
|
73
|
-
(defaults to the hosted API). Statuses: ${EVENT_STATUSES.join(" | ")}. --json for raw output.
|
|
74
|
-
`);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const status = args["--status"];
|
|
78
|
-
if (status && !EVENT_STATUSES.includes(status)) {
|
|
79
|
-
throw new FeedbackError(
|
|
80
|
-
`Invalid --status "${status}". Expected: ${EVENT_STATUSES.join(", ")}.`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
const api = await buildApi(args);
|
|
84
|
-
const result = await api.listFeedback({
|
|
85
|
-
...status ? { status } : {},
|
|
86
|
-
...args["--category"] ? { category: args["--category"] } : {},
|
|
87
|
-
...args["--thread"] ? { thread: args["--thread"] } : {},
|
|
88
|
-
...args["--limit"] ? { limit: args["--limit"] } : {}
|
|
89
|
-
});
|
|
90
|
-
if (args["--json"]) {
|
|
91
|
-
console.log(JSON.stringify(result, null, 2));
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (result.events.length === 0) {
|
|
95
|
-
console.log(`No matching feedback for ${result.project}.`);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
console.log(`${result.events.length} event(s) for ${result.project}:
|
|
99
|
-
`);
|
|
100
|
-
for (const event of result.events) {
|
|
101
|
-
printEvent(event);
|
|
102
|
-
}
|
|
103
|
-
console.log(
|
|
104
|
-
`
|
|
105
|
-
Triage: npx hivenet triage <eventId> --status <${EVENT_STATUSES.join("|")}> [--note "\u2026"]`
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
async function runTriage(argv) {
|
|
109
|
-
const args = (0, import_arg.default)(
|
|
110
|
-
{ ...OWNER_FLAGS, "--status": String, "--note": String, "--link": String },
|
|
111
|
-
{ argv }
|
|
112
|
-
);
|
|
113
|
-
if (args["--help"] || args._.length === 0) {
|
|
114
|
-
console.log(`
|
|
115
|
-
Usage
|
|
116
|
-
$ npx hivenet triage <eventId> [--status <status>] [--note "why"] [--link <url>]
|
|
117
|
-
|
|
118
|
-
Set triage status and/or attach an external link (Slack, Linear, GitHub, PR) to a
|
|
119
|
-
feedback event (owners only). Statuses: ${EVENT_STATUSES.join(" | ")}.
|
|
120
|
-
Auth: --secret <hv_sec_\u2026> or ${SECRET_ENV_VAR}. Destination: --to/--dsn/--api.
|
|
121
|
-
`);
|
|
122
|
-
if (!args["--help"]) {
|
|
123
|
-
throw new FeedbackError("An event ID is required.");
|
|
124
|
-
}
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
const status = args["--status"];
|
|
128
|
-
if (status && !EVENT_STATUSES.includes(status)) {
|
|
129
|
-
throw new FeedbackError(`Invalid --status. Expected: ${EVENT_STATUSES.join(", ")}.`);
|
|
130
|
-
}
|
|
131
|
-
if (!status && !args["--link"]) {
|
|
132
|
-
throw new FeedbackError("Provide --status and/or --link.");
|
|
133
|
-
}
|
|
134
|
-
const api = await buildApi(args);
|
|
135
|
-
const id = args._[0];
|
|
136
|
-
if (args["--link"]) {
|
|
137
|
-
await api.addLink(id, args["--link"]);
|
|
138
|
-
}
|
|
139
|
-
const event = status ? (await api.setFeedbackStatus(
|
|
140
|
-
id,
|
|
141
|
-
status,
|
|
142
|
-
args["--note"] !== void 0 ? args["--note"] : void 0
|
|
143
|
-
)).event : (await api.getFeedback(id)).event;
|
|
144
|
-
if (args["--json"]) {
|
|
145
|
-
console.log(JSON.stringify({ event }, null, 2));
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
console.log("Updated:");
|
|
149
|
-
printEvent(event, true);
|
|
150
|
-
printLinks(event.links_json);
|
|
151
|
-
}
|
|
152
|
-
function printLinks(linksJson) {
|
|
153
|
-
try {
|
|
154
|
-
const links = JSON.parse(linksJson ?? "[]");
|
|
155
|
-
for (const link of links) {
|
|
156
|
-
console.log(` \u21C4 ${link.kind}: ${link.url}`);
|
|
157
|
-
}
|
|
158
|
-
} catch {
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function issueIcon(status) {
|
|
162
|
-
return { open: "\u25CF", in_progress: "\u25D2", resolved: "\u2713", wont_fix: "\u2717", spam: "\u2298" }[status];
|
|
163
|
-
}
|
|
164
|
-
function printIssue(issue) {
|
|
165
|
-
const regressed = issue.reopened_count > 0 ? ` \u21BB regressed \xD7${issue.reopened_count}` : "";
|
|
166
|
-
console.log(
|
|
167
|
-
`${issueIcon(issue.status)} ${issue.id} [${issue.status}] ${issue.title} (${issue.event_count} event${issue.event_count === 1 ? "" : "s"}, last ${issue.last_seen.slice(0, 16).replace("T", " ")})${regressed}`
|
|
168
|
-
);
|
|
169
|
-
printLinks(issue.links_json);
|
|
170
|
-
}
|
|
171
|
-
async function runIssues(argv) {
|
|
172
|
-
const args = (0, import_arg.default)({ ...OWNER_FLAGS, "--status": String, "--limit": Number }, { argv });
|
|
173
|
-
if (args["--help"]) {
|
|
174
|
-
console.log(`
|
|
175
|
-
Usage
|
|
176
|
-
$ npx hivenet issues [--status open] [--limit 50]
|
|
177
|
-
|
|
178
|
-
List issues \u2014 feedback clustered by thread and (category, subject) fingerprint.
|
|
179
|
-
Statuses: ${ISSUE_STATUSES.join(" | ")}. Auth: --secret or ${SECRET_ENV_VAR}.
|
|
180
|
-
Manage one: npx hivenet issue <issueId> --status resolved --note "\u2026" --link <url>
|
|
181
|
-
`);
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
const status = args["--status"];
|
|
185
|
-
if (status && !ISSUE_STATUSES.includes(status)) {
|
|
186
|
-
throw new FeedbackError(`Invalid --status. Expected: ${ISSUE_STATUSES.join(", ")}.`);
|
|
187
|
-
}
|
|
188
|
-
const api = await buildApi(args);
|
|
189
|
-
const result = await api.listIssues({
|
|
190
|
-
...status ? { status } : {},
|
|
191
|
-
...args["--limit"] ? { limit: args["--limit"] } : {}
|
|
192
|
-
});
|
|
193
|
-
if (args["--json"]) {
|
|
194
|
-
console.log(JSON.stringify(result, null, 2));
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
if (result.issues.length === 0) {
|
|
198
|
-
console.log(`No matching issues for ${result.project}.`);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
console.log(`${result.issues.length} issue(s) for ${result.project}:
|
|
202
|
-
`);
|
|
203
|
-
for (const issue of result.issues) {
|
|
204
|
-
printIssue(issue);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
async function runIssue(argv) {
|
|
208
|
-
const args = (0, import_arg.default)(
|
|
209
|
-
{ ...OWNER_FLAGS, "--status": String, "--note": String, "--link": String },
|
|
210
|
-
{ argv }
|
|
211
|
-
);
|
|
212
|
-
if (args["--help"] || args._.length === 0) {
|
|
213
|
-
console.log(`
|
|
214
|
-
Usage
|
|
215
|
-
$ npx hivenet issue <issueId> (show with events)
|
|
216
|
-
$ npx hivenet issue <issueId> --status resolved --note "\u2026" --link <url>
|
|
217
|
-
|
|
218
|
-
Statuses: ${ISSUE_STATUSES.join(" | ")}. Resolving cascades to member events; new
|
|
219
|
-
feedback on a resolved issue reopens it. Auth: --secret or ${SECRET_ENV_VAR}.
|
|
220
|
-
`);
|
|
221
|
-
if (!args["--help"]) {
|
|
222
|
-
throw new FeedbackError("An issue ID is required.");
|
|
223
|
-
}
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
const status = args["--status"];
|
|
227
|
-
if (status && !ISSUE_STATUSES.includes(status)) {
|
|
228
|
-
throw new FeedbackError(`Invalid --status. Expected: ${ISSUE_STATUSES.join(", ")}.`);
|
|
229
|
-
}
|
|
230
|
-
const api = await buildApi(args);
|
|
231
|
-
const id = args._[0];
|
|
232
|
-
if (args["--link"]) {
|
|
233
|
-
await api.addLink(id, args["--link"]);
|
|
234
|
-
}
|
|
235
|
-
if (status) {
|
|
236
|
-
await api.setIssueStatus(id, status, args["--note"] !== void 0 ? args["--note"] : void 0);
|
|
237
|
-
}
|
|
238
|
-
const { issue, events } = await api.getIssue(id);
|
|
239
|
-
if (args["--json"]) {
|
|
240
|
-
console.log(JSON.stringify({ issue, events }, null, 2));
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
printIssue(issue);
|
|
244
|
-
if (issue.summary) {
|
|
245
|
-
console.log(` ${issue.summary}`);
|
|
246
|
-
}
|
|
247
|
-
console.log("");
|
|
248
|
-
for (const event of events) {
|
|
249
|
-
printEvent(event);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
export {
|
|
253
|
-
runInbox,
|
|
254
|
-
runIssue,
|
|
255
|
-
runIssues,
|
|
256
|
-
runTriage
|
|
257
|
-
};
|