@townco/agent 0.1.21 → 0.1.23

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.
Files changed (46) hide show
  1. package/dist/acp-server/adapter.d.ts +10 -14
  2. package/dist/acp-server/cli.d.ts +1 -3
  3. package/dist/acp-server/cli.js +5 -9
  4. package/dist/acp-server/http.d.ts +1 -3
  5. package/dist/bin.js +0 -0
  6. package/dist/definition/index.d.ts +6 -0
  7. package/dist/definition/index.js +9 -0
  8. package/dist/index.js +11 -5
  9. package/dist/runner/agent-runner.d.ts +6 -0
  10. package/dist/runner/index.d.ts +1 -3
  11. package/dist/runner/index.js +14 -18
  12. package/dist/runner/langchain/index.js +10 -0
  13. package/dist/runner/langchain/tools/todo.d.ts +32 -48
  14. package/dist/runner/langchain/tools/todo.js +13 -16
  15. package/dist/runner/langchain/tools/web_search.d.ts +1 -1
  16. package/dist/runner/langchain/tools/web_search.js +18 -21
  17. package/dist/runner/tools.d.ts +16 -0
  18. package/dist/runner/tools.js +10 -1
  19. package/dist/scaffold/copy-gui.js +7 -81
  20. package/dist/scaffold/copy-tui.js +1 -65
  21. package/dist/scaffold/index.d.ts +2 -0
  22. package/dist/scaffold/index.js +26 -31
  23. package/dist/scaffold/project-scaffold.d.ts +12 -0
  24. package/dist/scaffold/project-scaffold.js +314 -0
  25. package/dist/storage/index.d.ts +5 -0
  26. package/dist/storage/index.js +60 -24
  27. package/dist/templates/index.d.ts +7 -2
  28. package/dist/templates/index.js +13 -16
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/dist/utils/index.d.ts +1 -0
  31. package/dist/utils/index.js +1 -0
  32. package/dist/utils/tool.d.ts +36 -0
  33. package/dist/utils/tool.js +33 -0
  34. package/index.ts +11 -7
  35. package/package.json +6 -5
  36. package/templates/index.ts +23 -18
  37. package/dist/definition/mcp.d.ts +0 -0
  38. package/dist/definition/mcp.js +0 -0
  39. package/dist/definition/tools/todo.d.ts +0 -49
  40. package/dist/definition/tools/todo.js +0 -80
  41. package/dist/definition/tools/web_search.d.ts +0 -4
  42. package/dist/definition/tools/web_search.js +0 -26
  43. package/dist/dev-agent/index.d.ts +0 -2
  44. package/dist/dev-agent/index.js +0 -18
  45. package/dist/example.d.ts +0 -2
  46. package/dist/example.js +0 -19
@@ -2,18 +2,14 @@ import * as acp from "@agentclientprotocol/sdk";
2
2
  import type { AgentRunner } from "../runner";
3
3
  /** Adapts an Agent to speak the ACP protocol */
4
4
  export declare class AgentAcpAdapter implements acp.Agent {
5
- private connection;
6
- private sessions;
7
- private agent;
8
- constructor(agent: AgentRunner, connection: acp.AgentSideConnection);
9
- initialize(_params: acp.InitializeRequest): Promise<acp.InitializeResponse>;
10
- newSession(_params: acp.NewSessionRequest): Promise<acp.NewSessionResponse>;
11
- authenticate(
12
- _params: acp.AuthenticateRequest,
13
- ): Promise<acp.AuthenticateResponse | undefined>;
14
- setSessionMode(
15
- _params: acp.SetSessionModeRequest,
16
- ): Promise<acp.SetSessionModeResponse>;
17
- prompt(params: acp.PromptRequest): Promise<acp.PromptResponse>;
18
- cancel(params: acp.CancelNotification): Promise<void>;
5
+ private connection;
6
+ private sessions;
7
+ private agent;
8
+ constructor(agent: AgentRunner, connection: acp.AgentSideConnection);
9
+ initialize(_params: acp.InitializeRequest): Promise<acp.InitializeResponse>;
10
+ newSession(_params: acp.NewSessionRequest): Promise<acp.NewSessionResponse>;
11
+ authenticate(_params: acp.AuthenticateRequest): Promise<acp.AuthenticateResponse | undefined>;
12
+ setSessionMode(_params: acp.SetSessionModeRequest): Promise<acp.SetSessionModeResponse>;
13
+ prompt(params: acp.PromptRequest): Promise<acp.PromptResponse>;
14
+ cancel(params: acp.CancelNotification): Promise<void>;
19
15
  }
@@ -1,5 +1,3 @@
1
1
  import type { AgentDefinition } from "../definition";
2
2
  import { type AgentRunner } from "../runner";
3
- export declare function makeStdioTransport(
4
- agent: AgentRunner | AgentDefinition,
5
- ): void;
3
+ export declare function makeStdioTransport(agent: AgentRunner | AgentDefinition): void;
@@ -3,13 +3,9 @@ import * as acp from "@agentclientprotocol/sdk";
3
3
  import { makeRunnerFromDefinition } from "../runner";
4
4
  import { AgentAcpAdapter } from "./adapter";
5
5
  export function makeStdioTransport(agent) {
6
- const agentRunner =
7
- "definition" in agent ? agent : makeRunnerFromDefinition(agent);
8
- const input = Writable.toWeb(process.stdout);
9
- const output = Readable.toWeb(process.stdin);
10
- const stream = acp.ndJsonStream(input, output);
11
- new acp.AgentSideConnection(
12
- (conn) => new AgentAcpAdapter(agentRunner, conn),
13
- stream,
14
- );
6
+ const agentRunner = "definition" in agent ? agent : makeRunnerFromDefinition(agent);
7
+ const input = Writable.toWeb(process.stdout);
8
+ const output = Readable.toWeb(process.stdin);
9
+ const stream = acp.ndJsonStream(input, output);
10
+ new acp.AgentSideConnection((conn) => new AgentAcpAdapter(agentRunner, conn), stream);
15
11
  }
@@ -1,5 +1,3 @@
1
1
  import type { AgentDefinition } from "../definition";
2
2
  import { type AgentRunner } from "../runner";
3
- export declare function makeHttpTransport(
4
- agent: AgentRunner | AgentDefinition,
5
- ): void;
3
+ export declare function makeHttpTransport(agent: AgentRunner | AgentDefinition): void;
package/dist/bin.js CHANGED
File without changes
@@ -22,6 +22,12 @@ export declare const AgentDefinitionSchema: z.ZodObject<{
22
22
  }, z.core.$strip>, z.ZodObject<{
23
23
  type: z.ZodLiteral<"filesystem">;
24
24
  working_directory: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>, z.ZodObject<{
26
+ type: z.ZodLiteral<"direct">;
27
+ name: z.ZodString;
28
+ description: z.ZodString;
29
+ fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
30
+ schema: z.ZodAny;
25
31
  }, z.core.$strip>]>>>;
26
32
  mcps: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
27
33
  name: z.ZodString;
@@ -35,11 +35,20 @@ const FilesystemToolSchema = z.object({
35
35
  /** If omitted, defaults to process.cwd() at runtime */
36
36
  working_directory: z.string().optional(),
37
37
  });
38
+ /** Direct tool configuration schema (for tools imported directly in code). */
39
+ const DirectToolSchema = z.object({
40
+ type: z.literal("direct"),
41
+ name: z.string(),
42
+ description: z.string(),
43
+ fn: z.function(),
44
+ schema: z.any(), // Accept any Zod schema
45
+ });
38
46
  /** Tool schema - can be a string (built-in tool) or custom tool object. */
39
47
  const ToolSchema = z.union([
40
48
  z.string(),
41
49
  CustomToolSchema,
42
50
  FilesystemToolSchema,
51
+ DirectToolSchema,
43
52
  ]);
44
53
  /** Agent definition schema. */
45
54
  export const AgentDefinitionSchema = z.object({
package/dist/index.js CHANGED
@@ -1,9 +1,15 @@
1
- import { readFileSync } from "node:fs";
2
- import { join } from "node:path";
3
1
  import { makeHttpTransport, makeStdioTransport } from "./acp-server";
4
- // Load agent definition from shared JSON file at repo root
5
- const configPath = join(import.meta.dir, "../../agent.json");
6
- const exampleAgent = JSON.parse(readFileSync(configPath, "utf-8"));
2
+ const exampleAgent = {
3
+ model: "claude-sonnet-4-5-20250929",
4
+ systemPrompt: "You are a helpful assistant.",
5
+ tools: [
6
+ "todo_write",
7
+ "get_weather",
8
+ "web_search",
9
+ { type: "filesystem", working_directory: "/Users/michael/code/town" },
10
+ ],
11
+ mcps: [],
12
+ };
7
13
  // Parse transport type from command line argument
8
14
  const transport = process.argv[2] || "stdio";
9
15
  if (transport === "http") {
@@ -9,6 +9,12 @@ export declare const zAgentRunnerParams: z.ZodObject<{
9
9
  }, z.core.$strip>, z.ZodObject<{
10
10
  type: z.ZodLiteral<"filesystem">;
11
11
  working_directory: z.ZodOptional<z.ZodString>;
12
+ }, z.core.$strip>, z.ZodObject<{
13
+ type: z.ZodLiteral<"direct">;
14
+ name: z.ZodString;
15
+ description: z.ZodString;
16
+ fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
17
+ schema: z.ZodAny;
12
18
  }, z.core.$strip>]>>>;
13
19
  mcps: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
14
20
  name: z.ZodString;
@@ -1,6 +1,4 @@
1
1
  import type { AgentDefinition } from "../definition";
2
2
  import { type AgentRunner } from "./agent-runner";
3
3
  export type { AgentRunner };
4
- export declare const makeRunnerFromDefinition: (
5
- definition: AgentDefinition,
6
- ) => AgentRunner;
4
+ export declare const makeRunnerFromDefinition: (definition: AgentDefinition) => AgentRunner;
@@ -1,22 +1,18 @@
1
1
  import { zAgentRunnerParams } from "./agent-runner";
2
2
  import { LangchainAgent } from "./langchain";
3
3
  export const makeRunnerFromDefinition = (definition) => {
4
- const agentRunnerParams = zAgentRunnerParams.safeParse(definition);
5
- if (!agentRunnerParams.success) {
6
- throw new Error(
7
- `Invalid agent definition: ${agentRunnerParams.error.message}`,
8
- );
9
- }
10
- switch (definition.harnessImplementation) {
11
- case undefined:
12
- case "langchain": {
13
- return new LangchainAgent(agentRunnerParams.data);
14
- }
15
- default: {
16
- const _exhaustiveCheck = definition.harnessImplementation;
17
- throw new Error(
18
- `Unsupported harness implementation: ${definition.harnessImplementation}`,
19
- );
20
- }
21
- }
4
+ const agentRunnerParams = zAgentRunnerParams.safeParse(definition);
5
+ if (!agentRunnerParams.success) {
6
+ throw new Error(`Invalid agent definition: ${agentRunnerParams.error.message}`);
7
+ }
8
+ switch (definition.harnessImplementation) {
9
+ case undefined:
10
+ case "langchain": {
11
+ return new LangchainAgent(agentRunnerParams.data);
12
+ }
13
+ default: {
14
+ const _exhaustiveCheck = definition.harnessImplementation;
15
+ throw new Error(`Unsupported harness implementation: ${definition.harnessImplementation}`);
16
+ }
17
+ }
22
18
  };
@@ -73,6 +73,16 @@ export class LangchainAgent {
73
73
  process.cwd();
74
74
  enabledTools.push(...makeFilesystemTools(wd));
75
75
  }
76
+ else if (type === "direct") {
77
+ // Handle direct tool objects (imported in code)
78
+ // biome-ignore lint/suspicious/noExplicitAny: mlai unsure how to best type this
79
+ const addedTool = tool(t.fn, {
80
+ name: t.name,
81
+ description: t.description,
82
+ schema: t.schema,
83
+ });
84
+ enabledTools.push(addedTool);
85
+ }
76
86
  }
77
87
  }
78
88
  // Built-in tools from registry
@@ -1,49 +1,33 @@
1
1
  import { z } from "zod";
2
- export declare const todoItemSchema: z.ZodObject<
3
- {
4
- content: z.ZodString;
5
- status: z.ZodEnum<{
6
- pending: "pending";
7
- in_progress: "in_progress";
8
- completed: "completed";
9
- }>;
10
- activeForm: z.ZodString;
11
- },
12
- z.core.$strip
13
- >;
14
- export declare const todoWrite: import("langchain").DynamicStructuredTool<
15
- z.ZodObject<
16
- {
17
- todos: z.ZodArray<
18
- z.ZodObject<
19
- {
20
- content: z.ZodString;
21
- status: z.ZodEnum<{
22
- pending: "pending";
23
- in_progress: "in_progress";
24
- completed: "completed";
25
- }>;
26
- activeForm: z.ZodString;
27
- },
28
- z.core.$strip
29
- >
30
- >;
31
- },
32
- z.core.$strip
33
- >,
34
- {
35
- todos: {
36
- content: string;
37
- status: "pending" | "in_progress" | "completed";
38
- activeForm: string;
39
- }[];
40
- },
41
- {
42
- todos: {
43
- content: string;
44
- status: "pending" | "in_progress" | "completed";
45
- activeForm: string;
46
- }[];
47
- },
48
- string
49
- >;
2
+ export declare const todoItemSchema: z.ZodObject<{
3
+ content: z.ZodString;
4
+ status: z.ZodEnum<{
5
+ pending: "pending";
6
+ in_progress: "in_progress";
7
+ completed: "completed";
8
+ }>;
9
+ activeForm: z.ZodString;
10
+ }, z.core.$strip>;
11
+ export declare const todoWrite: import("langchain").DynamicStructuredTool<z.ZodObject<{
12
+ todos: z.ZodArray<z.ZodObject<{
13
+ content: z.ZodString;
14
+ status: z.ZodEnum<{
15
+ pending: "pending";
16
+ in_progress: "in_progress";
17
+ completed: "completed";
18
+ }>;
19
+ activeForm: z.ZodString;
20
+ }, z.core.$strip>>;
21
+ }, z.core.$strip>, {
22
+ todos: {
23
+ content: string;
24
+ status: "pending" | "in_progress" | "completed";
25
+ activeForm: string;
26
+ }[];
27
+ }, {
28
+ todos: {
29
+ content: string;
30
+ status: "pending" | "in_progress" | "completed";
31
+ activeForm: string;
32
+ }[];
33
+ }, string>;
@@ -1,18 +1,16 @@
1
1
  import { tool } from "langchain";
2
2
  import { z } from "zod";
3
3
  export const todoItemSchema = z.object({
4
- content: z.string().min(1),
5
- status: z.enum(["pending", "in_progress", "completed"]),
6
- activeForm: z.string().min(1),
4
+ content: z.string().min(1),
5
+ status: z.enum(["pending", "in_progress", "completed"]),
6
+ activeForm: z.string().min(1),
7
7
  });
8
- export const todoWrite = tool(
9
- ({ todos }) => {
10
- // Simple implementation that confirms the todos were written
11
- return `Successfully updated todo list with ${todos.length} items`;
12
- },
13
- {
14
- name: "todo_write",
15
- description: `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
8
+ export const todoWrite = tool(({ todos }) => {
9
+ // Simple implementation that confirms the todos were written
10
+ return `Successfully updated todo list with ${todos.length} items`;
11
+ }, {
12
+ name: "todo_write",
13
+ description: `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
16
14
  It also helps the user understand the progress of the task and overall progress of their requests.
17
15
 
18
16
  ## When to Use This Tool
@@ -73,8 +71,7 @@ NOTE that you should not use this tool if there is only one trivial task to do.
73
71
  - activeForm: "Fixing authentication bug"
74
72
 
75
73
  When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.`,
76
- schema: z.object({
77
- todos: z.array(todoItemSchema),
78
- }),
79
- },
80
- );
74
+ schema: z.object({
75
+ todos: z.array(todoItemSchema),
76
+ }),
77
+ });
@@ -1,4 +1,4 @@
1
1
  import { ExaSearchResults } from "@langchain/exa";
2
2
  export declare function makeWebSearchTool(): ExaSearchResults<{
3
- text: true;
3
+ text: true;
4
4
  }>;
@@ -1,26 +1,23 @@
1
1
  import { ExaSearchResults } from "@langchain/exa";
2
2
  import Exa from "exa-js";
3
-
4
3
  let _webSearchInstance = null;
5
4
  export function makeWebSearchTool() {
6
- if (_webSearchInstance) {
7
- return _webSearchInstance;
8
- }
9
- const apiKey = process.env.EXA_API_KEY;
10
- if (!apiKey) {
11
- throw new Error(
12
- "EXA_API_KEY environment variable is required to use the web_search tool. " +
13
- "Please set it to your Exa API key from https://exa.ai",
14
- );
15
- }
16
- const client = new Exa(apiKey);
17
- _webSearchInstance = new ExaSearchResults({
18
- client,
19
- searchArgs: {
20
- numResults: 5,
21
- type: "auto",
22
- text: true,
23
- },
24
- });
25
- return _webSearchInstance;
5
+ if (_webSearchInstance) {
6
+ return _webSearchInstance;
7
+ }
8
+ const apiKey = process.env.EXA_API_KEY;
9
+ if (!apiKey) {
10
+ throw new Error("EXA_API_KEY environment variable is required to use the web_search tool. " +
11
+ "Please set it to your Exa API key from https://exa.ai");
12
+ }
13
+ const client = new Exa(apiKey);
14
+ _webSearchInstance = new ExaSearchResults({
15
+ client,
16
+ searchArgs: {
17
+ numResults: 5,
18
+ type: "auto",
19
+ text: true,
20
+ },
21
+ });
22
+ return _webSearchInstance;
26
23
  }
@@ -1,6 +1,14 @@
1
1
  import { z } from "zod";
2
2
  /** Built-in tool types. */
3
3
  export declare const zBuiltInToolType: z.ZodUnion<readonly [z.ZodLiteral<"todo_write">, z.ZodLiteral<"get_weather">, z.ZodLiteral<"web_search">, z.ZodLiteral<"filesystem">]>;
4
+ /** Direct tool object schema (for tools imported directly in code). */
5
+ declare const zDirectTool: z.ZodObject<{
6
+ type: z.ZodLiteral<"direct">;
7
+ name: z.ZodString;
8
+ description: z.ZodString;
9
+ fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
10
+ schema: z.ZodAny;
11
+ }, z.core.$strip>;
4
12
  /** Tool type - can be a built-in tool string or custom tool object. */
5
13
  export declare const zToolType: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"todo_write">, z.ZodLiteral<"get_weather">, z.ZodLiteral<"web_search">, z.ZodLiteral<"filesystem">]>, z.ZodObject<{
6
14
  type: z.ZodLiteral<"custom">;
@@ -8,6 +16,14 @@ export declare const zToolType: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodL
8
16
  }, z.core.$strip>, z.ZodObject<{
9
17
  type: z.ZodLiteral<"filesystem">;
10
18
  working_directory: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>, z.ZodObject<{
20
+ type: z.ZodLiteral<"direct">;
21
+ name: z.ZodString;
22
+ description: z.ZodString;
23
+ fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
24
+ schema: z.ZodAny;
11
25
  }, z.core.$strip>]>;
12
26
  export type ToolType = z.infer<typeof zToolType>;
13
27
  export type BuiltInToolType = z.infer<typeof zBuiltInToolType>;
28
+ export type DirectTool = z.infer<typeof zDirectTool>;
29
+ export {};
@@ -6,7 +6,7 @@ export const zBuiltInToolType = z.union([
6
6
  z.literal("web_search"),
7
7
  z.literal("filesystem"),
8
8
  ]);
9
- /** Custom tool schema. */
9
+ /** Custom tool schema (loaded from module path). */
10
10
  const zCustomTool = z.object({
11
11
  type: z.literal("custom"),
12
12
  modulePath: z.string(),
@@ -16,9 +16,18 @@ const zFilesystemTool = z.object({
16
16
  type: z.literal("filesystem"),
17
17
  working_directory: z.string().optional(),
18
18
  });
19
+ /** Direct tool object schema (for tools imported directly in code). */
20
+ const zDirectTool = z.object({
21
+ type: z.literal("direct"),
22
+ name: z.string(),
23
+ description: z.string(),
24
+ fn: z.function(),
25
+ schema: z.any(), // Accept any Zod schema
26
+ });
19
27
  /** Tool type - can be a built-in tool string or custom tool object. */
20
28
  export const zToolType = z.union([
21
29
  zBuiltInToolType,
22
30
  zCustomTool,
23
31
  zFilesystemTool,
32
+ zDirectTool,
24
33
  ]);
@@ -1,4 +1,4 @@
1
- import { cp, mkdir, writeFile } from "node:fs/promises";
1
+ import { cp, mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
4
  const require = createRequire(import.meta.url);
@@ -34,84 +34,10 @@ export async function copyGuiApp(agentPath) {
34
34
  const targetPath = join(guiDir, item);
35
35
  await cp(sourcePath, targetPath, { recursive: true });
36
36
  }
37
- // Create a standalone tsconfig.json for the GUI (can't extend from workspace tsconfig)
38
- const guiTsConfig = {
39
- compilerOptions: {
40
- allowArbitraryExtensions: true,
41
- allowUnreachableCode: false,
42
- allowUnusedLabels: false,
43
- declaration: true,
44
- emitDecoratorMetadata: true,
45
- esModuleInterop: true,
46
- exactOptionalPropertyTypes: true,
47
- experimentalDecorators: true,
48
- jsx: "react-jsx",
49
- lib: ["DOM", "ESNext"],
50
- module: "ESNext",
51
- moduleResolution: "bundler",
52
- noFallthroughCasesInSwitch: true,
53
- noImplicitAny: true,
54
- noImplicitOverride: true,
55
- noImplicitReturns: true,
56
- noUncheckedIndexedAccess: true,
57
- noUncheckedSideEffectImports: true,
58
- noUnusedLocals: false,
59
- noUnusedParameters: true,
60
- resolveJsonModule: true,
61
- skipLibCheck: true,
62
- strict: true,
63
- stripInternal: true,
64
- target: "ESNext",
65
- verbatimModuleSyntax: true,
66
- outDir: "./dist",
67
- rootDir: "./src",
68
- },
69
- include: ["src/**/*"],
70
- exclude: ["node_modules", "dist"],
71
- };
72
- await writeFile(join(guiDir, "tsconfig.json"), JSON.stringify(guiTsConfig, null, 2));
73
- // Generate a custom package.json for the GUI
74
- // Use @townco/ui as a dependency instead of copying files
75
- const packageJson = {
76
- name: "agent-gui",
77
- version: "0.0.1",
78
- type: "module",
79
- private: true,
80
- scripts: {
81
- dev: "vite",
82
- build: "vite build",
83
- preview: "vite preview",
84
- },
85
- dependencies: {
86
- "@townco/ui": "^0.1.0",
87
- "@agentclientprotocol/sdk": "^0.5.1",
88
- "@radix-ui/react-dialog": "^1.1.15",
89
- "@radix-ui/react-label": "^2.1.8",
90
- "@radix-ui/react-select": "^2.2.6",
91
- "@radix-ui/react-slot": "^1.2.4",
92
- "@radix-ui/react-tabs": "^1.1.13",
93
- "class-variance-authority": "^0.7.1",
94
- clsx: "^2.1.1",
95
- "lucide-react": "^0.552.0",
96
- react: "^19.2.0",
97
- "react-dom": "^19.2.0",
98
- "react-markdown": "^10.1.0",
99
- "remark-gfm": "^4.0.1",
100
- "tailwind-merge": "^3.3.1",
101
- zod: "^4.1.12",
102
- zustand: "^5.0.8",
103
- },
104
- devDependencies: {
105
- "@tailwindcss/postcss": "^4.1.17",
106
- "@types/react": "^19.2.2",
107
- "@types/react-dom": "^19.2.2",
108
- "@vitejs/plugin-react": "^5.1.0",
109
- autoprefixer: "^10.4.21",
110
- postcss: "^8.5.6",
111
- tailwindcss: "^4.1.17",
112
- typescript: "^5.9.3",
113
- vite: "^7.2.1",
114
- },
115
- };
116
- await writeFile(join(guiDir, "package.json"), JSON.stringify(packageJson, null, 2));
37
+ // Fix the @source path in index.css to point to the correct node_modules location
38
+ // In agent projects, node_modules is at the project root (4 levels up from gui/src/)
39
+ const indexCssPath = join(guiDir, "src", "index.css");
40
+ const indexCssContent = await readFile(indexCssPath, "utf-8");
41
+ const updatedContent = indexCssContent.replace('@source "../node_modules/@townco/ui/dist/**/*.{js,d.ts}";', '@source "../../../../node_modules/@townco/ui/dist/**/*.{js,d.ts}";');
42
+ await writeFile(indexCssPath, updatedContent, "utf-8");
117
43
  }
@@ -1,4 +1,4 @@
1
- import { cp, mkdir, writeFile } from "node:fs/promises";
1
+ import { cp, mkdir } from "node:fs/promises";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
4
  const require = createRequire(import.meta.url);
@@ -29,68 +29,4 @@ export async function copyTuiApp(agentPath) {
29
29
  const targetPath = join(tuiDir, item);
30
30
  await cp(sourcePath, targetPath, { recursive: true });
31
31
  }
32
- // Create a standalone tsconfig.json for the TUI
33
- const tuiTsConfig = {
34
- compilerOptions: {
35
- allowArbitraryExtensions: true,
36
- allowUnreachableCode: false,
37
- allowUnusedLabels: false,
38
- declaration: true,
39
- emitDecoratorMetadata: true,
40
- esModuleInterop: true,
41
- exactOptionalPropertyTypes: true,
42
- experimentalDecorators: true,
43
- jsx: "react-jsx",
44
- lib: ["ESNext"],
45
- module: "ESNext",
46
- moduleResolution: "bundler",
47
- noFallthroughCasesInSwitch: true,
48
- noImplicitAny: true,
49
- noImplicitOverride: true,
50
- noImplicitReturns: true,
51
- noUncheckedIndexedAccess: true,
52
- noUncheckedSideEffectImports: true,
53
- noUnusedLocals: false,
54
- noUnusedParameters: true,
55
- resolveJsonModule: true,
56
- skipLibCheck: true,
57
- strict: true,
58
- stripInternal: true,
59
- target: "ESNext",
60
- verbatimModuleSyntax: true,
61
- outDir: "./dist",
62
- rootDir: "./src",
63
- },
64
- include: ["src/**/*"],
65
- exclude: ["node_modules", "dist"],
66
- };
67
- await writeFile(join(tuiDir, "tsconfig.json"), JSON.stringify(tuiTsConfig, null, 2));
68
- // Generate a custom package.json for the TUI
69
- const packageJson = {
70
- name: "agent-tui",
71
- version: "0.0.1",
72
- type: "module",
73
- private: true,
74
- bin: {
75
- "agent-tui": "./dist/index.js",
76
- },
77
- scripts: {
78
- build: "tsc",
79
- start: "bun dist/index.js",
80
- },
81
- dependencies: {
82
- "@townco/ui": "^0.1.0",
83
- "@optique/core": "^0.6.2",
84
- "@optique/run": "^0.6.2",
85
- ink: "^6.4.0",
86
- "ink-text-input": "^6.0.0",
87
- react: "^19.2.0",
88
- },
89
- devDependencies: {
90
- "@types/node": "^24.10.0",
91
- "@types/react": "^19.2.2",
92
- typescript: "^5.9.3",
93
- },
94
- };
95
- await writeFile(join(tuiDir, "package.json"), JSON.stringify(packageJson, null, 2));
96
32
  }
@@ -5,6 +5,7 @@ export interface ScaffoldOptions {
5
5
  overwrite?: boolean;
6
6
  includeGui?: boolean;
7
7
  includeTui?: boolean;
8
+ agentsDir: string;
8
9
  }
9
10
  export interface ScaffoldResult {
10
11
  success: boolean;
@@ -15,3 +16,4 @@ export interface ScaffoldResult {
15
16
  * Scaffold a new agent package
16
17
  */
17
18
  export declare function scaffoldAgent(options: ScaffoldOptions): Promise<ScaffoldResult>;
19
+ export { scaffoldProject } from "./project-scaffold";