@townco/cli 0.1.121 → 0.1.123

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.
@@ -6,6 +6,7 @@ declare const _default: {
6
6
  readonly tools: readonly string[];
7
7
  readonly systemPrompt: string | undefined;
8
8
  readonly mcps: string | undefined;
9
+ readonly subagents: string | undefined;
9
10
  readonly init: string | undefined;
10
11
  readonly claude: true | undefined;
11
12
  readonly yes: true | undefined;
@@ -16,6 +17,7 @@ declare const _default: {
16
17
  readonly tools: readonly (import("@optique/core").ValueParserResult<string> | undefined)[];
17
18
  readonly systemPrompt: [import("@optique/core").ValueParserResult<string> | undefined] | undefined;
18
19
  readonly mcps: [import("@optique/core").ValueParserResult<string> | undefined] | undefined;
20
+ readonly subagents: [import("@optique/core").ValueParserResult<string> | undefined] | undefined;
19
21
  readonly init: [import("@optique/core").ValueParserResult<string> | undefined] | undefined;
20
22
  readonly claude: [import("@optique/core").ValueParserResult<true> | undefined] | undefined;
21
23
  readonly yes: [import("@optique/core").ValueParserResult<true> | undefined] | undefined;
@@ -27,6 +29,7 @@ declare const _default: {
27
29
  readonly tools: readonly string[];
28
30
  readonly systemPrompt: string | undefined;
29
31
  readonly mcps: string | undefined;
32
+ readonly subagents: string | undefined;
30
33
  readonly init: string | undefined;
31
34
  readonly claude: true | undefined;
32
35
  readonly yes: true | undefined;
@@ -8,6 +8,13 @@ import { z } from "zod";
8
8
  import { createCommand } from "../lib/command";
9
9
  import { createCommand as createAgentCommand } from "./create";
10
10
  import { createProjectCommand } from "./create-project";
11
+ /** Config for a subagent passed via --subagents flag */
12
+ const SubagentConfigSchema = z.object({
13
+ agentName: z.string(),
14
+ toolDescription: z.string(),
15
+ displayName: z.string().optional(),
16
+ path: z.string(),
17
+ });
11
18
  export default createCommand({
12
19
  def: command("create", object({
13
20
  command: constant("create"),
@@ -18,6 +25,9 @@ export default createCommand({
18
25
  mcps: optional(option("--mcps", string(), {
19
26
  description: message `MCP servers configuration (JSON array)`,
20
27
  })),
28
+ subagents: optional(option("--subagents", string(), {
29
+ description: message `Subagent configurations (JSON array)`,
30
+ })),
21
31
  init: optional(option("--init", string(), {
22
32
  description: message `Initialize a new project at the given path`,
23
33
  })),
@@ -30,7 +40,7 @@ export default createCommand({
30
40
  }), {
31
41
  brief: message `Create a new agent or project`,
32
42
  }),
33
- impl: async ({ name, model, tools, systemPrompt, mcps: mcpsJson, init, claude, yes, }) => {
43
+ impl: async ({ name, model, tools, systemPrompt, mcps: mcpsJson, subagents: subagentsJson, init, claude, yes, }) => {
34
44
  // Parse and validate MCPs if provided
35
45
  let mcps;
36
46
  if (mcpsJson) {
@@ -48,6 +58,23 @@ export default createCommand({
48
58
  process.exit(1);
49
59
  }
50
60
  }
61
+ // Parse and validate subagents if provided
62
+ let subagents;
63
+ if (subagentsJson) {
64
+ try {
65
+ const parsed = JSON.parse(subagentsJson);
66
+ subagents = z.array(SubagentConfigSchema).parse(parsed);
67
+ }
68
+ catch (err) {
69
+ if (err instanceof z.ZodError) {
70
+ console.error("Invalid subagent configuration:", err.issues);
71
+ }
72
+ else {
73
+ console.error("Invalid JSON for --subagents:", err instanceof Error ? err.message : err);
74
+ }
75
+ process.exit(1);
76
+ }
77
+ }
51
78
  // Handle --claude flag (initialize .claude in existing project)
52
79
  if (claude === true) {
53
80
  if (init !== null && init !== undefined) {
@@ -99,6 +126,7 @@ export default createCommand({
99
126
  ...(tools.length > 0 && { tools }),
100
127
  ...(systemPrompt !== undefined && { systemPrompt }),
101
128
  ...(mcps !== undefined && { mcps }),
129
+ ...(subagents !== undefined && { subagents }),
102
130
  ...(yes === true && { yes: true }),
103
131
  agentsDir: join(process.cwd(), "agents"),
104
132
  });
@@ -120,6 +148,7 @@ export default createCommand({
120
148
  ...(tools.length > 0 && { tools }),
121
149
  ...(systemPrompt !== undefined && { systemPrompt }),
122
150
  ...(mcps !== undefined && { mcps }),
151
+ ...(subagents !== undefined && { subagents }),
123
152
  ...(yes === true && { yes: true }),
124
153
  agentsDir: join(projectRoot, "agents"),
125
154
  });
@@ -1,12 +1,20 @@
1
1
  import type { McpConfigSchema } from "@townco/agent/definition";
2
2
  import type { z } from "zod";
3
3
  type McpConfig = z.infer<typeof McpConfigSchema>;
4
+ /** Config for a subagent to wire up via makeSubagentsTool */
5
+ interface SubagentConfig {
6
+ agentName: string;
7
+ toolDescription: string;
8
+ displayName?: string | undefined;
9
+ path: string;
10
+ }
4
11
  interface CreateCommandProps {
5
12
  name?: string;
6
13
  model?: string;
7
14
  tools?: readonly string[];
8
15
  systemPrompt?: string;
9
16
  mcps?: McpConfig[];
17
+ subagents?: SubagentConfig[];
10
18
  overwrite?: boolean;
11
19
  yes?: boolean;
12
20
  agentsDir: string;
@@ -70,7 +70,7 @@ function NameInput({ nameInput, setNameInput, onSubmit }) {
70
70
  ] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter: Continue \u2022 Esc: Cancel" }) })
71
71
  ] }));
72
72
  }
73
- function CreateApp({ name: initialName, model: initialModel, tools: initialTools, systemPrompt: initialSystemPrompt, mcps: initialMcps, overwrite = false, yes = false, agentsDir, }) {
73
+ function CreateApp({ name: initialName, model: initialModel, tools: initialTools, systemPrompt: initialSystemPrompt, mcps: initialMcps, subagents: initialSubagents, overwrite = false, yes = false, agentsDir, }) {
74
74
  // Determine the starting stage based on what's provided
75
75
  const determineInitialStage = () => {
76
76
  // If --yes flag is set and we have name and model, skip directly to done
@@ -115,6 +115,8 @@ function CreateApp({ name: initialName, model: initialModel, tools: initialTools
115
115
  systemPrompt: agentDef.systemPrompt || "You are a helpful assistant.",
116
116
  tools: agentDef.tools || [],
117
117
  ...(initialMcps && initialMcps.length > 0 && { mcps: initialMcps }),
118
+ ...(initialSubagents &&
119
+ initialSubagents.length > 0 && { subagents: initialSubagents }),
118
120
  hooks: [
119
121
  {
120
122
  type: "tool_response",
@@ -161,7 +163,15 @@ function CreateApp({ name: initialName, model: initialModel, tools: initialTools
161
163
  }
162
164
  });
163
165
  }
164
- }, [stage, scaffoldStatus, agentDef, overwrite, agentsDir, initialMcps]);
166
+ }, [
167
+ stage,
168
+ scaffoldStatus,
169
+ agentDef,
170
+ overwrite,
171
+ agentsDir,
172
+ initialMcps,
173
+ initialSubagents,
174
+ ]);
165
175
  // Name stage
166
176
  if (stage === "name") {
167
177
  return (_jsx(NameInput, { nameInput: nameInput, setNameInput: setNameInput, onSubmit: () => {
@@ -3,8 +3,9 @@ import afs from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { command, constant, message, multiple, object, option, optional, string, } from "@optique/core";
5
5
  import { isInsideTownProject } from "@townco/agent/storage";
6
- import { createClient } from "@townco/apiclient";
6
+ import { createTRPCLinks } from "@townco/apiclient";
7
7
  import { findRoot } from "@townco/core/path";
8
+ import { createTRPCClient } from "@trpc/client";
8
9
  import archiver from "archiver";
9
10
  import walk from "ignore-walk";
10
11
  import { getValidCredentials } from "../lib/auth-fetch";
@@ -25,14 +26,14 @@ export default createCommand({
25
26
  error: message `${raw} must contain exactly one equal sign`,
26
27
  };
27
28
  const [k, v] = raw.split("=");
28
- if (!k || !v)
29
- return {
29
+ return !k || !v
30
+ ? {
30
31
  success: false,
31
32
  error: message `${raw} must be of the form FOO=bar`,
32
- };
33
- return { success: true, value: { [k]: v } };
33
+ }
34
+ : { success: true, value: { [k]: v } };
34
35
  },
35
- format: (v) => Object.entries(v).map((e) => e.join("="))[0],
36
+ format: ({ k, v }) => (!k || !v ? "" : `${k}=${v}`),
36
37
  }))),
37
38
  debug: option("-d", "--debug"),
38
39
  }), {
@@ -46,7 +47,7 @@ export default createCommand({
46
47
  if (!(await afs.exists(join(projectRoot, "agents", agent))))
47
48
  throw new Error(`Agent ${agent} not found`);
48
49
  const { accessToken, shedUrl } = await getValidCredentials();
49
- const client = createClient({ accessToken, shedUrl, debug });
50
+ const client = createTRPCClient(createTRPCLinks({ accessToken, shedUrl, debug }));
50
51
  console.log("Creating archive...");
51
52
  const root = await findRoot({ rootMarker: "package.json" });
52
53
  const chunks = [];
@@ -86,7 +87,9 @@ export default createCommand({
86
87
  agentPass,
87
88
  env: env ? Object.assign({}, ...env) : undefined,
88
89
  }, {
89
- onData: ({ status, error }) => console.log(status ? status : error),
90
+ onData: ({ status, error, agentUrl }) => console.log(agentUrl
91
+ ? `${status}: ${agentUrl}`
92
+ : (status ?? error ?? "Unknown error")),
90
93
  onError: (err) => console.error(err),
91
94
  onComplete: () => console.log("\n✓ Deployment complete!"),
92
95
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@townco/cli",
3
- "version": "0.1.121",
3
+ "version": "0.1.123",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "town": "./dist/index.js"
@@ -15,7 +15,7 @@
15
15
  "build": "tsgo"
16
16
  },
17
17
  "devDependencies": {
18
- "@townco/tsconfig": "0.1.113",
18
+ "@townco/tsconfig": "0.1.115",
19
19
  "@types/archiver": "^7.0.0",
20
20
  "@types/bun": "^1.3.1",
21
21
  "@types/ignore-walk": "^4.0.3",
@@ -24,13 +24,13 @@
24
24
  "dependencies": {
25
25
  "@optique/core": "^0.6.2",
26
26
  "@optique/run": "^0.6.2",
27
- "@townco/agent": "0.1.124",
28
- "@townco/apiclient": "0.0.36",
29
- "@townco/core": "0.0.94",
30
- "@townco/debugger": "0.1.72",
31
- "@townco/env": "0.1.66",
32
- "@townco/secret": "0.1.116",
33
- "@townco/ui": "0.1.116",
27
+ "@townco/agent": "0.1.126",
28
+ "@townco/apiclient": "0.0.38",
29
+ "@townco/core": "0.0.96",
30
+ "@townco/debugger": "0.1.74",
31
+ "@townco/env": "0.1.68",
32
+ "@townco/secret": "0.1.118",
33
+ "@townco/ui": "0.1.118",
34
34
  "@trpc/client": "^11.7.2",
35
35
  "archiver": "^7.0.1",
36
36
  "eventsource": "^4.1.0",