@allocator-one/harness-cli 1.0.0 → 1.0.1
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.
|
@@ -108,7 +108,11 @@ var Client = class {
|
|
|
108
108
|
async getBytes(path2) {
|
|
109
109
|
const response = await this.raw("GET", path2, {});
|
|
110
110
|
if (!response.ok) throw await this.toHttpError(response);
|
|
111
|
-
|
|
111
|
+
try {
|
|
112
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw new TransportError(transportMessage(error));
|
|
115
|
+
}
|
|
112
116
|
}
|
|
113
117
|
/**
|
|
114
118
|
* The server's API version, for `version`'s server side. The header rides
|
|
@@ -155,7 +159,12 @@ var Client = class {
|
|
|
155
159
|
}
|
|
156
160
|
async json(response) {
|
|
157
161
|
if (!response.ok) throw await this.toHttpError(response);
|
|
158
|
-
|
|
162
|
+
let text;
|
|
163
|
+
try {
|
|
164
|
+
text = await response.text();
|
|
165
|
+
} catch (error) {
|
|
166
|
+
throw new TransportError(transportMessage(error));
|
|
167
|
+
}
|
|
159
168
|
if (text === "") return { data: void 0 };
|
|
160
169
|
try {
|
|
161
170
|
return JSON.parse(text);
|
|
@@ -505,7 +514,7 @@ function pageCount(meta) {
|
|
|
505
514
|
function dedupe(records) {
|
|
506
515
|
const seen = /* @__PURE__ */ new Set();
|
|
507
516
|
return records.filter((record) => {
|
|
508
|
-
const key = record["id"] ?? record;
|
|
517
|
+
const key = record["id"] ?? JSON.stringify(record);
|
|
509
518
|
if (seen.has(key)) return false;
|
|
510
519
|
seen.add(key);
|
|
511
520
|
return true;
|
|
@@ -1016,7 +1025,7 @@ function str2(value) {
|
|
|
1016
1025
|
}
|
|
1017
1026
|
|
|
1018
1027
|
// src/commands/extended.ts
|
|
1019
|
-
var SAFE_ID = /^[A-Za-z0-9._-]+$/;
|
|
1028
|
+
var SAFE_ID = /^(?!\.{1,2}$)[A-Za-z0-9._-]+$/;
|
|
1020
1029
|
function requireSafeId(kind, id) {
|
|
1021
1030
|
if (!SAFE_ID.test(id)) throw new UsageError(`not a ${kind} id: ${id}`);
|
|
1022
1031
|
}
|
|
@@ -1219,7 +1228,7 @@ async function linkRm(ctx, issue, idOrUrl) {
|
|
|
1219
1228
|
const body = await ctx.client.get(`/api/v1/issues/${issue}/links`);
|
|
1220
1229
|
const link = body.data.find((candidate) => candidate["id"] === idOrUrl || candidate["url"] === idOrUrl);
|
|
1221
1230
|
if (link === void 0) {
|
|
1222
|
-
throw new
|
|
1231
|
+
throw new CommandError(`no link on ${issue} matches ${idOrUrl} (by id or exact URL)`);
|
|
1223
1232
|
}
|
|
1224
1233
|
await ctx.client.delete(`/api/v1/issues/${issue}/links/${str3(link["id"])}`);
|
|
1225
1234
|
return { json: { deleted: link["id"] }, human: `Removed ${clean(link["url"])} from ${issue}
|
|
@@ -1371,6 +1380,9 @@ function validateBaseUrl(baseUrl) {
|
|
|
1371
1380
|
if (parsed.username !== "" || parsed.password !== "") {
|
|
1372
1381
|
return { ok: false, message: "HARNESS_API_URL must not embed credentials (user:pass@) \u2014 use HARNESS_API_TOKEN" };
|
|
1373
1382
|
}
|
|
1383
|
+
if (parsed.search !== "" || parsed.hash !== "") {
|
|
1384
|
+
return { ok: false, message: `HARNESS_API_URL must not carry a query or fragment, got: ${baseUrl}` };
|
|
1385
|
+
}
|
|
1374
1386
|
if (parsed.protocol === "https:" && parsed.hostname !== "") return { ok: true };
|
|
1375
1387
|
if (parsed.protocol === "http:") {
|
|
1376
1388
|
if (["localhost", "127.0.0.1", "[::1]"].includes(parsed.hostname)) return { ok: true };
|
package/dist/cli.js
CHANGED
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
version,
|
|
54
54
|
workflowStates,
|
|
55
55
|
writeCredentials
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-BGBBEM3L.js";
|
|
57
57
|
|
|
58
58
|
// src/cli.ts
|
|
59
59
|
import { Command, CommanderError, InvalidArgumentError } from "commander";
|
|
@@ -654,7 +654,7 @@ program.command("upload").description("upload a file; prints markdown to referen
|
|
|
654
654
|
});
|
|
655
655
|
});
|
|
656
656
|
program.command("mcp").description("run the MCP server over stdio (for agents)").action(async () => {
|
|
657
|
-
const { startMcpServer } = await import("./server-
|
|
657
|
+
const { startMcpServer } = await import("./server-YNJDA7IY.js");
|
|
658
658
|
await startMcpServer();
|
|
659
659
|
});
|
|
660
660
|
program.command("login").description("sign in via the browser (infra.one session)").option("--url <url>", "host to sign in to").option("--no-browser", "print the URL and prompt for a pasted token instead").option("--timeout <ms>", "how long to wait for the browser callback", integer).option("--json", "emit JSON").action(async (opts) => {
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Client,
|
|
5
5
|
HttpError,
|
|
6
6
|
TransportError,
|
|
7
|
+
UsageError,
|
|
7
8
|
archive,
|
|
8
9
|
blocked,
|
|
9
10
|
close,
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
upload,
|
|
37
38
|
userList,
|
|
38
39
|
workflowStates
|
|
39
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-BGBBEM3L.js";
|
|
40
41
|
|
|
41
42
|
// src/mcp/server.ts
|
|
42
43
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -105,6 +106,9 @@ var TOOLS = [
|
|
|
105
106
|
scope: z.enum(["all", "archived"]).optional()
|
|
106
107
|
},
|
|
107
108
|
handler: (ctx, args) => {
|
|
109
|
+
if (args["ready"] === true && args["blocked"] === true) {
|
|
110
|
+
throw new UsageError("ready and blocked are mutually exclusive \u2014 pass one, not both");
|
|
111
|
+
}
|
|
108
112
|
if (args["ready"] === true) return ready(ctx, args);
|
|
109
113
|
if (args["blocked"] === true) return blocked(ctx, args);
|
|
110
114
|
return list(ctx, args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allocator-one/harness-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CLI and MCP server for Harness, allocator.one's issue tracker",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsup",
|
|
26
26
|
"typecheck": "tsc --noEmit",
|
|
27
|
+
"pretest": "npm run build",
|
|
27
28
|
"test": "vitest run",
|
|
28
29
|
"codegen": "openapi-typescript spec/openapi.json -o src/generated/api.ts",
|
|
29
30
|
"spec:refresh": "node scripts/spec-refresh.mjs",
|