@townco/agent 0.1.22 → 0.1.24

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 (48) 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/acp-server/http.js +2 -2
  6. package/dist/bin.js +0 -0
  7. package/dist/definition/index.d.ts +6 -0
  8. package/dist/definition/index.js +9 -0
  9. package/dist/index.js +11 -5
  10. package/dist/runner/agent-runner.d.ts +6 -0
  11. package/dist/runner/index.d.ts +1 -3
  12. package/dist/runner/index.js +14 -18
  13. package/dist/runner/langchain/index.js +35 -23
  14. package/dist/runner/langchain/tools/todo.d.ts +32 -48
  15. package/dist/runner/langchain/tools/web_search.d.ts +1 -1
  16. package/dist/runner/tools.d.ts +16 -0
  17. package/dist/runner/tools.js +10 -1
  18. package/dist/scaffold/claude-scaffold.d.ts +8 -0
  19. package/dist/scaffold/claude-scaffold.js +58 -0
  20. package/dist/scaffold/copy-gui.js +7 -81
  21. package/dist/scaffold/copy-tui.js +1 -65
  22. package/dist/scaffold/index.d.ts +3 -0
  23. package/dist/scaffold/index.js +27 -31
  24. package/dist/scaffold/project-scaffold.d.ts +12 -0
  25. package/dist/scaffold/project-scaffold.js +317 -0
  26. package/dist/scaffold/templates/dot-claude/CLAUDE-append.md +71 -0
  27. package/dist/storage/index.d.ts +5 -0
  28. package/dist/storage/index.js +60 -24
  29. package/dist/templates/index.d.ts +7 -2
  30. package/dist/templates/index.js +13 -16
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/dist/utils/index.d.ts +1 -0
  33. package/dist/utils/index.js +1 -0
  34. package/dist/utils/tool.d.ts +36 -0
  35. package/dist/utils/tool.js +33 -0
  36. package/index.ts +11 -7
  37. package/package.json +7 -6
  38. package/templates/index.ts +23 -18
  39. package/dist/definition/mcp.d.ts +0 -0
  40. package/dist/definition/mcp.js +0 -0
  41. package/dist/definition/tools/todo.d.ts +0 -49
  42. package/dist/definition/tools/todo.js +0 -80
  43. package/dist/definition/tools/web_search.d.ts +0 -4
  44. package/dist/definition/tools/web_search.js +0 -26
  45. package/dist/dev-agent/index.d.ts +0 -2
  46. package/dist/dev-agent/index.js +0 -18
  47. package/dist/example.d.ts +0 -2
  48. package/dist/example.js +0 -19
@@ -1,57 +1,93 @@
1
1
  import { mkdir, readdir, rm, stat } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
- import { join } from "node:path";
4
-
3
+ import { dirname, join } from "node:path";
5
4
  const AGENTS_DIR = join(homedir(), ".config", "town", "agents");
6
5
  /**
7
6
  * Get the base directory where all agents are stored
8
7
  */
9
8
  export function getAgentsDir() {
10
- return AGENTS_DIR;
9
+ return AGENTS_DIR;
11
10
  }
12
11
  /**
13
12
  * Get the directory path for a specific agent
14
13
  */
15
14
  export function getAgentPath(name) {
16
- return join(AGENTS_DIR, name);
15
+ return join(AGENTS_DIR, name);
17
16
  }
18
17
  /**
19
18
  * Check if an agent exists
20
19
  */
21
20
  export async function agentExists(name) {
22
- try {
23
- const agentPath = getAgentPath(name);
24
- const stats = await stat(agentPath);
25
- return stats.isDirectory();
26
- } catch {
27
- return false;
28
- }
21
+ try {
22
+ const agentPath = getAgentPath(name);
23
+ const stats = await stat(agentPath);
24
+ return stats.isDirectory();
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
29
  }
30
30
  /**
31
31
  * List all created agents
32
32
  */
33
33
  export async function listAgents() {
34
- try {
35
- await mkdir(AGENTS_DIR, { recursive: true });
36
- const entries = await readdir(AGENTS_DIR, { withFileTypes: true });
37
- return entries
38
- .filter((entry) => entry.isDirectory())
39
- .map((entry) => entry.name);
40
- } catch (error) {
41
- console.error("Error listing agents:", error);
42
- return [];
43
- }
34
+ try {
35
+ await mkdir(AGENTS_DIR, { recursive: true });
36
+ const entries = await readdir(AGENTS_DIR, { withFileTypes: true });
37
+ return entries
38
+ .filter((entry) => entry.isDirectory())
39
+ .map((entry) => entry.name);
40
+ }
41
+ catch (error) {
42
+ console.error("Error listing agents:", error);
43
+ return [];
44
+ }
44
45
  }
45
46
  /**
46
47
  * Delete an agent
47
48
  */
48
49
  export async function deleteAgent(name) {
49
- const agentPath = getAgentPath(name);
50
- await rm(agentPath, { recursive: true, force: true });
50
+ const agentPath = getAgentPath(name);
51
+ await rm(agentPath, { recursive: true, force: true });
51
52
  }
52
53
  /**
53
54
  * Ensure the agents directory exists
54
55
  */
55
56
  export async function ensureAgentsDir() {
56
- await mkdir(AGENTS_DIR, { recursive: true });
57
+ await mkdir(AGENTS_DIR, { recursive: true });
58
+ }
59
+ /**
60
+ * Check if we're inside a Town project by looking for project markers
61
+ * Returns the project root path if found, null otherwise
62
+ */
63
+ export async function isInsideTownProject(startPath = process.cwd()) {
64
+ let currentPath = startPath;
65
+ while (true) {
66
+ try {
67
+ // Check if this is a Town project by looking for:
68
+ // 1. agents/ directory exists
69
+ // (this is very naive right now)
70
+ const agentsDir = join(currentPath, "agents");
71
+ try {
72
+ const agentsDirStat = await stat(agentsDir);
73
+ if (agentsDirStat.isDirectory()) {
74
+ return currentPath;
75
+ }
76
+ }
77
+ catch {
78
+ // agents/ directory doesn't exist, continue searching
79
+ }
80
+ }
81
+ catch {
82
+ // package.json doesn't exist or can't be read, continue searching
83
+ }
84
+ // Move up one directory
85
+ const parentPath = dirname(currentPath);
86
+ if (parentPath === currentPath) {
87
+ // Reached the filesystem root
88
+ break;
89
+ }
90
+ currentPath = parentPath;
91
+ }
92
+ return null;
57
93
  }
@@ -8,14 +8,19 @@ export interface TemplateVars {
8
8
  } | {
9
9
  type: "filesystem";
10
10
  working_directory?: string | undefined;
11
+ } | {
12
+ type: "direct";
13
+ name: string;
14
+ description: string;
15
+ fn: any;
16
+ schema: unknown;
11
17
  }>;
12
18
  systemPrompt: string | null;
13
19
  hasWebSearch: boolean;
14
20
  }
15
21
  export declare function getTemplateVars(name: string, definition: AgentDefinition): TemplateVars;
16
22
  export declare function generatePackageJson(vars: TemplateVars): string;
17
- export declare function generateIndexTs(): string;
18
- export declare function generateAgentJson(vars: TemplateVars): string;
23
+ export declare function generateIndexTs(vars: TemplateVars): Promise<string>;
19
24
  export declare function generateBinTs(): string;
20
25
  export declare function generateGitignore(): string;
21
26
  export declare function generateTsConfig(): string;
@@ -1,3 +1,4 @@
1
+ import * as prettier from "prettier";
1
2
  export function getTemplateVars(name, definition) {
2
3
  const tools = definition.tools ?? [];
3
4
  return {
@@ -42,15 +43,17 @@ export function generatePackageJson(vars) {
42
43
  };
43
44
  return JSON.stringify(pkg, null, 2);
44
45
  }
45
- export function generateIndexTs() {
46
- return `import { readFileSync } from "node:fs";
47
- import { join } from "node:path";
48
- import { makeHttpTransport, makeStdioTransport } from "@townco/agent/acp-server";
46
+ export async function generateIndexTs(vars) {
47
+ const agentDef = {
48
+ model: vars.model,
49
+ systemPrompt: vars.systemPrompt,
50
+ tools: vars.tools,
51
+ };
52
+ return prettier.format(`import { makeHttpTransport, makeStdioTransport } from "@townco/agent/acp-server";
49
53
  import type { AgentDefinition } from "@townco/agent/definition";
50
54
 
51
55
  // Load agent definition from JSON file
52
- const configPath = join(import.meta.dir, "agent.json");
53
- const agent: AgentDefinition = JSON.parse(readFileSync(configPath, "utf-8"));
56
+ const agent: AgentDefinition = ${JSON.stringify(agentDef)};
54
57
 
55
58
  const transport = process.argv[2] || "stdio";
56
59
 
@@ -62,19 +65,11 @@ if (transport === "http") {
62
65
  console.error(\`Invalid transport: \${transport}\`);
63
66
  process.exit(1);
64
67
  }
65
- `;
66
- }
67
- export function generateAgentJson(vars) {
68
- const agentDef = {
69
- model: vars.model,
70
- systemPrompt: vars.systemPrompt,
71
- tools: vars.tools,
72
- };
73
- return JSON.stringify(agentDef, null, 2);
68
+ `, { parser: "typescript" });
74
69
  }
75
70
  export function generateBinTs() {
76
71
  return `#!/usr/bin/env bun
77
- import "./index.js";
72
+ import "./index.ts";
78
73
  `;
79
74
  }
80
75
  export function generateGitignore() {
@@ -113,6 +108,8 @@ export function generateReadme(vars) {
113
108
  return tool.modulePath;
114
109
  if (tool.type === "filesystem")
115
110
  return `filesystem${tool.working_directory ? ` (${tool.working_directory})` : ""}`;
111
+ if (tool.type === "direct")
112
+ return tool.name;
116
113
  return "";
117
114
  })
118
115
  .join(", ")