@lesscap/baton-cli 0.9.7 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/baton.mjs +1055 -1684
- package/package.json +1 -1
package/dist/baton.mjs
CHANGED
|
@@ -5852,11 +5852,6 @@ var clientFor = (args) => {
|
|
|
5852
5852
|
const auth = resolveAuth(process.env, fileToken);
|
|
5853
5853
|
return createClient(baseUrl, auth && auth !== "cookie" ? auth : void 0);
|
|
5854
5854
|
};
|
|
5855
|
-
var resolveBearer = () => {
|
|
5856
|
-
const fileToken = loadProjectConfigOrNull(projectConfigPath())?.worker?.apiToken;
|
|
5857
|
-
const auth = resolveAuth(process.env, fileToken);
|
|
5858
|
-
return auth && auth !== "cookie" ? auth.bearer : void 0;
|
|
5859
|
-
};
|
|
5860
5855
|
var resolveProjectId = (args) => {
|
|
5861
5856
|
if (args.project !== void 0 && args.project !== "") return Number(args.project);
|
|
5862
5857
|
if (process.env.BATON_PROJECT_ID !== void 0)
|
|
@@ -5877,7 +5872,6 @@ var parseWorkerHandle = (handle) => {
|
|
|
5877
5872
|
const m = handle.trim().match(/^(?:[wW]-)?(\d+)$/);
|
|
5878
5873
|
return m ? Number(m[1]) : null;
|
|
5879
5874
|
};
|
|
5880
|
-
var splitCsv = (s) => s ? s.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
|
|
5881
5875
|
var parseDuration = (s) => {
|
|
5882
5876
|
const m = s.trim().match(/^(\d+)\s*([smhd]?)$/);
|
|
5883
5877
|
if (!m) throw new Error(`bad interval "${s}" \u2014 use e.g. 90s, 30m, 2h, 1d`);
|
|
@@ -5959,771 +5953,422 @@ var artifact = defineCommand({
|
|
|
5959
5953
|
subCommands: { publish: publishCommand, ls: listCommand, rm: removeCommand }
|
|
5960
5954
|
});
|
|
5961
5955
|
|
|
5962
|
-
//
|
|
5963
|
-
var
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5956
|
+
// src/commands/host.ts
|
|
5957
|
+
var findHost = (hosts, handle) => {
|
|
5958
|
+
const host2 = hosts.find((item) => item.name === handle || String(item.id) === handle);
|
|
5959
|
+
if (!host2) throw new Error(`host not found: ${handle}`);
|
|
5960
|
+
return host2;
|
|
5967
5961
|
};
|
|
5968
|
-
var
|
|
5969
|
-
var
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
const input = pendingFragments.join("");
|
|
5997
|
-
pendingFragments.length = 0, pendingFragmentsLength = 0;
|
|
5998
|
-
const trailing = processLines(input);
|
|
5999
|
-
trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();
|
|
6000
|
-
}
|
|
6001
|
-
function checkBufferSize() {
|
|
6002
|
-
maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = true, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = "", dataLines = 0, eventType = void 0, onError(
|
|
6003
|
-
new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
|
|
6004
|
-
type: "max-buffer-size-exceeded"
|
|
6005
|
-
})
|
|
6006
|
-
)));
|
|
6007
|
-
}
|
|
6008
|
-
function processLines(chunk) {
|
|
6009
|
-
let searchIndex = 0;
|
|
6010
|
-
if (chunk.indexOf("\r") === -1) {
|
|
6011
|
-
let lfIndex = chunk.indexOf(`
|
|
6012
|
-
`, searchIndex);
|
|
6013
|
-
for (; lfIndex !== -1; ) {
|
|
6014
|
-
if (searchIndex === lfIndex) {
|
|
6015
|
-
dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
6016
|
-
`, searchIndex);
|
|
6017
|
-
continue;
|
|
6018
|
-
}
|
|
6019
|
-
const firstCharCode = chunk.charCodeAt(searchIndex);
|
|
6020
|
-
if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
|
|
6021
|
-
const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
|
|
6022
|
-
if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
|
|
6023
|
-
onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
|
|
6024
|
-
`, searchIndex);
|
|
6025
|
-
continue;
|
|
6026
|
-
}
|
|
6027
|
-
data = dataLines === 0 ? value : `${data}
|
|
6028
|
-
${value}`, dataLines++;
|
|
6029
|
-
} else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
|
|
6030
|
-
chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
|
|
6031
|
-
lfIndex
|
|
6032
|
-
) || void 0 : parseLine(chunk, searchIndex, lfIndex);
|
|
6033
|
-
searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
6034
|
-
`, searchIndex);
|
|
5962
|
+
var adminHost = async (c, handle) => findHost(await c.hosts.list(), handle);
|
|
5963
|
+
var positiveId = (raw) => {
|
|
5964
|
+
const id = Number(raw);
|
|
5965
|
+
if (!Number.isSafeInteger(id) || id <= 0) throw new Error("workspace must be a positive id");
|
|
5966
|
+
return id;
|
|
5967
|
+
};
|
|
5968
|
+
var hostArg = {
|
|
5969
|
+
host: { type: "positional", required: true, description: "host name or id" }
|
|
5970
|
+
};
|
|
5971
|
+
var workspaceArg = {
|
|
5972
|
+
workspace: { type: "string", required: true, description: "workspace id" }
|
|
5973
|
+
};
|
|
5974
|
+
var host = defineCommand({
|
|
5975
|
+
meta: { name: "host", description: "manage machines and which workspaces can use them (admin)" },
|
|
5976
|
+
subCommands: {
|
|
5977
|
+
add: defineCommand({
|
|
5978
|
+
meta: { name: "add", description: "add a host; prints its Provisioner token once" },
|
|
5979
|
+
args: {
|
|
5980
|
+
name: { type: "positional", required: true, description: "host name" },
|
|
5981
|
+
workspace: { type: "string", description: "also assign it to this workspace id" },
|
|
5982
|
+
...common
|
|
5983
|
+
},
|
|
5984
|
+
run: async ({ args }) => {
|
|
5985
|
+
const c = clientFor(args);
|
|
5986
|
+
const workspaceId = args.workspace === void 0 ? null : positiveId(args.workspace);
|
|
5987
|
+
const credential = await c.hosts.create(args.name);
|
|
5988
|
+
console.log(renderOne(credential, fmtHostCredential, Boolean(args.json)));
|
|
5989
|
+
if (workspaceId !== null) await c.hosts.assign(credential.host.id, workspaceId);
|
|
6035
5990
|
}
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
}
|
|
6046
|
-
return chunk.slice(searchIndex);
|
|
6047
|
-
}
|
|
6048
|
-
function parseLine(chunk, start, end) {
|
|
6049
|
-
if (start === end) {
|
|
6050
|
-
dispatchEvent();
|
|
6051
|
-
return;
|
|
6052
|
-
}
|
|
6053
|
-
const firstCharCode = chunk.charCodeAt(start);
|
|
6054
|
-
if (isDataPrefix(chunk, start, firstCharCode)) {
|
|
6055
|
-
const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
|
|
6056
|
-
data = dataLines === 0 ? value2 : `${data}
|
|
6057
|
-
${value2}`, dataLines++;
|
|
6058
|
-
return;
|
|
6059
|
-
}
|
|
6060
|
-
if (isEventPrefix(chunk, start, firstCharCode)) {
|
|
6061
|
-
eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
|
|
6062
|
-
return;
|
|
6063
|
-
}
|
|
6064
|
-
if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
|
|
6065
|
-
const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
|
|
6066
|
-
id = value2.includes("\0") ? void 0 : value2;
|
|
6067
|
-
return;
|
|
6068
|
-
}
|
|
6069
|
-
if (firstCharCode === 58) {
|
|
6070
|
-
if (onComment) {
|
|
6071
|
-
const line2 = chunk.slice(start, end);
|
|
6072
|
-
onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
|
|
5991
|
+
}),
|
|
5992
|
+
ls: defineCommand({
|
|
5993
|
+
meta: {
|
|
5994
|
+
name: "ls",
|
|
5995
|
+
description: "list hosts, whether they are online, and their workspaces"
|
|
5996
|
+
},
|
|
5997
|
+
args: { ...common },
|
|
5998
|
+
run: async ({ args }) => {
|
|
5999
|
+
console.log(renderList(await clientFor(args).hosts.list(), fmtHost, Boolean(args.json)));
|
|
6073
6000
|
}
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
id
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
);
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
new ParseError(
|
|
6108
|
-
`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`,
|
|
6109
|
-
{ type: "unknown-field", field, value, line }
|
|
6110
|
-
)
|
|
6111
|
-
);
|
|
6112
|
-
break;
|
|
6113
|
-
}
|
|
6114
|
-
}
|
|
6115
|
-
function dispatchEvent() {
|
|
6116
|
-
dataLines > 0 && onEvent({
|
|
6117
|
-
id,
|
|
6118
|
-
event: eventType,
|
|
6119
|
-
data
|
|
6120
|
-
}), id = void 0, data = "", dataLines = 0, eventType = void 0;
|
|
6121
|
-
}
|
|
6122
|
-
function reset(options = {}) {
|
|
6123
|
-
if (options.consume && pendingFragments.length > 0) {
|
|
6124
|
-
const incompleteLine = pendingFragments.join("");
|
|
6125
|
-
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
6126
|
-
}
|
|
6127
|
-
isFirstChunk = true, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = false;
|
|
6001
|
+
}),
|
|
6002
|
+
assign: defineCommand({
|
|
6003
|
+
meta: { name: "assign", description: "let a workspace create Workers on this host" },
|
|
6004
|
+
args: { ...hostArg, ...workspaceArg, ...common },
|
|
6005
|
+
run: async ({ args }) => {
|
|
6006
|
+
const c = clientFor(args);
|
|
6007
|
+
const { id, name } = await adminHost(c, args.host);
|
|
6008
|
+
await c.hosts.assign(id, positiveId(args.workspace));
|
|
6009
|
+
console.log(`assigned ${name} to workspace ${args.workspace}`);
|
|
6010
|
+
}
|
|
6011
|
+
}),
|
|
6012
|
+
unassign: defineCommand({
|
|
6013
|
+
meta: {
|
|
6014
|
+
name: "unassign",
|
|
6015
|
+
description: "stop new Workers on this host for a workspace; existing ones keep running"
|
|
6016
|
+
},
|
|
6017
|
+
args: { ...hostArg, ...workspaceArg, ...common },
|
|
6018
|
+
run: async ({ args }) => {
|
|
6019
|
+
const c = clientFor(args);
|
|
6020
|
+
const { id, name } = await adminHost(c, args.host);
|
|
6021
|
+
await c.hosts.unassign(id, positiveId(args.workspace));
|
|
6022
|
+
console.log(`unassigned ${name} from workspace ${args.workspace}`);
|
|
6023
|
+
}
|
|
6024
|
+
}),
|
|
6025
|
+
rotate: defineCommand({
|
|
6026
|
+
meta: { name: "rotate", description: "replace a host token; the old one stops working" },
|
|
6027
|
+
args: { ...hostArg, ...common },
|
|
6028
|
+
run: async ({ args }) => {
|
|
6029
|
+
const c = clientFor(args);
|
|
6030
|
+
const { id } = await adminHost(c, args.host);
|
|
6031
|
+
console.log(renderOne(await c.hosts.rotate(id), fmtHostCredential, Boolean(args.json)));
|
|
6032
|
+
}
|
|
6033
|
+
})
|
|
6128
6034
|
}
|
|
6129
|
-
|
|
6130
|
-
}
|
|
6131
|
-
function isDataPrefix(chunk, i, firstCharCode) {
|
|
6132
|
-
return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
|
|
6133
|
-
}
|
|
6134
|
-
function isEventPrefix(chunk, i, firstCharCode) {
|
|
6135
|
-
return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
|
|
6136
|
-
}
|
|
6035
|
+
});
|
|
6137
6036
|
|
|
6138
|
-
//
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6037
|
+
// src/commands/init.ts
|
|
6038
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
6039
|
+
import * as readline from "node:readline/promises";
|
|
6040
|
+
var promptPick = async (label, items) => {
|
|
6041
|
+
if (items.length === 0) throw new Error(`no ${label}s found on server`);
|
|
6042
|
+
console.log(`${label}s:`);
|
|
6043
|
+
items.forEach((it, i) => {
|
|
6044
|
+
console.log(` [${i + 1}] #${it.id} ${it.name}`);
|
|
6045
|
+
});
|
|
6046
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
6047
|
+
try {
|
|
6048
|
+
const ans = (await rl.question(`pick a ${label} (1-${items.length}): `)).trim();
|
|
6049
|
+
const idx = Number(ans) - 1;
|
|
6050
|
+
const picked = items[idx];
|
|
6051
|
+
if (!picked) throw new Error(`invalid choice: ${ans}`);
|
|
6052
|
+
return picked;
|
|
6053
|
+
} finally {
|
|
6054
|
+
rl.close();
|
|
6150
6055
|
}
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6056
|
+
};
|
|
6057
|
+
var init = defineCommand({
|
|
6058
|
+
meta: {
|
|
6059
|
+
name: "init",
|
|
6060
|
+
description: `write ${PROJECT_CONFIG_NAME} in the current directory (local state, gitignored)`
|
|
6061
|
+
},
|
|
6062
|
+
args: {
|
|
6063
|
+
workspace: { type: "string", description: "workspace id (skip prompt)" },
|
|
6064
|
+
project: { type: "string", description: "project id (skip prompt)" },
|
|
6065
|
+
force: { type: "boolean", description: `overwrite existing ${PROJECT_CONFIG_NAME}` },
|
|
6066
|
+
...common
|
|
6067
|
+
},
|
|
6068
|
+
run: async ({ args }) => {
|
|
6069
|
+
const server = resolveBaseUrl(args.url);
|
|
6070
|
+
const cfgPath = projectConfigPath();
|
|
6071
|
+
if (existsSync2(cfgPath) && !args.force)
|
|
6072
|
+
throw new Error(`${PROJECT_CONFIG_NAME} already exists. use --force to overwrite.`);
|
|
6073
|
+
const c = createClient(server);
|
|
6074
|
+
let project2;
|
|
6075
|
+
let workspace2;
|
|
6076
|
+
if (args.project) {
|
|
6077
|
+
project2 = await c.projects.get(Number(args.project));
|
|
6078
|
+
workspace2 = await c.workspaces.get(project2.workspaceId);
|
|
6079
|
+
} else {
|
|
6080
|
+
const wsList = await c.workspaces.list();
|
|
6081
|
+
workspace2 = args.workspace ? wsList.find((w) => w.id === Number(args.workspace)) ?? (() => {
|
|
6082
|
+
throw new Error(`workspace ${args.workspace} not found`);
|
|
6083
|
+
})() : await promptPick("workspace", wsList);
|
|
6084
|
+
const projects = await c.projects.listByWorkspace(workspace2.id);
|
|
6085
|
+
project2 = await promptPick("project", projects);
|
|
6086
|
+
}
|
|
6087
|
+
const cfg = {
|
|
6088
|
+
server,
|
|
6089
|
+
workspace: workspace2.id,
|
|
6090
|
+
project: project2.id,
|
|
6091
|
+
name: project2.name
|
|
6092
|
+
};
|
|
6093
|
+
saveProjectConfig(cfgPath, cfg);
|
|
6094
|
+
console.log(`wrote ${cfgPath}`);
|
|
6095
|
+
console.log(` server: ${server}`);
|
|
6096
|
+
console.log(` workspace: #${workspace2.id} ${workspace2.name}`);
|
|
6097
|
+
console.log(` project: #${project2.id} ${project2.name}`);
|
|
6165
6098
|
}
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
* @param options - The options passed to `Deno.inspect`
|
|
6175
|
-
* @returns A string representation of the error
|
|
6176
|
-
*/
|
|
6177
|
-
[/* @__PURE__ */ Symbol.for("Deno.customInspect")](inspect, options) {
|
|
6178
|
-
return inspect(inspectableError(this), options);
|
|
6099
|
+
});
|
|
6100
|
+
|
|
6101
|
+
// src/commands/session/shared.ts
|
|
6102
|
+
var resolveSession = async (client, projectId, handle) => {
|
|
6103
|
+
const asInt = Number(handle);
|
|
6104
|
+
if (Number.isInteger(asInt) && asInt > 0) {
|
|
6105
|
+
const byId = await client.sessions.get(asInt).catch(() => null);
|
|
6106
|
+
if (byId) return { id: byId.id, name: byId.name };
|
|
6179
6107
|
}
|
|
6108
|
+
const byName = await client.sessions.findByName(projectId, handle);
|
|
6109
|
+
if (byName) return { id: byName.id, name: byName.name };
|
|
6110
|
+
throw new Error(`session "${handle}" not found in project ${projectId}`);
|
|
6180
6111
|
};
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
}
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
}
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
var _fetch;
|
|
6211
|
-
var _reconnectInterval;
|
|
6212
|
-
var _reconnectTimer;
|
|
6213
|
-
var _lastEventId;
|
|
6214
|
-
var _controller;
|
|
6215
|
-
var _parser;
|
|
6216
|
-
var _onError;
|
|
6217
|
-
var _onMessage;
|
|
6218
|
-
var _onOpen;
|
|
6219
|
-
var _EventSource_instances;
|
|
6220
|
-
var connect_fn;
|
|
6221
|
-
var _onFetchResponse;
|
|
6222
|
-
var _onFetchError;
|
|
6223
|
-
var getRequestOptions_fn;
|
|
6224
|
-
var _onEvent;
|
|
6225
|
-
var _onRetryChange;
|
|
6226
|
-
var failConnection_fn;
|
|
6227
|
-
var scheduleReconnect_fn;
|
|
6228
|
-
var _reconnect;
|
|
6229
|
-
var EventSource = class extends EventTarget {
|
|
6230
|
-
constructor(url, eventSourceInitDict) {
|
|
6231
|
-
var _a, _b;
|
|
6232
|
-
super(), __privateAdd(this, _EventSource_instances), this.CONNECTING = 0, this.OPEN = 1, this.CLOSED = 2, __privateAdd(this, _readyState), __privateAdd(this, _url), __privateAdd(this, _redirectUrl), __privateAdd(this, _withCredentials), __privateAdd(this, _fetch), __privateAdd(this, _reconnectInterval), __privateAdd(this, _reconnectTimer), __privateAdd(this, _lastEventId, null), __privateAdd(this, _controller), __privateAdd(this, _parser), __privateAdd(this, _onError, null), __privateAdd(this, _onMessage, null), __privateAdd(this, _onOpen, null), __privateAdd(this, _onFetchResponse, async (response) => {
|
|
6233
|
-
var _a2;
|
|
6234
|
-
__privateGet(this, _parser).reset();
|
|
6235
|
-
const { body, redirected, status, headers } = response;
|
|
6236
|
-
if (status === 204) {
|
|
6237
|
-
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Server sent HTTP 204, not reconnecting", 204), this.close();
|
|
6238
|
-
return;
|
|
6239
|
-
}
|
|
6240
|
-
if (redirected ? __privateSet(this, _redirectUrl, new URL(response.url)) : __privateSet(this, _redirectUrl, void 0), status !== 200) {
|
|
6241
|
-
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, `Non-200 status code (${status})`, status);
|
|
6242
|
-
return;
|
|
6243
|
-
}
|
|
6244
|
-
if (!(headers.get("content-type") || "").startsWith("text/event-stream")) {
|
|
6245
|
-
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, 'Invalid content type, expected "text/event-stream"', status);
|
|
6246
|
-
return;
|
|
6247
|
-
}
|
|
6248
|
-
if (__privateGet(this, _readyState) === this.CLOSED)
|
|
6249
|
-
return;
|
|
6250
|
-
__privateSet(this, _readyState, this.OPEN);
|
|
6251
|
-
const openEvent = new Event("open");
|
|
6252
|
-
if ((_a2 = __privateGet(this, _onOpen)) == null || _a2.call(this, openEvent), this.dispatchEvent(openEvent), typeof body != "object" || !body || !("getReader" in body)) {
|
|
6253
|
-
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid response body, expected a web ReadableStream", status), this.close();
|
|
6254
|
-
return;
|
|
6255
|
-
}
|
|
6256
|
-
const decoder = new TextDecoder(), reader = body.getReader();
|
|
6257
|
-
let open3 = true;
|
|
6258
|
-
do {
|
|
6259
|
-
const { done, value } = await reader.read();
|
|
6260
|
-
value && __privateGet(this, _parser).feed(decoder.decode(value, { stream: !done })), done && (open3 = false, __privateGet(this, _parser).reset(), __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this));
|
|
6261
|
-
} while (open3);
|
|
6262
|
-
}), __privateAdd(this, _onFetchError, (err) => {
|
|
6263
|
-
__privateSet(this, _controller, void 0), !(err.name === "AbortError" || err.type === "aborted") && __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this, flattenError(err));
|
|
6264
|
-
}), __privateAdd(this, _onEvent, (event) => {
|
|
6265
|
-
typeof event.id == "string" && __privateSet(this, _lastEventId, event.id);
|
|
6266
|
-
const messageEvent = new MessageEvent(event.event || "message", {
|
|
6267
|
-
data: event.data,
|
|
6268
|
-
origin: __privateGet(this, _redirectUrl) ? __privateGet(this, _redirectUrl).origin : __privateGet(this, _url).origin,
|
|
6269
|
-
lastEventId: event.id || ""
|
|
6270
|
-
});
|
|
6271
|
-
__privateGet(this, _onMessage) && (!event.event || event.event === "message") && __privateGet(this, _onMessage).call(this, messageEvent), this.dispatchEvent(messageEvent);
|
|
6272
|
-
}), __privateAdd(this, _onRetryChange, (value) => {
|
|
6273
|
-
__privateSet(this, _reconnectInterval, value);
|
|
6274
|
-
}), __privateAdd(this, _reconnect, () => {
|
|
6275
|
-
__privateSet(this, _reconnectTimer, void 0), __privateGet(this, _readyState) === this.CONNECTING && __privateMethod(this, _EventSource_instances, connect_fn).call(this);
|
|
6112
|
+
|
|
6113
|
+
// src/commands/loop/create.ts
|
|
6114
|
+
var loopCreateCommand = defineCommand({
|
|
6115
|
+
meta: { name: "create", description: "create a recurring scheduled message on a session" },
|
|
6116
|
+
args: {
|
|
6117
|
+
session: { type: "positional", required: true, description: "session int id or name" },
|
|
6118
|
+
message: {
|
|
6119
|
+
type: "string",
|
|
6120
|
+
required: true,
|
|
6121
|
+
description: "message sent to the session each beat"
|
|
6122
|
+
},
|
|
6123
|
+
every: {
|
|
6124
|
+
type: "string",
|
|
6125
|
+
required: true,
|
|
6126
|
+
description: "interval: 90s / 30m / 2h / 1d (min 30s)"
|
|
6127
|
+
},
|
|
6128
|
+
name: { type: "string", description: "optional label" },
|
|
6129
|
+
off: { type: "boolean", description: "create paused (disabled)" },
|
|
6130
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
6131
|
+
...common
|
|
6132
|
+
},
|
|
6133
|
+
run: async ({ args }) => {
|
|
6134
|
+
const c = clientFor(args);
|
|
6135
|
+
const session2 = await resolveSession(c, resolveProjectId(args), args.session);
|
|
6136
|
+
const loop2 = await c.loops.create(session2.id, {
|
|
6137
|
+
message: args.message,
|
|
6138
|
+
intervalSec: parseDuration(args.every),
|
|
6139
|
+
name: args.name,
|
|
6140
|
+
enabled: !args.off
|
|
6276
6141
|
});
|
|
6277
|
-
|
|
6278
|
-
if (url instanceof URL)
|
|
6279
|
-
__privateSet(this, _url, url);
|
|
6280
|
-
else if (typeof url == "string")
|
|
6281
|
-
__privateSet(this, _url, new URL(url, getBaseURL()));
|
|
6282
|
-
else
|
|
6283
|
-
throw new Error("Invalid URL");
|
|
6284
|
-
} catch {
|
|
6285
|
-
throw syntaxError("An invalid or illegal string was specified");
|
|
6286
|
-
}
|
|
6287
|
-
__privateSet(this, _parser, createParser({
|
|
6288
|
-
onEvent: __privateGet(this, _onEvent),
|
|
6289
|
-
onRetry: __privateGet(this, _onRetryChange)
|
|
6290
|
-
})), __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _reconnectInterval, 3e3), __privateSet(this, _fetch, (_a = eventSourceInitDict == null ? void 0 : eventSourceInitDict.fetch) != null ? _a : globalThis.fetch), __privateSet(this, _withCredentials, (_b = eventSourceInitDict == null ? void 0 : eventSourceInitDict.withCredentials) != null ? _b : false), __privateMethod(this, _EventSource_instances, connect_fn).call(this);
|
|
6291
|
-
}
|
|
6292
|
-
/**
|
|
6293
|
-
* Returns the state of this EventSource object's connection. It can have the values described below.
|
|
6294
|
-
*
|
|
6295
|
-
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)
|
|
6296
|
-
*
|
|
6297
|
-
* Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,
|
|
6298
|
-
* defined in the TypeScript `dom` library.
|
|
6299
|
-
*
|
|
6300
|
-
* @public
|
|
6301
|
-
*/
|
|
6302
|
-
get readyState() {
|
|
6303
|
-
return __privateGet(this, _readyState);
|
|
6142
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6304
6143
|
}
|
|
6305
|
-
/**
|
|
6306
|
-
* Returns the URL providing the event stream.
|
|
6307
|
-
*
|
|
6308
|
-
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)
|
|
6309
|
-
*
|
|
6310
|
-
* @public
|
|
6311
|
-
*/
|
|
6312
|
-
get url() {
|
|
6313
|
-
return __privateGet(this, _url).href;
|
|
6314
|
-
}
|
|
6315
|
-
/**
|
|
6316
|
-
* Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
|
|
6317
|
-
*
|
|
6318
|
-
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)
|
|
6319
|
-
*/
|
|
6320
|
-
get withCredentials() {
|
|
6321
|
-
return __privateGet(this, _withCredentials);
|
|
6322
|
-
}
|
|
6323
|
-
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */
|
|
6324
|
-
get onerror() {
|
|
6325
|
-
return __privateGet(this, _onError);
|
|
6326
|
-
}
|
|
6327
|
-
set onerror(value) {
|
|
6328
|
-
__privateSet(this, _onError, value);
|
|
6329
|
-
}
|
|
6330
|
-
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */
|
|
6331
|
-
get onmessage() {
|
|
6332
|
-
return __privateGet(this, _onMessage);
|
|
6333
|
-
}
|
|
6334
|
-
set onmessage(value) {
|
|
6335
|
-
__privateSet(this, _onMessage, value);
|
|
6336
|
-
}
|
|
6337
|
-
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */
|
|
6338
|
-
get onopen() {
|
|
6339
|
-
return __privateGet(this, _onOpen);
|
|
6340
|
-
}
|
|
6341
|
-
set onopen(value) {
|
|
6342
|
-
__privateSet(this, _onOpen, value);
|
|
6343
|
-
}
|
|
6344
|
-
addEventListener(type, listener, options) {
|
|
6345
|
-
const listen = listener;
|
|
6346
|
-
super.addEventListener(type, listen, options);
|
|
6347
|
-
}
|
|
6348
|
-
removeEventListener(type, listener, options) {
|
|
6349
|
-
const listen = listener;
|
|
6350
|
-
super.removeEventListener(type, listen, options);
|
|
6351
|
-
}
|
|
6352
|
-
/**
|
|
6353
|
-
* Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
|
|
6354
|
-
*
|
|
6355
|
-
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)
|
|
6356
|
-
*
|
|
6357
|
-
* @public
|
|
6358
|
-
*/
|
|
6359
|
-
close() {
|
|
6360
|
-
__privateGet(this, _reconnectTimer) && clearTimeout(__privateGet(this, _reconnectTimer)), __privateGet(this, _readyState) !== this.CLOSED && (__privateGet(this, _controller) && __privateGet(this, _controller).abort(), __privateSet(this, _readyState, this.CLOSED), __privateSet(this, _controller, void 0));
|
|
6361
|
-
}
|
|
6362
|
-
};
|
|
6363
|
-
_readyState = /* @__PURE__ */ new WeakMap(), _url = /* @__PURE__ */ new WeakMap(), _redirectUrl = /* @__PURE__ */ new WeakMap(), _withCredentials = /* @__PURE__ */ new WeakMap(), _fetch = /* @__PURE__ */ new WeakMap(), _reconnectInterval = /* @__PURE__ */ new WeakMap(), _reconnectTimer = /* @__PURE__ */ new WeakMap(), _lastEventId = /* @__PURE__ */ new WeakMap(), _controller = /* @__PURE__ */ new WeakMap(), _parser = /* @__PURE__ */ new WeakMap(), _onError = /* @__PURE__ */ new WeakMap(), _onMessage = /* @__PURE__ */ new WeakMap(), _onOpen = /* @__PURE__ */ new WeakMap(), _EventSource_instances = /* @__PURE__ */ new WeakSet(), /**
|
|
6364
|
-
* Connect to the given URL and start receiving events
|
|
6365
|
-
*
|
|
6366
|
-
* @internal
|
|
6367
|
-
*/
|
|
6368
|
-
connect_fn = function() {
|
|
6369
|
-
__privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _controller, new AbortController()), __privateGet(this, _fetch)(__privateGet(this, _url), __privateMethod(this, _EventSource_instances, getRequestOptions_fn).call(this)).then(__privateGet(this, _onFetchResponse)).catch(__privateGet(this, _onFetchError));
|
|
6370
|
-
}, _onFetchResponse = /* @__PURE__ */ new WeakMap(), _onFetchError = /* @__PURE__ */ new WeakMap(), /**
|
|
6371
|
-
* Get request options for the `fetch()` request
|
|
6372
|
-
*
|
|
6373
|
-
* @returns The request options
|
|
6374
|
-
* @internal
|
|
6375
|
-
*/
|
|
6376
|
-
getRequestOptions_fn = function() {
|
|
6377
|
-
var _a;
|
|
6378
|
-
const init2 = {
|
|
6379
|
-
// [spec] Let `corsAttributeState` be `Anonymous`…
|
|
6380
|
-
// [spec] …will have their mode set to "cors"…
|
|
6381
|
-
mode: "cors",
|
|
6382
|
-
redirect: "follow",
|
|
6383
|
-
headers: { Accept: "text/event-stream", ...__privateGet(this, _lastEventId) ? { "Last-Event-ID": __privateGet(this, _lastEventId) } : void 0 },
|
|
6384
|
-
cache: "no-store",
|
|
6385
|
-
signal: (_a = __privateGet(this, _controller)) == null ? void 0 : _a.signal
|
|
6386
|
-
};
|
|
6387
|
-
return "window" in globalThis && (init2.credentials = this.withCredentials ? "include" : "same-origin"), init2;
|
|
6388
|
-
}, _onEvent = /* @__PURE__ */ new WeakMap(), _onRetryChange = /* @__PURE__ */ new WeakMap(), /**
|
|
6389
|
-
* Handles the process referred to in the EventSource specification as "failing a connection".
|
|
6390
|
-
*
|
|
6391
|
-
* @param error - The error causing the connection to fail
|
|
6392
|
-
* @param code - The HTTP status code, if available
|
|
6393
|
-
* @internal
|
|
6394
|
-
*/
|
|
6395
|
-
failConnection_fn = function(message, code) {
|
|
6396
|
-
var _a;
|
|
6397
|
-
__privateGet(this, _readyState) !== this.CLOSED && __privateSet(this, _readyState, this.CLOSED);
|
|
6398
|
-
const errorEvent = new ErrorEvent("error", { code, message });
|
|
6399
|
-
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent);
|
|
6400
|
-
}, /**
|
|
6401
|
-
* Schedules a reconnection attempt against the EventSource endpoint.
|
|
6402
|
-
*
|
|
6403
|
-
* @param message - The error causing the connection to fail
|
|
6404
|
-
* @param code - The HTTP status code, if available
|
|
6405
|
-
* @internal
|
|
6406
|
-
*/
|
|
6407
|
-
scheduleReconnect_fn = function(message, code) {
|
|
6408
|
-
var _a;
|
|
6409
|
-
if (__privateGet(this, _readyState) === this.CLOSED)
|
|
6410
|
-
return;
|
|
6411
|
-
__privateSet(this, _readyState, this.CONNECTING);
|
|
6412
|
-
const errorEvent = new ErrorEvent("error", { code, message });
|
|
6413
|
-
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent), __privateSet(this, _reconnectTimer, setTimeout(__privateGet(this, _reconnect), __privateGet(this, _reconnectInterval)));
|
|
6414
|
-
}, _reconnect = /* @__PURE__ */ new WeakMap(), /**
|
|
6415
|
-
* ReadyState representing an EventSource currently trying to connect
|
|
6416
|
-
*
|
|
6417
|
-
* @public
|
|
6418
|
-
*/
|
|
6419
|
-
EventSource.CONNECTING = 0, /**
|
|
6420
|
-
* ReadyState representing an EventSource connection that is open (eg connected)
|
|
6421
|
-
*
|
|
6422
|
-
* @public
|
|
6423
|
-
*/
|
|
6424
|
-
EventSource.OPEN = 1, /**
|
|
6425
|
-
* ReadyState representing an EventSource connection that is closed (eg disconnected)
|
|
6426
|
-
*
|
|
6427
|
-
* @public
|
|
6428
|
-
*/
|
|
6429
|
-
EventSource.CLOSED = 2;
|
|
6430
|
-
Object.defineProperty(EventSource, /* @__PURE__ */ Symbol.for("eventsource.supports-fetch-override"), {
|
|
6431
|
-
value: true,
|
|
6432
|
-
writable: false,
|
|
6433
|
-
configurable: false,
|
|
6434
|
-
enumerable: false
|
|
6435
6144
|
});
|
|
6436
|
-
function getBaseURL() {
|
|
6437
|
-
const doc = "document" in globalThis ? globalThis.document : void 0;
|
|
6438
|
-
return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
|
|
6439
|
-
}
|
|
6440
|
-
|
|
6441
|
-
// src/client/channel.ts
|
|
6442
|
-
var channelClient = (baseUrl) => {
|
|
6443
|
-
const u = (p) => `${baseUrl}${p}`;
|
|
6444
|
-
const JSON_CT = { "content-type": "application/json" };
|
|
6445
|
-
const member = (channelId, name) => u(`/channels/${channelId}/members/${encodeURIComponent(name)}`);
|
|
6446
|
-
return {
|
|
6447
|
-
create: async (workspaceId, title, description, token) => {
|
|
6448
|
-
const res = await fetch(u(`/workspaces/${workspaceId}/channels`), {
|
|
6449
|
-
method: "POST",
|
|
6450
|
-
headers: { ...JSON_CT, ...token ? { authorization: `Bearer ${token}` } : {} },
|
|
6451
|
-
body: JSON.stringify({
|
|
6452
|
-
...title ? { title } : {},
|
|
6453
|
-
...description ? { description } : {}
|
|
6454
|
-
})
|
|
6455
|
-
});
|
|
6456
|
-
if (!res.ok)
|
|
6457
|
-
throw new Error(
|
|
6458
|
-
`POST /workspaces/${workspaceId}/channels \u2192 ${res.status}: ${await res.text()}`
|
|
6459
|
-
);
|
|
6460
|
-
return await res.json();
|
|
6461
|
-
},
|
|
6462
|
-
manifest: async (channelId) => {
|
|
6463
|
-
const res = await fetch(u(`/channels/${channelId}`));
|
|
6464
|
-
if (!res.ok) throw new Error(`GET channel \u2192 ${res.status}: ${await res.text()}`);
|
|
6465
|
-
return await res.json();
|
|
6466
|
-
},
|
|
6467
|
-
update: async (channelId, patch) => {
|
|
6468
|
-
const res = await fetch(u(`/channels/${channelId}`), {
|
|
6469
|
-
method: "PATCH",
|
|
6470
|
-
headers: JSON_CT,
|
|
6471
|
-
body: JSON.stringify(patch)
|
|
6472
|
-
});
|
|
6473
|
-
if (!res.ok) throw new Error(`PATCH channel \u2192 ${res.status}: ${await res.text()}`);
|
|
6474
|
-
return await res.json();
|
|
6475
|
-
},
|
|
6476
|
-
help: async () => {
|
|
6477
|
-
const res = await fetch(u("/channels/help"));
|
|
6478
|
-
if (!res.ok) throw new Error(`GET /channels/help \u2192 ${res.status}: ${await res.text()}`);
|
|
6479
|
-
return await res.text();
|
|
6480
|
-
},
|
|
6481
|
-
destroy: async (channelId) => {
|
|
6482
|
-
const res = await fetch(u(`/channels/${channelId}`), { method: "DELETE" });
|
|
6483
|
-
if (!res.ok) throw new Error(`DELETE channel \u2192 ${res.status}: ${await res.text()}`);
|
|
6484
|
-
},
|
|
6485
|
-
join: async (channelId, name, kind) => {
|
|
6486
|
-
const res = await fetch(member(channelId, name), {
|
|
6487
|
-
method: "PUT",
|
|
6488
|
-
headers: JSON_CT,
|
|
6489
|
-
body: JSON.stringify({ kind: kind ?? "agent" })
|
|
6490
|
-
});
|
|
6491
|
-
if (!res.ok) throw new Error(`join channel \u2192 ${res.status}: ${await res.text()}`);
|
|
6492
|
-
return (await res.json()).members;
|
|
6493
|
-
},
|
|
6494
|
-
leave: async (channelId, name) => {
|
|
6495
|
-
const res = await fetch(member(channelId, name), { method: "DELETE" });
|
|
6496
|
-
if (!res.ok) throw new Error(`leave channel \u2192 ${res.status}: ${await res.text()}`);
|
|
6497
|
-
},
|
|
6498
|
-
members: async (channelId) => {
|
|
6499
|
-
const res = await fetch(u(`/channels/${channelId}/members`));
|
|
6500
|
-
if (!res.ok) throw new Error(`GET members \u2192 ${res.status}: ${await res.text()}`);
|
|
6501
|
-
return (await res.json()).members;
|
|
6502
|
-
},
|
|
6503
|
-
send: async (channelId, msg) => {
|
|
6504
|
-
const res = await fetch(u(`/channels/${channelId}/messages`), {
|
|
6505
|
-
method: "POST",
|
|
6506
|
-
headers: JSON_CT,
|
|
6507
|
-
body: JSON.stringify(msg)
|
|
6508
|
-
});
|
|
6509
|
-
if (!res.ok) throw new Error(`POST channel message \u2192 ${res.status}: ${await res.text()}`);
|
|
6510
|
-
return await res.json();
|
|
6511
|
-
},
|
|
6512
|
-
uploadAttachment: async (channelId, input) => {
|
|
6513
|
-
const res = await fetch(
|
|
6514
|
-
u(`/channels/${channelId}/attachments?filename=${encodeURIComponent(input.filename)}`),
|
|
6515
|
-
{ method: "POST", headers: { "content-type": input.contentType }, body: input.body }
|
|
6516
|
-
);
|
|
6517
|
-
if (!res.ok) throw new Error(`upload attachment \u2192 ${res.status}: ${await res.text()}`);
|
|
6518
|
-
return await res.json();
|
|
6519
|
-
},
|
|
6520
|
-
downloadAttachment: async (channelId, attId) => {
|
|
6521
|
-
const res = await fetch(u(`/channels/${channelId}/attachments/${attId}`));
|
|
6522
|
-
if (!res.ok) throw new Error(`download attachment \u2192 ${res.status}: ${await res.text()}`);
|
|
6523
|
-
return res;
|
|
6524
|
-
},
|
|
6525
|
-
read: async (channelId, opts) => {
|
|
6526
|
-
const params = new URLSearchParams({ since: String(opts?.since ?? 0) });
|
|
6527
|
-
if (opts?.for) params.set("for", opts.for);
|
|
6528
|
-
const res = await fetch(u(`/channels/${channelId}/messages?${params}`));
|
|
6529
|
-
if (!res.ok) throw new Error(`GET messages \u2192 ${res.status}: ${await res.text()}`);
|
|
6530
|
-
return (await res.json()).messages;
|
|
6531
|
-
},
|
|
6532
|
-
listen: (channelId, opts) => {
|
|
6533
|
-
let cursor = opts.since ?? 0;
|
|
6534
|
-
const params = new URLSearchParams({ since: String(cursor) });
|
|
6535
|
-
if (opts.for) params.set("for", opts.for);
|
|
6536
|
-
if (opts.as) params.set("as", opts.as);
|
|
6537
|
-
const es = new EventSource(u(`/channels/${channelId}/stream?${params}`));
|
|
6538
|
-
es.onmessage = (e) => {
|
|
6539
|
-
try {
|
|
6540
|
-
const m = JSON.parse(e.data);
|
|
6541
|
-
if (m.seq <= cursor) return;
|
|
6542
|
-
cursor = m.seq;
|
|
6543
|
-
opts.onMessage(m);
|
|
6544
|
-
} catch (err) {
|
|
6545
|
-
opts.onError?.(err);
|
|
6546
|
-
}
|
|
6547
|
-
};
|
|
6548
|
-
es.onerror = (err) => opts.onError?.(err);
|
|
6549
|
-
return () => es.close();
|
|
6550
|
-
}
|
|
6551
|
-
};
|
|
6552
|
-
};
|
|
6553
6145
|
|
|
6554
|
-
// src/commands/
|
|
6555
|
-
var
|
|
6556
|
-
meta: { name: "
|
|
6146
|
+
// src/commands/loop/disable.ts
|
|
6147
|
+
var loopDisableCommand = defineCommand({
|
|
6148
|
+
meta: { name: "disable", description: "disable (pause) a loop" },
|
|
6557
6149
|
args: {
|
|
6558
|
-
|
|
6150
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
6559
6151
|
...common
|
|
6560
6152
|
},
|
|
6561
6153
|
run: async ({ args }) => {
|
|
6562
|
-
|
|
6563
|
-
|
|
6154
|
+
const c = clientFor(args);
|
|
6155
|
+
const loop2 = await c.loops.update(Number(args.loop), { enabled: false });
|
|
6156
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6564
6157
|
}
|
|
6565
6158
|
});
|
|
6566
6159
|
|
|
6567
|
-
// src/commands/
|
|
6568
|
-
var
|
|
6569
|
-
|
|
6570
|
-
for await (const c of process.stdin) chunks.push(c);
|
|
6571
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
6572
|
-
};
|
|
6573
|
-
var renderRoster = (members) => members.length ? members.map((m) => ` ${m.name} (${m.kind})`).join("\n") : " (nobody online)";
|
|
6574
|
-
var webLink = (url, channelId) => {
|
|
6575
|
-
const origin = url.replace(/\/api\/?$/, "");
|
|
6576
|
-
return origin === url ? null : `${origin}/channel/${channelId}`;
|
|
6577
|
-
};
|
|
6578
|
-
var inviteBlock = (url, channelId) => {
|
|
6579
|
-
const web = webLink(url, channelId);
|
|
6580
|
-
return [
|
|
6581
|
-
"\u2500\u2500 Share this to invite anyone into the room \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
6582
|
-
...web ? [`Humans \u2014 open in a browser: ${web}`, ""] : [],
|
|
6583
|
-
"Agents \u2014 two curl steps:",
|
|
6584
|
-
` 1) see the room: curl -sS "${url}/channels/${channelId}"`,
|
|
6585
|
-
` 2) read protocol: curl -sS "${url}/channels/help" (then join / listen / send, pick your own NAME)`,
|
|
6586
|
-
"",
|
|
6587
|
-
`connection: url=${url} channel=${channelId}`,
|
|
6588
|
-
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
6589
|
-
].join("\n");
|
|
6590
|
-
};
|
|
6591
|
-
|
|
6592
|
-
// src/commands/channel/create.ts
|
|
6593
|
-
var createCommand = defineCommand({
|
|
6594
|
-
meta: {
|
|
6595
|
-
name: "create",
|
|
6596
|
-
description: "open a channel (chat room) in a workspace and print an invite"
|
|
6597
|
-
},
|
|
6160
|
+
// src/commands/loop/enable.ts
|
|
6161
|
+
var loopEnableCommand = defineCommand({
|
|
6162
|
+
meta: { name: "enable", description: "enable (resume) a loop" },
|
|
6598
6163
|
args: {
|
|
6599
|
-
|
|
6600
|
-
type: "string",
|
|
6601
|
-
description: "owning workspace id (or the cwd .baton.json workspace)"
|
|
6602
|
-
},
|
|
6603
|
-
name: { type: "string", description: "room title (optional)" },
|
|
6604
|
-
desc: {
|
|
6605
|
-
type: "string",
|
|
6606
|
-
description: "room self-description: purpose / topic / how to participate"
|
|
6607
|
-
},
|
|
6164
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
6608
6165
|
...common
|
|
6609
6166
|
},
|
|
6610
6167
|
run: async ({ args }) => {
|
|
6611
|
-
const
|
|
6612
|
-
const
|
|
6613
|
-
|
|
6614
|
-
workspaceId,
|
|
6615
|
-
args.name,
|
|
6616
|
-
args.desc,
|
|
6617
|
-
resolveBearer()
|
|
6618
|
-
);
|
|
6619
|
-
if (args.json) {
|
|
6620
|
-
console.log(toJson({ channelId, url, workspaceId, name: args.name, description: args.desc }));
|
|
6621
|
-
return;
|
|
6622
|
-
}
|
|
6623
|
-
console.log(`channel ${channelId} opened in workspace ${workspaceId}
|
|
6624
|
-
`);
|
|
6625
|
-
console.log(inviteBlock(url, channelId));
|
|
6168
|
+
const c = clientFor(args);
|
|
6169
|
+
const loop2 = await c.loops.update(Number(args.loop), { enabled: true });
|
|
6170
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6626
6171
|
}
|
|
6627
6172
|
});
|
|
6628
6173
|
|
|
6629
|
-
// src/commands/
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
meta: { name: "download", description: "download a channel attachment to a file" },
|
|
6174
|
+
// src/commands/loop/get.ts
|
|
6175
|
+
var loopGetCommand = defineCommand({
|
|
6176
|
+
meta: { name: "get", description: "show one loop" },
|
|
6633
6177
|
args: {
|
|
6634
|
-
|
|
6635
|
-
att: { type: "positional", required: true, description: "attachment id (from a message ref)" },
|
|
6636
|
-
out: { type: "string", alias: "o", description: "output file path (default: ./<attId>)" },
|
|
6178
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
6637
6179
|
...common
|
|
6638
6180
|
},
|
|
6639
6181
|
run: async ({ args }) => {
|
|
6640
|
-
const
|
|
6641
|
-
const
|
|
6642
|
-
|
|
6643
|
-
writeFileSync2(out, Buffer.from(await res.arrayBuffer()));
|
|
6644
|
-
console.log(`saved \u2192 ${out}`);
|
|
6182
|
+
const c = clientFor(args);
|
|
6183
|
+
const loop2 = await c.loops.get(Number(args.loop));
|
|
6184
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6645
6185
|
}
|
|
6646
6186
|
});
|
|
6647
6187
|
|
|
6648
|
-
// src/commands/
|
|
6649
|
-
var
|
|
6650
|
-
meta: { name: "
|
|
6188
|
+
// src/commands/loop/ls.ts
|
|
6189
|
+
var loopLsCommand = defineCommand({
|
|
6190
|
+
meta: { name: "ls", description: "list a session's loops" },
|
|
6651
6191
|
args: {
|
|
6652
|
-
|
|
6192
|
+
session: { type: "positional", required: true, description: "session int id or name" },
|
|
6193
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
6653
6194
|
...common
|
|
6654
6195
|
},
|
|
6655
6196
|
run: async ({ args }) => {
|
|
6656
|
-
const
|
|
6657
|
-
const
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
return;
|
|
6661
|
-
}
|
|
6662
|
-
console.log(`${m.title ?? "(untitled)"} [${m.id}]`);
|
|
6663
|
-
if (m.description) console.log(m.description);
|
|
6664
|
-
console.log(`
|
|
6665
|
-
online (${m.members.length}):
|
|
6666
|
-
${renderRoster(m.members)}`);
|
|
6667
|
-
console.log(`
|
|
6668
|
-
protocol: curl -sS "${url}${m.help}"`);
|
|
6669
|
-
}
|
|
6670
|
-
});
|
|
6671
|
-
var helpCommand = defineCommand({
|
|
6672
|
-
meta: { name: "help", description: "print the channel protocol doc" },
|
|
6673
|
-
args: { ...common },
|
|
6674
|
-
run: async ({ args }) => {
|
|
6675
|
-
console.log(await channelClient(resolveBaseUrl(args.url)).help());
|
|
6197
|
+
const c = clientFor(args);
|
|
6198
|
+
const session2 = await resolveSession(c, resolveProjectId(args), args.session);
|
|
6199
|
+
const loops = await c.loops.listBySession(session2.id);
|
|
6200
|
+
console.log(renderList(loops, fmtLoop, Boolean(args.json)));
|
|
6676
6201
|
}
|
|
6677
6202
|
});
|
|
6678
|
-
|
|
6679
|
-
|
|
6203
|
+
|
|
6204
|
+
// src/commands/loop/rm.ts
|
|
6205
|
+
var loopRmCommand = defineCommand({
|
|
6206
|
+
meta: { name: "rm", description: "delete a loop" },
|
|
6680
6207
|
args: {
|
|
6681
|
-
|
|
6208
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
6682
6209
|
...common
|
|
6683
6210
|
},
|
|
6684
6211
|
run: async ({ args }) => {
|
|
6685
|
-
const
|
|
6686
|
-
const
|
|
6687
|
-
|
|
6212
|
+
const c = clientFor(args);
|
|
6213
|
+
const id = Number(args.loop);
|
|
6214
|
+
await c.loops.remove(id);
|
|
6215
|
+
console.log(removed("loop", id, Boolean(args.json)));
|
|
6688
6216
|
}
|
|
6689
6217
|
});
|
|
6690
|
-
|
|
6691
|
-
|
|
6218
|
+
|
|
6219
|
+
// src/commands/loop/set.ts
|
|
6220
|
+
var loopSetCommand = defineCommand({
|
|
6221
|
+
meta: { name: "set", description: "update a loop (message / interval / name)" },
|
|
6692
6222
|
args: {
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6223
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
6224
|
+
message: { type: "string", description: "new message" },
|
|
6225
|
+
every: { type: "string", description: "new interval: 90s / 30m / 2h / 1d" },
|
|
6226
|
+
name: { type: "string", description: "new label" },
|
|
6696
6227
|
...common
|
|
6697
6228
|
},
|
|
6698
6229
|
run: async ({ args }) => {
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
console.log(args.json ? toJson(ch) : `updated ${ch.id}${ch.title ? ` \u2014 ${ch.title}` : ""}`);
|
|
6230
|
+
const c = clientFor(args);
|
|
6231
|
+
const patch = {};
|
|
6232
|
+
if (args.message !== void 0) patch.message = args.message;
|
|
6233
|
+
if (args.every !== void 0 && args.every !== "") patch.intervalSec = parseDuration(args.every);
|
|
6234
|
+
if (args.name !== void 0) patch.name = args.name;
|
|
6235
|
+
const loop2 = await c.loops.update(Number(args.loop), patch);
|
|
6236
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6707
6237
|
}
|
|
6708
6238
|
});
|
|
6709
6239
|
|
|
6710
|
-
// src/commands/
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6240
|
+
// src/commands/loop.ts
|
|
6241
|
+
var loop = defineCommand({
|
|
6242
|
+
meta: { name: "loop", description: "recurring scheduled messages that wake a session" },
|
|
6243
|
+
subCommands: {
|
|
6244
|
+
create: loopCreateCommand,
|
|
6245
|
+
ls: loopLsCommand,
|
|
6246
|
+
get: loopGetCommand,
|
|
6247
|
+
set: loopSetCommand,
|
|
6248
|
+
enable: loopEnableCommand,
|
|
6249
|
+
disable: loopDisableCommand,
|
|
6250
|
+
rm: loopRmCommand
|
|
6251
|
+
}
|
|
6252
|
+
});
|
|
6253
|
+
|
|
6254
|
+
// src/commands/notify.ts
|
|
6255
|
+
var describe = (result) => {
|
|
6256
|
+
if (result.status === "sent") return `notified ${result.devices} device(s)`;
|
|
6257
|
+
if (result.status === "throttled")
|
|
6258
|
+
return `throttled: this session can notify again in ${result.retryAfterSec}s`;
|
|
6259
|
+
return "nobody to notify: no human has messaged this session, or they have not enabled notifications";
|
|
6723
6260
|
};
|
|
6261
|
+
var notify = defineCommand({
|
|
6262
|
+
meta: {
|
|
6263
|
+
name: "notify",
|
|
6264
|
+
description: "Push a phone notification to the person working with this session. Use it only when a human needs to act now: something is wrong, a decision is needed, or the work is blocked. Do not use it for routine progress, and not to announce that a turn finished (that is already pushed). At most one notification per session every 10 minutes; text is cut at 200 characters."
|
|
6265
|
+
},
|
|
6266
|
+
args: {
|
|
6267
|
+
text: { type: "positional", required: true, description: "one short line for the lock screen" },
|
|
6268
|
+
...common
|
|
6269
|
+
},
|
|
6270
|
+
run: async ({ args }) => {
|
|
6271
|
+
const raw = process.env.BATON_SESSION_ID;
|
|
6272
|
+
if (raw === void 0)
|
|
6273
|
+
throw new Error("baton notify only works inside a baton session (BATON_SESSION_ID is unset)");
|
|
6274
|
+
const sessionId = Number(raw);
|
|
6275
|
+
if (!Number.isSafeInteger(sessionId) || sessionId <= 0)
|
|
6276
|
+
throw new Error("invalid BATON_SESSION_ID");
|
|
6277
|
+
const result = await clientFor(args).sessions.notify(sessionId, args.text);
|
|
6278
|
+
console.log(args.json ? toJson(result) : describe(result));
|
|
6279
|
+
}
|
|
6280
|
+
});
|
|
6281
|
+
|
|
6282
|
+
// src/commands/project.ts
|
|
6283
|
+
var createProject = (c, input, json) => c.projects.create(input).then((p) => renderOne(p, fmtProject, json));
|
|
6284
|
+
var listProjects = (c, workspaceId, json) => c.projects.listByWorkspace(workspaceId).then((ps) => renderList(ps, fmtProject, json));
|
|
6285
|
+
var getProject = (c, id, json) => c.projects.get(id).then((p) => renderOne(p, fmtProject, json));
|
|
6286
|
+
var updateProject = (c, id, patch, json) => c.projects.update(id, patch).then((p) => renderOne(p, fmtProject, json));
|
|
6287
|
+
var removeProject = (c, id, json) => c.projects.remove(id).then(() => removed("project", id, json));
|
|
6288
|
+
var project = defineCommand({
|
|
6289
|
+
meta: { name: "project", description: "manage projects" },
|
|
6290
|
+
subCommands: {
|
|
6291
|
+
create: defineCommand({
|
|
6292
|
+
meta: { name: "create", description: "create a project" },
|
|
6293
|
+
args: {
|
|
6294
|
+
name: { type: "positional", required: true },
|
|
6295
|
+
workspace: { type: "string", description: "workspace id (overrides .baton.json)" },
|
|
6296
|
+
desc: { type: "string", description: "description" },
|
|
6297
|
+
...common
|
|
6298
|
+
},
|
|
6299
|
+
run: async ({ args }) => {
|
|
6300
|
+
const out = await createProject(
|
|
6301
|
+
clientFor(args),
|
|
6302
|
+
{ workspaceId: resolveWorkspaceId(args), name: args.name, description: args.desc },
|
|
6303
|
+
Boolean(args.json)
|
|
6304
|
+
);
|
|
6305
|
+
console.log(out);
|
|
6306
|
+
}
|
|
6307
|
+
}),
|
|
6308
|
+
ls: defineCommand({
|
|
6309
|
+
meta: { name: "ls", description: "list projects in a workspace" },
|
|
6310
|
+
args: {
|
|
6311
|
+
workspace: { type: "string", description: "workspace id (overrides .baton.json)" },
|
|
6312
|
+
...common
|
|
6313
|
+
},
|
|
6314
|
+
run: async ({ args }) => {
|
|
6315
|
+
console.log(
|
|
6316
|
+
await listProjects(clientFor(args), resolveWorkspaceId(args), Boolean(args.json))
|
|
6317
|
+
);
|
|
6318
|
+
}
|
|
6319
|
+
}),
|
|
6320
|
+
get: defineCommand({
|
|
6321
|
+
meta: { name: "get", description: "get a project" },
|
|
6322
|
+
args: { id: { type: "positional", required: true }, ...common },
|
|
6323
|
+
run: async ({ args }) => {
|
|
6324
|
+
console.log(await getProject(clientFor(args), Number(args.id), Boolean(args.json)));
|
|
6325
|
+
}
|
|
6326
|
+
}),
|
|
6327
|
+
update: defineCommand({
|
|
6328
|
+
meta: { name: "update", description: "rename a project / set its description" },
|
|
6329
|
+
args: {
|
|
6330
|
+
id: { type: "positional", required: true },
|
|
6331
|
+
name: { type: "string", description: "new name" },
|
|
6332
|
+
desc: { type: "string", description: "new description" },
|
|
6333
|
+
...common
|
|
6334
|
+
},
|
|
6335
|
+
run: async ({ args }) => {
|
|
6336
|
+
const patch = {
|
|
6337
|
+
...args.name !== void 0 ? { name: args.name } : {},
|
|
6338
|
+
...args.desc !== void 0 ? { description: args.desc } : {}
|
|
6339
|
+
};
|
|
6340
|
+
if (Object.keys(patch).length === 0) throw new Error("pass --name and/or --desc");
|
|
6341
|
+
console.log(
|
|
6342
|
+
await updateProject(clientFor(args), Number(args.id), patch, Boolean(args.json))
|
|
6343
|
+
);
|
|
6344
|
+
}
|
|
6345
|
+
}),
|
|
6346
|
+
rm: defineCommand({
|
|
6347
|
+
meta: { name: "rm", description: "delete a project" },
|
|
6348
|
+
args: { id: { type: "positional", required: true }, ...common },
|
|
6349
|
+
run: async ({ args }) => {
|
|
6350
|
+
console.log(await removeProject(clientFor(args), Number(args.id), Boolean(args.json)));
|
|
6351
|
+
}
|
|
6352
|
+
})
|
|
6353
|
+
}
|
|
6354
|
+
});
|
|
6724
6355
|
|
|
6725
|
-
//
|
|
6726
|
-
|
|
6356
|
+
// src/provisioner/config.ts
|
|
6357
|
+
import { execFile } from "node:child_process";
|
|
6358
|
+
import { constants } from "node:fs";
|
|
6359
|
+
import { access, readFile, stat as stat2 } from "node:fs/promises";
|
|
6360
|
+
import { isAbsolute } from "node:path";
|
|
6361
|
+
import { promisify } from "node:util";
|
|
6362
|
+
|
|
6363
|
+
// ../shared/src/domain/attachment.ts
|
|
6364
|
+
var labelAttachments = (attachments) => {
|
|
6365
|
+
const counters = { image: 0, file: 0 };
|
|
6366
|
+
return attachments.map((att) => {
|
|
6367
|
+
const kind = att.contentType.startsWith("image/") ? "image" : "file";
|
|
6368
|
+
counters[kind] += 1;
|
|
6369
|
+
return `${kind}-${counters[kind]}`;
|
|
6370
|
+
});
|
|
6371
|
+
};
|
|
6727
6372
|
|
|
6728
6373
|
// ../shared/src/domain/file.ts
|
|
6729
6374
|
var FILE_TEXT_MAX_BYTES = 5 * 1024 * 1024;
|
|
@@ -6840,747 +6485,578 @@ var WORKER_TEMPLATES = [
|
|
|
6840
6485
|
var workerTemplateAgentKinds = (id) => id === "mini-local" ? AGENT_KINDS : WORKER_TEMPLATES.find((template) => template.id === id)?.agentKinds ?? [];
|
|
6841
6486
|
var isWorkerTemplateId = (value) => typeof value === "string" && workerTemplateAgentKinds(value).length > 0;
|
|
6842
6487
|
|
|
6843
|
-
// src/
|
|
6844
|
-
var
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6488
|
+
// src/provisioner/config.ts
|
|
6489
|
+
var forbiddenEnv = /* @__PURE__ */ new Set([
|
|
6490
|
+
"BATON_PROVISIONER_TOKEN",
|
|
6491
|
+
"BATON_TOKEN",
|
|
6492
|
+
"BATON_WORKER_TOKEN",
|
|
6493
|
+
"BATON_USER",
|
|
6494
|
+
"BATON_PASS",
|
|
6495
|
+
"HOME",
|
|
6496
|
+
"XDG_DATA_HOME"
|
|
6497
|
+
]);
|
|
6498
|
+
var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6499
|
+
var absolutePath = (value, field) => {
|
|
6500
|
+
if (typeof value !== "string" || !isAbsolute(value) || value.includes("\0"))
|
|
6501
|
+
throw new Error(`${field} must be an absolute path`);
|
|
6502
|
+
return value;
|
|
6848
6503
|
};
|
|
6849
|
-
var
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
const file = join2(spillDir, `${m.seq}.txt`);
|
|
6859
|
-
writeFileSync3(file, text);
|
|
6860
|
-
const truncated = text.length > PREVIEW;
|
|
6861
|
-
emit({
|
|
6862
|
-
type: "channel.message",
|
|
6863
|
-
seq: m.seq,
|
|
6864
|
-
from: m.from,
|
|
6865
|
-
senderKind: m.senderKind,
|
|
6866
|
-
to: m.to,
|
|
6867
|
-
mine: o.from ? isMessageFor(m, o.from) : void 0,
|
|
6868
|
-
ts: m.ts,
|
|
6869
|
-
chars: text.length,
|
|
6870
|
-
truncated,
|
|
6871
|
-
preview: truncated ? `${text.slice(0, PREVIEW)} \u2026` : text,
|
|
6872
|
-
// BASE-prefixed urls so the subscribing agent can fetch directly.
|
|
6873
|
-
attachments: m.attachments?.length ? m.attachments.map((a) => ({
|
|
6874
|
-
filename: a.filename,
|
|
6875
|
-
contentType: a.contentType,
|
|
6876
|
-
size: a.size,
|
|
6877
|
-
url: `${o.url}${a.url}`
|
|
6878
|
-
})) : void 0,
|
|
6879
|
-
file
|
|
6880
|
-
});
|
|
6881
|
-
};
|
|
6882
|
-
const close = channelClient(o.url).listen(o.channel, {
|
|
6883
|
-
since: o.since,
|
|
6884
|
-
for: o.for,
|
|
6885
|
-
as: o.from,
|
|
6886
|
-
// Skip our own messages (they echo back over the same channel).
|
|
6887
|
-
onMessage: (m) => {
|
|
6888
|
-
if (m.from !== o.from) surface(m);
|
|
6889
|
-
},
|
|
6890
|
-
onError: (e) => emit({ type: "channel.error", error: describe(e) })
|
|
6891
|
-
});
|
|
6892
|
-
emit({ type: "channel.listening", channel: o.channel, from: o.from, url: o.url });
|
|
6893
|
-
await new Promise((resolve4) => {
|
|
6894
|
-
const stop = () => {
|
|
6895
|
-
close();
|
|
6896
|
-
resolve4();
|
|
6897
|
-
};
|
|
6898
|
-
process.on("SIGINT", stop);
|
|
6899
|
-
process.on("SIGTERM", stop);
|
|
6900
|
-
});
|
|
6504
|
+
var environment = (value) => {
|
|
6505
|
+
if (!object(value)) throw new Error("workerEnv must be an object");
|
|
6506
|
+
return Object.fromEntries(
|
|
6507
|
+
Object.entries(value).map(([key, entry]) => {
|
|
6508
|
+
if (forbiddenEnv.has(key) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || typeof entry !== "string" || entry.includes("\0"))
|
|
6509
|
+
throw new Error(`invalid worker environment key: ${key}`);
|
|
6510
|
+
return [key, entry];
|
|
6511
|
+
})
|
|
6512
|
+
);
|
|
6901
6513
|
};
|
|
6902
|
-
var
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6514
|
+
var templates = (value) => {
|
|
6515
|
+
if (!object(value)) throw new Error("templates must be an object");
|
|
6516
|
+
return Object.fromEntries(
|
|
6517
|
+
WORKER_TEMPLATES.filter((template) => value[template.id] !== void 0).map((template) => {
|
|
6518
|
+
const raw = value[template.id];
|
|
6519
|
+
if (!object(raw)) throw new Error(`template ${template.id} must be an object`);
|
|
6520
|
+
const workerEnv2 = environment(raw.workerEnv);
|
|
6521
|
+
if (template.id === "mini-codex") {
|
|
6522
|
+
if (raw.pi !== void 0) throw new Error("mini-codex does not support pi");
|
|
6523
|
+
return [template.id, { workerEnv: workerEnv2 }];
|
|
6524
|
+
}
|
|
6525
|
+
const provider = template.id === "mini-glm-codeplan" ? "zai-coding-cn" : "qwen-token-plan-cn";
|
|
6526
|
+
const apiKey = template.id === "mini-glm-codeplan" ? "ZAI_CODING_CN_API_KEY" : "QWEN_TOKEN_PLAN_CN_API_KEY";
|
|
6527
|
+
if (!workerEnv2.ANTHROPIC_BASE_URL || !(workerEnv2.ANTHROPIC_AUTH_TOKEN || workerEnv2.ANTHROPIC_API_KEY) || !workerEnv2[apiKey])
|
|
6528
|
+
throw new Error(`template ${template.id} requires Claude and Pi credentials`);
|
|
6529
|
+
if (!object(raw.pi) || raw.pi.provider !== provider || typeof raw.pi.model !== "string" || !raw.pi.model.trim())
|
|
6530
|
+
throw new Error(`template ${template.id} requires its Pi provider and model`);
|
|
6531
|
+
return [template.id, { workerEnv: workerEnv2, pi: { provider, model: raw.pi.model.trim() } }];
|
|
6532
|
+
})
|
|
6533
|
+
);
|
|
6534
|
+
};
|
|
6535
|
+
var commandEnvironment = (config) => ({
|
|
6536
|
+
...process.env,
|
|
6537
|
+
PATH: config.workerEnv.PATH ?? process.env.PATH ?? "/usr/bin:/bin"
|
|
6926
6538
|
});
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
listen: {
|
|
6939
|
-
type: "boolean",
|
|
6940
|
-
description: "after joining, stream messages (background subscriber)"
|
|
6941
|
-
},
|
|
6942
|
-
since: { type: "string", description: "with --listen: replay after this seq (default 0)" },
|
|
6943
|
-
...common
|
|
6944
|
-
},
|
|
6945
|
-
run: async ({ args }) => {
|
|
6946
|
-
const url = resolveBaseUrl(args.url);
|
|
6947
|
-
const kind = args.kind === "human" ? "human" : "agent";
|
|
6948
|
-
const members = await channelClient(url).join(args.channel, args.from, kind);
|
|
6949
|
-
if (!args.listen) {
|
|
6950
|
-
if (args.json) console.log(toJson({ joined: args.from, members }));
|
|
6951
|
-
else
|
|
6952
|
-
console.log(`joined as ${args.from} (${members.length} online)
|
|
6953
|
-
${renderRoster(members)}`);
|
|
6954
|
-
return;
|
|
6955
|
-
}
|
|
6956
|
-
await runListen({
|
|
6957
|
-
url,
|
|
6958
|
-
channel: args.channel,
|
|
6959
|
-
from: args.from,
|
|
6960
|
-
since: args.since ? Number(args.since) : 0
|
|
6961
|
-
});
|
|
6539
|
+
var loadProvisionerConfig = async (path) => {
|
|
6540
|
+
if (process.platform !== "darwin") throw new Error("provisioner requires macOS");
|
|
6541
|
+
absolutePath(path, "config");
|
|
6542
|
+
if ((await stat2(path)).mode & 63) throw new Error("config must be private: chmod 600 <config>");
|
|
6543
|
+
const text = await readFile(path, "utf8");
|
|
6544
|
+
let raw;
|
|
6545
|
+
try {
|
|
6546
|
+
raw = JSON.parse(text);
|
|
6547
|
+
} catch (error) {
|
|
6548
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
6549
|
+
throw new Error("invalid provisioner JSON config");
|
|
6962
6550
|
}
|
|
6963
|
-
|
|
6551
|
+
if (!object(raw) || typeof raw.server !== "string" || typeof raw.token !== "string")
|
|
6552
|
+
throw new Error("server and token required");
|
|
6553
|
+
let server;
|
|
6554
|
+
try {
|
|
6555
|
+
server = new URL(raw.server);
|
|
6556
|
+
} catch (error) {
|
|
6557
|
+
if (!(error instanceof TypeError)) throw error;
|
|
6558
|
+
throw new Error("server must be a valid HTTP(S) URL");
|
|
6559
|
+
}
|
|
6560
|
+
if (!["http:", "https:"].includes(server.protocol) || server.username || server.password || server.search || server.hash)
|
|
6561
|
+
throw new Error("server must be an HTTP(S) URL without credentials, query, or fragment");
|
|
6562
|
+
if (!raw.token.trim() || /[\r\n]/.test(raw.token))
|
|
6563
|
+
throw new Error("valid provisioner token required");
|
|
6564
|
+
const config = {
|
|
6565
|
+
server: server.toString().replace(/\/$/, ""),
|
|
6566
|
+
token: raw.token.trim(),
|
|
6567
|
+
projectsRoot: absolutePath(raw.projectsRoot, "projectsRoot"),
|
|
6568
|
+
cliPath: absolutePath(raw.cliPath, "cliPath"),
|
|
6569
|
+
nodePath: absolutePath(raw.nodePath ?? process.execPath, "nodePath"),
|
|
6570
|
+
workerEnv: environment(raw.workerEnv),
|
|
6571
|
+
templates: templates(raw.templates)
|
|
6572
|
+
};
|
|
6573
|
+
await access(config.cliPath, constants.R_OK);
|
|
6574
|
+
await access(config.nodePath ?? process.execPath, constants.X_OK);
|
|
6575
|
+
const env = commandEnvironment(config);
|
|
6576
|
+
await promisify(execFile)("git", ["--version"], { env, timeout: 1e4 });
|
|
6577
|
+
await promisify(execFile)("launchctl", ["help"], { env, timeout: 1e4 });
|
|
6578
|
+
await promisify(execFile)("/usr/bin/plutil", ["-help"], { timeout: 1e4 });
|
|
6579
|
+
return config;
|
|
6580
|
+
};
|
|
6964
6581
|
|
|
6965
|
-
//
|
|
6966
|
-
var
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
return head + atts;
|
|
6582
|
+
// ../../node_modules/.pnpm/eventsource-parser@3.1.0/node_modules/eventsource-parser/dist/index.js
|
|
6583
|
+
var ParseError = class extends Error {
|
|
6584
|
+
constructor(message, options) {
|
|
6585
|
+
super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
|
|
6586
|
+
}
|
|
6971
6587
|
};
|
|
6972
|
-
var
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
run: async ({ args }) => {
|
|
6982
|
-
const url = resolveBaseUrl(args.url);
|
|
6983
|
-
const msgs = await channelClient(url).read(args.channel, {
|
|
6984
|
-
since: args.since ? Number(args.since) : 0,
|
|
6985
|
-
for: args.for
|
|
6986
|
-
});
|
|
6987
|
-
const out = args.from ? msgs.filter((m) => m.from !== args.from) : msgs;
|
|
6988
|
-
if (args.json) console.log(toJson(out));
|
|
6989
|
-
else console.log(out.length ? out.map((m) => fmtMessage(m, url)).join("\n") : "(none)");
|
|
6990
|
-
}
|
|
6991
|
-
});
|
|
6992
|
-
|
|
6993
|
-
// src/commands/channel/send.ts
|
|
6994
|
-
import { openAsBlob as openAsBlob3, readFileSync as readFileSync2 } from "node:fs";
|
|
6995
|
-
import { basename as basename3 } from "node:path";
|
|
6996
|
-
|
|
6997
|
-
// src/commands/attach.ts
|
|
6998
|
-
import { openAsBlob as openAsBlob2 } from "node:fs";
|
|
6999
|
-
import { basename as basename2 } from "node:path";
|
|
7000
|
-
var attachPaths = (raw) => (raw === void 0 ? [] : Array.isArray(raw) ? raw : [raw]).flatMap((p) => p.split(",")).map((p) => p.trim()).filter(Boolean);
|
|
7001
|
-
var uploadAttachments = async (client, sessionId, paths) => {
|
|
7002
|
-
const out = [];
|
|
7003
|
-
for (const path of paths) {
|
|
7004
|
-
const body = await openAsBlob2(path, { type: contentTypeForPath(path) });
|
|
7005
|
-
out.push(
|
|
7006
|
-
await client.sessions.uploadAttachment(sessionId, {
|
|
7007
|
-
filename: basename2(path),
|
|
7008
|
-
contentType: contentTypeForPath(path),
|
|
7009
|
-
body
|
|
7010
|
-
})
|
|
6588
|
+
var LF = 10;
|
|
6589
|
+
var CR = 13;
|
|
6590
|
+
var SPACE = 32;
|
|
6591
|
+
function noop(_arg) {
|
|
6592
|
+
}
|
|
6593
|
+
function createParser(config) {
|
|
6594
|
+
if (typeof config == "function")
|
|
6595
|
+
throw new TypeError(
|
|
6596
|
+
"`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?"
|
|
7011
6597
|
);
|
|
7012
|
-
}
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
// src/commands/channel/send.ts
|
|
7017
|
-
var sendCommand = defineCommand({
|
|
7018
|
-
meta: { name: "send", description: "post one message to a channel" },
|
|
7019
|
-
args: {
|
|
7020
|
-
channel: { type: "positional", required: true, description: "channel id" },
|
|
7021
|
-
text: { type: "positional", required: false, description: "message text (short one-liner)" },
|
|
7022
|
-
from: { type: "string", description: "your participant name (default: peer)" },
|
|
7023
|
-
to: {
|
|
7024
|
-
type: "string",
|
|
7025
|
-
description: "direct it at these names (comma-separated); omit = broadcast"
|
|
7026
|
-
},
|
|
7027
|
-
file: { type: "string", description: "read message body from this file (for large content)" },
|
|
7028
|
-
attach: {
|
|
7029
|
-
type: "string",
|
|
7030
|
-
description: "attach file(s) (comma-separated paths); uploaded + carried on the message"
|
|
7031
|
-
},
|
|
7032
|
-
...common
|
|
7033
|
-
},
|
|
7034
|
-
run: async ({ args }) => {
|
|
7035
|
-
const url = resolveBaseUrl(args.url);
|
|
7036
|
-
const client = channelClient(url);
|
|
7037
|
-
let text = args.text;
|
|
7038
|
-
if (text === void 0 && args.file) text = readFileSync2(args.file, "utf8");
|
|
7039
|
-
if (text === void 0 && !process.stdin.isTTY) text = await readStdin();
|
|
7040
|
-
const attachments = [];
|
|
7041
|
-
for (const path of attachPaths(args.attach)) {
|
|
7042
|
-
attachments.push(
|
|
7043
|
-
await client.uploadAttachment(args.channel, {
|
|
7044
|
-
filename: basename3(path),
|
|
7045
|
-
contentType: contentTypeForPath(path),
|
|
7046
|
-
body: await openAsBlob3(path, { type: contentTypeForPath(path) })
|
|
7047
|
-
})
|
|
7048
|
-
);
|
|
7049
|
-
}
|
|
7050
|
-
if (!text && attachments.length === 0)
|
|
6598
|
+
const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config, pendingFragments = [];
|
|
6599
|
+
let pendingFragmentsLength = 0, isFirstChunk = true, id, data = "", dataLines = 0, eventType, terminated = false;
|
|
6600
|
+
function feed(chunk) {
|
|
6601
|
+
if (terminated)
|
|
7051
6602
|
throw new Error(
|
|
7052
|
-
"
|
|
6603
|
+
"Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing."
|
|
7053
6604
|
);
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
6605
|
+
if (isFirstChunk && (isFirstChunk = false, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
|
|
6606
|
+
const trailing2 = processLines(chunk);
|
|
6607
|
+
trailing2 !== "" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();
|
|
6608
|
+
return;
|
|
6609
|
+
}
|
|
6610
|
+
if (chunk.indexOf(`
|
|
6611
|
+
`) === -1 && chunk.indexOf("\r") === -1) {
|
|
6612
|
+
pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();
|
|
6613
|
+
return;
|
|
6614
|
+
}
|
|
6615
|
+
pendingFragments.push(chunk);
|
|
6616
|
+
const input = pendingFragments.join("");
|
|
6617
|
+
pendingFragments.length = 0, pendingFragmentsLength = 0;
|
|
6618
|
+
const trailing = processLines(input);
|
|
6619
|
+
trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();
|
|
7062
6620
|
}
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
description: "multi-agent chat room: create / about / update / help / join / members / send / read / listen / download / close"
|
|
7070
|
-
},
|
|
7071
|
-
subCommands: {
|
|
7072
|
-
create: createCommand,
|
|
7073
|
-
about: aboutCommand,
|
|
7074
|
-
update: updateCommand,
|
|
7075
|
-
help: helpCommand,
|
|
7076
|
-
join: joinCommand,
|
|
7077
|
-
members: membersCommand,
|
|
7078
|
-
send: sendCommand,
|
|
7079
|
-
read: readCommand,
|
|
7080
|
-
listen: listenCommand,
|
|
7081
|
-
download: downloadCommand,
|
|
7082
|
-
close: closeCommand
|
|
6621
|
+
function checkBufferSize() {
|
|
6622
|
+
maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = true, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = "", dataLines = 0, eventType = void 0, onError(
|
|
6623
|
+
new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
|
|
6624
|
+
type: "max-buffer-size-exceeded"
|
|
6625
|
+
})
|
|
6626
|
+
)));
|
|
7083
6627
|
}
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
}
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
}
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
workspace: { type: "string", description: "also assign it to this workspace id" },
|
|
7112
|
-
...common
|
|
7113
|
-
},
|
|
7114
|
-
run: async ({ args }) => {
|
|
7115
|
-
const c = clientFor(args);
|
|
7116
|
-
const workspaceId = args.workspace === void 0 ? null : positiveId(args.workspace);
|
|
7117
|
-
const credential = await c.hosts.create(args.name);
|
|
7118
|
-
console.log(renderOne(credential, fmtHostCredential, Boolean(args.json)));
|
|
7119
|
-
if (workspaceId !== null) await c.hosts.assign(credential.host.id, workspaceId);
|
|
7120
|
-
}
|
|
7121
|
-
}),
|
|
7122
|
-
ls: defineCommand({
|
|
7123
|
-
meta: {
|
|
7124
|
-
name: "ls",
|
|
7125
|
-
description: "list hosts, whether they are online, and their workspaces"
|
|
7126
|
-
},
|
|
7127
|
-
args: { ...common },
|
|
7128
|
-
run: async ({ args }) => {
|
|
7129
|
-
console.log(renderList(await clientFor(args).hosts.list(), fmtHost, Boolean(args.json)));
|
|
7130
|
-
}
|
|
7131
|
-
}),
|
|
7132
|
-
assign: defineCommand({
|
|
7133
|
-
meta: { name: "assign", description: "let a workspace create Workers on this host" },
|
|
7134
|
-
args: { ...hostArg, ...workspaceArg, ...common },
|
|
7135
|
-
run: async ({ args }) => {
|
|
7136
|
-
const c = clientFor(args);
|
|
7137
|
-
const { id, name } = await adminHost(c, args.host);
|
|
7138
|
-
await c.hosts.assign(id, positiveId(args.workspace));
|
|
7139
|
-
console.log(`assigned ${name} to workspace ${args.workspace}`);
|
|
7140
|
-
}
|
|
7141
|
-
}),
|
|
7142
|
-
unassign: defineCommand({
|
|
7143
|
-
meta: {
|
|
7144
|
-
name: "unassign",
|
|
7145
|
-
description: "stop new Workers on this host for a workspace; existing ones keep running"
|
|
7146
|
-
},
|
|
7147
|
-
args: { ...hostArg, ...workspaceArg, ...common },
|
|
7148
|
-
run: async ({ args }) => {
|
|
7149
|
-
const c = clientFor(args);
|
|
7150
|
-
const { id, name } = await adminHost(c, args.host);
|
|
7151
|
-
await c.hosts.unassign(id, positiveId(args.workspace));
|
|
7152
|
-
console.log(`unassigned ${name} from workspace ${args.workspace}`);
|
|
7153
|
-
}
|
|
7154
|
-
}),
|
|
7155
|
-
rotate: defineCommand({
|
|
7156
|
-
meta: { name: "rotate", description: "replace a host token; the old one stops working" },
|
|
7157
|
-
args: { ...hostArg, ...common },
|
|
7158
|
-
run: async ({ args }) => {
|
|
7159
|
-
const c = clientFor(args);
|
|
7160
|
-
const { id } = await adminHost(c, args.host);
|
|
7161
|
-
console.log(renderOne(await c.hosts.rotate(id), fmtHostCredential, Boolean(args.json)));
|
|
6628
|
+
function processLines(chunk) {
|
|
6629
|
+
let searchIndex = 0;
|
|
6630
|
+
if (chunk.indexOf("\r") === -1) {
|
|
6631
|
+
let lfIndex = chunk.indexOf(`
|
|
6632
|
+
`, searchIndex);
|
|
6633
|
+
for (; lfIndex !== -1; ) {
|
|
6634
|
+
if (searchIndex === lfIndex) {
|
|
6635
|
+
dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
6636
|
+
`, searchIndex);
|
|
6637
|
+
continue;
|
|
6638
|
+
}
|
|
6639
|
+
const firstCharCode = chunk.charCodeAt(searchIndex);
|
|
6640
|
+
if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
|
|
6641
|
+
const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
|
|
6642
|
+
if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
|
|
6643
|
+
onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
|
|
6644
|
+
`, searchIndex);
|
|
6645
|
+
continue;
|
|
6646
|
+
}
|
|
6647
|
+
data = dataLines === 0 ? value : `${data}
|
|
6648
|
+
${value}`, dataLines++;
|
|
6649
|
+
} else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
|
|
6650
|
+
chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
|
|
6651
|
+
lfIndex
|
|
6652
|
+
) || void 0 : parseLine(chunk, searchIndex, lfIndex);
|
|
6653
|
+
searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
6654
|
+
`, searchIndex);
|
|
7162
6655
|
}
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
console.log(` [${i + 1}] #${it.id} ${it.name}`);
|
|
7175
|
-
});
|
|
7176
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
7177
|
-
try {
|
|
7178
|
-
const ans = (await rl.question(`pick a ${label} (1-${items.length}): `)).trim();
|
|
7179
|
-
const idx = Number(ans) - 1;
|
|
7180
|
-
const picked = items[idx];
|
|
7181
|
-
if (!picked) throw new Error(`invalid choice: ${ans}`);
|
|
7182
|
-
return picked;
|
|
7183
|
-
} finally {
|
|
7184
|
-
rl.close();
|
|
6656
|
+
return chunk.slice(searchIndex);
|
|
6657
|
+
}
|
|
6658
|
+
for (; searchIndex < chunk.length; ) {
|
|
6659
|
+
const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
|
|
6660
|
+
`, searchIndex);
|
|
6661
|
+
let lineEnd = -1;
|
|
6662
|
+
if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)
|
|
6663
|
+
break;
|
|
6664
|
+
parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;
|
|
6665
|
+
}
|
|
6666
|
+
return chunk.slice(searchIndex);
|
|
7185
6667
|
}
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
description: `write ${PROJECT_CONFIG_NAME} in the current directory (local state, gitignored)`
|
|
7191
|
-
},
|
|
7192
|
-
args: {
|
|
7193
|
-
workspace: { type: "string", description: "workspace id (skip prompt)" },
|
|
7194
|
-
project: { type: "string", description: "project id (skip prompt)" },
|
|
7195
|
-
force: { type: "boolean", description: `overwrite existing ${PROJECT_CONFIG_NAME}` },
|
|
7196
|
-
...common
|
|
7197
|
-
},
|
|
7198
|
-
run: async ({ args }) => {
|
|
7199
|
-
const server = resolveBaseUrl(args.url);
|
|
7200
|
-
const cfgPath = projectConfigPath();
|
|
7201
|
-
if (existsSync2(cfgPath) && !args.force)
|
|
7202
|
-
throw new Error(`${PROJECT_CONFIG_NAME} already exists. use --force to overwrite.`);
|
|
7203
|
-
const c = createClient(server);
|
|
7204
|
-
let project2;
|
|
7205
|
-
let workspace2;
|
|
7206
|
-
if (args.project) {
|
|
7207
|
-
project2 = await c.projects.get(Number(args.project));
|
|
7208
|
-
workspace2 = await c.workspaces.get(project2.workspaceId);
|
|
7209
|
-
} else {
|
|
7210
|
-
const wsList = await c.workspaces.list();
|
|
7211
|
-
workspace2 = args.workspace ? wsList.find((w) => w.id === Number(args.workspace)) ?? (() => {
|
|
7212
|
-
throw new Error(`workspace ${args.workspace} not found`);
|
|
7213
|
-
})() : await promptPick("workspace", wsList);
|
|
7214
|
-
const projects = await c.projects.listByWorkspace(workspace2.id);
|
|
7215
|
-
project2 = await promptPick("project", projects);
|
|
6668
|
+
function parseLine(chunk, start, end) {
|
|
6669
|
+
if (start === end) {
|
|
6670
|
+
dispatchEvent();
|
|
6671
|
+
return;
|
|
7216
6672
|
}
|
|
7217
|
-
const
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
6673
|
+
const firstCharCode = chunk.charCodeAt(start);
|
|
6674
|
+
if (isDataPrefix(chunk, start, firstCharCode)) {
|
|
6675
|
+
const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
|
|
6676
|
+
data = dataLines === 0 ? value2 : `${data}
|
|
6677
|
+
${value2}`, dataLines++;
|
|
6678
|
+
return;
|
|
6679
|
+
}
|
|
6680
|
+
if (isEventPrefix(chunk, start, firstCharCode)) {
|
|
6681
|
+
eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
|
|
6682
|
+
return;
|
|
6683
|
+
}
|
|
6684
|
+
if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
|
|
6685
|
+
const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
|
|
6686
|
+
id = value2.includes("\0") ? void 0 : value2;
|
|
6687
|
+
return;
|
|
6688
|
+
}
|
|
6689
|
+
if (firstCharCode === 58) {
|
|
6690
|
+
if (onComment) {
|
|
6691
|
+
const line2 = chunk.slice(start, end);
|
|
6692
|
+
onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
|
|
6693
|
+
}
|
|
6694
|
+
return;
|
|
6695
|
+
}
|
|
6696
|
+
const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":");
|
|
6697
|
+
if (fieldSeparatorIndex === -1) {
|
|
6698
|
+
processField(line, "", line);
|
|
6699
|
+
return;
|
|
6700
|
+
}
|
|
6701
|
+
const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
|
|
6702
|
+
processField(field, value, line);
|
|
7237
6703
|
}
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
intervalSec: parseDuration(args.every),
|
|
7269
|
-
name: args.name,
|
|
7270
|
-
enabled: !args.off
|
|
7271
|
-
});
|
|
7272
|
-
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6704
|
+
function processField(field, value, line) {
|
|
6705
|
+
switch (field) {
|
|
6706
|
+
case "event":
|
|
6707
|
+
eventType = value || void 0;
|
|
6708
|
+
break;
|
|
6709
|
+
case "data":
|
|
6710
|
+
data = dataLines === 0 ? value : `${data}
|
|
6711
|
+
${value}`, dataLines++;
|
|
6712
|
+
break;
|
|
6713
|
+
case "id":
|
|
6714
|
+
id = value.includes("\0") ? void 0 : value;
|
|
6715
|
+
break;
|
|
6716
|
+
case "retry":
|
|
6717
|
+
/^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(
|
|
6718
|
+
new ParseError(`Invalid \`retry\` value: "${value}"`, {
|
|
6719
|
+
type: "invalid-retry",
|
|
6720
|
+
value,
|
|
6721
|
+
line
|
|
6722
|
+
})
|
|
6723
|
+
);
|
|
6724
|
+
break;
|
|
6725
|
+
default:
|
|
6726
|
+
onError(
|
|
6727
|
+
new ParseError(
|
|
6728
|
+
`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`,
|
|
6729
|
+
{ type: "unknown-field", field, value, line }
|
|
6730
|
+
)
|
|
6731
|
+
);
|
|
6732
|
+
break;
|
|
6733
|
+
}
|
|
7273
6734
|
}
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
loop: { type: "positional", required: true, description: "loop int id" },
|
|
7281
|
-
...common
|
|
7282
|
-
},
|
|
7283
|
-
run: async ({ args }) => {
|
|
7284
|
-
const c = clientFor(args);
|
|
7285
|
-
const loop2 = await c.loops.update(Number(args.loop), { enabled: false });
|
|
7286
|
-
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6735
|
+
function dispatchEvent() {
|
|
6736
|
+
dataLines > 0 && onEvent({
|
|
6737
|
+
id,
|
|
6738
|
+
event: eventType,
|
|
6739
|
+
data
|
|
6740
|
+
}), id = void 0, data = "", dataLines = 0, eventType = void 0;
|
|
7287
6741
|
}
|
|
7288
|
-
})
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
loop: { type: "positional", required: true, description: "loop int id" },
|
|
7295
|
-
...common
|
|
7296
|
-
},
|
|
7297
|
-
run: async ({ args }) => {
|
|
7298
|
-
const c = clientFor(args);
|
|
7299
|
-
const loop2 = await c.loops.update(Number(args.loop), { enabled: true });
|
|
7300
|
-
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
6742
|
+
function reset(options = {}) {
|
|
6743
|
+
if (options.consume && pendingFragments.length > 0) {
|
|
6744
|
+
const incompleteLine = pendingFragments.join("");
|
|
6745
|
+
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
6746
|
+
}
|
|
6747
|
+
isFirstChunk = true, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = false;
|
|
7301
6748
|
}
|
|
7302
|
-
}
|
|
6749
|
+
return { feed, reset };
|
|
6750
|
+
}
|
|
6751
|
+
function isDataPrefix(chunk, i, firstCharCode) {
|
|
6752
|
+
return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
|
|
6753
|
+
}
|
|
6754
|
+
function isEventPrefix(chunk, i, firstCharCode) {
|
|
6755
|
+
return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
|
|
6756
|
+
}
|
|
7303
6757
|
|
|
7304
|
-
//
|
|
7305
|
-
var
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
6758
|
+
// ../../node_modules/.pnpm/eventsource@4.1.0/node_modules/eventsource/dist/index.js
|
|
6759
|
+
var ErrorEvent = class extends Event {
|
|
6760
|
+
/**
|
|
6761
|
+
* Constructs a new `ErrorEvent` instance. This is typically not called directly,
|
|
6762
|
+
* but rather emitted by the `EventSource` object when an error occurs.
|
|
6763
|
+
*
|
|
6764
|
+
* @param type - The type of the event (should be "error")
|
|
6765
|
+
* @param errorEventInitDict - Optional properties to include in the error event
|
|
6766
|
+
*/
|
|
6767
|
+
constructor(type, errorEventInitDict) {
|
|
6768
|
+
var _a, _b;
|
|
6769
|
+
super(type), this.code = (_a = errorEventInitDict == null ? void 0 : errorEventInitDict.code) != null ? _a : void 0, this.message = (_b = errorEventInitDict == null ? void 0 : errorEventInitDict.message) != null ? _b : void 0;
|
|
7315
6770
|
}
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
console.log(renderList(loops, fmtLoop, Boolean(args.json)));
|
|
6771
|
+
/**
|
|
6772
|
+
* Node.js "hides" the `message` and `code` properties of the `ErrorEvent` instance,
|
|
6773
|
+
* when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
|
|
6774
|
+
* we explicitly include the properties in the `inspect` method.
|
|
6775
|
+
*
|
|
6776
|
+
* This is automatically called by Node.js when you `console.log` an instance of this class.
|
|
6777
|
+
*
|
|
6778
|
+
* @param _depth - The current depth
|
|
6779
|
+
* @param options - The options passed to `util.inspect`
|
|
6780
|
+
* @param inspect - The inspect function to use (prevents having to import it from `util`)
|
|
6781
|
+
* @returns A string representation of the error
|
|
6782
|
+
*/
|
|
6783
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")](_depth, options, inspect) {
|
|
6784
|
+
return inspect(inspectableError(this), options);
|
|
7331
6785
|
}
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
console.log(removed("loop", id, Boolean(args.json)));
|
|
6786
|
+
/**
|
|
6787
|
+
* Deno "hides" the `message` and `code` properties of the `ErrorEvent` instance,
|
|
6788
|
+
* when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
|
|
6789
|
+
* we explicitly include the properties in the `inspect` method.
|
|
6790
|
+
*
|
|
6791
|
+
* This is automatically called by Deno when you `console.log` an instance of this class.
|
|
6792
|
+
*
|
|
6793
|
+
* @param inspect - The inspect function to use (prevents having to import it from `util`)
|
|
6794
|
+
* @param options - The options passed to `Deno.inspect`
|
|
6795
|
+
* @returns A string representation of the error
|
|
6796
|
+
*/
|
|
6797
|
+
[/* @__PURE__ */ Symbol.for("Deno.customInspect")](inspect, options) {
|
|
6798
|
+
return inspect(inspectableError(this), options);
|
|
7346
6799
|
}
|
|
7347
|
-
});
|
|
7348
|
-
|
|
7349
|
-
// src/commands/loop/set.ts
|
|
7350
|
-
var loopSetCommand = defineCommand({
|
|
7351
|
-
meta: { name: "set", description: "update a loop (message / interval / name)" },
|
|
7352
|
-
args: {
|
|
7353
|
-
loop: { type: "positional", required: true, description: "loop int id" },
|
|
7354
|
-
message: { type: "string", description: "new message" },
|
|
7355
|
-
every: { type: "string", description: "new interval: 90s / 30m / 2h / 1d" },
|
|
7356
|
-
name: { type: "string", description: "new label" },
|
|
7357
|
-
...common
|
|
7358
|
-
},
|
|
7359
|
-
run: async ({ args }) => {
|
|
7360
|
-
const c = clientFor(args);
|
|
7361
|
-
const patch = {};
|
|
7362
|
-
if (args.message !== void 0) patch.message = args.message;
|
|
7363
|
-
if (args.every !== void 0 && args.every !== "") patch.intervalSec = parseDuration(args.every);
|
|
7364
|
-
if (args.name !== void 0) patch.name = args.name;
|
|
7365
|
-
const loop2 = await c.loops.update(Number(args.loop), patch);
|
|
7366
|
-
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
7367
|
-
}
|
|
7368
|
-
});
|
|
7369
|
-
|
|
7370
|
-
// src/commands/loop.ts
|
|
7371
|
-
var loop = defineCommand({
|
|
7372
|
-
meta: { name: "loop", description: "recurring scheduled messages that wake a session" },
|
|
7373
|
-
subCommands: {
|
|
7374
|
-
create: loopCreateCommand,
|
|
7375
|
-
ls: loopLsCommand,
|
|
7376
|
-
get: loopGetCommand,
|
|
7377
|
-
set: loopSetCommand,
|
|
7378
|
-
enable: loopEnableCommand,
|
|
7379
|
-
disable: loopDisableCommand,
|
|
7380
|
-
rm: loopRmCommand
|
|
7381
|
-
}
|
|
7382
|
-
});
|
|
7383
|
-
|
|
7384
|
-
// src/commands/notify.ts
|
|
7385
|
-
var describe2 = (result) => {
|
|
7386
|
-
if (result.status === "sent") return `notified ${result.devices} device(s)`;
|
|
7387
|
-
if (result.status === "throttled")
|
|
7388
|
-
return `throttled: this session can notify again in ${result.retryAfterSec}s`;
|
|
7389
|
-
return "nobody to notify: no human has messaged this session, or they have not enabled notifications";
|
|
7390
6800
|
};
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
}
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
var
|
|
7414
|
-
var
|
|
7415
|
-
var
|
|
7416
|
-
var
|
|
7417
|
-
var
|
|
7418
|
-
var
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
);
|
|
6801
|
+
function syntaxError(message) {
|
|
6802
|
+
const DomException = globalThis.DOMException;
|
|
6803
|
+
return typeof DomException == "function" ? new DomException(message, "SyntaxError") : new SyntaxError(message);
|
|
6804
|
+
}
|
|
6805
|
+
function flattenError(err) {
|
|
6806
|
+
return err instanceof Error ? "errors" in err && Array.isArray(err.errors) ? err.errors.map(flattenError).join(", ") : "cause" in err && err.cause instanceof Error ? `${err}: ${flattenError(err.cause)}` : err.message : `${err}`;
|
|
6807
|
+
}
|
|
6808
|
+
function inspectableError(err) {
|
|
6809
|
+
return {
|
|
6810
|
+
type: err.type,
|
|
6811
|
+
message: err.message,
|
|
6812
|
+
code: err.code,
|
|
6813
|
+
defaultPrevented: err.defaultPrevented,
|
|
6814
|
+
cancelable: err.cancelable,
|
|
6815
|
+
timeStamp: err.timeStamp
|
|
6816
|
+
};
|
|
6817
|
+
}
|
|
6818
|
+
var __typeError = (msg) => {
|
|
6819
|
+
throw TypeError(msg);
|
|
6820
|
+
};
|
|
6821
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
6822
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6823
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
6824
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
6825
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
6826
|
+
var _readyState;
|
|
6827
|
+
var _url;
|
|
6828
|
+
var _redirectUrl;
|
|
6829
|
+
var _withCredentials;
|
|
6830
|
+
var _fetch;
|
|
6831
|
+
var _reconnectInterval;
|
|
6832
|
+
var _reconnectTimer;
|
|
6833
|
+
var _lastEventId;
|
|
6834
|
+
var _controller;
|
|
6835
|
+
var _parser;
|
|
6836
|
+
var _onError;
|
|
6837
|
+
var _onMessage;
|
|
6838
|
+
var _onOpen;
|
|
6839
|
+
var _EventSource_instances;
|
|
6840
|
+
var connect_fn;
|
|
6841
|
+
var _onFetchResponse;
|
|
6842
|
+
var _onFetchError;
|
|
6843
|
+
var getRequestOptions_fn;
|
|
6844
|
+
var _onEvent;
|
|
6845
|
+
var _onRetryChange;
|
|
6846
|
+
var failConnection_fn;
|
|
6847
|
+
var scheduleReconnect_fn;
|
|
6848
|
+
var _reconnect;
|
|
6849
|
+
var EventSource = class extends EventTarget {
|
|
6850
|
+
constructor(url, eventSourceInitDict) {
|
|
6851
|
+
var _a, _b;
|
|
6852
|
+
super(), __privateAdd(this, _EventSource_instances), this.CONNECTING = 0, this.OPEN = 1, this.CLOSED = 2, __privateAdd(this, _readyState), __privateAdd(this, _url), __privateAdd(this, _redirectUrl), __privateAdd(this, _withCredentials), __privateAdd(this, _fetch), __privateAdd(this, _reconnectInterval), __privateAdd(this, _reconnectTimer), __privateAdd(this, _lastEventId, null), __privateAdd(this, _controller), __privateAdd(this, _parser), __privateAdd(this, _onError, null), __privateAdd(this, _onMessage, null), __privateAdd(this, _onOpen, null), __privateAdd(this, _onFetchResponse, async (response) => {
|
|
6853
|
+
var _a2;
|
|
6854
|
+
__privateGet(this, _parser).reset();
|
|
6855
|
+
const { body, redirected, status, headers } = response;
|
|
6856
|
+
if (status === 204) {
|
|
6857
|
+
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Server sent HTTP 204, not reconnecting", 204), this.close();
|
|
6858
|
+
return;
|
|
7448
6859
|
}
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
args: { id: { type: "positional", required: true }, ...common },
|
|
7453
|
-
run: async ({ args }) => {
|
|
7454
|
-
console.log(await getProject(clientFor(args), Number(args.id), Boolean(args.json)));
|
|
6860
|
+
if (redirected ? __privateSet(this, _redirectUrl, new URL(response.url)) : __privateSet(this, _redirectUrl, void 0), status !== 200) {
|
|
6861
|
+
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, `Non-200 status code (${status})`, status);
|
|
6862
|
+
return;
|
|
7455
6863
|
}
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
args: {
|
|
7460
|
-
id: { type: "positional", required: true },
|
|
7461
|
-
name: { type: "string", description: "new name" },
|
|
7462
|
-
desc: { type: "string", description: "new description" },
|
|
7463
|
-
...common
|
|
7464
|
-
},
|
|
7465
|
-
run: async ({ args }) => {
|
|
7466
|
-
const patch = {
|
|
7467
|
-
...args.name !== void 0 ? { name: args.name } : {},
|
|
7468
|
-
...args.desc !== void 0 ? { description: args.desc } : {}
|
|
7469
|
-
};
|
|
7470
|
-
if (Object.keys(patch).length === 0) throw new Error("pass --name and/or --desc");
|
|
7471
|
-
console.log(
|
|
7472
|
-
await updateProject(clientFor(args), Number(args.id), patch, Boolean(args.json))
|
|
7473
|
-
);
|
|
6864
|
+
if (!(headers.get("content-type") || "").startsWith("text/event-stream")) {
|
|
6865
|
+
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, 'Invalid content type, expected "text/event-stream"', status);
|
|
6866
|
+
return;
|
|
7474
6867
|
}
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
6868
|
+
if (__privateGet(this, _readyState) === this.CLOSED)
|
|
6869
|
+
return;
|
|
6870
|
+
__privateSet(this, _readyState, this.OPEN);
|
|
6871
|
+
const openEvent = new Event("open");
|
|
6872
|
+
if ((_a2 = __privateGet(this, _onOpen)) == null || _a2.call(this, openEvent), this.dispatchEvent(openEvent), typeof body != "object" || !body || !("getReader" in body)) {
|
|
6873
|
+
__privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid response body, expected a web ReadableStream", status), this.close();
|
|
6874
|
+
return;
|
|
7481
6875
|
}
|
|
7482
|
-
|
|
6876
|
+
const decoder = new TextDecoder(), reader = body.getReader();
|
|
6877
|
+
let open3 = true;
|
|
6878
|
+
do {
|
|
6879
|
+
const { done, value } = await reader.read();
|
|
6880
|
+
value && __privateGet(this, _parser).feed(decoder.decode(value, { stream: !done })), done && (open3 = false, __privateGet(this, _parser).reset(), __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this));
|
|
6881
|
+
} while (open3);
|
|
6882
|
+
}), __privateAdd(this, _onFetchError, (err) => {
|
|
6883
|
+
__privateSet(this, _controller, void 0), !(err.name === "AbortError" || err.type === "aborted") && __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this, flattenError(err));
|
|
6884
|
+
}), __privateAdd(this, _onEvent, (event) => {
|
|
6885
|
+
typeof event.id == "string" && __privateSet(this, _lastEventId, event.id);
|
|
6886
|
+
const messageEvent = new MessageEvent(event.event || "message", {
|
|
6887
|
+
data: event.data,
|
|
6888
|
+
origin: __privateGet(this, _redirectUrl) ? __privateGet(this, _redirectUrl).origin : __privateGet(this, _url).origin,
|
|
6889
|
+
lastEventId: event.id || ""
|
|
6890
|
+
});
|
|
6891
|
+
__privateGet(this, _onMessage) && (!event.event || event.event === "message") && __privateGet(this, _onMessage).call(this, messageEvent), this.dispatchEvent(messageEvent);
|
|
6892
|
+
}), __privateAdd(this, _onRetryChange, (value) => {
|
|
6893
|
+
__privateSet(this, _reconnectInterval, value);
|
|
6894
|
+
}), __privateAdd(this, _reconnect, () => {
|
|
6895
|
+
__privateSet(this, _reconnectTimer, void 0), __privateGet(this, _readyState) === this.CONNECTING && __privateMethod(this, _EventSource_instances, connect_fn).call(this);
|
|
6896
|
+
});
|
|
6897
|
+
try {
|
|
6898
|
+
if (url instanceof URL)
|
|
6899
|
+
__privateSet(this, _url, url);
|
|
6900
|
+
else if (typeof url == "string")
|
|
6901
|
+
__privateSet(this, _url, new URL(url, getBaseURL()));
|
|
6902
|
+
else
|
|
6903
|
+
throw new Error("Invalid URL");
|
|
6904
|
+
} catch {
|
|
6905
|
+
throw syntaxError("An invalid or illegal string was specified");
|
|
6906
|
+
}
|
|
6907
|
+
__privateSet(this, _parser, createParser({
|
|
6908
|
+
onEvent: __privateGet(this, _onEvent),
|
|
6909
|
+
onRetry: __privateGet(this, _onRetryChange)
|
|
6910
|
+
})), __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _reconnectInterval, 3e3), __privateSet(this, _fetch, (_a = eventSourceInitDict == null ? void 0 : eventSourceInitDict.fetch) != null ? _a : globalThis.fetch), __privateSet(this, _withCredentials, (_b = eventSourceInitDict == null ? void 0 : eventSourceInitDict.withCredentials) != null ? _b : false), __privateMethod(this, _EventSource_instances, connect_fn).call(this);
|
|
7483
6911
|
}
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
])
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
}
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
)
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
if (!object(value)) throw new Error("templates must be an object");
|
|
7519
|
-
return Object.fromEntries(
|
|
7520
|
-
WORKER_TEMPLATES.filter((template) => value[template.id] !== void 0).map((template) => {
|
|
7521
|
-
const raw = value[template.id];
|
|
7522
|
-
if (!object(raw)) throw new Error(`template ${template.id} must be an object`);
|
|
7523
|
-
const workerEnv2 = environment(raw.workerEnv);
|
|
7524
|
-
if (template.id === "mini-codex") {
|
|
7525
|
-
if (raw.pi !== void 0) throw new Error("mini-codex does not support pi");
|
|
7526
|
-
return [template.id, { workerEnv: workerEnv2 }];
|
|
7527
|
-
}
|
|
7528
|
-
const provider = template.id === "mini-glm-codeplan" ? "zai-coding-cn" : "qwen-token-plan-cn";
|
|
7529
|
-
const apiKey = template.id === "mini-glm-codeplan" ? "ZAI_CODING_CN_API_KEY" : "QWEN_TOKEN_PLAN_CN_API_KEY";
|
|
7530
|
-
if (!workerEnv2.ANTHROPIC_BASE_URL || !(workerEnv2.ANTHROPIC_AUTH_TOKEN || workerEnv2.ANTHROPIC_API_KEY) || !workerEnv2[apiKey])
|
|
7531
|
-
throw new Error(`template ${template.id} requires Claude and Pi credentials`);
|
|
7532
|
-
if (!object(raw.pi) || raw.pi.provider !== provider || typeof raw.pi.model !== "string" || !raw.pi.model.trim())
|
|
7533
|
-
throw new Error(`template ${template.id} requires its Pi provider and model`);
|
|
7534
|
-
return [template.id, { workerEnv: workerEnv2, pi: { provider, model: raw.pi.model.trim() } }];
|
|
7535
|
-
})
|
|
7536
|
-
);
|
|
7537
|
-
};
|
|
7538
|
-
var commandEnvironment = (config) => ({
|
|
7539
|
-
...process.env,
|
|
7540
|
-
PATH: config.workerEnv.PATH ?? process.env.PATH ?? "/usr/bin:/bin"
|
|
7541
|
-
});
|
|
7542
|
-
var loadProvisionerConfig = async (path) => {
|
|
7543
|
-
if (process.platform !== "darwin") throw new Error("provisioner requires macOS");
|
|
7544
|
-
absolutePath(path, "config");
|
|
7545
|
-
if ((await stat2(path)).mode & 63) throw new Error("config must be private: chmod 600 <config>");
|
|
7546
|
-
const text = await readFile(path, "utf8");
|
|
7547
|
-
let raw;
|
|
7548
|
-
try {
|
|
7549
|
-
raw = JSON.parse(text);
|
|
7550
|
-
} catch (error) {
|
|
7551
|
-
if (!(error instanceof SyntaxError)) throw error;
|
|
7552
|
-
throw new Error("invalid provisioner JSON config");
|
|
6912
|
+
/**
|
|
6913
|
+
* Returns the state of this EventSource object's connection. It can have the values described below.
|
|
6914
|
+
*
|
|
6915
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)
|
|
6916
|
+
*
|
|
6917
|
+
* Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,
|
|
6918
|
+
* defined in the TypeScript `dom` library.
|
|
6919
|
+
*
|
|
6920
|
+
* @public
|
|
6921
|
+
*/
|
|
6922
|
+
get readyState() {
|
|
6923
|
+
return __privateGet(this, _readyState);
|
|
6924
|
+
}
|
|
6925
|
+
/**
|
|
6926
|
+
* Returns the URL providing the event stream.
|
|
6927
|
+
*
|
|
6928
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)
|
|
6929
|
+
*
|
|
6930
|
+
* @public
|
|
6931
|
+
*/
|
|
6932
|
+
get url() {
|
|
6933
|
+
return __privateGet(this, _url).href;
|
|
6934
|
+
}
|
|
6935
|
+
/**
|
|
6936
|
+
* Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
|
|
6937
|
+
*
|
|
6938
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)
|
|
6939
|
+
*/
|
|
6940
|
+
get withCredentials() {
|
|
6941
|
+
return __privateGet(this, _withCredentials);
|
|
6942
|
+
}
|
|
6943
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */
|
|
6944
|
+
get onerror() {
|
|
6945
|
+
return __privateGet(this, _onError);
|
|
7553
6946
|
}
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
6947
|
+
set onerror(value) {
|
|
6948
|
+
__privateSet(this, _onError, value);
|
|
6949
|
+
}
|
|
6950
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */
|
|
6951
|
+
get onmessage() {
|
|
6952
|
+
return __privateGet(this, _onMessage);
|
|
6953
|
+
}
|
|
6954
|
+
set onmessage(value) {
|
|
6955
|
+
__privateSet(this, _onMessage, value);
|
|
6956
|
+
}
|
|
6957
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */
|
|
6958
|
+
get onopen() {
|
|
6959
|
+
return __privateGet(this, _onOpen);
|
|
6960
|
+
}
|
|
6961
|
+
set onopen(value) {
|
|
6962
|
+
__privateSet(this, _onOpen, value);
|
|
6963
|
+
}
|
|
6964
|
+
addEventListener(type, listener, options) {
|
|
6965
|
+
const listen = listener;
|
|
6966
|
+
super.addEventListener(type, listen, options);
|
|
6967
|
+
}
|
|
6968
|
+
removeEventListener(type, listener, options) {
|
|
6969
|
+
const listen = listener;
|
|
6970
|
+
super.removeEventListener(type, listen, options);
|
|
6971
|
+
}
|
|
6972
|
+
/**
|
|
6973
|
+
* Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
|
|
6974
|
+
*
|
|
6975
|
+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)
|
|
6976
|
+
*
|
|
6977
|
+
* @public
|
|
6978
|
+
*/
|
|
6979
|
+
close() {
|
|
6980
|
+
__privateGet(this, _reconnectTimer) && clearTimeout(__privateGet(this, _reconnectTimer)), __privateGet(this, _readyState) !== this.CLOSED && (__privateGet(this, _controller) && __privateGet(this, _controller).abort(), __privateSet(this, _readyState, this.CLOSED), __privateSet(this, _controller, void 0));
|
|
7562
6981
|
}
|
|
7563
|
-
if (!["http:", "https:"].includes(server.protocol) || server.username || server.password || server.search || server.hash)
|
|
7564
|
-
throw new Error("server must be an HTTP(S) URL without credentials, query, or fragment");
|
|
7565
|
-
if (!raw.token.trim() || /[\r\n]/.test(raw.token))
|
|
7566
|
-
throw new Error("valid provisioner token required");
|
|
7567
|
-
const config = {
|
|
7568
|
-
server: server.toString().replace(/\/$/, ""),
|
|
7569
|
-
token: raw.token.trim(),
|
|
7570
|
-
projectsRoot: absolutePath(raw.projectsRoot, "projectsRoot"),
|
|
7571
|
-
cliPath: absolutePath(raw.cliPath, "cliPath"),
|
|
7572
|
-
nodePath: absolutePath(raw.nodePath ?? process.execPath, "nodePath"),
|
|
7573
|
-
workerEnv: environment(raw.workerEnv),
|
|
7574
|
-
templates: templates(raw.templates)
|
|
7575
|
-
};
|
|
7576
|
-
await access(config.cliPath, constants.R_OK);
|
|
7577
|
-
await access(config.nodePath ?? process.execPath, constants.X_OK);
|
|
7578
|
-
const env = commandEnvironment(config);
|
|
7579
|
-
await promisify(execFile)("git", ["--version"], { env, timeout: 1e4 });
|
|
7580
|
-
await promisify(execFile)("launchctl", ["help"], { env, timeout: 1e4 });
|
|
7581
|
-
await promisify(execFile)("/usr/bin/plutil", ["-help"], { timeout: 1e4 });
|
|
7582
|
-
return config;
|
|
7583
6982
|
};
|
|
6983
|
+
_readyState = /* @__PURE__ */ new WeakMap(), _url = /* @__PURE__ */ new WeakMap(), _redirectUrl = /* @__PURE__ */ new WeakMap(), _withCredentials = /* @__PURE__ */ new WeakMap(), _fetch = /* @__PURE__ */ new WeakMap(), _reconnectInterval = /* @__PURE__ */ new WeakMap(), _reconnectTimer = /* @__PURE__ */ new WeakMap(), _lastEventId = /* @__PURE__ */ new WeakMap(), _controller = /* @__PURE__ */ new WeakMap(), _parser = /* @__PURE__ */ new WeakMap(), _onError = /* @__PURE__ */ new WeakMap(), _onMessage = /* @__PURE__ */ new WeakMap(), _onOpen = /* @__PURE__ */ new WeakMap(), _EventSource_instances = /* @__PURE__ */ new WeakSet(), /**
|
|
6984
|
+
* Connect to the given URL and start receiving events
|
|
6985
|
+
*
|
|
6986
|
+
* @internal
|
|
6987
|
+
*/
|
|
6988
|
+
connect_fn = function() {
|
|
6989
|
+
__privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _controller, new AbortController()), __privateGet(this, _fetch)(__privateGet(this, _url), __privateMethod(this, _EventSource_instances, getRequestOptions_fn).call(this)).then(__privateGet(this, _onFetchResponse)).catch(__privateGet(this, _onFetchError));
|
|
6990
|
+
}, _onFetchResponse = /* @__PURE__ */ new WeakMap(), _onFetchError = /* @__PURE__ */ new WeakMap(), /**
|
|
6991
|
+
* Get request options for the `fetch()` request
|
|
6992
|
+
*
|
|
6993
|
+
* @returns The request options
|
|
6994
|
+
* @internal
|
|
6995
|
+
*/
|
|
6996
|
+
getRequestOptions_fn = function() {
|
|
6997
|
+
var _a;
|
|
6998
|
+
const init2 = {
|
|
6999
|
+
// [spec] Let `corsAttributeState` be `Anonymous`…
|
|
7000
|
+
// [spec] …will have their mode set to "cors"…
|
|
7001
|
+
mode: "cors",
|
|
7002
|
+
redirect: "follow",
|
|
7003
|
+
headers: { Accept: "text/event-stream", ...__privateGet(this, _lastEventId) ? { "Last-Event-ID": __privateGet(this, _lastEventId) } : void 0 },
|
|
7004
|
+
cache: "no-store",
|
|
7005
|
+
signal: (_a = __privateGet(this, _controller)) == null ? void 0 : _a.signal
|
|
7006
|
+
};
|
|
7007
|
+
return "window" in globalThis && (init2.credentials = this.withCredentials ? "include" : "same-origin"), init2;
|
|
7008
|
+
}, _onEvent = /* @__PURE__ */ new WeakMap(), _onRetryChange = /* @__PURE__ */ new WeakMap(), /**
|
|
7009
|
+
* Handles the process referred to in the EventSource specification as "failing a connection".
|
|
7010
|
+
*
|
|
7011
|
+
* @param error - The error causing the connection to fail
|
|
7012
|
+
* @param code - The HTTP status code, if available
|
|
7013
|
+
* @internal
|
|
7014
|
+
*/
|
|
7015
|
+
failConnection_fn = function(message, code) {
|
|
7016
|
+
var _a;
|
|
7017
|
+
__privateGet(this, _readyState) !== this.CLOSED && __privateSet(this, _readyState, this.CLOSED);
|
|
7018
|
+
const errorEvent = new ErrorEvent("error", { code, message });
|
|
7019
|
+
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent);
|
|
7020
|
+
}, /**
|
|
7021
|
+
* Schedules a reconnection attempt against the EventSource endpoint.
|
|
7022
|
+
*
|
|
7023
|
+
* @param message - The error causing the connection to fail
|
|
7024
|
+
* @param code - The HTTP status code, if available
|
|
7025
|
+
* @internal
|
|
7026
|
+
*/
|
|
7027
|
+
scheduleReconnect_fn = function(message, code) {
|
|
7028
|
+
var _a;
|
|
7029
|
+
if (__privateGet(this, _readyState) === this.CLOSED)
|
|
7030
|
+
return;
|
|
7031
|
+
__privateSet(this, _readyState, this.CONNECTING);
|
|
7032
|
+
const errorEvent = new ErrorEvent("error", { code, message });
|
|
7033
|
+
(_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent), __privateSet(this, _reconnectTimer, setTimeout(__privateGet(this, _reconnect), __privateGet(this, _reconnectInterval)));
|
|
7034
|
+
}, _reconnect = /* @__PURE__ */ new WeakMap(), /**
|
|
7035
|
+
* ReadyState representing an EventSource currently trying to connect
|
|
7036
|
+
*
|
|
7037
|
+
* @public
|
|
7038
|
+
*/
|
|
7039
|
+
EventSource.CONNECTING = 0, /**
|
|
7040
|
+
* ReadyState representing an EventSource connection that is open (eg connected)
|
|
7041
|
+
*
|
|
7042
|
+
* @public
|
|
7043
|
+
*/
|
|
7044
|
+
EventSource.OPEN = 1, /**
|
|
7045
|
+
* ReadyState representing an EventSource connection that is closed (eg disconnected)
|
|
7046
|
+
*
|
|
7047
|
+
* @public
|
|
7048
|
+
*/
|
|
7049
|
+
EventSource.CLOSED = 2;
|
|
7050
|
+
Object.defineProperty(EventSource, /* @__PURE__ */ Symbol.for("eventsource.supports-fetch-override"), {
|
|
7051
|
+
value: true,
|
|
7052
|
+
writable: false,
|
|
7053
|
+
configurable: false,
|
|
7054
|
+
enumerable: false
|
|
7055
|
+
});
|
|
7056
|
+
function getBaseURL() {
|
|
7057
|
+
const doc = "document" in globalThis ? globalThis.document : void 0;
|
|
7058
|
+
return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
|
|
7059
|
+
}
|
|
7584
7060
|
|
|
7585
7061
|
// src/provisioner/client.ts
|
|
7586
7062
|
var createProvisionerClient = (config) => {
|
|
@@ -7613,7 +7089,7 @@ var createProvisionerClient = (config) => {
|
|
|
7613
7089
|
import { execFile as execFile3 } from "node:child_process";
|
|
7614
7090
|
import { lstat, mkdir as mkdir3, realpath, writeFile as writeFile2 } from "node:fs/promises";
|
|
7615
7091
|
import { hostname } from "node:os";
|
|
7616
|
-
import { dirname as dirname2, join as
|
|
7092
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
7617
7093
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
7618
7094
|
import { promisify as promisify3 } from "node:util";
|
|
7619
7095
|
|
|
@@ -7621,18 +7097,18 @@ import { promisify as promisify3 } from "node:util";
|
|
|
7621
7097
|
import { execFile as execFile2 } from "node:child_process";
|
|
7622
7098
|
import { mkdir, open } from "node:fs/promises";
|
|
7623
7099
|
import { homedir } from "node:os";
|
|
7624
|
-
import { dirname, join as
|
|
7100
|
+
import { dirname, join as join2 } from "node:path";
|
|
7625
7101
|
import { promisify as promisify2 } from "node:util";
|
|
7626
|
-
var workerStatePath = (config, creation) =>
|
|
7102
|
+
var workerStatePath = (config, creation) => join2(
|
|
7627
7103
|
config.projectsRoot,
|
|
7628
7104
|
".worker-state",
|
|
7629
7105
|
`project-${creation.projectId}`,
|
|
7630
7106
|
`creation-${creation.id}`
|
|
7631
7107
|
);
|
|
7632
|
-
var workerLogPath = (creation) =>
|
|
7108
|
+
var workerLogPath = (creation) => join2(homedir(), "Library/Logs", `baton-worker-creation-${creation.id}.log`);
|
|
7633
7109
|
var startAgent = async (config, agent, signal) => {
|
|
7634
7110
|
signal?.throwIfAborted();
|
|
7635
|
-
const plist =
|
|
7111
|
+
const plist = join2(homedir(), "Library/LaunchAgents", `${agent.label}.plist`);
|
|
7636
7112
|
await mkdir(dirname(plist), { recursive: true });
|
|
7637
7113
|
await mkdir(dirname(agent.log), { recursive: true });
|
|
7638
7114
|
const domain = `gui/${process.getuid?.()}`;
|
|
@@ -7718,12 +7194,12 @@ var installProvisionerAgent = async (config, configPath) => startAgent(config, {
|
|
|
7718
7194
|
],
|
|
7719
7195
|
cwd: dirname(configPath),
|
|
7720
7196
|
env: { HOME: homedir(), PATH: config.workerEnv.PATH ?? process.env.PATH ?? "/usr/bin:/bin" },
|
|
7721
|
-
log:
|
|
7197
|
+
log: join2(homedir(), "Library/Logs/baton-provisioner.log")
|
|
7722
7198
|
});
|
|
7723
7199
|
|
|
7724
7200
|
// src/provisioner/worker-template.ts
|
|
7725
7201
|
import { mkdir as mkdir2, writeFile } from "node:fs/promises";
|
|
7726
|
-
import { join as
|
|
7202
|
+
import { join as join3 } from "node:path";
|
|
7727
7203
|
var requireWorkerTemplate = (config, creation) => {
|
|
7728
7204
|
if (!workerTemplateAgentKinds(creation.templateId).includes(creation.agentKind))
|
|
7729
7205
|
throw new Error("agentKind is not supported by this template");
|
|
@@ -7737,10 +7213,10 @@ var workerTemplateEnvironment = async (config, creation, state) => {
|
|
|
7737
7213
|
if (!profile) return config.workerEnv;
|
|
7738
7214
|
if (creation.agentKind !== "pi") return profile.workerEnv;
|
|
7739
7215
|
if (!profile.pi) throw new Error("Pi provider and model are not configured");
|
|
7740
|
-
const agentDir =
|
|
7216
|
+
const agentDir = join3(state, "pi");
|
|
7741
7217
|
await mkdir2(agentDir, { mode: 448 });
|
|
7742
7218
|
await writeFile(
|
|
7743
|
-
|
|
7219
|
+
join3(agentDir, "settings.json"),
|
|
7744
7220
|
JSON.stringify({
|
|
7745
7221
|
defaultProvider: profile.pi.provider,
|
|
7746
7222
|
defaultModel: profile.pi.model
|
|
@@ -7778,13 +7254,13 @@ var initRepository = async (config, creation, repoPath, progress, signal) => {
|
|
|
7778
7254
|
signal.throwIfAborted();
|
|
7779
7255
|
await mkdir3(config.projectsRoot, { recursive: true, mode: 448 });
|
|
7780
7256
|
const root = await realpath(config.projectsRoot);
|
|
7781
|
-
await directory(
|
|
7782
|
-
await mkdir3(
|
|
7257
|
+
await directory(join4(root, `project-${creation.projectId}`));
|
|
7258
|
+
await mkdir3(join4(root, `project-${creation.projectId}`, `creation-${creation.id}`), {
|
|
7783
7259
|
mode: 448
|
|
7784
7260
|
});
|
|
7785
7261
|
await progress("git");
|
|
7786
7262
|
await gitIn(config, repoPath, ["init", "-b", "main"], signal);
|
|
7787
|
-
await writeFile2(
|
|
7263
|
+
await writeFile2(join4(repoPath, ".git/info/exclude"), "\n.baton.json\n", { flag: "a" });
|
|
7788
7264
|
await gitIn(
|
|
7789
7265
|
config,
|
|
7790
7266
|
repoPath,
|
|
@@ -7805,7 +7281,7 @@ var adoptRepository = async (config, creation, repoPath, progress, signal) => {
|
|
|
7805
7281
|
await progress("directory");
|
|
7806
7282
|
signal.throwIfAborted();
|
|
7807
7283
|
const real = await realpath(repoPath);
|
|
7808
|
-
const project2 =
|
|
7284
|
+
const project2 = join4(await realpath(config.projectsRoot), `project-${creation.projectId}`);
|
|
7809
7285
|
if (dirname2(real) !== project2 || !(await lstat(real)).isDirectory())
|
|
7810
7286
|
throw new Error(`unsafe directory: ${repoPath}`);
|
|
7811
7287
|
await progress("git");
|
|
@@ -7822,18 +7298,18 @@ var adoptRepository = async (config, creation, repoPath, progress, signal) => {
|
|
|
7822
7298
|
var provisionWorker = async (config, creation, client, signal) => {
|
|
7823
7299
|
requireWorkerTemplate(config, creation);
|
|
7824
7300
|
const shared = creation.repoPath !== null;
|
|
7825
|
-
const repoPath = creation.repoPath ??
|
|
7301
|
+
const repoPath = creation.repoPath ?? join4(config.projectsRoot, `project-${creation.projectId}`, `creation-${creation.id}`);
|
|
7826
7302
|
const progress = (step) => client.report(creation.id, { status: "running", step, repoPath }, signal);
|
|
7827
7303
|
await (shared ? adoptRepository : initRepository)(config, creation, repoPath, progress, signal);
|
|
7828
7304
|
await progress("register");
|
|
7829
7305
|
const result = await client.register(creation.id, hostname(), signal);
|
|
7830
7306
|
const state = workerStatePath(config, creation);
|
|
7831
7307
|
const root = await realpath(config.projectsRoot);
|
|
7832
|
-
await directory(
|
|
7833
|
-
await directory(
|
|
7308
|
+
await directory(join4(root, ".worker-state"));
|
|
7309
|
+
await directory(join4(root, ".worker-state", `project-${creation.projectId}`));
|
|
7834
7310
|
await mkdir3(state, { mode: 448 });
|
|
7835
|
-
await mkdir3(
|
|
7836
|
-
await writeFile2(
|
|
7311
|
+
await mkdir3(join4(state, "baton"), { mode: 448 });
|
|
7312
|
+
await writeFile2(join4(state, "baton/machine-id"), `${creation.machineId}
|
|
7837
7313
|
`, {
|
|
7838
7314
|
flag: "wx",
|
|
7839
7315
|
mode: 384
|
|
@@ -7847,7 +7323,7 @@ var provisionWorker = async (config, creation, client, signal) => {
|
|
|
7847
7323
|
machineId: result.worker.machineId,
|
|
7848
7324
|
apiToken: result.apiToken
|
|
7849
7325
|
});
|
|
7850
|
-
const configPath = shared ?
|
|
7326
|
+
const configPath = shared ? join4(state, "worker.json") : join4(repoPath, ".baton.json");
|
|
7851
7327
|
await writeFile2(configPath, `${JSON.stringify(cfg, null, 2)}
|
|
7852
7328
|
`, { flag: "wx", mode: 384 });
|
|
7853
7329
|
await progress("start");
|
|
@@ -8027,183 +7503,6 @@ var provisioner = defineCommand({
|
|
|
8027
7503
|
}
|
|
8028
7504
|
});
|
|
8029
7505
|
|
|
8030
|
-
// src/commands/relay.ts
|
|
8031
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
8032
|
-
import { tmpdir as tmpdir2 } from "node:os";
|
|
8033
|
-
import { join as join6 } from "node:path";
|
|
8034
|
-
|
|
8035
|
-
// src/client/relay.ts
|
|
8036
|
-
var relayClient = (baseUrl) => {
|
|
8037
|
-
const u = (p) => `${baseUrl}${p}`;
|
|
8038
|
-
const authed = (token) => ({ authorization: `Bearer ${token}` });
|
|
8039
|
-
return {
|
|
8040
|
-
create: async () => {
|
|
8041
|
-
const res = await fetch(u("/relay/channels"), { method: "POST" });
|
|
8042
|
-
if (!res.ok) throw new Error(`POST /relay/channels \u2192 ${res.status}: ${await res.text()}`);
|
|
8043
|
-
return await res.json();
|
|
8044
|
-
},
|
|
8045
|
-
send: async (channelId, token, msg) => {
|
|
8046
|
-
const res = await fetch(u(`/relay/channels/${channelId}/messages`), {
|
|
8047
|
-
method: "POST",
|
|
8048
|
-
headers: { "content-type": "application/json", ...authed(token) },
|
|
8049
|
-
body: JSON.stringify(msg)
|
|
8050
|
-
});
|
|
8051
|
-
if (!res.ok) throw new Error(`POST relay message \u2192 ${res.status}: ${await res.text()}`);
|
|
8052
|
-
return await res.json();
|
|
8053
|
-
},
|
|
8054
|
-
listen: (channelId, token, opts) => {
|
|
8055
|
-
let cursor = opts.since ?? 0;
|
|
8056
|
-
const es = new EventSource(u(`/relay/channels/${channelId}/stream?since=${cursor}`), {
|
|
8057
|
-
fetch: (url, init2) => fetch(url, {
|
|
8058
|
-
...init2,
|
|
8059
|
-
headers: { ...init2?.headers, ...authed(token) }
|
|
8060
|
-
})
|
|
8061
|
-
});
|
|
8062
|
-
es.onmessage = (e) => {
|
|
8063
|
-
try {
|
|
8064
|
-
const m = JSON.parse(e.data);
|
|
8065
|
-
if (m.seq <= cursor) return;
|
|
8066
|
-
cursor = m.seq;
|
|
8067
|
-
opts.onMessage(m);
|
|
8068
|
-
} catch (err) {
|
|
8069
|
-
opts.onError?.(err);
|
|
8070
|
-
}
|
|
8071
|
-
};
|
|
8072
|
-
es.onerror = (err) => opts.onError?.(err);
|
|
8073
|
-
return () => es.close();
|
|
8074
|
-
}
|
|
8075
|
-
};
|
|
8076
|
-
};
|
|
8077
|
-
|
|
8078
|
-
// src/commands/relay.ts
|
|
8079
|
-
var PREVIEW2 = 280;
|
|
8080
|
-
var readStdin2 = async () => {
|
|
8081
|
-
const chunks = [];
|
|
8082
|
-
for await (const c of process.stdin) chunks.push(c);
|
|
8083
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
8084
|
-
};
|
|
8085
|
-
var inviteBlock2 = (url, channelId, token) => [
|
|
8086
|
-
"\u2500\u2500 Copy everything below to your peer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
8087
|
-
"You're invited to a live Claude\u2194Claude channel. Use the `hotline` skill in",
|
|
8088
|
-
"join mode, or run these two commands directly (pick your own NAME):",
|
|
8089
|
-
"",
|
|
8090
|
-
` baton relay listen ${channelId} --token ${token} --from NAME --url ${url}`,
|
|
8091
|
-
` baton relay send ${channelId} --token ${token} --from NAME --text "..." --url ${url}`,
|
|
8092
|
-
"",
|
|
8093
|
-
`connection: url=${url} channel=${channelId} token=${token}`,
|
|
8094
|
-
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
8095
|
-
].join("\n");
|
|
8096
|
-
var hostCommand = defineCommand({
|
|
8097
|
-
meta: { name: "host", description: "open a relay channel and print an invite for a peer" },
|
|
8098
|
-
args: {
|
|
8099
|
-
name: { type: "string", description: "your participant name (default: host)" },
|
|
8100
|
-
...common
|
|
8101
|
-
},
|
|
8102
|
-
run: async ({ args }) => {
|
|
8103
|
-
const url = resolveBaseUrl(args.url);
|
|
8104
|
-
const { channelId, token } = await relayClient(url).create();
|
|
8105
|
-
if (args.json) {
|
|
8106
|
-
console.log(toJson({ channelId, token, url, host: args.name ?? "host" }));
|
|
8107
|
-
return;
|
|
8108
|
-
}
|
|
8109
|
-
console.log(`channel ${channelId} opened
|
|
8110
|
-
`);
|
|
8111
|
-
console.log(inviteBlock2(url, channelId, token));
|
|
8112
|
-
}
|
|
8113
|
-
});
|
|
8114
|
-
var sendCommand2 = defineCommand({
|
|
8115
|
-
meta: { name: "send", description: "post one message to a relay channel" },
|
|
8116
|
-
args: {
|
|
8117
|
-
channel: { type: "positional", required: true, description: "channel id" },
|
|
8118
|
-
text: { type: "positional", required: false, description: "message text (short one-liner)" },
|
|
8119
|
-
token: { type: "string", required: true, description: "channel token" },
|
|
8120
|
-
from: { type: "string", description: "your participant name (default: peer)" },
|
|
8121
|
-
file: { type: "string", description: "read message body from this file (for large content)" },
|
|
8122
|
-
...common
|
|
8123
|
-
},
|
|
8124
|
-
run: async ({ args }) => {
|
|
8125
|
-
const url = resolveBaseUrl(args.url);
|
|
8126
|
-
let text = args.text;
|
|
8127
|
-
if (text === void 0 && args.file) text = readFileSync3(args.file, "utf8");
|
|
8128
|
-
if (text === void 0 && !process.stdin.isTTY) text = await readStdin2();
|
|
8129
|
-
if (text === void 0 || text === "")
|
|
8130
|
-
throw new Error("nothing to send: provide text, --file <path>, or pipe stdin");
|
|
8131
|
-
const msg = await relayClient(url).send(args.channel, args.token, {
|
|
8132
|
-
from: args.from ?? "peer",
|
|
8133
|
-
text
|
|
8134
|
-
});
|
|
8135
|
-
if (args.json) console.log(toJson(msg));
|
|
8136
|
-
else console.log(`sent (seq ${msg.seq})`);
|
|
8137
|
-
}
|
|
8138
|
-
});
|
|
8139
|
-
var listenCommand2 = defineCommand({
|
|
8140
|
-
meta: {
|
|
8141
|
-
name: "listen",
|
|
8142
|
-
description: "stream a channel: one JSON line per peer message (for a background subscriber)"
|
|
8143
|
-
},
|
|
8144
|
-
args: {
|
|
8145
|
-
channel: { type: "positional", required: true, description: "channel id" },
|
|
8146
|
-
token: { type: "string", required: true, description: "channel token" },
|
|
8147
|
-
from: {
|
|
8148
|
-
type: "string",
|
|
8149
|
-
description: "your name; messages from this name are skipped (no echo)"
|
|
8150
|
-
},
|
|
8151
|
-
since: { type: "string", description: "replay messages after this seq (default 0 = full)" },
|
|
8152
|
-
...common
|
|
8153
|
-
},
|
|
8154
|
-
run: async ({ args }) => {
|
|
8155
|
-
const url = resolveBaseUrl(args.url);
|
|
8156
|
-
const me = args.from ?? "";
|
|
8157
|
-
const emit = (o) => {
|
|
8158
|
-
process.stdout.write(`${JSON.stringify(o)}
|
|
8159
|
-
`);
|
|
8160
|
-
};
|
|
8161
|
-
const spillDir = join6(tmpdir2(), "hotline", args.channel);
|
|
8162
|
-
mkdirSync2(spillDir, { recursive: true });
|
|
8163
|
-
const surface = (m) => {
|
|
8164
|
-
const text = typeof m.text === "string" ? m.text : "";
|
|
8165
|
-
const file = join6(spillDir, `${m.seq}.txt`);
|
|
8166
|
-
writeFileSync4(file, text);
|
|
8167
|
-
const truncated = text.length > PREVIEW2;
|
|
8168
|
-
emit({
|
|
8169
|
-
type: "relay.message",
|
|
8170
|
-
seq: m.seq,
|
|
8171
|
-
from: m.from,
|
|
8172
|
-
ts: m.ts,
|
|
8173
|
-
chars: text.length,
|
|
8174
|
-
truncated,
|
|
8175
|
-
preview: truncated ? `${text.slice(0, PREVIEW2)} \u2026` : text,
|
|
8176
|
-
file
|
|
8177
|
-
});
|
|
8178
|
-
};
|
|
8179
|
-
const describe3 = (e) => {
|
|
8180
|
-
const ev = e;
|
|
8181
|
-
return ev?.code ? `${ev.code}${ev.message ? ` ${ev.message}` : ""}` : String(e);
|
|
8182
|
-
};
|
|
8183
|
-
const close = relayClient(url).listen(args.channel, args.token, {
|
|
8184
|
-
since: args.since ? Number(args.since) : 0,
|
|
8185
|
-
// Skip our own messages (they come back over the same channel).
|
|
8186
|
-
onMessage: (m) => {
|
|
8187
|
-
if (m.from !== me) surface(m);
|
|
8188
|
-
},
|
|
8189
|
-
onError: (e) => emit({ type: "relay.error", error: describe3(e) })
|
|
8190
|
-
});
|
|
8191
|
-
emit({ type: "relay.listening", channel: args.channel, from: me, url });
|
|
8192
|
-
await new Promise((resolve4) => {
|
|
8193
|
-
const stop = () => {
|
|
8194
|
-
close();
|
|
8195
|
-
resolve4();
|
|
8196
|
-
};
|
|
8197
|
-
process.on("SIGINT", stop);
|
|
8198
|
-
process.on("SIGTERM", stop);
|
|
8199
|
-
});
|
|
8200
|
-
}
|
|
8201
|
-
});
|
|
8202
|
-
var relay = defineCommand({
|
|
8203
|
-
meta: { name: "relay", description: "Claude\u2194Claude live channel: host / listen / send" },
|
|
8204
|
-
subCommands: { host: hostCommand, listen: listenCommand2, send: sendCommand2 }
|
|
8205
|
-
});
|
|
8206
|
-
|
|
8207
7506
|
// src/commands/service.ts
|
|
8208
7507
|
import { resolve as resolve2 } from "node:path";
|
|
8209
7508
|
|
|
@@ -8523,14 +7822,14 @@ import { randomUUID } from "node:crypto";
|
|
|
8523
7822
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
8524
7823
|
|
|
8525
7824
|
// src/session/runner/transcript.ts
|
|
8526
|
-
import { readdirSync, readFileSync as
|
|
7825
|
+
import { readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
8527
7826
|
import { homedir as homedir2 } from "node:os";
|
|
8528
|
-
import { join as
|
|
7827
|
+
import { join as join5 } from "node:path";
|
|
8529
7828
|
var findTranscriptPath = (agentSessionId) => {
|
|
8530
|
-
const root =
|
|
7829
|
+
const root = join5(homedir2(), ".claude", "projects");
|
|
8531
7830
|
try {
|
|
8532
7831
|
for (const dir of readdirSync(root)) {
|
|
8533
|
-
const candidate =
|
|
7832
|
+
const candidate = join5(root, dir, `${agentSessionId}.jsonl`);
|
|
8534
7833
|
try {
|
|
8535
7834
|
if (statSync(candidate).isFile()) return candidate;
|
|
8536
7835
|
} catch {
|
|
@@ -8601,7 +7900,7 @@ var readFirstExchange = (agentSessionId) => {
|
|
|
8601
7900
|
const path = findTranscriptPath(agentSessionId);
|
|
8602
7901
|
if (!path) return null;
|
|
8603
7902
|
try {
|
|
8604
|
-
return parseFirstExchange(
|
|
7903
|
+
return parseFirstExchange(readFileSync2(path, "utf8"));
|
|
8605
7904
|
} catch {
|
|
8606
7905
|
return null;
|
|
8607
7906
|
}
|
|
@@ -8609,12 +7908,12 @@ var readFirstExchange = (agentSessionId) => {
|
|
|
8609
7908
|
|
|
8610
7909
|
// src/session/runner/turn.ts
|
|
8611
7910
|
import { mkdir as mkdir5, writeFile as writeFile3 } from "node:fs/promises";
|
|
8612
|
-
import { join as
|
|
7911
|
+
import { join as join10 } from "node:path";
|
|
8613
7912
|
|
|
8614
7913
|
// src/session/runner/attachments.ts
|
|
8615
7914
|
import { createWriteStream } from "node:fs";
|
|
8616
7915
|
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
8617
|
-
import { join as
|
|
7916
|
+
import { join as join6 } from "node:path";
|
|
8618
7917
|
import { Readable } from "node:stream";
|
|
8619
7918
|
import { pipeline } from "node:stream/promises";
|
|
8620
7919
|
var dedupe = (name, taken) => {
|
|
@@ -8644,8 +7943,8 @@ var materializeAttachments = async (opts) => {
|
|
|
8644
7943
|
const name = dedupe(att.filename, taken);
|
|
8645
7944
|
const res = await fetchImpl(`${opts.serverBase}${att.url}`);
|
|
8646
7945
|
if (!res.ok || !res.body) throw new Error(`attachment ${att.id} \u2192 ${res.status}`);
|
|
8647
|
-
await pipeline(Readable.fromWeb(res.body), createWriteStream(
|
|
8648
|
-
paths.push(
|
|
7946
|
+
await pipeline(Readable.fromWeb(res.body), createWriteStream(join6(dir, name)));
|
|
7947
|
+
paths.push(join6(dir, name));
|
|
8649
7948
|
}
|
|
8650
7949
|
return paths;
|
|
8651
7950
|
};
|
|
@@ -8661,7 +7960,7 @@ ${text}` : header;
|
|
|
8661
7960
|
};
|
|
8662
7961
|
|
|
8663
7962
|
// src/session/runner/codex.ts
|
|
8664
|
-
import { join as
|
|
7963
|
+
import { join as join7 } from "node:path";
|
|
8665
7964
|
import { Codex } from "@openai/codex-sdk";
|
|
8666
7965
|
|
|
8667
7966
|
// src/session/runner/sdk-env.ts
|
|
@@ -8823,7 +8122,7 @@ async function* startCodexEvents(config, input, worker2, opts) {
|
|
|
8823
8122
|
const env = compactEnv(buildSdkEnv(opts.envOverlay));
|
|
8824
8123
|
const codex = new Codex(env ? { env } : void 0);
|
|
8825
8124
|
const resuming = !config.agentSessionId.startsWith("pending:");
|
|
8826
|
-
const addDirs = additionalDirs([
|
|
8125
|
+
const addDirs = additionalDirs([join7(config.runtimeDir, "attachments")]);
|
|
8827
8126
|
const sandboxMode = codexSandboxMode(opts.planMode ?? false);
|
|
8828
8127
|
const approvalPolicy = codexApprovalPolicy();
|
|
8829
8128
|
const networkAccessEnabled = codexNetworkAccess();
|
|
@@ -8864,7 +8163,7 @@ async function* startCodexEvents(config, input, worker2, opts) {
|
|
|
8864
8163
|
// src/session/runner/pi.ts
|
|
8865
8164
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
8866
8165
|
import { homedir as homedir3 } from "node:os";
|
|
8867
|
-
import { join as
|
|
8166
|
+
import { join as join8 } from "node:path";
|
|
8868
8167
|
var newPiTurnState = (startedAt = Date.now()) => ({
|
|
8869
8168
|
startedAt,
|
|
8870
8169
|
usage: {},
|
|
@@ -9009,7 +8308,7 @@ async function* startPiEvents(config, input, opts) {
|
|
|
9009
8308
|
agentDir,
|
|
9010
8309
|
// pi discovers .pi/ and .agents/ skills natively; Baton workers deploy theirs
|
|
9011
8310
|
// under .claude/skills (project and user level).
|
|
9012
|
-
additionalSkillPaths: [
|
|
8311
|
+
additionalSkillPaths: [join8(config.cwd, ".claude/skills"), join8(homedir3(), ".claude/skills")]
|
|
9013
8312
|
});
|
|
9014
8313
|
await resourceLoader.reload();
|
|
9015
8314
|
const existing = pi.SessionManager.findById(config.cwd, config.agentSessionId);
|
|
@@ -9084,11 +8383,11 @@ async function* startPiEvents(config, input, opts) {
|
|
|
9084
8383
|
}
|
|
9085
8384
|
|
|
9086
8385
|
// src/session/runner/query.ts
|
|
9087
|
-
import { join as
|
|
8386
|
+
import { join as join9 } from "node:path";
|
|
9088
8387
|
var startQuery = (config, text, resuming, queryFn, abortController, log, { envOverlay, planMode = false, model, effort } = {}) => {
|
|
9089
8388
|
const env = buildSdkEnv(envOverlay);
|
|
9090
8389
|
const exe = claudeExecutable();
|
|
9091
|
-
const addDirs = additionalDirs([
|
|
8390
|
+
const addDirs = additionalDirs([join9(config.runtimeDir, "attachments")]);
|
|
9092
8391
|
const level = claudeEffort(effort);
|
|
9093
8392
|
if (addDirs) log(`[add-dir] ${addDirs.join(", ")}`);
|
|
9094
8393
|
if (planMode) log("[plan] read-only planning turn");
|
|
@@ -9339,7 +8638,7 @@ var UnsettledExecution = class extends Error {
|
|
|
9339
8638
|
var materializeImages = async (config, execution) => {
|
|
9340
8639
|
const images = execution.message.payload.images ?? [];
|
|
9341
8640
|
if (!images.length) return [];
|
|
9342
|
-
const directory2 =
|
|
8641
|
+
const directory2 = join10(
|
|
9343
8642
|
config.runtimeDir,
|
|
9344
8643
|
"attachments",
|
|
9345
8644
|
`message-${execution.message.id}`,
|
|
@@ -9350,7 +8649,7 @@ var materializeImages = async (config, execution) => {
|
|
|
9350
8649
|
images.map(async (image, index) => {
|
|
9351
8650
|
const match = /^data:image\/(png|jpeg|webp|gif);base64,([A-Za-z0-9+/=\r\n]+)$/.exec(image);
|
|
9352
8651
|
if (!match) throw new Error("unsupported pasted image");
|
|
9353
|
-
const path =
|
|
8652
|
+
const path = join10(directory2, `pasted-${index + 1}.${match[1]}`);
|
|
9354
8653
|
await writeFile3(path, Buffer.from(match[2] ?? "", "base64"));
|
|
9355
8654
|
return path;
|
|
9356
8655
|
})
|
|
@@ -9359,7 +8658,7 @@ var materializeImages = async (config, execution) => {
|
|
|
9359
8658
|
var buildPrompt = async (config, execution, fetchImpl) => {
|
|
9360
8659
|
const { text: rawText, attachments = [] } = execution.message.payload;
|
|
9361
8660
|
const paths = attachments.length ? await materializeAttachments({
|
|
9362
|
-
directory:
|
|
8661
|
+
directory: join10(
|
|
9363
8662
|
config.runtimeDir,
|
|
9364
8663
|
"attachments",
|
|
9365
8664
|
`message-${execution.message.id}`,
|
|
@@ -9616,15 +8915,15 @@ var runDaemon = async (config, deps, signal) => {
|
|
|
9616
8915
|
// src/worker/runtime-paths.ts
|
|
9617
8916
|
import { createHash } from "node:crypto";
|
|
9618
8917
|
import { homedir as homedir4 } from "node:os";
|
|
9619
|
-
import { join as
|
|
9620
|
-
var workerRuntimeDir = (owner, env = process.env) =>
|
|
9621
|
-
env.XDG_DATA_HOME ??
|
|
8918
|
+
import { join as join11 } from "node:path";
|
|
8919
|
+
var workerRuntimeDir = (owner, env = process.env) => join11(
|
|
8920
|
+
env.XDG_DATA_HOME ?? join11(env.HOME ?? homedir4(), ".local/share"),
|
|
9622
8921
|
"baton",
|
|
9623
8922
|
"runtime",
|
|
9624
8923
|
createHash("sha256").update(owner.server).digest("hex"),
|
|
9625
8924
|
`worker-${owner.workerId}`
|
|
9626
8925
|
);
|
|
9627
|
-
var sessionRuntimeDir = (owner, sessionId, env = process.env) =>
|
|
8926
|
+
var sessionRuntimeDir = (owner, sessionId, env = process.env) => join11(workerRuntimeDir(owner, env), "sessions", String(sessionId));
|
|
9628
8927
|
|
|
9629
8928
|
// src/commands/session/run.ts
|
|
9630
8929
|
var bearerFetch = (token) => (input, init2) => fetch(input, {
|
|
@@ -9719,6 +9018,25 @@ var sessionRunCommand = defineCommand({
|
|
|
9719
9018
|
}
|
|
9720
9019
|
});
|
|
9721
9020
|
|
|
9021
|
+
// src/commands/attach.ts
|
|
9022
|
+
import { openAsBlob as openAsBlob2 } from "node:fs";
|
|
9023
|
+
import { basename as basename2 } from "node:path";
|
|
9024
|
+
var attachPaths = (raw) => (raw === void 0 ? [] : Array.isArray(raw) ? raw : [raw]).flatMap((p) => p.split(",")).map((p) => p.trim()).filter(Boolean);
|
|
9025
|
+
var uploadAttachments = async (client, sessionId, paths) => {
|
|
9026
|
+
const out = [];
|
|
9027
|
+
for (const path of paths) {
|
|
9028
|
+
const body = await openAsBlob2(path, { type: contentTypeForPath(path) });
|
|
9029
|
+
out.push(
|
|
9030
|
+
await client.sessions.uploadAttachment(sessionId, {
|
|
9031
|
+
filename: basename2(path),
|
|
9032
|
+
contentType: contentTypeForPath(path),
|
|
9033
|
+
body
|
|
9034
|
+
})
|
|
9035
|
+
);
|
|
9036
|
+
}
|
|
9037
|
+
return out;
|
|
9038
|
+
};
|
|
9039
|
+
|
|
9722
9040
|
// src/commands/session/send.ts
|
|
9723
9041
|
var sessionSendCommand = defineCommand({
|
|
9724
9042
|
meta: { name: "send", description: "post a chat message into a session (no streaming reply)" },
|
|
@@ -9766,6 +9084,60 @@ var sessionStopCommand = defineCommand({
|
|
|
9766
9084
|
}
|
|
9767
9085
|
});
|
|
9768
9086
|
|
|
9087
|
+
// src/commands/session/tell.ts
|
|
9088
|
+
var TELL_LOOP_LIMIT = 10;
|
|
9089
|
+
var TELL_HEADER = /^\[Message from baton session #\d+ /gm;
|
|
9090
|
+
var renderTell = (from, body) => [
|
|
9091
|
+
`[Message from baton session #${from.id} ${JSON.stringify(from.name)}]`,
|
|
9092
|
+
`To reply, run: baton session tell ${from.id} "<your reply>"`,
|
|
9093
|
+
"Reply only if a response is actually needed.",
|
|
9094
|
+
"",
|
|
9095
|
+
body
|
|
9096
|
+
].join("\n");
|
|
9097
|
+
var headerCount = (event) => {
|
|
9098
|
+
const text = event.payload?.text ?? "";
|
|
9099
|
+
return text.match(TELL_HEADER)?.length ?? 0;
|
|
9100
|
+
};
|
|
9101
|
+
var countConsecutiveTells = (events) => {
|
|
9102
|
+
const newestFirst = events.filter((event) => event.type === "user_message").map(headerCount).reverse();
|
|
9103
|
+
const end = newestFirst.indexOf(0);
|
|
9104
|
+
return (end < 0 ? newestFirst : newestFirst.slice(0, end)).reduce((sum, n) => sum + n, 0);
|
|
9105
|
+
};
|
|
9106
|
+
var sendTell = async (c, { fromId, toId, body }) => {
|
|
9107
|
+
if (body.trim() === "") throw new Error("nothing to send: message text is empty");
|
|
9108
|
+
if (toId === fromId) throw new Error("cannot tell your own session");
|
|
9109
|
+
const [from, events] = await Promise.all([c.sessions.get(fromId), c.sessions.listEvents(fromId)]);
|
|
9110
|
+
const received = countConsecutiveTells(events);
|
|
9111
|
+
if (received >= TELL_LOOP_LIMIT)
|
|
9112
|
+
throw new Error(
|
|
9113
|
+
`not sent: this session received ${received} agent messages in a row. Stop and ask a human; a message from them resets the count.`
|
|
9114
|
+
);
|
|
9115
|
+
return c.sessions.sendMessage(toId, renderTell(from, body));
|
|
9116
|
+
};
|
|
9117
|
+
var parseId = (raw) => raw !== void 0 && /^[1-9]\d*$/.test(raw) ? Number(raw) : null;
|
|
9118
|
+
var sessionTellCommand = defineCommand({
|
|
9119
|
+
meta: {
|
|
9120
|
+
name: "tell",
|
|
9121
|
+
description: "Send a message to another agent session in this workspace. It includes who sent it and how to reply, and wakes the target if needed. Delivery is fire-and-forget: end your turn, and any reply arrives as a new message. You cannot read another session; ask it instead."
|
|
9122
|
+
},
|
|
9123
|
+
args: {
|
|
9124
|
+
session: { type: "positional", required: true, description: "target session int id" },
|
|
9125
|
+
text: { type: "positional", required: true, description: "message text" },
|
|
9126
|
+
...common
|
|
9127
|
+
},
|
|
9128
|
+
run: async ({ args }) => {
|
|
9129
|
+
const fromId = parseId(process.env.BATON_SESSION_ID);
|
|
9130
|
+
const bearer = process.env.BATON_WORKER_TOKEN;
|
|
9131
|
+
if (fromId === null || !bearer)
|
|
9132
|
+
throw new Error("baton session tell only works inside a baton session");
|
|
9133
|
+
const toId = parseId(args.session);
|
|
9134
|
+
if (toId === null) throw new Error(`invalid session "${args.session}": pass the session id`);
|
|
9135
|
+
const client = createClient(resolveBaseUrl(args.url), { bearer });
|
|
9136
|
+
const result = await sendTell(client, { fromId, toId, body: args.text });
|
|
9137
|
+
console.log(args.json ? toJson(result) : `told session #${toId} (input ${result.input.id})`);
|
|
9138
|
+
}
|
|
9139
|
+
});
|
|
9140
|
+
|
|
9769
9141
|
// src/commands/session/terminal.ts
|
|
9770
9142
|
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
9771
9143
|
var sessionTerminalCommand = defineCommand({
|
|
@@ -9814,6 +9186,7 @@ var session = defineCommand({
|
|
|
9814
9186
|
rename: sessionRenameCommand,
|
|
9815
9187
|
rm: sessionRmCommand,
|
|
9816
9188
|
send: sessionSendCommand,
|
|
9189
|
+
tell: sessionTellCommand,
|
|
9817
9190
|
ls: sessionLsCommand,
|
|
9818
9191
|
get: sessionGetCommand,
|
|
9819
9192
|
run: sessionRunCommand,
|
|
@@ -9827,12 +9200,12 @@ import { hostname as osHostname } from "node:os";
|
|
|
9827
9200
|
// src/worker/bundled-skills.ts
|
|
9828
9201
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
9829
9202
|
import { cpSync, existsSync as existsSync5 } from "node:fs";
|
|
9830
|
-
import { dirname as dirname4, join as
|
|
9203
|
+
import { dirname as dirname4, join as join12 } from "node:path";
|
|
9831
9204
|
import { fileURLToPath } from "node:url";
|
|
9832
9205
|
|
|
9833
9206
|
// src/worker/git-exclude.ts
|
|
9834
9207
|
import { spawnSync } from "node:child_process";
|
|
9835
|
-
import { appendFileSync, existsSync as existsSync4, mkdirSync
|
|
9208
|
+
import { appendFileSync, existsSync as existsSync4, mkdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
9836
9209
|
import { dirname as dirname3, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
|
|
9837
9210
|
var ensureExcluded = (cwd, pattern) => {
|
|
9838
9211
|
const result = spawnSync("git", ["-C", cwd, "rev-parse", "--git-path", "info/exclude"], {
|
|
@@ -9846,9 +9219,9 @@ var ensureExcluded = (cwd, pattern) => {
|
|
|
9846
9219
|
}
|
|
9847
9220
|
const location = result.stdout.trim();
|
|
9848
9221
|
const path = isAbsolute3(location) ? location : resolve3(cwd, location);
|
|
9849
|
-
const current = existsSync4(path) ?
|
|
9222
|
+
const current = existsSync4(path) ? readFileSync3(path, "utf8") : "";
|
|
9850
9223
|
if (current.split("\n").includes(pattern)) return;
|
|
9851
|
-
|
|
9224
|
+
mkdirSync(dirname3(path), { recursive: true });
|
|
9852
9225
|
appendFileSync(path, `${current && !current.endsWith("\n") ? "\n" : ""}${pattern}
|
|
9853
9226
|
`);
|
|
9854
9227
|
};
|
|
@@ -9859,8 +9232,8 @@ var TARGETS = [`.claude/skills/${SKILL_NAME}`, `.agents/skills/${SKILL_NAME}`];
|
|
|
9859
9232
|
var bundledSkillPath = () => {
|
|
9860
9233
|
const here = dirname4(fileURLToPath(import.meta.url));
|
|
9861
9234
|
const candidates = [
|
|
9862
|
-
|
|
9863
|
-
|
|
9235
|
+
join12(here, "..", "skills", SKILL_NAME),
|
|
9236
|
+
join12(here, "..", "..", "skills", SKILL_NAME)
|
|
9864
9237
|
];
|
|
9865
9238
|
const found = candidates.find(existsSync5);
|
|
9866
9239
|
if (!found) throw new Error(`bundled skill missing: ${SKILL_NAME}`);
|
|
@@ -9877,7 +9250,7 @@ var syncBundledArtifactSkill = (cwd) => {
|
|
|
9877
9250
|
const source = bundledSkillPath();
|
|
9878
9251
|
TARGETS.filter((target) => !isTracked(cwd, target)).forEach((target) => {
|
|
9879
9252
|
ensureExcluded(cwd, `${target}/`);
|
|
9880
|
-
cpSync(source,
|
|
9253
|
+
cpSync(source, join12(cwd, target), { recursive: true, force: true });
|
|
9881
9254
|
});
|
|
9882
9255
|
};
|
|
9883
9256
|
|
|
@@ -10148,7 +9521,7 @@ var openCommitDownload = async (repo, commit, path, signal) => {
|
|
|
10148
9521
|
// src/worker/files/disk.ts
|
|
10149
9522
|
import { constants as constants2 } from "node:fs";
|
|
10150
9523
|
import { open as open2, readdir, realpath as realpath3, stat as stat3 } from "node:fs/promises";
|
|
10151
|
-
import { isAbsolute as isAbsolute4, join as
|
|
9524
|
+
import { isAbsolute as isAbsolute4, join as join13, relative, sep } from "node:path";
|
|
10152
9525
|
import { Readable as Readable3 } from "node:stream";
|
|
10153
9526
|
var isMissing = (error) => ["ENOENT", "ENOTDIR", "ELOOP"].includes(error.code ?? "");
|
|
10154
9527
|
var childPath = (parent, name) => parent ? `${parent}/${name}` : name;
|
|
@@ -10161,7 +9534,7 @@ var resolveInside = async (root, path, allowRoot) => {
|
|
|
10161
9534
|
const rel = checkedPath(path, allowRoot);
|
|
10162
9535
|
let real;
|
|
10163
9536
|
try {
|
|
10164
|
-
real = await realpath3(
|
|
9537
|
+
real = await realpath3(join13(root, rel));
|
|
10165
9538
|
} catch (error) {
|
|
10166
9539
|
if (isMissing(error)) throw notFound(rel);
|
|
10167
9540
|
throw error;
|
|
@@ -10191,7 +9564,7 @@ var toEntry = async (root, dir, dirent) => {
|
|
|
10191
9564
|
if (dirent.isDirectory())
|
|
10192
9565
|
return isExcludedDirectoryName(dirent.name) ? null : { name: dirent.name, path, kind: "directory" };
|
|
10193
9566
|
if (dirent.isFile()) return { name: dirent.name, path, kind: "file" };
|
|
10194
|
-
return dirent.isSymbolicLink() ? symlinkEntry(root,
|
|
9567
|
+
return dirent.isSymbolicLink() ? symlinkEntry(root, join13(dir.real, dirent.name), dirent.name, path) : null;
|
|
10195
9568
|
};
|
|
10196
9569
|
var listDirectory = async (root, path) => {
|
|
10197
9570
|
const dir = await resolveInside(root, path, true);
|
|
@@ -10214,7 +9587,7 @@ var searchFiles = async (root, query3, now = Date.now) => {
|
|
|
10214
9587
|
const dir = pending[index] ?? "";
|
|
10215
9588
|
let dirents;
|
|
10216
9589
|
try {
|
|
10217
|
-
dirents = await readdir(
|
|
9590
|
+
dirents = await readdir(join13(root, dir), { withFileTypes: true });
|
|
10218
9591
|
} catch (error) {
|
|
10219
9592
|
console.warn(`[files] search skipped unreadable directory ${dir || "."}`, error);
|
|
10220
9593
|
continue;
|
|
@@ -10458,14 +9831,14 @@ var createLiveness = (deps) => {
|
|
|
10458
9831
|
};
|
|
10459
9832
|
|
|
10460
9833
|
// src/worker/service-supervisor.ts
|
|
10461
|
-
import { mkdirSync as
|
|
9834
|
+
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
10462
9835
|
import { stat as stat4 } from "node:fs/promises";
|
|
10463
|
-
import { join as
|
|
9836
|
+
import { join as join15 } from "node:path";
|
|
10464
9837
|
|
|
10465
9838
|
// src/worker/service-process.ts
|
|
10466
9839
|
import { spawn as spawn3 } from "node:child_process";
|
|
10467
9840
|
import { closeSync, existsSync as existsSync6, openSync } from "node:fs";
|
|
10468
|
-
import { dirname as dirname5, join as
|
|
9841
|
+
import { dirname as dirname5, join as join14 } from "node:path";
|
|
10469
9842
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
10470
9843
|
var START_TIMEOUT_MS = 1e4;
|
|
10471
9844
|
var isWrapperMessage = (message) => {
|
|
@@ -10476,7 +9849,7 @@ var isWrapperMessage = (message) => {
|
|
|
10476
9849
|
};
|
|
10477
9850
|
var binPath = () => {
|
|
10478
9851
|
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
10479
|
-
const devShim =
|
|
9852
|
+
const devShim = join14(here, "..", "..", "bin", "baton.mjs");
|
|
10480
9853
|
return existsSync6(devShim) ? devShim : fileURLToPath2(import.meta.url);
|
|
10481
9854
|
};
|
|
10482
9855
|
var startServiceProcess = (input) => {
|
|
@@ -10570,9 +9943,9 @@ var createServiceSupervisor = (deps) => {
|
|
|
10570
9943
|
if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
|
|
10571
9944
|
return report({ requestId, ok: false, error: `directory not found: ${cwd}`, status: 400 });
|
|
10572
9945
|
}
|
|
10573
|
-
const logDir =
|
|
10574
|
-
const logPath =
|
|
10575
|
-
|
|
9946
|
+
const logDir = join15(workerRuntimeDir(cfg), "services");
|
|
9947
|
+
const logPath = join15(logDir, `${name}.log`);
|
|
9948
|
+
mkdirSync2(logDir, { recursive: true, mode: 448 });
|
|
10576
9949
|
if (entries.has(name))
|
|
10577
9950
|
return report({
|
|
10578
9951
|
requestId,
|
|
@@ -10637,7 +10010,7 @@ import { spawn as spawn4 } from "node:child_process";
|
|
|
10637
10010
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
10638
10011
|
import { existsSync as existsSync7 } from "node:fs";
|
|
10639
10012
|
import { mkdir as mkdir6, rm as rm3, stat as stat5 } from "node:fs/promises";
|
|
10640
|
-
import { dirname as dirname6, join as
|
|
10013
|
+
import { dirname as dirname6, join as join19 } from "node:path";
|
|
10641
10014
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
10642
10015
|
import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
|
|
10643
10016
|
|
|
@@ -10730,8 +10103,8 @@ var generateTitle = async (input) => {
|
|
|
10730
10103
|
|
|
10731
10104
|
// src/session/runner/title-codex.ts
|
|
10732
10105
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
10733
|
-
import { tmpdir
|
|
10734
|
-
import { join as
|
|
10106
|
+
import { tmpdir } from "node:os";
|
|
10107
|
+
import { join as join16 } from "node:path";
|
|
10735
10108
|
import { Codex as Codex2 } from "@openai/codex-sdk";
|
|
10736
10109
|
var generateTitleWithCodex = async (input) => {
|
|
10737
10110
|
const { userText, assistantText } = input;
|
|
@@ -10740,7 +10113,7 @@ var generateTitleWithCodex = async (input) => {
|
|
|
10740
10113
|
const timer = setTimeout(() => abort.abort(), TITLE_TIMEOUT_MS);
|
|
10741
10114
|
let cwd = "";
|
|
10742
10115
|
try {
|
|
10743
|
-
cwd = await mkdtemp(
|
|
10116
|
+
cwd = await mkdtemp(join16(tmpdir(), "baton-title-"));
|
|
10744
10117
|
const client = input.client ?? new Codex2();
|
|
10745
10118
|
const thread = client.startThread({
|
|
10746
10119
|
workingDirectory: cwd,
|
|
@@ -10768,8 +10141,8 @@ var generateTitleWithCodex = async (input) => {
|
|
|
10768
10141
|
|
|
10769
10142
|
// src/session/runner/title-pi.ts
|
|
10770
10143
|
import { mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
10771
|
-
import { tmpdir as
|
|
10772
|
-
import { join as
|
|
10144
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
10145
|
+
import { join as join17 } from "node:path";
|
|
10773
10146
|
var generateTitleWithPi = async (input) => {
|
|
10774
10147
|
const { userText, assistantText } = input;
|
|
10775
10148
|
if (`${userText}${assistantText}`.trim().length < 4) return { kind: "declined" };
|
|
@@ -10777,7 +10150,7 @@ var generateTitleWithPi = async (input) => {
|
|
|
10777
10150
|
let timedOut = false;
|
|
10778
10151
|
let timer;
|
|
10779
10152
|
try {
|
|
10780
|
-
cwd = await mkdtemp2(
|
|
10153
|
+
cwd = await mkdtemp2(join17(tmpdir2(), "baton-title-"));
|
|
10781
10154
|
const pi = await import("@earendil-works/pi-coding-agent");
|
|
10782
10155
|
const agentDir = pi.getAgentDir();
|
|
10783
10156
|
const resourceLoader = new pi.DefaultResourceLoader({
|
|
@@ -10829,11 +10202,11 @@ var generateTitleWithPi = async (input) => {
|
|
|
10829
10202
|
// src/worker/session-process.ts
|
|
10830
10203
|
import { execFile as execFile5 } from "node:child_process";
|
|
10831
10204
|
import { readFile as readFile3, rename, writeFile as writeFile4 } from "node:fs/promises";
|
|
10832
|
-
import { join as
|
|
10205
|
+
import { join as join18 } from "node:path";
|
|
10833
10206
|
import { promisify as promisify5 } from "node:util";
|
|
10834
10207
|
var run3 = promisify5(execFile5);
|
|
10835
10208
|
var RUNNER_RECORD = ".baton-runner.json";
|
|
10836
|
-
var recordPath = (cwd) =>
|
|
10209
|
+
var recordPath = (cwd) => join18(cwd, RUNNER_RECORD);
|
|
10837
10210
|
var codeOf = (error) => typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
|
|
10838
10211
|
var readRunnerRecord = async (cwd) => {
|
|
10839
10212
|
let raw;
|
|
@@ -10901,7 +10274,7 @@ var stopRecordedRunner = async (record, expected, graceMs = 5e3) => {
|
|
|
10901
10274
|
// src/worker/session-supervisor.ts
|
|
10902
10275
|
var binPath2 = () => {
|
|
10903
10276
|
const here = dirname6(fileURLToPath3(import.meta.url));
|
|
10904
|
-
const devShim =
|
|
10277
|
+
const devShim = join19(here, "..", "..", "bin", "baton.mjs");
|
|
10905
10278
|
return existsSync7(devShim) ? devShim : fileURLToPath3(import.meta.url);
|
|
10906
10279
|
};
|
|
10907
10280
|
var createSessionSupervisor = (deps) => {
|
|
@@ -11146,7 +10519,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
11146
10519
|
import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
|
|
11147
10520
|
import { createRequire as createModuleRequire } from "node:module";
|
|
11148
10521
|
import { homedir as homedir5 } from "node:os";
|
|
11149
|
-
import { dirname as dirname7, join as
|
|
10522
|
+
import { dirname as dirname7, join as join20 } from "node:path";
|
|
11150
10523
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11151
10524
|
var MAX_TERMINALS = 10;
|
|
11152
10525
|
var claudePtyCommand = (agentSessionId, hasJsonl, env = process.env) => ({
|
|
@@ -11167,13 +10540,13 @@ var piPtyCommand = (agentSessionId, env = process.env) => {
|
|
|
11167
10540
|
const override = env.BATON_PI_BIN?.trim();
|
|
11168
10541
|
if (override) return { file: override, args };
|
|
11169
10542
|
const entry = fileURLToPath4(import.meta.resolve("@earendil-works/pi-coding-agent"));
|
|
11170
|
-
return { file: process.execPath, args: [
|
|
10543
|
+
return { file: process.execPath, args: [join20(dirname7(entry), "bundle", "cli.js"), ...args] };
|
|
11171
10544
|
};
|
|
11172
10545
|
var hasSessionJsonl = (agentSessionId) => {
|
|
11173
|
-
const root =
|
|
10546
|
+
const root = join20(homedir5(), ".claude", "projects");
|
|
11174
10547
|
if (!existsSync8(root)) return false;
|
|
11175
10548
|
for (const dir of readdirSync2(root))
|
|
11176
|
-
if (existsSync8(
|
|
10549
|
+
if (existsSync8(join20(root, dir, `${agentSessionId}.jsonl`))) return true;
|
|
11177
10550
|
return false;
|
|
11178
10551
|
};
|
|
11179
10552
|
var ptyCommand = (kind, agentSessionId) => ({
|
|
@@ -11370,18 +10743,18 @@ var runWorkerDaemon = async (cfg, client, signal) => {
|
|
|
11370
10743
|
|
|
11371
10744
|
// src/worker/machine-id.ts
|
|
11372
10745
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
11373
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
10746
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11374
10747
|
import { homedir as homedir6 } from "node:os";
|
|
11375
|
-
import { dirname as dirname8, join as
|
|
11376
|
-
var machineIdPath = (env = process.env) =>
|
|
10748
|
+
import { dirname as dirname8, join as join21 } from "node:path";
|
|
10749
|
+
var machineIdPath = (env = process.env) => join21(env.XDG_DATA_HOME ?? join21(env.HOME ?? homedir6(), ".local/share"), "baton", "machine-id");
|
|
11377
10750
|
var readOrCreateMachineId = (path = machineIdPath()) => {
|
|
11378
10751
|
if (existsSync9(path)) {
|
|
11379
|
-
const s =
|
|
10752
|
+
const s = readFileSync4(path, "utf8").trim();
|
|
11380
10753
|
if (s) return s;
|
|
11381
10754
|
}
|
|
11382
10755
|
const id = randomUUID3();
|
|
11383
|
-
|
|
11384
|
-
|
|
10756
|
+
mkdirSync3(dirname8(path), { recursive: true });
|
|
10757
|
+
writeFileSync2(path, `${id}
|
|
11385
10758
|
`, "utf8");
|
|
11386
10759
|
return id;
|
|
11387
10760
|
};
|
|
@@ -11765,8 +11138,6 @@ var main = defineCommand({
|
|
|
11765
11138
|
artifact,
|
|
11766
11139
|
loop,
|
|
11767
11140
|
notify,
|
|
11768
|
-
relay,
|
|
11769
|
-
channel,
|
|
11770
11141
|
workspace,
|
|
11771
11142
|
project
|
|
11772
11143
|
}
|