@integrity-labs/agt-cli 0.28.833 → 0.28.834

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/bin/agt.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-LGVB4OTX.js";
43
+ } from "../chunk-LLIAJK4F.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
@@ -5467,7 +5467,7 @@ import { execFileSync, execSync } from "child_process";
5467
5467
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5468
5468
  import chalk18 from "chalk";
5469
5469
  import ora16 from "ora";
5470
- var cliVersion = true ? "0.28.833" : "dev";
5470
+ var cliVersion = true ? "0.28.834" : "dev";
5471
5471
  async function fetchLatestVersion() {
5472
5472
  const host2 = getHost();
5473
5473
  if (!host2) return null;
@@ -6658,7 +6658,7 @@ function handleError(err) {
6658
6658
  }
6659
6659
 
6660
6660
  // src/bin/agt.ts
6661
- var cliVersion2 = true ? "0.28.833" : "dev";
6661
+ var cliVersion2 = true ? "0.28.834" : "dev";
6662
6662
  var program = new Command();
6663
6663
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6664
6664
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -6537,7 +6537,7 @@ function exchangeFailureKind(err) {
6537
6537
  }
6538
6538
 
6539
6539
  // src/lib/api-client.ts
6540
- var agtCliVersion = true ? "0.28.833" : "dev";
6540
+ var agtCliVersion = true ? "0.28.834" : "dev";
6541
6541
  var lastConfigHash = null;
6542
6542
  function setConfigHash(hash) {
6543
6543
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10895,4 +10895,4 @@ export {
10895
10895
  managerInstallSystemUnitCommand,
10896
10896
  managerUninstallSystemUnitCommand
10897
10897
  };
10898
- //# sourceMappingURL=chunk-LGVB4OTX.js.map
10898
+ //# sourceMappingURL=chunk-LLIAJK4F.js.map
@@ -60,7 +60,7 @@ import {
60
60
  safeWriteJsonAtomic,
61
61
  setConfigHash,
62
62
  tripClass
63
- } from "../chunk-LGVB4OTX.js";
63
+ } from "../chunk-LLIAJK4F.js";
64
64
  import {
65
65
  getProjectDir as getProjectDir2,
66
66
  getReadyTasks,
@@ -13621,7 +13621,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
13621
13621
  var lastVersionCheckAt = 0;
13622
13622
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
13623
13623
  var lastResponsivenessProbeAt = 0;
13624
- var agtCliVersion = true ? "0.28.833" : "dev";
13624
+ var agtCliVersion = true ? "0.28.834" : "dev";
13625
13625
  function resolveBrewPath(execFileSync2) {
13626
13626
  try {
13627
13627
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -0,0 +1,285 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __augmentedCreateRequire } from 'module';
3
+ globalThis.require ??= __augmentedCreateRequire(import.meta.url);
4
+
5
+ // src/computer-use-proxy.ts
6
+ import { createInterface } from "readline";
7
+ import { spawn } from "child_process";
8
+ import { fileURLToPath } from "url";
9
+ import { resolve as resolvePath } from "path";
10
+ var INCLUDE_SCREENSHOT_PARAM = "include_screenshot";
11
+ var STRIPPED_IMAGE_STUB = `[screenshot omitted to save tokens \u2014 pass ${INCLUDE_SCREENSHOT_PARAM}: true to receive it. Element indices in the accessibility tree above are usually enough to act.]`;
12
+ var RELIABILITY_NOTE = `
13
+
14
+ IMPORTANT: isError:false does NOT mean this action took effect. Some key combinations are silently ignored (super+n opens a window; super+a returns the same isError:false and does nothing). Verify by comparing the accessibility tree in this response against what you expected \u2014 it reflects the state after the action. set_value with an empty string is a no-op.`;
15
+ function isImageBlock(block) {
16
+ return typeof block === "object" && block !== null && block.type === "image";
17
+ }
18
+ var WINDOW_FURNITURE_ROLES = [
19
+ "container",
20
+ "standard window",
21
+ "close button",
22
+ "minimise button",
23
+ "minimize button",
24
+ "zoom button",
25
+ "full screen button",
26
+ "menu bar"
27
+ ];
28
+ function treeHasActionableContent(text) {
29
+ if (typeof text !== "string") return false;
30
+ let skipDeeperThan = null;
31
+ for (const raw of text.split("\n")) {
32
+ const m = /^(\s*)(\d+) (.+)$/.exec(raw);
33
+ if (!m) continue;
34
+ const indent = m[1].length;
35
+ const rest = m[3].toLowerCase();
36
+ if (skipDeeperThan !== null) {
37
+ if (indent > skipDeeperThan) continue;
38
+ skipDeeperThan = null;
39
+ }
40
+ if (rest.startsWith("menu bar")) {
41
+ skipDeeperThan = indent;
42
+ continue;
43
+ }
44
+ if (WINDOW_FURNITURE_ROLES.some((role) => rest.startsWith(role))) continue;
45
+ return true;
46
+ }
47
+ return false;
48
+ }
49
+ function stripImages(result) {
50
+ if (typeof result !== "object" || result === null) return { result, stripped: 0 };
51
+ const content = result.content;
52
+ if (!Array.isArray(content)) return { result, stripped: 0 };
53
+ if (!content.some(isImageBlock)) return { result, stripped: 0 };
54
+ const next = [];
55
+ let stripped = 0;
56
+ for (const block of content) {
57
+ if (isImageBlock(block)) {
58
+ stripped += 1;
59
+ next.push({ type: "text", text: STRIPPED_IMAGE_STUB });
60
+ } else {
61
+ next.push(block);
62
+ }
63
+ }
64
+ return { result: { ...result, content: next }, stripped };
65
+ }
66
+ function decorateToolsList(result) {
67
+ if (typeof result !== "object" || result === null) return result;
68
+ const tools = result.tools;
69
+ if (!Array.isArray(tools)) return result;
70
+ const decorated = tools.map((tool) => {
71
+ if (typeof tool !== "object" || tool === null) return tool;
72
+ const t = tool;
73
+ const schema = t["inputSchema"] ?? {};
74
+ const props = schema["properties"] ?? {};
75
+ return {
76
+ ...t,
77
+ description: `${typeof t["description"] === "string" ? t["description"] : ""}${RELIABILITY_NOTE}`,
78
+ inputSchema: {
79
+ ...schema,
80
+ type: schema["type"] ?? "object",
81
+ properties: {
82
+ ...props,
83
+ [INCLUDE_SCREENSHOT_PARAM]: {
84
+ type: "boolean",
85
+ description: "Return the screenshot for this call. Omitted by default: it is ~99% of the response and element indices in the accessibility tree are usually enough to act on."
86
+ }
87
+ }
88
+ }
89
+ };
90
+ });
91
+ return { ...result, tools: decorated };
92
+ }
93
+ function takeIncludeScreenshot(params) {
94
+ if (typeof params !== "object" || params === null) return { include: false, params };
95
+ const p = params;
96
+ if (typeof p.arguments !== "object" || p.arguments === null) {
97
+ return { include: false, params };
98
+ }
99
+ const args = p.arguments;
100
+ if (!(INCLUDE_SCREENSHOT_PARAM in args)) return { include: false, params };
101
+ const { [INCLUDE_SCREENSHOT_PARAM]: raw, ...rest } = args;
102
+ return { include: raw === true, params: { ...params, arguments: rest } };
103
+ }
104
+ function logErr(msg) {
105
+ process.stderr.write(`[computer-use-proxy] ${msg}
106
+ `);
107
+ }
108
+ var allowAll = async () => null;
109
+ function createProxy(deps) {
110
+ const beforeForward = deps.beforeForward ?? allowAll;
111
+ const pending = /* @__PURE__ */ new Map();
112
+ async function handleDownstream(line) {
113
+ const text = line.trim();
114
+ if (!text) return [];
115
+ let frame;
116
+ try {
117
+ frame = JSON.parse(text);
118
+ } catch {
119
+ logErr("dropping non-JSON frame from client");
120
+ return [];
121
+ }
122
+ if (frame.method !== "tools/call") {
123
+ return [text];
124
+ }
125
+ const isRequest = "id" in frame;
126
+ const { include, params } = takeIncludeScreenshot(frame.params);
127
+ const toolName = typeof params?.name === "string" ? params.name : "";
128
+ const args = params?.arguments;
129
+ const short = await beforeForward(toolName, args);
130
+ if (short) {
131
+ if (!isRequest) {
132
+ logErr(`short-circuited notification tools/call ${toolName} (no reply sent)`);
133
+ return [];
134
+ }
135
+ return [JSON.stringify({ jsonrpc: "2.0", id: frame.id, result: short })];
136
+ }
137
+ if (isRequest) {
138
+ pending.set(String(frame.id), { method: "tools/call", includeScreenshot: include });
139
+ }
140
+ return [JSON.stringify({ ...frame, params })];
141
+ }
142
+ async function handleUpstream(line) {
143
+ const text = line.trim();
144
+ if (!text) return [];
145
+ let frame;
146
+ try {
147
+ frame = JSON.parse(text);
148
+ } catch {
149
+ logErr("dropping non-JSON frame from upstream");
150
+ return [];
151
+ }
152
+ if (!("id" in frame)) return [text];
153
+ const key = String(frame.id);
154
+ if (frame.result === void 0) {
155
+ pending.delete(key);
156
+ return [text];
157
+ }
158
+ const p = pending.get(key);
159
+ if (!p) {
160
+ const decorated = decorateToolsList(frame.result);
161
+ if (decorated !== frame.result) {
162
+ return [JSON.stringify({ ...frame, result: decorated })];
163
+ }
164
+ return [text];
165
+ }
166
+ pending.delete(key);
167
+ if (p.includeScreenshot) return [text];
168
+ const firstText = frame.result?.content;
169
+ if (Array.isArray(firstText)) {
170
+ const treeBlock = firstText.find(
171
+ (b) => typeof b === "object" && b !== null && b.type === "text"
172
+ );
173
+ if (treeBlock && !treeHasActionableContent(treeBlock.text)) {
174
+ logErr("tree carries no actionable content; keeping screenshot");
175
+ return [text];
176
+ }
177
+ }
178
+ const { result, stripped } = stripImages(frame.result);
179
+ if (stripped === 0) return [text];
180
+ return [JSON.stringify({ ...frame, result })];
181
+ }
182
+ return { handleDownstream, handleUpstream };
183
+ }
184
+ function createWriter(sink) {
185
+ let lock = Promise.resolve();
186
+ return (lines) => {
187
+ lock = lock.then(async () => {
188
+ try {
189
+ for (const line of lines) {
190
+ if (!sink.write(line + "\n")) {
191
+ await new Promise((res) => sink.once("drain", res));
192
+ }
193
+ }
194
+ } catch (err) {
195
+ logErr(`write failed: ${err.message}`);
196
+ }
197
+ });
198
+ return lock;
199
+ };
200
+ }
201
+ async function wirePump(deps) {
202
+ const { child, clientIn, clientOut, proxy } = deps;
203
+ const exit = deps.onExit ?? ((code) => process.exit(code));
204
+ const toUpstream = createWriter(child.stdin);
205
+ const toClient = createWriter(clientOut);
206
+ child.stdin.on("error", (err) => {
207
+ logErr(`upstream stdin: ${err.message}`);
208
+ });
209
+ return new Promise((resolve) => {
210
+ let settled = false;
211
+ const finish = async (code) => {
212
+ if (settled) return;
213
+ settled = true;
214
+ await toClient([]);
215
+ exit(code);
216
+ resolve();
217
+ };
218
+ child.on("error", (err) => {
219
+ logErr(`upstream error: ${err.message}`);
220
+ void finish(1);
221
+ });
222
+ child.on("exit", (code) => {
223
+ logErr(`upstream exited with code ${code ?? "null"}`);
224
+ void finish(code ?? 1);
225
+ });
226
+ createInterface({ input: clientIn, crlfDelay: Infinity }).on("line", (line) => {
227
+ void proxy.handleDownstream(line).then(toUpstream).catch((err) => logErr(`downstream handler: ${err.message}`));
228
+ }).on("close", () => {
229
+ logErr("client disconnected; terminating upstream");
230
+ child.kill("SIGTERM");
231
+ void finish(0);
232
+ });
233
+ createInterface({ input: child.stdout, crlfDelay: Infinity }).on("line", (line) => {
234
+ void proxy.handleUpstream(line).then(toClient).catch((err) => logErr(`upstream handler: ${err.message}`));
235
+ });
236
+ });
237
+ }
238
+ async function main(argv = process.argv) {
239
+ const sep = argv.indexOf("--");
240
+ const upstream = sep >= 0 ? argv.slice(sep + 1) : [];
241
+ if (upstream.length === 0) {
242
+ logErr("no upstream command; usage: computer-use-proxy -- <cmd> [args...]");
243
+ process.exit(1);
244
+ }
245
+ let child;
246
+ try {
247
+ child = spawn(upstream[0], upstream.slice(1), { stdio: ["pipe", "pipe", "inherit"] });
248
+ } catch (err) {
249
+ logErr(`failed to spawn upstream: ${err.message}`);
250
+ process.exit(1);
251
+ }
252
+ await wirePump({
253
+ child,
254
+ clientIn: process.stdin,
255
+ clientOut: process.stdout,
256
+ proxy: createProxy({ upstream })
257
+ });
258
+ }
259
+ var invokedDirectly = (() => {
260
+ try {
261
+ const entry = process.argv[1];
262
+ if (!entry) return false;
263
+ return fileURLToPath(import.meta.url) === resolvePath(entry);
264
+ } catch {
265
+ return false;
266
+ }
267
+ })();
268
+ if (invokedDirectly) {
269
+ void main();
270
+ }
271
+ export {
272
+ INCLUDE_SCREENSHOT_PARAM,
273
+ RELIABILITY_NOTE,
274
+ STRIPPED_IMAGE_STUB,
275
+ allowAll,
276
+ createProxy,
277
+ createWriter,
278
+ decorateToolsList,
279
+ isImageBlock,
280
+ main,
281
+ stripImages,
282
+ takeIncludeScreenshot,
283
+ treeHasActionableContent,
284
+ wirePump
285
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.833",
3
+ "version": "0.28.834",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "scripts": {
25
25
  "build": "tsup && npm run build:mcp-assets && npm run build:cli-assets",
26
- "build:mcp-assets": "mkdir -p dist/mcp && cp ../../packages/mcp/dist/index.js dist/mcp/index.js && cp ../../packages/mcp/dist/slack-channel.js dist/mcp/slack-channel.js && cp ../../packages/mcp/dist/direct-chat-channel.js dist/mcp/direct-chat-channel.js && cp ../../packages/mcp/dist/telegram-channel.js dist/mcp/telegram-channel.js && cp ../../packages/mcp/dist/teams-channel.js dist/mcp/teams-channel.js && cp ../../packages/mcp/dist/whatsapp-channel.js dist/mcp/whatsapp-channel.js && cp ../../packages/mcp/dist/whatsapp-link.js dist/mcp/whatsapp-link.js && cp ../../packages/mcp/dist/remote-oauth-proxy.js dist/mcp/remote-oauth-proxy.js && cp ../../packages/augmented-admin-mcp/dist/index.js dist/mcp/augmented-admin.js && cp ../../packages/augmented-support-mcp/dist/index.js dist/mcp/augmented-support.js && cp ../../packages/augmented-help-kb-mcp/dist/index.js dist/mcp/augmented-help-kb.js && cp ../../packages/origami-mcp-server/dist/index.js dist/mcp/origami.js && cp ../../packages/xero-mcp-server/dist/index.js dist/mcp/xero.js",
26
+ "build:mcp-assets": "mkdir -p dist/mcp && cp ../../packages/mcp/dist/index.js dist/mcp/index.js && cp ../../packages/mcp/dist/slack-channel.js dist/mcp/slack-channel.js && cp ../../packages/mcp/dist/direct-chat-channel.js dist/mcp/direct-chat-channel.js && cp ../../packages/mcp/dist/telegram-channel.js dist/mcp/telegram-channel.js && cp ../../packages/mcp/dist/teams-channel.js dist/mcp/teams-channel.js && cp ../../packages/mcp/dist/whatsapp-channel.js dist/mcp/whatsapp-channel.js && cp ../../packages/mcp/dist/whatsapp-link.js dist/mcp/whatsapp-link.js && cp ../../packages/mcp/dist/remote-oauth-proxy.js dist/mcp/remote-oauth-proxy.js && cp ../../packages/mcp/dist/computer-use-proxy.js dist/mcp/computer-use-proxy.js && cp ../../packages/augmented-admin-mcp/dist/index.js dist/mcp/augmented-admin.js && cp ../../packages/augmented-support-mcp/dist/index.js dist/mcp/augmented-support.js && cp ../../packages/augmented-help-kb-mcp/dist/index.js dist/mcp/augmented-help-kb.js && cp ../../packages/origami-mcp-server/dist/index.js dist/mcp/origami.js && cp ../../packages/xero-mcp-server/dist/index.js dist/mcp/xero.js",
27
27
  "build:cli-assets": "mkdir -p dist/assets && cp assets/impersonate-statusline.sh dist/assets/impersonate-statusline.sh && chmod +x dist/assets/impersonate-statusline.sh",
28
28
  "dev": "tsx watch src/bin/agt.ts",
29
29
  "test": "vitest run",