@agntn/harnesses 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agntn/harnesses",
3
- "version": "0.0.1",
3
+ "version": "0.1.1",
4
4
  "description": "Metadata registry for AI coding harnesses: binaries, configs, sessions, and capabilities.",
5
5
  "homepage": "https://github.com/agntn/harnesses#readme",
6
6
  "bugs": "https://github.com/agntn/harnesses/issues",
@@ -92,6 +92,7 @@
92
92
  "scripts": {
93
93
  "build": "obuild",
94
94
  "dev": "obuild --stub",
95
+ "docs": "pnpm --dir docs dev",
95
96
  "lint": "pnpm build && oxlint . && oxfmt --check .",
96
97
  "lint:fix": "pnpm build && oxlint . --fix && oxfmt . && pnpm build",
97
98
  "typecheck": "tsgo --noEmit --skipLibCheck && pnpm build && tsgo --noEmit --skipLibCheck -p tsconfig.extensions.json",
@@ -106,20 +106,24 @@ export default function harnessesExtension(pi: ExtensionAPI): void {
106
106
  async execute(
107
107
  _toolCallId,
108
108
  params: HarnessSchemas.ModelsParams,
109
+ signal,
109
110
  ): Promise<AgentToolResult<HarnessTools.ModelsOutcome | HarnessTools.RunFailure>> {
110
111
  const { listHarnessModels } = await loadToolOperations();
111
112
  const { content, details, isError } = await listHarnessModels(params.id, {
112
113
  search: params.search,
113
114
  cwd: params.cwd,
114
115
  timeoutSeconds: params.timeoutSeconds,
116
+ signal,
115
117
  });
116
118
  if (isError) {
117
119
  const message =
118
120
  "error" in details
119
121
  ? details.error
120
- : details.timedOut
121
- ? `Harness ${details.id} model listing timed out`
122
- : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
122
+ : details.aborted
123
+ ? `Harness ${details.id} model listing aborted`
124
+ : details.timedOut
125
+ ? `Harness ${details.id} model listing timed out`
126
+ : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
123
127
  throw new Error(message);
124
128
  }
125
129
  return { content, details };
@@ -137,23 +141,25 @@ export default function harnessesExtension(pi: ExtensionAPI): void {
137
141
  async execute(
138
142
  _toolCallId,
139
143
  params: HarnessSchemas.RunParams,
144
+ signal,
140
145
  ): Promise<AgentToolResult<HarnessTools.RunOutcome | HarnessTools.RunFailure>> {
141
146
  const { runHarness } = await loadToolOperations();
142
147
  const { content, details, isError } = await runHarness(params.id, params.prompt, {
143
148
  cwd: params.cwd,
144
149
  model: params.model,
145
150
  timeoutSeconds: params.timeoutSeconds,
151
+ signal,
146
152
  structured: params.structured,
147
153
  tools: params.tools,
148
154
  readOnly: params.readOnly,
149
155
  });
150
156
  if (isError) {
157
+ if ("error" in details) throw new Error(details.error);
151
158
  const message =
152
- "error" in details
153
- ? details.error
154
- : details.timedOut
155
- ? `Harness ${details.id} timed out`
156
- : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
159
+ content[0]?.text ??
160
+ (details.timedOut
161
+ ? `Harness ${details.id} timed out`
162
+ : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`);
157
163
  throw new Error(message);
158
164
  }
159
165
  return { content, details };
@@ -38,6 +38,21 @@ function loadToolOperations(): Promise<typeof HarnessTools> {
38
38
  return toolOperationsPromise;
39
39
  }
40
40
 
41
+ function prepareInfoArguments(args: unknown): unknown {
42
+ if (typeof args !== "object" || args === null || !("id" in args) || typeof args.id !== "string") {
43
+ return args;
44
+ }
45
+
46
+ try {
47
+ const id: unknown = JSON.parse(args.id);
48
+ return Array.isArray(id) && id.every((value) => typeof value === "string")
49
+ ? { ...args, id }
50
+ : args;
51
+ } catch {
52
+ return args;
53
+ }
54
+ }
55
+
41
56
  function statusRenderers(tool: HarnessToolName) {
42
57
  return {
43
58
  renderCall(args: unknown, theme: StatusTheme, context: RenderOptions) {
@@ -87,6 +102,7 @@ export default function harnessesExtension(pi: ExtensionAPI): void {
87
102
  "Resolved paths are absolute for the current platform and home directory.",
88
103
  ],
89
104
  parameters: schemas.info,
105
+ prepareArguments: prepareInfoArguments,
90
106
  ...statusRenderers("harnesses_info"),
91
107
  async execute(
92
108
  _toolCallId,
@@ -114,20 +130,24 @@ export default function harnessesExtension(pi: ExtensionAPI): void {
114
130
  async execute(
115
131
  _toolCallId,
116
132
  params: HarnessSchemas.ModelsParams,
133
+ signal,
117
134
  ): Promise<AgentToolResult<HarnessTools.ModelsOutcome | HarnessTools.RunFailure>> {
118
135
  const { listHarnessModels } = await loadToolOperations();
119
136
  const { content, details, isError } = await listHarnessModels(params.id, {
120
137
  search: params.search,
121
138
  cwd: params.cwd,
122
139
  timeoutSeconds: params.timeoutSeconds,
140
+ signal,
123
141
  });
124
142
  if (isError) {
125
143
  const message =
126
144
  "error" in details
127
145
  ? details.error
128
- : details.timedOut
129
- ? `Harness ${details.id} model listing timed out`
130
- : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
146
+ : details.aborted
147
+ ? `Harness ${details.id} model listing aborted`
148
+ : details.timedOut
149
+ ? `Harness ${details.id} model listing timed out`
150
+ : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
131
151
  throw new Error(message);
132
152
  }
133
153
  return { content, details };
@@ -152,23 +172,25 @@ export default function harnessesExtension(pi: ExtensionAPI): void {
152
172
  async execute(
153
173
  _toolCallId,
154
174
  params: HarnessSchemas.RunParams,
175
+ signal,
155
176
  ): Promise<AgentToolResult<HarnessTools.RunOutcome | HarnessTools.RunFailure>> {
156
177
  const { runHarness } = await loadToolOperations();
157
178
  const { content, details, isError } = await runHarness(params.id, params.prompt, {
158
179
  cwd: params.cwd,
159
180
  model: params.model,
160
181
  timeoutSeconds: params.timeoutSeconds,
182
+ signal,
161
183
  structured: params.structured,
162
184
  tools: params.tools,
163
185
  readOnly: params.readOnly,
164
186
  });
165
187
  if (isError) {
188
+ if ("error" in details) throw new Error(details.error);
166
189
  const message =
167
- "error" in details
168
- ? details.error
169
- : details.timedOut
170
- ? `Harness ${details.id} timed out`
171
- : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`;
190
+ content[0]?.text ??
191
+ (details.timedOut
192
+ ? `Harness ${details.id} timed out`
193
+ : details.stderr || `Harness ${details.id} exited with code ${details.exitCode}`);
172
194
  throw new Error(message);
173
195
  }
174
196
  return { content, details };
@@ -222,7 +222,7 @@ function modelsMeta(details: ResultDetails): string[] {
222
222
  const models = listLength(details, "models");
223
223
  return compactStrings([
224
224
  id ? sanitizeTerminalText(id) : undefined,
225
- models === undefined ? undefined : `${models} models`,
225
+ details.aborted === true ? "aborted" : models === undefined ? undefined : `${models} models`,
226
226
  ]);
227
227
  }
228
228
 
@@ -230,7 +230,9 @@ function runMeta(details: ResultDetails): string[] {
230
230
  const meta: string[] = [];
231
231
  const id = scalar(details, "id");
232
232
  if (id) meta.push(sanitizeTerminalText(id));
233
- if (details.timedOut === true) {
233
+ if (details.aborted === true) {
234
+ meta.push("aborted");
235
+ } else if (details.timedOut === true) {
234
236
  meta.push("timed out");
235
237
  } else if (typeof details.exitCode === "number") {
236
238
  meta.push(`exit ${details.exitCode}`);