@townco/agent 0.1.22 → 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.
- package/dist/acp-server/adapter.d.ts +10 -14
- package/dist/acp-server/cli.d.ts +1 -3
- package/dist/acp-server/cli.js +5 -9
- package/dist/acp-server/http.d.ts +1 -3
- package/dist/bin.js +0 -0
- package/dist/definition/index.d.ts +6 -0
- package/dist/definition/index.js +9 -0
- package/dist/index.js +11 -5
- package/dist/runner/agent-runner.d.ts +6 -0
- package/dist/runner/index.d.ts +1 -3
- package/dist/runner/index.js +14 -18
- package/dist/runner/langchain/index.js +10 -0
- package/dist/runner/langchain/tools/todo.d.ts +32 -48
- package/dist/runner/langchain/tools/web_search.d.ts +1 -1
- package/dist/runner/tools.d.ts +16 -0
- package/dist/runner/tools.js +10 -1
- package/dist/scaffold/copy-gui.js +7 -81
- package/dist/scaffold/copy-tui.js +1 -65
- package/dist/scaffold/index.d.ts +2 -0
- package/dist/scaffold/index.js +26 -31
- package/dist/scaffold/project-scaffold.d.ts +12 -0
- package/dist/scaffold/project-scaffold.js +314 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +60 -24
- package/dist/templates/index.d.ts +7 -2
- package/dist/templates/index.js +13 -16
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/tool.d.ts +36 -0
- package/dist/utils/tool.js +33 -0
- package/index.ts +11 -7
- package/package.json +6 -5
- package/templates/index.ts +23 -18
- package/dist/definition/mcp.d.ts +0 -0
- package/dist/definition/mcp.js +0 -0
- package/dist/definition/tools/todo.d.ts +0 -49
- package/dist/definition/tools/todo.js +0 -80
- package/dist/definition/tools/web_search.d.ts +0 -4
- package/dist/definition/tools/web_search.js +0 -26
- package/dist/dev-agent/index.d.ts +0 -2
- package/dist/dev-agent/index.js +0 -18
- package/dist/example.d.ts +0 -2
- 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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
}
|
package/dist/acp-server/cli.d.ts
CHANGED
|
@@ -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;
|
package/dist/acp-server/cli.js
CHANGED
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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;
|
package/dist/definition/index.js
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
package/dist/runner/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/runner/index.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { zAgentRunnerParams } from "./agent-runner";
|
|
2
2
|
import { LangchainAgent } from "./langchain";
|
|
3
3
|
export const makeRunnerFromDefinition = (definition) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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>;
|
package/dist/runner/tools.d.ts
CHANGED
|
@@ -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 {};
|
package/dist/runner/tools.js
CHANGED
|
@@ -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
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
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
|
}
|
package/dist/scaffold/index.d.ts
CHANGED
|
@@ -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";
|
package/dist/scaffold/index.js
CHANGED
|
@@ -1,52 +1,47 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import {
|
|
2
|
+
import { mkdir, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import {
|
|
5
|
-
import { generateAgentJson, generateBinTs, generateEnvExample, generateGitignore, generateIndexTs, generatePackageJson, generateReadme, generateTsConfig, getTemplateVars, } from "../templates";
|
|
4
|
+
import { generateBinTs, generateIndexTs, getTemplateVars } from "../templates";
|
|
6
5
|
import { copyGuiApp } from "./copy-gui";
|
|
7
6
|
import { copyTuiApp } from "./copy-tui";
|
|
8
7
|
/**
|
|
9
8
|
* Scaffold a new agent package
|
|
10
9
|
*/
|
|
11
10
|
export async function scaffoldAgent(options) {
|
|
12
|
-
const { name, definition, overwrite = false, includeGui = true, includeTui = true, } = options;
|
|
11
|
+
const { name, definition, overwrite = false, includeGui = true, includeTui = true, agentsDir, } = options;
|
|
13
12
|
try {
|
|
14
|
-
// Ensure
|
|
15
|
-
await
|
|
13
|
+
// Ensure the agents directory exists
|
|
14
|
+
await mkdir(agentsDir, { recursive: true });
|
|
16
15
|
// Check if agent already exists
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
const agentPath = join(agentsDir, name);
|
|
17
|
+
try {
|
|
18
|
+
const agentStat = await stat(agentPath);
|
|
19
|
+
if (agentStat.isDirectory() && !overwrite) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
path: agentPath,
|
|
23
|
+
error: `Agent "${name}" already exists. Use overwrite option to replace it.`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Agent doesn't exist, which is fine
|
|
24
29
|
}
|
|
25
|
-
const agentPath = getAgentPath(name);
|
|
26
30
|
// Create the agent directory
|
|
27
31
|
await mkdir(agentPath, { recursive: true });
|
|
28
32
|
const vars = getTemplateVars(name, definition);
|
|
29
|
-
// Generate
|
|
33
|
+
// Generate template files - just the essentials
|
|
30
34
|
const files = [
|
|
31
|
-
{ path: "
|
|
32
|
-
{ path: "agent.json", content: generateAgentJson(vars) },
|
|
33
|
-
{ path: "index.ts", content: generateIndexTs() },
|
|
35
|
+
{ path: "index.ts", content: await generateIndexTs(vars) },
|
|
34
36
|
{ path: "bin.ts", content: generateBinTs(), executable: true },
|
|
35
|
-
{ path: "tsconfig.json", content: generateTsConfig() },
|
|
36
|
-
{ path: "README.md", content: generateReadme(vars) },
|
|
37
|
-
{ path: ".gitignore", content: generateGitignore() },
|
|
38
37
|
];
|
|
39
|
-
// Add .env.example if needed
|
|
40
|
-
const envExample = generateEnvExample(vars);
|
|
41
|
-
if (envExample) {
|
|
42
|
-
files.push({ path: ".env.example", content: envExample });
|
|
43
|
-
}
|
|
44
38
|
// Write all files
|
|
45
39
|
for (const file of files) {
|
|
46
40
|
const filePath = join(agentPath, file.path);
|
|
47
41
|
await writeFile(filePath, file.content, "utf-8");
|
|
48
|
-
// Make executable if
|
|
49
|
-
if (file.executable) {
|
|
42
|
+
// Make executable if specified
|
|
43
|
+
if ("executable" in file && file.executable) {
|
|
44
|
+
const { chmod } = await import("node:fs/promises");
|
|
50
45
|
await chmod(filePath, 0o755);
|
|
51
46
|
}
|
|
52
47
|
}
|
|
@@ -64,8 +59,6 @@ export async function scaffoldAgent(options) {
|
|
|
64
59
|
const tuiPath = join(agentPath, "tui");
|
|
65
60
|
await runBunInstall(tuiPath);
|
|
66
61
|
}
|
|
67
|
-
// Run bun install in agent root to fetch dependencies from npm
|
|
68
|
-
await runBunInstall(agentPath);
|
|
69
62
|
return {
|
|
70
63
|
success: true,
|
|
71
64
|
path: agentPath,
|
|
@@ -74,7 +67,7 @@ export async function scaffoldAgent(options) {
|
|
|
74
67
|
catch (error) {
|
|
75
68
|
return {
|
|
76
69
|
success: false,
|
|
77
|
-
path:
|
|
70
|
+
path: join(agentsDir, name),
|
|
78
71
|
error: error instanceof Error ? error.message : String(error),
|
|
79
72
|
};
|
|
80
73
|
}
|
|
@@ -101,3 +94,5 @@ function runBunInstall(agentPath) {
|
|
|
101
94
|
});
|
|
102
95
|
});
|
|
103
96
|
}
|
|
97
|
+
// Export project scaffolding
|
|
98
|
+
export { scaffoldProject } from "./project-scaffold";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ScaffoldProjectOptions {
|
|
2
|
+
path: string;
|
|
3
|
+
}
|
|
4
|
+
export interface ScaffoldProjectResult {
|
|
5
|
+
success: boolean;
|
|
6
|
+
path: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Scaffold a new standalone project
|
|
11
|
+
*/
|
|
12
|
+
export declare function scaffoldProject(options: ScaffoldProjectOptions): Promise<ScaffoldProjectResult>;
|