haas-mcp 0.2.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 +98 -0
- package/dist/check.d.ts +23 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +34 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +173 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +44 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +168 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +53 -0
- package/dist/config.js.map +1 -0
- package/dist/connect.d.ts +68 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +117 -0
- package/dist/connect.js.map +1 -0
- package/dist/server.d.ts +20 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +77 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.d.ts +94 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +149 -0
- package/dist/setup.js.map +1 -0
- package/dist/tools/cancel_job.d.ts +3 -0
- package/dist/tools/cancel_job.d.ts.map +1 -0
- package/dist/tools/cancel_job.js +22 -0
- package/dist/tools/cancel_job.js.map +1 -0
- package/dist/tools/estimate_cost.d.ts +3 -0
- package/dist/tools/estimate_cost.d.ts.map +1 -0
- package/dist/tools/estimate_cost.js +28 -0
- package/dist/tools/estimate_cost.js.map +1 -0
- package/dist/tools/get_balance.d.ts +3 -0
- package/dist/tools/get_balance.d.ts.map +1 -0
- package/dist/tools/get_balance.js +13 -0
- package/dist/tools/get_balance.js.map +1 -0
- package/dist/tools/get_job_status.d.ts +3 -0
- package/dist/tools/get_job_status.d.ts.map +1 -0
- package/dist/tools/get_job_status.js +19 -0
- package/dist/tools/get_job_status.js.map +1 -0
- package/dist/tools/list_devices.d.ts +3 -0
- package/dist/tools/list_devices.d.ts.map +1 -0
- package/dist/tools/list_devices.js +13 -0
- package/dist/tools/list_devices.js.map +1 -0
- package/dist/tools/purchase_lease.d.ts +16 -0
- package/dist/tools/purchase_lease.d.ts.map +1 -0
- package/dist/tools/purchase_lease.js +50 -0
- package/dist/tools/purchase_lease.js.map +1 -0
- package/dist/tools/submit_batch.d.ts +3 -0
- package/dist/tools/submit_batch.d.ts.map +1 -0
- package/dist/tools/submit_batch.js +58 -0
- package/dist/tools/submit_batch.js.map +1 -0
- package/dist/tools/submit_job.d.ts +3 -0
- package/dist/tools/submit_job.d.ts.map +1 -0
- package/dist/tools/submit_job.js +49 -0
- package/dist/tools/submit_job.js.map +1 -0
- package/dist/tools/submit_source.d.ts +3 -0
- package/dist/tools/submit_source.d.ts.map +1 -0
- package/dist/tools/submit_source.js +55 -0
- package/dist/tools/submit_source.js.map +1 -0
- package/dist/tools/tail_serial.d.ts +3 -0
- package/dist/tools/tail_serial.d.ts.map +1 -0
- package/dist/tools/tail_serial.js +26 -0
- package/dist/tools/tail_serial.js.map +1 -0
- package/dist/tools/types.d.ts +9 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const cancelJobTool = {
|
|
2
|
+
name: "cancel_job",
|
|
3
|
+
description: "Cancel a job. If still pre-flight (DRAFT/STATIC_CHECK/ESTIMATED/ESCROW_HELD/QUEUED), the escrow is fully refunded. If mid-flight (FLASHING/RUNNING), elapsed time is charged and the rest refunded.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["job_id"],
|
|
7
|
+
properties: {
|
|
8
|
+
job_id: { type: "string" },
|
|
9
|
+
reason: { type: "string" },
|
|
10
|
+
},
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
},
|
|
13
|
+
async handler(rawArgs, client) {
|
|
14
|
+
const args = rawArgs;
|
|
15
|
+
if (!args.job_id)
|
|
16
|
+
throw new Error("job_id is required");
|
|
17
|
+
return client.postJson(`/api/jobs/${encodeURIComponent(args.job_id)}/cancel`, {
|
|
18
|
+
reason: args.reason,
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=cancel_job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cancel_job.js","sourceRoot":"","sources":["../../src/tools/cancel_job.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAY;IACpC,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,qMAAqM;IACvM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC3B;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAAyD,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;YAC5E,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate_cost.d.ts","sourceRoot":"","sources":["../../src/tools/estimate_cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAS1C,eAAO,MAAM,gBAAgB,EAAE,OA2B9B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const estimateCostTool = {
|
|
2
|
+
name: "estimate_cost",
|
|
3
|
+
description: "Compute the cost estimate for a hypothetical job without submitting it. Returns flash + run cost, deposit (sized by reputation tier), and the total escrow that would be reserved.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["firmware_size"],
|
|
7
|
+
properties: {
|
|
8
|
+
firmware_size: { type: "number", description: "Size in bytes" },
|
|
9
|
+
device_id: { type: "string" },
|
|
10
|
+
profile_key: { type: "string" },
|
|
11
|
+
runtime_s: { type: "number", description: "Expected runtime in seconds" },
|
|
12
|
+
},
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
},
|
|
15
|
+
async handler(rawArgs, client) {
|
|
16
|
+
const args = rawArgs;
|
|
17
|
+
if (typeof args.firmware_size !== "number" || args.firmware_size <= 0) {
|
|
18
|
+
throw new Error("firmware_size (positive number) is required");
|
|
19
|
+
}
|
|
20
|
+
return client.postJson("/api/v1/estimate", {
|
|
21
|
+
firmwareSize: args.firmware_size,
|
|
22
|
+
deviceId: args.device_id,
|
|
23
|
+
profileKey: args.profile_key,
|
|
24
|
+
expectedRuntimeSec: args.runtime_s,
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=estimate_cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate_cost.js","sourceRoot":"","sources":["../../src/tools/estimate_cost.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,gBAAgB,GAAY;IACvC,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,oLAAoL;IACtL,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,eAAe,CAAC;QAC3B,UAAU,EAAE;YACV,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;YAC/D,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC7B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;SAC1E;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE;YACzC,YAAY,EAAE,IAAI,CAAC,aAAa;YAChC,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,kBAAkB,EAAE,IAAI,CAAC,SAAS;SACnC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_balance.d.ts","sourceRoot":"","sources":["../../src/tools/get_balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,cAAc,EAAE,OAY5B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const getBalanceTool = {
|
|
2
|
+
name: "get_balance",
|
|
3
|
+
description: "Fetch the caller's wallet balance: available credits, reserved credits (held by open escrows), reputation tier, and account status.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {},
|
|
7
|
+
additionalProperties: false,
|
|
8
|
+
},
|
|
9
|
+
async handler(_args, client) {
|
|
10
|
+
return client.get("/api/v1/balance");
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=get_balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_balance.js","sourceRoot":"","sources":["../../src/tools/get_balance.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,qIAAqI;IACvI,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM;QACzB,OAAO,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_job_status.d.ts","sourceRoot":"","sources":["../../src/tools/get_job_status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,gBAAgB,EAAE,OAiB9B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const getJobStatusTool = {
|
|
2
|
+
name: "get_job_status",
|
|
3
|
+
description: "Fetch the current state of a job: status, estimate, actual cost, escrow link, static check result, damage report, settled timestamp. While the job is QUEUED the response also carries queuePosition, its one-based place among the jobs waiting for the same boards (null in every other status). Jobs are taken oldest first as boards free up, so there is no need to poll for the position; read it when you need it.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["job_id"],
|
|
7
|
+
properties: {
|
|
8
|
+
job_id: { type: "string" },
|
|
9
|
+
},
|
|
10
|
+
additionalProperties: false,
|
|
11
|
+
},
|
|
12
|
+
async handler(rawArgs, client) {
|
|
13
|
+
const args = rawArgs;
|
|
14
|
+
if (!args.job_id)
|
|
15
|
+
throw new Error("job_id is required");
|
|
16
|
+
return client.get(`/api/v1/jobs/${encodeURIComponent(args.job_id)}`);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=get_job_status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_job_status.js","sourceRoot":"","sources":["../../src/tools/get_job_status.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAY;IACvC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,2ZAA2Z;IAC7Z,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC3B;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAAwC,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,GAAG,CAAC,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_devices.d.ts","sourceRoot":"","sources":["../../src/tools/list_devices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,eAAe,EAAE,OAY7B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const listDevicesTool = {
|
|
2
|
+
name: "list_devices",
|
|
3
|
+
description: "List the hardware devices available for flashing. Each entry includes profile key, status, replacement cost, queue depth, current job, agent, and any active lease.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {},
|
|
7
|
+
additionalProperties: false,
|
|
8
|
+
},
|
|
9
|
+
async handler(_args, client) {
|
|
10
|
+
return client.get("/api/v1/devices");
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=list_devices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_devices.js","sourceRoot":"","sources":["../../src/tools/list_devices.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,qKAAqK;IACvK,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM;QACzB,OAAO,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolDef } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Book a board for a window. HAAS-211.
|
|
4
|
+
*
|
|
5
|
+
* A stub until 2026-09-07 that threw "not yet implemented; lease endpoints
|
|
6
|
+
* land in Phase E" — months after `POST /api/v1/leases` shipped and the
|
|
7
|
+
* dashboard began leasing through it. An MCP client asking for a lease was
|
|
8
|
+
* told the feature did not exist while the web app sold it. This calls the
|
|
9
|
+
* same route the dashboard's panel calls, with the same three fields.
|
|
10
|
+
*
|
|
11
|
+
* The arguments are renamed on the way through, the way `estimate_cost`
|
|
12
|
+
* renames its own: the tool speaks snake_case to the model and the API takes
|
|
13
|
+
* camelCase, and the seam is here rather than in every caller.
|
|
14
|
+
*/
|
|
15
|
+
export declare const purchaseLeaseTool: ToolDef;
|
|
16
|
+
//# sourceMappingURL=purchase_lease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchase_lease.d.ts","sourceRoot":"","sources":["../../src/tools/purchase_lease.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ1C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,EAAE,OAqC/B,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Book a board for a window. HAAS-211.
|
|
3
|
+
*
|
|
4
|
+
* A stub until 2026-09-07 that threw "not yet implemented; lease endpoints
|
|
5
|
+
* land in Phase E" — months after `POST /api/v1/leases` shipped and the
|
|
6
|
+
* dashboard began leasing through it. An MCP client asking for a lease was
|
|
7
|
+
* told the feature did not exist while the web app sold it. This calls the
|
|
8
|
+
* same route the dashboard's panel calls, with the same three fields.
|
|
9
|
+
*
|
|
10
|
+
* The arguments are renamed on the way through, the way `estimate_cost`
|
|
11
|
+
* renames its own: the tool speaks snake_case to the model and the API takes
|
|
12
|
+
* camelCase, and the seam is here rather than in every caller.
|
|
13
|
+
*/
|
|
14
|
+
export const purchaseLeaseTool = {
|
|
15
|
+
name: "purchase_lease",
|
|
16
|
+
description: "Book a board exclusively for a number of hours. Jobs you run on it during the window pay no runtime cost. The price falls with the length, up to ten percent off at a day. Refused with a reason when the account may not lease (a reputation tier, or a balance covering the board's replacement cost, qualifies), when the window overlaps a lease already on the board, or when the balance is short. Returns the lease: id, deviceId, startsAt, endsAt, hourCount, costMicroCreds.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
required: ["device_id", "hours"],
|
|
20
|
+
properties: {
|
|
21
|
+
device_id: { type: "string", description: "The board to book, from list_devices" },
|
|
22
|
+
hours: { type: "number", description: "Whole hours, at least 1" },
|
|
23
|
+
starts_at: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "ISO timestamp for a window starting later; omit to start now",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
},
|
|
30
|
+
async handler(rawArgs, client) {
|
|
31
|
+
const args = rawArgs;
|
|
32
|
+
if (typeof args.device_id !== "string" || args.device_id.length === 0) {
|
|
33
|
+
throw new Error("device_id (non-empty string) is required");
|
|
34
|
+
}
|
|
35
|
+
if (typeof args.hours !== "number" || !Number.isFinite(args.hours) || args.hours <= 0) {
|
|
36
|
+
throw new Error("hours (positive number) is required");
|
|
37
|
+
}
|
|
38
|
+
if (args.starts_at !== undefined && Number.isNaN(new Date(args.starts_at).getTime())) {
|
|
39
|
+
throw new Error(`starts_at is not a timestamp: ${JSON.stringify(args.starts_at)}`);
|
|
40
|
+
}
|
|
41
|
+
const body = {
|
|
42
|
+
deviceId: args.device_id,
|
|
43
|
+
hours: args.hours,
|
|
44
|
+
};
|
|
45
|
+
if (args.starts_at !== undefined)
|
|
46
|
+
body.startsAt = args.starts_at;
|
|
47
|
+
return client.postJson("/api/v1/leases", body);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=purchase_lease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchase_lease.js","sourceRoot":"","sources":["../../src/tools/purchase_lease.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAY;IACxC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,wdAAwd;IAC1d,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC;QAChC,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;YAClF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;YACjE,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8DAA8D;aAC5E;SACF;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;YACtF,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,IAAI,GAA2D;YACnE,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjE,OAAO,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_batch.d.ts","sourceRoot":"","sources":["../../src/tools/submit_batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAc1C,eAAO,MAAM,eAAe,EAAE,OAyD7B,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const submitBatchTool = {
|
|
2
|
+
name: "submit_batch",
|
|
3
|
+
description: "Fan out N firmware variants across the device pool in a single round-trip. Primary tool for parallel iteration. Up to 32 jobs per call. Each job is estimated and escrowed independently; with policy='all_or_nothing' any failure rolls back the entire batch.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["jobs"],
|
|
7
|
+
properties: {
|
|
8
|
+
jobs: {
|
|
9
|
+
type: "array",
|
|
10
|
+
maxItems: 32,
|
|
11
|
+
items: {
|
|
12
|
+
type: "object",
|
|
13
|
+
required: ["firmware_b64"],
|
|
14
|
+
properties: {
|
|
15
|
+
firmware_b64: { type: "string" },
|
|
16
|
+
target: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
device_id: { type: "string" },
|
|
20
|
+
profile_key: { type: "string" },
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
},
|
|
24
|
+
params: {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
expected_runtime_s: { type: "number" },
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
policy: { type: "string", enum: ["best_effort", "all_or_nothing"] },
|
|
36
|
+
auto_confirm: { type: "boolean" },
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
},
|
|
40
|
+
async handler(rawArgs, client) {
|
|
41
|
+
const args = rawArgs;
|
|
42
|
+
if (!Array.isArray(args.jobs) || args.jobs.length === 0) {
|
|
43
|
+
throw new Error("jobs array is required and non-empty");
|
|
44
|
+
}
|
|
45
|
+
const body = {
|
|
46
|
+
jobs: args.jobs.map((j) => ({
|
|
47
|
+
firmware_b64: j.firmware_b64,
|
|
48
|
+
device_id: j.target?.device_id,
|
|
49
|
+
profile_key: j.target?.profile_key,
|
|
50
|
+
expected_runtime_s: j.params?.expected_runtime_s,
|
|
51
|
+
})),
|
|
52
|
+
policy: args.policy ?? "best_effort",
|
|
53
|
+
auto_confirm: args.auto_confirm ?? false,
|
|
54
|
+
};
|
|
55
|
+
return client.postJson("/api/jobs/batch", body);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=submit_batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_batch.js","sourceRoot":"","sources":["../../src/tools/submit_batch.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,iQAAiQ;IACnQ,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,CAAC,cAAc,CAAC;oBAC1B,UAAU,EAAE;wBACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAChC,MAAM,EAAE;4BACN,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gCAC7B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;6BAChC;4BACD,oBAAoB,EAAE,KAAK;yBAC5B;wBACD,MAAM,EAAE;4BACN,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACV,kBAAkB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;6BACvC;4BACD,oBAAoB,EAAE,KAAK;yBAC5B;qBACF;oBACD,oBAAoB,EAAE,KAAK;iBAC5B;aACF;YACD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,gBAAgB,CAAC,EAAE;YACnE,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAClC;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1B,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS;gBAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,WAAW;gBAClC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,kBAAkB;aACjD,CAAC,CAAC;YACH,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa;YACpC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK;SACzC,CAAC;QACF,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_job.d.ts","sourceRoot":"","sources":["../../src/tools/submit_job.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ1C,eAAO,MAAM,aAAa,EAAE,OA+C3B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export const submitJobTool = {
|
|
2
|
+
name: "submit_job",
|
|
3
|
+
description: "Submit a single firmware (base64-encoded .bin) to be flashed and run on a device. Returns job id, status, and the cost estimate. With auto_confirm=true, the job goes straight to QUEUED and the response carries queuePosition, its one-based place among the jobs waiting for the same boards; otherwise it lands in ESCROW_HELD and the caller must call confirm.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["firmware_b64"],
|
|
7
|
+
properties: {
|
|
8
|
+
firmware_b64: { type: "string", description: "Base64-encoded firmware blob (.bin)" },
|
|
9
|
+
target: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
device_id: { type: "string" },
|
|
13
|
+
profile_key: { type: "string" },
|
|
14
|
+
},
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
},
|
|
17
|
+
params: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
auto_confirm: { type: "boolean" },
|
|
21
|
+
expected_runtime_s: {
|
|
22
|
+
type: "number",
|
|
23
|
+
description: "The run seconds you book. The job's booked window is this plus the profile's flash allowance, and the escrow is reserved against it (HAAS-20).",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
async handler(rawArgs, client) {
|
|
32
|
+
const args = rawArgs;
|
|
33
|
+
const buf = Buffer.from(args.firmware_b64, "base64");
|
|
34
|
+
if (buf.length === 0)
|
|
35
|
+
throw new Error("firmware_b64 decoded to empty buffer");
|
|
36
|
+
const fields = {};
|
|
37
|
+
if (args.target?.device_id)
|
|
38
|
+
fields.device_id = args.target.device_id;
|
|
39
|
+
if (args.target?.profile_key)
|
|
40
|
+
fields.profile_key = args.target.profile_key;
|
|
41
|
+
if (args.params?.auto_confirm)
|
|
42
|
+
fields.auto_confirm = "true";
|
|
43
|
+
if (args.params?.expected_runtime_s !== undefined) {
|
|
44
|
+
fields.expected_runtime_s = String(args.params.expected_runtime_s);
|
|
45
|
+
}
|
|
46
|
+
return client.postMultipartFirmware("/api/jobs", buf, fields);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=submit_job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_job.js","sourceRoot":"","sources":["../../src/tools/submit_job.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,aAAa,GAAY;IACpC,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,sWAAsW;IACxW,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,cAAc,CAAC;QAC1B,UAAU,EAAE;YACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;YACpF,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC7B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAChC;gBACD,oBAAoB,EAAE,KAAK;aAC5B;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACjC,kBAAkB,EAAE;wBAClB,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,gJAAgJ;qBACnJ;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACrD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAE9E,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACrE,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3E,IAAI,IAAI,CAAC,MAAM,EAAE,YAAY;YAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC;QAC5D,IAAI,IAAI,CAAC,MAAM,EAAE,kBAAkB,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,CAAC,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_source.d.ts","sourceRoot":"","sources":["../../src/tools/submit_source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ1C,eAAO,MAAM,gBAAgB,EAAE,OAuD9B,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const submitSourceTool = {
|
|
2
|
+
name: "submit_source",
|
|
3
|
+
description: "Submit C source to be compiled on the bench into a FreeRTOS app for the board and then flashed (HAAS-230). This is the default way to run a program: you write `void app_main(void) { ... }` with FreeRTOS tasks and the whole of ESP-IDF available, and the bench builds it for the chosen chip — no local toolchain. Returns job id, status and the cost estimate, exactly like submit_job; with auto_confirm=true it goes straight to QUEUED. Use submit_job instead only when you already have a prebuilt .bin.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["source"],
|
|
7
|
+
properties: {
|
|
8
|
+
source: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "C source for one ESP-IDF app. Must define `void app_main(void)`, the entry point ESP-IDF calls. Everything else — the CMake, the partition table, the console — is the bench's; you write the program. The default template (two FreeRTOS tasks and a queue) is a good starting point.",
|
|
11
|
+
},
|
|
12
|
+
target: {
|
|
13
|
+
type: "object",
|
|
14
|
+
properties: {
|
|
15
|
+
device_id: { type: "string" },
|
|
16
|
+
profile_key: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "e.g. esp32c3-mini-v1. The bench compiles for this board's chip.",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
},
|
|
23
|
+
params: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
auto_confirm: { type: "boolean" },
|
|
27
|
+
expected_runtime_s: {
|
|
28
|
+
type: "number",
|
|
29
|
+
description: "The run seconds you book. The booked window is this plus the profile's flash allowance; the compile happens before the window opens (HAAS-20, HAAS-230).",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
},
|
|
37
|
+
async handler(rawArgs, client) {
|
|
38
|
+
const args = rawArgs;
|
|
39
|
+
if (typeof args.source !== "string" || args.source.trim().length === 0) {
|
|
40
|
+
throw new Error("source is required and must be non-empty C");
|
|
41
|
+
}
|
|
42
|
+
const fields = {};
|
|
43
|
+
if (args.target?.device_id)
|
|
44
|
+
fields.device_id = args.target.device_id;
|
|
45
|
+
if (args.target?.profile_key)
|
|
46
|
+
fields.profile_key = args.target.profile_key;
|
|
47
|
+
if (args.params?.auto_confirm)
|
|
48
|
+
fields.auto_confirm = "true";
|
|
49
|
+
if (args.params?.expected_runtime_s !== undefined) {
|
|
50
|
+
fields.expected_runtime_s = String(args.params.expected_runtime_s);
|
|
51
|
+
}
|
|
52
|
+
return client.postMultipartSource("/api/jobs", args.source, fields);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=submit_source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit_source.js","sourceRoot":"","sources":["../../src/tools/submit_source.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,gBAAgB,GAAY;IACvC,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,qfAAqf;IACvf,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,wRAAwR;aAC3R;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC7B,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,iEAAiE;qBAC/E;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACjC,kBAAkB,EAAE;wBAClB,IAAI,EAAE,QAAQ;wBACd,WAAW,EACT,0JAA0J;qBAC7J;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACrE,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3E,IAAI,IAAI,CAAC,MAAM,EAAE,YAAY;YAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC;QAC5D,IAAI,IAAI,CAAC,MAAM,EAAE,kBAAkB,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,CAAC,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail_serial.d.ts","sourceRoot":"","sources":["../../src/tools/tail_serial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ1C,eAAO,MAAM,cAAc,EAAE,OAwB5B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const tailSerialTool = {
|
|
2
|
+
name: "tail_serial",
|
|
3
|
+
description: "Long-poll the SSE feed for a job and return up to max_chunks of serial output. Returns once chunks arrive or after a 25-second timeout. Use repeatedly to follow a live job.",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
required: ["job_id"],
|
|
7
|
+
properties: {
|
|
8
|
+
job_id: { type: "string" },
|
|
9
|
+
since_seq: { type: "number" },
|
|
10
|
+
max_chunks: { type: "number" },
|
|
11
|
+
},
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
},
|
|
14
|
+
async handler(rawArgs, client) {
|
|
15
|
+
const args = rawArgs;
|
|
16
|
+
if (!args.job_id)
|
|
17
|
+
throw new Error("job_id is required");
|
|
18
|
+
const max = Math.min(Math.max(1, args.max_chunks ?? 50), 200);
|
|
19
|
+
return client.streamFeed(`/api/v1/jobs/${encodeURIComponent(args.job_id)}/feed`, {
|
|
20
|
+
timeoutMs: 25_000,
|
|
21
|
+
maxChunks: max,
|
|
22
|
+
sinceSeq: args.since_seq,
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=tail_serial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail_serial.js","sourceRoot":"","sources":["../../src/tools/tail_serial.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,8KAA8K;IAChL,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC7B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC/B;QACD,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;QAC3B,MAAM,IAAI,GAAG,OAA0B,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,UAAU,CAAC,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YAC/E,SAAS,EAAE,MAAM;YACjB,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HaasClient } from "../client.js";
|
|
2
|
+
export interface ToolDef {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
/** JSON Schema (subset) describing the tool's input. */
|
|
6
|
+
inputSchema: Record<string, unknown>;
|
|
7
|
+
handler: (args: Record<string, unknown>, client: HaasClient) => Promise<unknown>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "haas-mcp",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MCP server (stdio) for haas-lab — flash firmware to real boards in the cloud from any AI client.",
|
|
5
|
+
"homepage": "https://haas-lab.com/docs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"haas-mcp": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/cli.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsx src/cli.ts",
|
|
18
|
+
"start": "node dist/cli.js",
|
|
19
|
+
"type-check": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"prepublishOnly": "npm run type-check && npm test && npm run build"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.0.4"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22",
|
|
31
|
+
"tsx": "^4.19.2",
|
|
32
|
+
"typescript": "^5",
|
|
33
|
+
"vitest": "^4.1.5"
|
|
34
|
+
}
|
|
35
|
+
}
|