Typescript SDK for ACP extension methods (#7319)

This commit is contained in:
Jack Amadeo
2026-02-18 21:08:26 -05:00
committed by GitHub
parent 4b3eef0c9a
commit f425ea7474
23 changed files with 3740 additions and 34 deletions
+230
View File
@@ -0,0 +1,230 @@
#!/usr/bin/env node
/**
* Generates TypeScript types + Zod validators for Goose custom extension methods.
*
* Usage:
* npm run generate # build Rust schema, then generate TS
*/
import { createClient } from "@hey-api/openapi-ts";
import { execSync } from "child_process";
import * as fs from "fs/promises";
import { dirname, resolve } from "path";
import { fileURLToPath } from "url";
import * as prettier from "prettier";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const ROOT = resolve(__dirname, "../..");
const SCHEMA_PATH = resolve(ROOT, "crates/goose-acp/acp-schema.json");
const META_PATH = resolve(ROOT, "crates/goose-acp/acp-meta.json");
const OUTPUT_DIR = resolve(__dirname, "src/generated");
main().catch((err) => {
console.error(err);
process.exit(1);
});
async function main() {
const schemaSrc = await fs.readFile(SCHEMA_PATH, "utf8");
const jsonSchema = JSON.parse(
// Convert JSON Schema $defs refs to OpenAPI component refs
schemaSrc.replaceAll("#/$defs/", "#/components/schemas/"),
);
const metaSrc = await fs.readFile(META_PATH, "utf8");
const meta = JSON.parse(metaSrc);
await createClient({
input: {
openapi: "3.1.0",
info: {
title: "Goose Extensions",
version: "1.0.0",
},
components: {
schemas: jsonSchema.$defs,
},
},
output: {
path: OUTPUT_DIR,
},
plugins: ["zod", "@hey-api/typescript"],
});
await postProcessTypes();
await postProcessIndex(meta);
await generateClient(meta);
console.log(`\nGenerated Goose extension schema in ${OUTPUT_DIR}`);
}
async function postProcessTypes() {
const tsPath = resolve(OUTPUT_DIR, "types.gen.ts");
let src = await fs.readFile(tsPath, "utf8");
// Remove the ClientOptions type block injected by @hey-api (not part of our schema)
src = src.replace(/\nexport type ClientOptions =[\s\S]*?^};\n/m, "\n");
await fs.writeFile(tsPath, src);
}
async function postProcessIndex(meta: { methods: unknown[] }) {
const indexPath = resolve(OUTPUT_DIR, "index.ts");
let src = await fs.readFile(indexPath, "utf8");
// Strip ClientOptions from re-exports
src = src.replace(/,?\s*ClientOptions\s*,?/g, (match) => {
if (match.startsWith(",") && match.endsWith(",")) return ",";
if (match.startsWith(",")) return "";
return "";
});
// Fix bare relative imports to use .js extensions (required by nodenext consumers)
src = fixRelativeImports(src);
// Append method constants
const methodConstants = await prettier.format(
`
export const GOOSE_EXT_METHODS = ${JSON.stringify(meta.methods, null, 2)} as const;
export type GooseExtMethod = (typeof GOOSE_EXT_METHODS)[number];
`,
{ parser: "typescript" },
);
await fs.writeFile(indexPath, `${src}\n${methodConstants}`);
// Also fix imports in zod.gen.ts (it may import from types.gen)
for (const file of ["zod.gen.ts", "types.gen.ts"]) {
const filePath = resolve(OUTPUT_DIR, file);
try {
const content = await fs.readFile(filePath, "utf8");
const fixed = fixRelativeImports(content);
if (fixed !== content) {
await fs.writeFile(filePath, fixed);
}
} catch {
// File may not exist
}
}
}
function fixRelativeImports(src: string): string {
return src.replace(
/from\s+['"](\.[^'"]+)['"]/g,
(_match, importPath: string) => {
if (importPath.endsWith(".js") || importPath.endsWith(".json")) {
return `from '${importPath}'`;
}
return `from '${importPath}.js'`;
},
);
}
interface MethodMeta {
method: string;
requestType: string | null;
responseType: string | null;
}
/**
* Convert a method path like "session/list" or "working_dir/update" to camelCase "sessionList", "workingDirUpdate".
*/
function methodToCamelCase(method: string): string {
return method
.split(/[/_]/)
.map((part, i) =>
i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1),
)
.join("");
}
/**
* Generate a typed GooseClient class that wraps ClientSideConnection.extMethod()
* with proper TypeScript types and Zod runtime validation.
*/
async function generateClient(meta: { methods: MethodMeta[] }) {
const typeImports = new Set<string>();
const zodImports = new Set<string>();
const methodDefs: string[] = [];
for (const m of meta.methods) {
const fnName = methodToCamelCase(m.method);
const fullMethod = `_goose/${m.method}`;
// Build param type and arg
let paramType = "";
let paramArg = "";
let callParams = "{}";
if (m.requestType) {
typeImports.add(m.requestType);
paramType = m.requestType;
paramArg = `params: ${paramType}`;
callParams = "params";
}
// Build return type and validation
let returnType: string;
let bodyLines: string[];
if (m.responseType && m.responseType !== "EmptyResponse") {
typeImports.add(m.responseType);
const zodName = `z${m.responseType}`;
zodImports.add(zodName);
returnType = m.responseType;
bodyLines = [
`const raw = await this.conn.extMethod("${fullMethod}", ${callParams});`,
`return ${zodName}.parse(raw) as ${returnType};`,
];
} else if (m.responseType === "EmptyResponse") {
returnType = "void";
bodyLines = [
`await this.conn.extMethod("${fullMethod}", ${callParams});`,
];
} else {
// Both request and response are untyped (serde_json::Value)
returnType = "Record<string, unknown>";
bodyLines = [
`return await this.conn.extMethod("${fullMethod}", ${callParams ? callParams : "{}"});`,
];
}
methodDefs.push(`
async ${fnName}(${paramArg}): Promise<${returnType}> {
${bodyLines.join("\n ")}
}`);
}
const typeImportLine = typeImports.size
? `import type { ${[...typeImports].sort().join(", ")} } from "./types.gen.js";`
: "";
const zodImportLine = zodImports.size
? `import { ${[...zodImports].sort().join(", ")} } from "./zod.gen.js";`
: "";
let src = `// This file is auto-generated — do not edit manually.
export interface ExtMethodProvider {
extMethod(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>>;
}
${typeImportLine}
${zodImportLine}
/**
* Typed client for Goose custom extension methods.
* Wraps an ExtMethodProvider (e.g. ClientSideConnection) with proper types and Zod validation.
*/
export class GooseClient {
constructor(private conn: ExtMethodProvider) {}
${methodDefs.join("\n")}
}
`;
src = await prettier.format(src, { parser: "typescript" });
src = fixRelativeImports(src);
const clientPath = resolve(OUTPUT_DIR, "client.gen.ts");
await fs.writeFile(clientPath, src);
}
+1277
View File
File diff suppressed because it is too large Load Diff
+26
View File
@@ -0,0 +1,26 @@
{
"name": "goose-acp-types",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"generate": "tsx generate-schema.ts",
"lint": "tsc --noEmit",
"format": "prettier --write src/"
},
"dependencies": {
"zod": "^3.25.76"
},
"peerDependencies": {
"@agentclientprotocol/sdk": "*"
},
"devDependencies": {
"@agentclientprotocol/sdk": "^0.14.1",
"@hey-api/openapi-ts": "^0.92.3",
"prettier": "^3.8.1",
"tsx": "^4.21.0",
"typescript": "~5.9.3"
}
}
+129
View File
@@ -0,0 +1,129 @@
// This file is auto-generated — do not edit manually.
export interface ExtMethodProvider {
extMethod(
method: string,
params: Record<string, unknown>,
): Promise<Record<string, unknown>>;
}
import type {
AddExtensionRequest,
DeleteSessionRequest,
ExportSessionRequest,
ExportSessionResponse,
GetExtensionsResponse,
GetSessionRequest,
GetSessionResponse,
GetToolsRequest,
GetToolsResponse,
ImportSessionRequest,
ImportSessionResponse,
ListSessionsResponse,
ReadResourceRequest,
ReadResourceResponse,
RemoveExtensionRequest,
UpdateWorkingDirRequest,
} from './types.gen.js';
import {
zExportSessionResponse,
zGetExtensionsResponse,
zGetSessionResponse,
zGetToolsResponse,
zImportSessionResponse,
zListSessionsResponse,
zReadResourceResponse,
} from './zod.gen.js';
/**
* Typed client for Goose custom extension methods.
* Wraps an ExtMethodProvider (e.g. ClientSideConnection) with proper types and Zod validation.
*/
export class GooseClient {
constructor(private conn: ExtMethodProvider) {}
async extensionsAdd(params: AddExtensionRequest): Promise<void> {
await this.conn.extMethod("_goose/extensions/add", params);
}
async extensionsRemove(params: RemoveExtensionRequest): Promise<void> {
await this.conn.extMethod("_goose/extensions/remove", params);
}
async tools(params: GetToolsRequest): Promise<GetToolsResponse> {
const raw = await this.conn.extMethod("_goose/tools", params);
return zGetToolsResponse.parse(raw) as GetToolsResponse;
}
async resourceRead(
params: ReadResourceRequest,
): Promise<ReadResourceResponse> {
const raw = await this.conn.extMethod("_goose/resource/read", params);
return zReadResourceResponse.parse(raw) as ReadResourceResponse;
}
async workingDirUpdate(params: UpdateWorkingDirRequest): Promise<void> {
await this.conn.extMethod("_goose/working_dir/update", params);
}
async sessionList(): Promise<ListSessionsResponse> {
const raw = await this.conn.extMethod("_goose/session/list", {});
return zListSessionsResponse.parse(raw) as ListSessionsResponse;
}
async sessionGet(params: GetSessionRequest): Promise<GetSessionResponse> {
const raw = await this.conn.extMethod("_goose/session/get", params);
return zGetSessionResponse.parse(raw) as GetSessionResponse;
}
async sessionDelete(params: DeleteSessionRequest): Promise<void> {
await this.conn.extMethod("_goose/session/delete", params);
}
async sessionExport(
params: ExportSessionRequest,
): Promise<ExportSessionResponse> {
const raw = await this.conn.extMethod("_goose/session/export", params);
return zExportSessionResponse.parse(raw) as ExportSessionResponse;
}
async sessionImport(
params: ImportSessionRequest,
): Promise<ImportSessionResponse> {
const raw = await this.conn.extMethod("_goose/session/import", params);
return zImportSessionResponse.parse(raw) as ImportSessionResponse;
}
async configExtensions(): Promise<GetExtensionsResponse> {
const raw = await this.conn.extMethod("_goose/config/extensions", {});
return zGetExtensionsResponse.parse(raw) as GetExtensionsResponse;
}
async toolCall(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/tool/call", {});
}
async providerUpdate(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/provider/update", {});
}
async containerSet(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/container/set", {});
}
async appsList(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/apps/list", {});
}
async appsExport(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/apps/export", {});
}
async appsImport(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/apps/import", {});
}
async configProviders(): Promise<Record<string, unknown>> {
return await this.conn.extMethod("_goose/config/providers", {});
}
}
+98
View File
@@ -0,0 +1,98 @@
// This file is auto-generated by @hey-api/openapi-ts
export type { AddExtensionRequest, DeleteSessionRequest, EmptyResponse, ExportSessionRequest, ExportSessionResponse, ExtRequest, ExtResponse, GetExtensionsResponse, GetSessionRequest, GetSessionResponse, GetToolsRequest, GetToolsResponse, ImportSessionRequest, ImportSessionResponse, ListSessionsResponse, ReadResourceRequest, ReadResourceResponse, RemoveExtensionRequest, UpdateWorkingDirRequest } from './types.gen.js';
export const GOOSE_EXT_METHODS = [
{
method: "extensions/add",
requestType: "AddExtensionRequest",
responseType: "EmptyResponse",
},
{
method: "extensions/remove",
requestType: "RemoveExtensionRequest",
responseType: "EmptyResponse",
},
{
method: "tools",
requestType: "GetToolsRequest",
responseType: "GetToolsResponse",
},
{
method: "resource/read",
requestType: "ReadResourceRequest",
responseType: "ReadResourceResponse",
},
{
method: "working_dir/update",
requestType: "UpdateWorkingDirRequest",
responseType: "EmptyResponse",
},
{
method: "session/list",
requestType: null,
responseType: "ListSessionsResponse",
},
{
method: "session/get",
requestType: "GetSessionRequest",
responseType: "GetSessionResponse",
},
{
method: "session/delete",
requestType: "DeleteSessionRequest",
responseType: "EmptyResponse",
},
{
method: "session/export",
requestType: "ExportSessionRequest",
responseType: "ExportSessionResponse",
},
{
method: "session/import",
requestType: "ImportSessionRequest",
responseType: "ImportSessionResponse",
},
{
method: "config/extensions",
requestType: null,
responseType: "GetExtensionsResponse",
},
{
method: "tool/call",
requestType: null,
responseType: null,
},
{
method: "provider/update",
requestType: null,
responseType: null,
},
{
method: "container/set",
requestType: null,
responseType: null,
},
{
method: "apps/list",
requestType: null,
responseType: null,
},
{
method: "apps/export",
requestType: null,
responseType: null,
},
{
method: "apps/import",
requestType: null,
responseType: null,
},
{
method: "config/providers",
requestType: null,
responseType: null,
},
] as const;
export type GooseExtMethod = (typeof GOOSE_EXT_METHODS)[number];
+165
View File
@@ -0,0 +1,165 @@
// This file is auto-generated by @hey-api/openapi-ts
/**
* Add an extension to an active session.
* Method: `_agent/extensions/add`
*/
export type AddExtensionRequest = {
session_id: string;
/**
* Extension configuration (see ExtensionConfig variants: Stdio, StreamableHttp, Builtin, Platform).
*/
config: unknown;
};
/**
* Empty success response for operations that return no data.
*/
export type EmptyResponse = {
[key: string]: unknown;
};
/**
* Remove an extension from an active session.
* Method: `_agent/extensions/remove`
*/
export type RemoveExtensionRequest = {
session_id: string;
name: string;
};
/**
* List all tools available in a session.
* Method: `_agent/tools`
*/
export type GetToolsRequest = {
session_id: string;
};
export type GetToolsResponse = {
/**
* Array of tool info objects with `name`, `description`, `parameters`, and optional `permission`.
*/
tools: Array<unknown>;
};
/**
* Read a resource from an extension.
* Method: `_agent/resource/read`
*/
export type ReadResourceRequest = {
session_id: string;
uri: string;
extension_name: string;
};
export type ReadResourceResponse = {
/**
* The resource result from the extension (MCP ReadResourceResult).
*/
result: unknown;
};
/**
* Update the working directory for a session.
* Method: `_agent/working_dir/update`
*/
export type UpdateWorkingDirRequest = {
session_id: string;
working_dir: string;
};
/**
* List all sessions.
* Method: `_session/list`
*/
export type ListSessionsResponse = {
sessions: Array<unknown>;
};
/**
* Get a session by ID.
* Method: `_session/get`
*/
export type GetSessionRequest = {
session_id: string;
include_messages?: boolean;
};
/**
* Get a session response.
*/
export type GetSessionResponse = {
/**
* The session object with id, name, working_dir, timestamps, tokens, etc.
*/
session: unknown;
};
/**
* Delete a session.
* Method: `_session/delete`
*/
export type DeleteSessionRequest = {
session_id: string;
};
/**
* Export a session as a JSON string.
* Method: `_session/export`
*/
export type ExportSessionRequest = {
session_id: string;
};
export type ExportSessionResponse = {
data: string;
};
/**
* Import a session from a JSON string.
* Method: `_session/import`
*/
export type ImportSessionRequest = {
data: string;
};
export type ImportSessionResponse = {
/**
* The imported session object.
*/
session: unknown;
};
/**
* List configured extensions and any warnings.
* Method: `_config/extensions`
*/
export type GetExtensionsResponse = {
/**
* Array of ExtensionEntry objects with `enabled` flag and config details.
*/
extensions: Array<unknown>;
warnings: Array<string>;
};
export type ExtRequest = {
id: string;
method: string;
params?: AddExtensionRequest | RemoveExtensionRequest | GetToolsRequest | ReadResourceRequest | UpdateWorkingDirRequest | GetSessionRequest | DeleteSessionRequest | ExportSessionRequest | ImportSessionRequest | {
[key: string]: unknown;
} | null;
};
export type ExtResponse = {
id: string;
result?: EmptyResponse | GetToolsResponse | ReadResourceResponse | ListSessionsResponse | GetSessionResponse | ExportSessionResponse | ImportSessionResponse | GetExtensionsResponse | unknown;
} | {
error: {
code: number;
message: string;
data?: unknown;
};
id: string;
};
+175
View File
@@ -0,0 +1,175 @@
// This file is auto-generated by @hey-api/openapi-ts
import { z } from 'zod';
/**
* Add an extension to an active session.
* Method: `_agent/extensions/add`
*/
export const zAddExtensionRequest = z.object({
session_id: z.string(),
config: z.unknown()
});
/**
* Empty success response for operations that return no data.
*/
export const zEmptyResponse = z.record(z.unknown());
/**
* Remove an extension from an active session.
* Method: `_agent/extensions/remove`
*/
export const zRemoveExtensionRequest = z.object({
session_id: z.string(),
name: z.string()
});
/**
* List all tools available in a session.
* Method: `_agent/tools`
*/
export const zGetToolsRequest = z.object({
session_id: z.string()
});
export const zGetToolsResponse = z.object({
tools: z.array(z.unknown())
});
/**
* Read a resource from an extension.
* Method: `_agent/resource/read`
*/
export const zReadResourceRequest = z.object({
session_id: z.string(),
uri: z.string(),
extension_name: z.string()
});
export const zReadResourceResponse = z.object({
result: z.unknown()
});
/**
* Update the working directory for a session.
* Method: `_agent/working_dir/update`
*/
export const zUpdateWorkingDirRequest = z.object({
session_id: z.string(),
working_dir: z.string()
});
/**
* List all sessions.
* Method: `_session/list`
*/
export const zListSessionsResponse = z.object({
sessions: z.array(z.unknown())
});
/**
* Get a session by ID.
* Method: `_session/get`
*/
export const zGetSessionRequest = z.object({
session_id: z.string(),
include_messages: z.boolean().optional().default(false)
});
/**
* Get a session response.
*/
export const zGetSessionResponse = z.object({
session: z.unknown()
});
/**
* Delete a session.
* Method: `_session/delete`
*/
export const zDeleteSessionRequest = z.object({
session_id: z.string()
});
/**
* Export a session as a JSON string.
* Method: `_session/export`
*/
export const zExportSessionRequest = z.object({
session_id: z.string()
});
export const zExportSessionResponse = z.object({
data: z.string()
});
/**
* Import a session from a JSON string.
* Method: `_session/import`
*/
export const zImportSessionRequest = z.object({
data: z.string()
});
export const zImportSessionResponse = z.object({
session: z.unknown()
});
/**
* List configured extensions and any warnings.
* Method: `_config/extensions`
*/
export const zGetExtensionsResponse = z.object({
extensions: z.array(z.unknown()),
warnings: z.array(z.string())
});
export const zExtRequest = z.object({
id: z.string(),
method: z.string(),
params: z.union([
z.union([
zAddExtensionRequest,
zRemoveExtensionRequest,
zGetToolsRequest,
zReadResourceRequest,
zUpdateWorkingDirRequest,
zGetSessionRequest,
zDeleteSessionRequest,
zExportSessionRequest,
zImportSessionRequest
]),
z.union([
z.record(z.unknown()),
z.null()
])
]).optional()
});
export const zExtResponse = z.union([
z.object({
id: z.string(),
result: z.union([
z.union([
zEmptyResponse,
zGetToolsResponse,
zReadResourceResponse,
zListSessionsResponse,
zGetSessionResponse,
zExportSessionResponse,
zImportSessionResponse,
zGetExtensionsResponse
]),
z.unknown()
]).optional()
}),
z.object({
error: z.object({
code: z.number().int(),
message: z.string(),
data: z.unknown().optional()
}),
id: z.string()
})
]);
+3
View File
@@ -0,0 +1,3 @@
export * from "./generated/index.js";
export * from "./generated/zod.gen.js";
export { GooseClient } from "./generated/client.gen.js";
+14
View File
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"]
}
+28 -32
View File
@@ -36,6 +36,7 @@
"electron-updater": "^6.7.3",
"electron-window-state": "^5.0.3",
"express": "^5.2.1",
"goose-acp-types": "file:../acp",
"katex": "^0.16.28",
"lodash": "^4.17.23",
"lucide-react": "^0.563.0",
@@ -120,6 +121,19 @@
"npm": "^11.6.1"
}
},
"../acp": {
"name": "goose-acp-types",
"version": "0.1.0",
"dependencies": {
"zod": "^3.25.76"
},
"devDependencies": {
"@hey-api/openapi-ts": "^0.92.3",
"prettier": "^3.8.1",
"tsx": "^4.21.0",
"typescript": "~5.9.3"
}
},
"node_modules/@acemir/cssom": {
"version": "0.9.31",
"resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz",
@@ -219,7 +233,6 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@@ -589,7 +602,6 @@
}
],
"license": "MIT",
"peer": true,
"engines": {
"node": ">=20.19.0"
},
@@ -630,7 +642,6 @@
}
],
"license": "MIT",
"peer": true,
"engines": {
"node": ">=20.19.0"
}
@@ -1088,7 +1099,6 @@
"integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"chalk": "^4.1.1",
"fs-extra": "^9.0.1",
@@ -2722,7 +2732,6 @@
"integrity": "sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@inquirer/checkbox": "^3.0.1",
"@inquirer/confirm": "^4.0.1",
@@ -3198,7 +3207,6 @@
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz",
"integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@hono/node-server": "^1.19.9",
"ajv": "^8.17.1",
@@ -6523,7 +6531,8 @@
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"dev": true,
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
@@ -6811,7 +6820,6 @@
"integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -6853,7 +6861,6 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -6864,7 +6871,6 @@
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -7005,7 +7011,6 @@
"integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/types": "8.55.0",
@@ -7391,7 +7396,6 @@
"integrity": "sha512-CGJ25bc8fRi8Lod/3GHSvXRKi7nBo3kxh0ApW4yCjmrWmRmlT53B5E08XRSZRliygG0aVNxLrBEqPYdz/KcCtQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vitest/utils": "4.0.18",
"fflate": "^0.8.2",
@@ -7640,7 +7644,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -7713,7 +7716,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -8254,7 +8256,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -9557,7 +9558,8 @@
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"dev": true,
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/dom-helpers": {
"version": "5.2.1",
@@ -9615,7 +9617,6 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@electron/get": "^2.0.0",
"@types/node": "^24.9.0",
@@ -10623,7 +10624,6 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -11107,7 +11107,6 @@
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"peer": true,
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
@@ -11986,6 +11985,10 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/goose-acp-types": {
"resolved": "../acp",
"link": true
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -12337,7 +12340,6 @@
"resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz",
"integrity": "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=16.9.0"
}
@@ -13394,7 +13396,6 @@
"integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@acemir/cssom": "^0.9.31",
"@asamuzakjp/dom-selector": "^6.7.6",
@@ -14637,6 +14638,7 @@
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"lz-string": "bin/bin.js"
}
@@ -14657,7 +14659,6 @@
"integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.29.0",
"@babel/types": "^7.29.0",
@@ -17033,7 +17034,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -17135,6 +17135,7 @@
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
@@ -17150,6 +17151,7 @@
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
},
@@ -17505,7 +17507,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -17515,7 +17516,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -17537,7 +17537,8 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true,
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/react-markdown": {
"version": "10.1.0",
@@ -19454,8 +19455,7 @@
"version": "4.1.18",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
@@ -19986,7 +19986,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -20411,7 +20410,6 @@
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -20502,7 +20500,6 @@
"integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vitest/expect": "4.0.18",
"@vitest/mocker": "4.0.18",
@@ -21151,7 +21148,6 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
+1
View File
@@ -42,6 +42,7 @@
"start-alpha-gui": "ALPHA=true npm run start-gui"
},
"dependencies": {
"goose-acp-types": "file:../acp",
"@mcp-ui/client": "^6.1.0",
"@modelcontextprotocol/ext-apps": "^1.0.1",
"@radix-ui/react-accordion": "^1.2.12",