@particle-academy/agent-integrations 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/bridges/terminal.d.cts +56 -24
- package/dist/bridges/terminal.d.ts +56 -24
- package/dist/bridges-terminal.cjs +116 -53
- package/dist/bridges-terminal.cjs.map +1 -1
- package/dist/bridges-terminal.js +1 -1
- package/dist/chunk-57KAMBAR.js +275 -0
- package/dist/chunk-57KAMBAR.js.map +1 -0
- package/dist/index.cjs +116 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-FZ7Q5NS3.js +0 -212
- package/dist/chunk-FZ7Q5NS3.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1953,19 +1953,39 @@ function serialize(entry) {
|
|
|
1953
1953
|
var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
1954
1954
|
var truncate = (s, n = 60) => s.length > n ? s.slice(0, n) + "\u2026" : s;
|
|
1955
1955
|
function registerTerminalBridge(host, options) {
|
|
1956
|
-
const { adapter } = options;
|
|
1957
1956
|
const agent = { ...DEFAULT_AGENT8, ...options.agent ?? {} };
|
|
1958
1957
|
const pendingMode = options.pendingMode ?? false;
|
|
1958
|
+
const screenId = options.screenId ?? options.adapter?.screenId;
|
|
1959
1959
|
const disposers = [];
|
|
1960
1960
|
const staged = /* @__PURE__ */ new Map();
|
|
1961
1961
|
let seq = 0;
|
|
1962
1962
|
ensureUndoToolsRegistered(host);
|
|
1963
|
-
const
|
|
1963
|
+
const listTerminals = () => {
|
|
1964
|
+
if (options.terminals) return options.terminals();
|
|
1965
|
+
if (options.adapter) return [{ id: "terminal", label: "Terminal", active: true, ...options.adapter }];
|
|
1966
|
+
return [];
|
|
1967
|
+
};
|
|
1968
|
+
const resolve = (id) => {
|
|
1969
|
+
const list = listTerminals();
|
|
1970
|
+
if (typeof id === "string" && id !== "") return list.find((t) => t.id === id);
|
|
1971
|
+
return list.find((t) => t.active) ?? list[0];
|
|
1972
|
+
};
|
|
1973
|
+
const anyMulti = !!options.terminals;
|
|
1974
|
+
const canClear = anyMulti || !!options.adapter?.clear;
|
|
1975
|
+
const canShells = anyMulti || !!options.adapter?.listShells;
|
|
1976
|
+
const canSetShell = anyMulti || !!options.adapter?.setShell;
|
|
1977
|
+
const target = (label, terminalId) => ({
|
|
1964
1978
|
kind: "terminal",
|
|
1965
|
-
screenId
|
|
1966
|
-
elementId:
|
|
1979
|
+
screenId,
|
|
1980
|
+
elementId: terminalId ?? screenId ?? "terminal",
|
|
1967
1981
|
label: label ?? "terminal"
|
|
1968
1982
|
});
|
|
1983
|
+
const TERMINAL_ARG = {
|
|
1984
|
+
terminal: {
|
|
1985
|
+
type: "string",
|
|
1986
|
+
description: "Terminal id to target (call terminal_list for ids). Omit for the active / only terminal."
|
|
1987
|
+
}
|
|
1988
|
+
};
|
|
1969
1989
|
const reg = (name, description, properties, required, handler, isMutation, resolveTarget) => {
|
|
1970
1990
|
const wrapped = async (args) => {
|
|
1971
1991
|
try {
|
|
@@ -1978,7 +1998,7 @@ function registerTerminalBridge(host, options) {
|
|
|
1978
1998
|
toolName: name,
|
|
1979
1999
|
agent,
|
|
1980
2000
|
kind: "terminal",
|
|
1981
|
-
screenId
|
|
2001
|
+
screenId,
|
|
1982
2002
|
resolveTarget: ({ args, result }) => resolveTarget?.(args, result) ?? target()
|
|
1983
2003
|
}) : wrapped;
|
|
1984
2004
|
disposers.push(
|
|
@@ -1992,38 +2012,66 @@ function registerTerminalBridge(host, options) {
|
|
|
1992
2012
|
)
|
|
1993
2013
|
);
|
|
1994
2014
|
};
|
|
1995
|
-
|
|
2015
|
+
const need = (args) => {
|
|
2016
|
+
const t = resolve(args.terminal);
|
|
2017
|
+
if (!t) {
|
|
2018
|
+
const ids = listTerminals().map((x) => x.id).join(", ") || "(none)";
|
|
2019
|
+
throw new Error(
|
|
2020
|
+
typeof args.terminal === "string" && args.terminal ? `Unknown terminal '${args.terminal}'. Available: ${ids}. Use terminal_list.` : "No terminal available."
|
|
2021
|
+
);
|
|
2022
|
+
}
|
|
2023
|
+
return t;
|
|
2024
|
+
};
|
|
2025
|
+
async function exec(t, kind, data) {
|
|
1996
2026
|
if (kind === "run") {
|
|
1997
|
-
if (
|
|
1998
|
-
else
|
|
2027
|
+
if (t.runCommand) await t.runCommand(data);
|
|
2028
|
+
else t.write(data + "\r");
|
|
1999
2029
|
} else {
|
|
2000
|
-
|
|
2030
|
+
t.write(data);
|
|
2001
2031
|
}
|
|
2002
2032
|
}
|
|
2003
|
-
async function stageOrExec(kind, data) {
|
|
2033
|
+
async function stageOrExec(t, kind, data) {
|
|
2004
2034
|
if (!pendingMode) {
|
|
2005
|
-
await exec(kind, data);
|
|
2006
|
-
return textResult(`${kind === "run" ? "ran" : "wrote"}: ${truncate(data)}`, {
|
|
2035
|
+
await exec(t, kind, data);
|
|
2036
|
+
return textResult(`${kind === "run" ? "ran" : "wrote"} on ${t.id}: ${truncate(data)}`, {
|
|
2037
|
+
kind,
|
|
2038
|
+
data,
|
|
2039
|
+
terminal: t.id,
|
|
2040
|
+
executed: true
|
|
2041
|
+
});
|
|
2007
2042
|
}
|
|
2008
2043
|
const id = `t${++seq}`;
|
|
2009
|
-
const entry = { id, kind, data };
|
|
2044
|
+
const entry = { id, kind, data, terminalId: t.id };
|
|
2010
2045
|
staged.set(id, entry);
|
|
2011
2046
|
options.onPending?.(entry);
|
|
2012
2047
|
return textResult(
|
|
2013
|
-
`Staged ${kind} (id ${id}) \u2014 awaiting human confirmation: ${truncate(data)}`,
|
|
2048
|
+
`Staged ${kind} on ${t.id} (id ${id}) \u2014 awaiting human confirmation: ${truncate(data)}`,
|
|
2014
2049
|
{ ...entry, pending: true }
|
|
2015
2050
|
);
|
|
2016
2051
|
}
|
|
2052
|
+
reg(
|
|
2053
|
+
"terminal_list",
|
|
2054
|
+
"List the terminals on this screen (id, label, which is active) \u2014 so you can reach into another terminal, not just the active one. Pass the chosen id as `terminal` to the other tools.",
|
|
2055
|
+
{},
|
|
2056
|
+
[],
|
|
2057
|
+
() => {
|
|
2058
|
+
const list = listTerminals().map((t) => ({ id: t.id, label: t.label ?? t.id, active: !!t.active }));
|
|
2059
|
+
const text = list.length ? list.map((t) => `${t.active ? "* " : " "}${t.id} \u2014 ${t.label}`).join("\n") : "(no terminals)";
|
|
2060
|
+
return textResult(text, { terminals: list });
|
|
2061
|
+
},
|
|
2062
|
+
false
|
|
2063
|
+
);
|
|
2017
2064
|
reg(
|
|
2018
2065
|
"terminal_read",
|
|
2019
|
-
"Read
|
|
2020
|
-
{ tail: { type: "number", description: "Return only the last N lines." } },
|
|
2066
|
+
"Read a terminal's visible buffer as text \u2014 what the user sees. Pass `tail` for only the last N lines, `terminal` to read a specific one.",
|
|
2067
|
+
{ ...TERMINAL_ARG, tail: { type: "number", description: "Return only the last N lines." } },
|
|
2021
2068
|
[],
|
|
2022
2069
|
(args) => {
|
|
2023
|
-
|
|
2070
|
+
const t = need(args);
|
|
2071
|
+
let buf = t.getBuffer();
|
|
2024
2072
|
const tail = typeof args.tail === "number" ? args.tail : void 0;
|
|
2025
2073
|
if (tail && tail > 0) buf = buf.split("\n").slice(-tail).join("\n");
|
|
2026
|
-
return textResult(buf, { buffer: buf });
|
|
2074
|
+
return textResult(buf, { buffer: buf, terminal: t.id });
|
|
2027
2075
|
},
|
|
2028
2076
|
false
|
|
2029
2077
|
);
|
|
@@ -2035,7 +2083,7 @@ function registerTerminalBridge(host, options) {
|
|
|
2035
2083
|
() => {
|
|
2036
2084
|
const list = [...staged.values()];
|
|
2037
2085
|
return textResult(
|
|
2038
|
-
list.length ? list.map((s) => `${s.id}: ${s.kind} ${truncate(s.data)}`).join("\n") : "(none)",
|
|
2086
|
+
list.length ? list.map((s) => `${s.id}: ${s.kind} on ${s.terminalId} ${truncate(s.data)}`).join("\n") : "(none)",
|
|
2039
2087
|
{ pending: list }
|
|
2040
2088
|
);
|
|
2041
2089
|
},
|
|
@@ -2043,20 +2091,21 @@ function registerTerminalBridge(host, options) {
|
|
|
2043
2091
|
);
|
|
2044
2092
|
reg(
|
|
2045
2093
|
"terminal_write",
|
|
2046
|
-
"Write raw data / keystrokes to
|
|
2047
|
-
{ data: { type: "string", description: "Raw bytes to write." } },
|
|
2094
|
+
"Write raw data / keystrokes to a terminal (input, control chars, ANSI). Pass `terminal` to target a specific one. In pendingMode this stages instead of executing.",
|
|
2095
|
+
{ ...TERMINAL_ARG, data: { type: "string", description: "Raw bytes to write." } },
|
|
2048
2096
|
["data"],
|
|
2049
|
-
(args) => stageOrExec("write", String(args.data)),
|
|
2050
|
-
true
|
|
2097
|
+
(args) => stageOrExec(need(args), "write", String(args.data)),
|
|
2098
|
+
true,
|
|
2099
|
+
(args) => target(`write:${String(args.terminal ?? "")}`, resolve(args.terminal)?.id)
|
|
2051
2100
|
);
|
|
2052
2101
|
reg(
|
|
2053
2102
|
"terminal_run",
|
|
2054
|
-
"Run a shell command \u2014 writes the command
|
|
2055
|
-
{ command: { type: "string", description: "The command line to run." } },
|
|
2103
|
+
"Run a shell command in a terminal \u2014 writes the command + Enter (or the host's runner). Pass `terminal` to target a specific one. In pendingMode this stages it for confirmation.",
|
|
2104
|
+
{ ...TERMINAL_ARG, command: { type: "string", description: "The command line to run." } },
|
|
2056
2105
|
["command"],
|
|
2057
|
-
(args) => stageOrExec("run", String(args.command)),
|
|
2106
|
+
(args) => stageOrExec(need(args), "run", String(args.command)),
|
|
2058
2107
|
true,
|
|
2059
|
-
(args) => target(truncate(String(args.command ?? "")))
|
|
2108
|
+
(args) => target(truncate(String(args.command ?? "")), resolve(args.terminal)?.id)
|
|
2060
2109
|
);
|
|
2061
2110
|
reg(
|
|
2062
2111
|
"terminal_confirm",
|
|
@@ -2067,11 +2116,17 @@ function registerTerminalBridge(host, options) {
|
|
|
2067
2116
|
const id = String(args.id);
|
|
2068
2117
|
const entry = staged.get(id);
|
|
2069
2118
|
if (!entry) return errorResult(`No staged command ${id}`);
|
|
2119
|
+
const t = resolve(entry.terminalId);
|
|
2120
|
+
if (!t) return errorResult(`Terminal '${entry.terminalId}' is gone \u2014 cannot run ${id}`);
|
|
2070
2121
|
staged.delete(id);
|
|
2071
|
-
await exec(entry.kind, entry.data);
|
|
2072
|
-
return textResult(`Confirmed ${id}: ${entry.kind} ${truncate(entry.data)}`, { ...entry, executed: true });
|
|
2122
|
+
await exec(t, entry.kind, entry.data);
|
|
2123
|
+
return textResult(`Confirmed ${id}: ${entry.kind} on ${t.id} ${truncate(entry.data)}`, { ...entry, executed: true });
|
|
2073
2124
|
},
|
|
2074
|
-
true
|
|
2125
|
+
true,
|
|
2126
|
+
(args) => {
|
|
2127
|
+
const e = staged.get(String(args.id));
|
|
2128
|
+
return target(`confirm:${String(args.id ?? "")}`, e?.terminalId);
|
|
2129
|
+
}
|
|
2075
2130
|
);
|
|
2076
2131
|
reg(
|
|
2077
2132
|
"terminal_reject",
|
|
@@ -2085,51 +2140,58 @@ function registerTerminalBridge(host, options) {
|
|
|
2085
2140
|
},
|
|
2086
2141
|
false
|
|
2087
2142
|
);
|
|
2088
|
-
if (
|
|
2143
|
+
if (canClear) {
|
|
2089
2144
|
reg(
|
|
2090
2145
|
"terminal_clear",
|
|
2091
|
-
"Clear
|
|
2092
|
-
{},
|
|
2146
|
+
"Clear a terminal's viewport. Pass `terminal` to target a specific one.",
|
|
2147
|
+
{ ...TERMINAL_ARG },
|
|
2093
2148
|
[],
|
|
2094
|
-
() => {
|
|
2095
|
-
|
|
2096
|
-
return
|
|
2149
|
+
(args) => {
|
|
2150
|
+
const t = need(args);
|
|
2151
|
+
if (!t.clear) return errorResult(`Terminal '${t.id}' can't be cleared.`);
|
|
2152
|
+
t.clear();
|
|
2153
|
+
return textResult(`cleared ${t.id}`, { terminal: t.id });
|
|
2097
2154
|
},
|
|
2098
|
-
true
|
|
2155
|
+
true,
|
|
2156
|
+
(args) => target(`clear:${String(args.terminal ?? "")}`, resolve(args.terminal)?.id)
|
|
2099
2157
|
);
|
|
2100
2158
|
}
|
|
2101
|
-
if (
|
|
2159
|
+
if (canShells) {
|
|
2102
2160
|
reg(
|
|
2103
2161
|
"terminal_list_shells",
|
|
2104
|
-
"List the shells
|
|
2105
|
-
{},
|
|
2162
|
+
"List the shells a terminal can switch to (cmd, PowerShell, Git Bash, \u2026) \u2014 id + label, active one marked. Pass `terminal` to target a specific one.",
|
|
2163
|
+
{ ...TERMINAL_ARG },
|
|
2106
2164
|
[],
|
|
2107
|
-
() => {
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2165
|
+
(args) => {
|
|
2166
|
+
const t = need(args);
|
|
2167
|
+
if (!t.listShells) return errorResult(`Terminal '${t.id}' has no switchable shells.`);
|
|
2168
|
+
const shells = t.listShells();
|
|
2169
|
+
const active = t.getShell?.();
|
|
2110
2170
|
const text = shells.length ? shells.map((s) => `${s.id === active ? "* " : " "}${s.id} \u2014 ${s.label}`).join("\n") : "(none)";
|
|
2111
|
-
return textResult(text, { shells, active });
|
|
2171
|
+
return textResult(text, { shells, active, terminal: t.id });
|
|
2112
2172
|
},
|
|
2113
2173
|
false
|
|
2114
2174
|
);
|
|
2115
2175
|
}
|
|
2116
|
-
if (
|
|
2176
|
+
if (canSetShell) {
|
|
2117
2177
|
reg(
|
|
2118
2178
|
"terminal_set_shell",
|
|
2119
|
-
"Switch
|
|
2120
|
-
{ id: { type: "string", description: "Shell id to switch to." } },
|
|
2179
|
+
"Switch a terminal's active shell by id (e.g. 'powershell', 'git-bash'). Call terminal_list_shells first for valid ids. Pass `terminal` to target a specific one.",
|
|
2180
|
+
{ ...TERMINAL_ARG, id: { type: "string", description: "Shell id to switch to." } },
|
|
2121
2181
|
["id"],
|
|
2122
2182
|
async (args) => {
|
|
2183
|
+
const t = need(args);
|
|
2184
|
+
if (!t.setShell) return errorResult(`Terminal '${t.id}' can't switch shells.`);
|
|
2123
2185
|
const id = String(args.id);
|
|
2124
|
-
const shells =
|
|
2186
|
+
const shells = t.listShells?.();
|
|
2125
2187
|
if (shells && shells.length && !shells.some((s) => s.id === id)) {
|
|
2126
|
-
return errorResult(`Unknown shell '${id}'. Use terminal_list_shells for valid ids.`);
|
|
2188
|
+
return errorResult(`Unknown shell '${id}' for ${t.id}. Use terminal_list_shells for valid ids.`);
|
|
2127
2189
|
}
|
|
2128
|
-
await
|
|
2129
|
-
return textResult(`Switched shell to ${id}`, { shell: id });
|
|
2190
|
+
await t.setShell(id);
|
|
2191
|
+
return textResult(`Switched ${t.id} shell to ${id}`, { shell: id, terminal: t.id });
|
|
2130
2192
|
},
|
|
2131
2193
|
true,
|
|
2132
|
-
(args) => target(`shell:${String(args.id ?? "")}
|
|
2194
|
+
(args) => target(`shell:${String(args.id ?? "")}`, resolve(args.terminal)?.id)
|
|
2133
2195
|
);
|
|
2134
2196
|
}
|
|
2135
2197
|
return {
|
|
@@ -2143,8 +2205,9 @@ function registerTerminalBridge(host, options) {
|
|
|
2143
2205
|
confirm: (id) => {
|
|
2144
2206
|
const e = staged.get(id);
|
|
2145
2207
|
if (e) {
|
|
2208
|
+
const t = resolve(e.terminalId);
|
|
2146
2209
|
staged.delete(id);
|
|
2147
|
-
void exec(e.kind, e.data);
|
|
2210
|
+
if (t) void exec(t, e.kind, e.data);
|
|
2148
2211
|
}
|
|
2149
2212
|
},
|
|
2150
2213
|
reject: (id) => {
|