@standardagents/cli 0.11.11 → 0.12.0-next.30cb17a

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/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import path3 from 'path';
4
- import fs3 from 'fs';
3
+ import fs3, { readFileSync } from 'fs';
4
+ import path3, { dirname, resolve } from 'path';
5
+ import { fileURLToPath } from 'url';
5
6
  import crypto from 'crypto';
6
7
  import readline from 'readline';
7
8
  import { spawn } from 'child_process';
@@ -10,7 +11,6 @@ import { parse, modify, applyEdits } from 'jsonc-parser';
10
11
  import { loadFile, writeFile, generateCode } from 'magicast';
11
12
  import { addVitePlugin } from 'magicast/helpers';
12
13
  import net from 'net';
13
- import { fileURLToPath } from 'url';
14
14
 
15
15
  var logger = {
16
16
  success: (message) => {
@@ -116,32 +116,30 @@ agents/
116
116
 
117
117
  Files are **auto-discovered** at runtime. No manual registration needed.
118
118
 
119
- ## ThreadState
119
+ ## FlowState
120
120
 
121
- \`ThreadState\` is the state object available in tools and hooks:
121
+ \`FlowState\` is the central state object available in tools and hooks:
122
122
 
123
123
  \`\`\`typescript
124
- interface ThreadState {
125
- // Identity (readonly)
126
- threadId: string; // Thread identifier
127
- agentId: string; // Agent identifier
128
- userId: string | null; // User identifier (if set)
129
- createdAt: number; // Creation timestamp
130
-
131
- // Methods
132
- getMessages(options?): Promise<MessagesResult>; // Get conversation history
133
- injectMessage(input): Promise<Message>; // Add message to thread
134
- loadModel(name): Promise<ModelConfig>; // Load model definition
135
- loadPrompt(name): Promise<PromptConfig>; // Load prompt definition
136
- loadAgent(name): Promise<AgentConfig>; // Load agent definition
124
+ interface FlowState {
125
+ thread: {
126
+ id: string; // Thread identifier
127
+ instance: DurableThread; // Durable Object instance
128
+ };
129
+ agent: AgentConfig; // Current agent configuration
130
+ prompt: PromptConfig; // Current prompt configuration
131
+ model: ModelConfig; // Current model configuration
132
+ messages: Message[]; // Conversation history
133
+ env: Env; // Cloudflare Worker environment
134
+ rootState: FlowState; // Parent state (for sub-prompts)
137
135
  }
138
136
  \`\`\`
139
137
 
140
138
  Access in tools:
141
139
  \`\`\`typescript
142
140
  export default defineTool('...', schema, async (flow, args) => {
143
- const threadId = flow.threadId;
144
- const { messages } = await flow.getMessages();
141
+ const threadId = flow.thread.id;
142
+ const messages = flow.messages;
145
143
  // ...
146
144
  });
147
145
  \`\`\`
@@ -527,12 +525,12 @@ Tools extend agent capabilities beyond text generation. They allow LLMs to fetch
527
525
  ## Function Signature
528
526
 
529
527
  \`\`\`typescript
530
- defineTool({
528
+ defineTool(
531
529
  description: string, // What the tool does (shown to LLM)
532
- args?: z.ZodObject, // Input validation schema (optional)
533
- execute: (state, args) => ToolResult, // Implementation
534
- tenvs?: z.ZodObject, // Thread environment variables (optional)
535
- })
530
+ args: z.ZodObject, // Input validation schema
531
+ handler: (flow, args) => ToolResult, // Implementation
532
+ returnSchema?: z.ZodObject // Optional output schema
533
+ )
536
534
  \`\`\`
537
535
 
538
536
  ## Basic Example
@@ -541,20 +539,20 @@ defineTool({
541
539
  import { defineTool } from '@standardagents/builder';
542
540
  import { z } from 'zod';
543
541
 
544
- export default defineTool({
545
- description: 'Search the knowledge base for articles matching a query',
546
- args: z.object({
542
+ export default defineTool(
543
+ 'Search the knowledge base for articles matching a query',
544
+ z.object({
547
545
  query: z.string().describe('Search query'),
548
546
  limit: z.number().optional().default(10).describe('Max results'),
549
547
  }),
550
- execute: async (state, args) => {
548
+ async (flow, args) => {
551
549
  const results = await searchKB(args.query, args.limit);
552
550
  return {
553
551
  status: 'success',
554
552
  result: JSON.stringify(results),
555
553
  };
556
- },
557
- });
554
+ }
555
+ );
558
556
  \`\`\`
559
557
 
560
558
  ## ToolResult Interface
@@ -564,45 +562,44 @@ export default defineTool({
564
562
  | \`status\` | \`'success' \\| 'error'\` | Whether the tool succeeded |
565
563
  | \`result\` | \`string\` | Tool output (required for success) |
566
564
  | \`error\` | \`string\` | Error message (for error status) |
567
- | \`attachments\` | \`ToolAttachment[]\` | Files to attach (images, etc.) |
568
565
 
569
- ## ThreadState Access
566
+ ## FlowState Access
570
567
 
571
- The \`state\` parameter provides access to:
568
+ The \`flow\` parameter provides access to:
572
569
 
573
570
  \`\`\`typescript
574
- execute: async (state, args) => {
571
+ async (flow, args) => {
575
572
  // Thread information
576
- const threadId = state.thread.id;
577
- const thread = state.thread.instance;
573
+ const threadId = flow.thread.id;
574
+ const thread = flow.thread.instance;
578
575
 
579
576
  // Configuration
580
- const agentName = state.agent.name;
581
- const modelName = state.model.name;
577
+ const agentName = flow.agent.name;
578
+ const modelName = flow.model.name;
582
579
 
583
580
  // Message history
584
- const messages = state.messages;
581
+ const messages = flow.messages;
585
582
 
586
583
  // Environment bindings
587
- const env = state.env;
584
+ const env = flow.env;
588
585
 
589
586
  // Parent state (for sub-prompts)
590
- const root = state.rootState;
587
+ const root = flow.rootState;
591
588
  }
592
589
  \`\`\`
593
590
 
594
591
  ## Tool Without Arguments
595
592
 
596
593
  \`\`\`typescript
597
- export default defineTool({
598
- description: 'Get current server time',
599
- execute: async (state) => {
594
+ export default defineTool(
595
+ 'Get current server time',
596
+ async (flow) => {
600
597
  return {
601
598
  status: 'success',
602
599
  result: new Date().toISOString(),
603
600
  };
604
- },
605
- });
601
+ }
602
+ );
606
603
  \`\`\`
607
604
 
608
605
  ## Error Handling
@@ -610,10 +607,10 @@ export default defineTool({
610
607
  Return errors gracefully instead of throwing:
611
608
 
612
609
  \`\`\`typescript
613
- export default defineTool({
614
- description: 'Fetch user data',
615
- args: z.object({ userId: z.string() }),
616
- execute: async (state, args) => {
610
+ export default defineTool(
611
+ 'Fetch user data',
612
+ z.object({ userId: z.string() }),
613
+ async (flow, args) => {
617
614
  try {
618
615
  const user = await fetchUser(args.userId);
619
616
  return { status: 'success', result: JSON.stringify(user) };
@@ -623,8 +620,8 @@ export default defineTool({
623
620
  error: \`Failed to fetch user: \${error.message}\`,
624
621
  };
625
622
  }
626
- },
627
- });
623
+ }
624
+ );
628
625
  \`\`\`
629
626
 
630
627
  ## Queueing Additional Tools
@@ -634,21 +631,21 @@ Queue another tool to run after the current one:
634
631
  \`\`\`typescript
635
632
  import { queueTool } from '@standardagents/builder';
636
633
 
637
- export default defineTool({
638
- description: 'Create order and send confirmation',
639
- args: z.object({ items: z.array(z.string()) }),
640
- execute: async (state, args) => {
634
+ export default defineTool(
635
+ 'Create order and send confirmation',
636
+ z.object({ items: z.array(z.string()) }),
637
+ async (flow, args) => {
641
638
  const order = await createOrder(args.items);
642
639
 
643
640
  // Queue email tool to run next
644
- queueTool(state, 'send_confirmation_email', {
641
+ queueTool(flow, 'send_confirmation_email', {
645
642
  orderId: order.id,
646
- email: state.thread.metadata.userEmail,
643
+ email: flow.thread.metadata.userEmail,
647
644
  });
648
645
 
649
646
  return { status: 'success', result: JSON.stringify(order) };
650
- },
651
- });
647
+ }
648
+ );
652
649
  \`\`\`
653
650
 
654
651
  ## Injecting Messages
@@ -658,61 +655,17 @@ Add messages without triggering re-execution:
658
655
  \`\`\`typescript
659
656
  import { injectMessage } from '@standardagents/builder';
660
657
 
661
- export default defineTool({
662
- description: 'Log audit event',
663
- args: z.object({ event: z.string() }),
664
- execute: async (state, args) => {
665
- await injectMessage(state, {
658
+ export default defineTool(
659
+ 'Log audit event',
660
+ z.object({ event: z.string() }),
661
+ async (flow, args) => {
662
+ await injectMessage(flow, {
666
663
  role: 'system',
667
664
  content: \`[AUDIT] \${args.event}\`,
668
665
  });
669
666
  return { status: 'success', result: 'Logged' };
670
- },
671
- });
672
- \`\`\`
673
-
674
- ## Thread Environment Variables (tenvs)
675
-
676
- Tools can declare required thread environment variables:
677
-
678
- \`\`\`typescript
679
- export default defineTool({
680
- description: 'Search uploaded documents',
681
- args: z.object({ query: z.string() }),
682
- execute: async (state, args) => {
683
- const vectorStoreId = state.tenvs.vectorStoreId;
684
- const results = await searchVectorStore(vectorStoreId, args.query);
685
- return { status: 'success', result: JSON.stringify(results) };
686
- },
687
- tenvs: z.object({
688
- vectorStoreId: z.string().describe('OpenAI Vector Store ID'),
689
- }),
690
- });
691
- \`\`\`
692
-
693
- ## Returning Attachments
694
-
695
- Tools can return file attachments (e.g., generated images):
696
-
697
- \`\`\`typescript
698
- export default defineTool({
699
- description: 'Generate a chart from data',
700
- args: z.object({ data: z.array(z.number()) }),
701
- execute: async (state, args) => {
702
- const chartImage = await generateChart(args.data);
703
- return {
704
- status: 'success',
705
- result: 'Chart generated successfully',
706
- attachments: [{
707
- name: 'chart.png',
708
- mimeType: 'image/png',
709
- data: chartImage.base64,
710
- width: 800,
711
- height: 600,
712
- }],
713
- };
714
- },
715
- });
667
+ }
668
+ );
716
669
  \`\`\`
717
670
 
718
671
  ## Best Practices
@@ -722,7 +675,7 @@ export default defineTool({
722
675
  - **Handle errors gracefully** - return error status, don't throw
723
676
  - **Use snake_case** for file names (\`search_knowledge_base.ts\`)
724
677
  - **Keep tools focused** - one task per tool
725
- - **Use \`state.rootState\`** when queueing from sub-prompts
678
+ - **Use \`flow.rootState\`** when queueing from sub-prompts
726
679
 
727
680
  ## Supported Zod Types
728
681
 
@@ -878,7 +831,7 @@ Full reference: https://docs.standardagentbuilder.com/api-reference/define/hook
878
831
  // src/templates/api.ts
879
832
  var API_CLAUDE_MD = `# Thread-Specific API Endpoints
880
833
 
881
- Define custom API endpoints that operate on specific threads with access to the thread's ThreadState.
834
+ Define custom API endpoints that operate on specific threads with access to the thread's Durable Object instance and SQLite storage.
882
835
 
883
836
  ## File-Based Routing
884
837
 
@@ -895,14 +848,15 @@ Define custom API endpoints that operate on specific threads with access to the
895
848
 
896
849
  \`\`\`typescript
897
850
  // agents/api/status.get.ts -> GET /api/threads/:id/status
898
- import { defineThreadEndpoint } from '@standardagents/spec';
851
+ import { defineThreadEndpoint } from '@standardagents/builder';
899
852
 
900
- export default defineThreadEndpoint(async (req, state) => {
901
- const { messages, total } = await state.getMessages();
902
- return Response.json({
903
- threadId: state.threadId,
904
- messageCount: total,
853
+ export default defineThreadEndpoint(async (thread, request, env) => {
854
+ const messages = await thread.getMessages();
855
+ return new Response(JSON.stringify({
856
+ messageCount: messages.length,
905
857
  status: 'active',
858
+ }), {
859
+ headers: { 'Content-Type': 'application/json' },
906
860
  });
907
861
  });
908
862
  \`\`\`
@@ -911,40 +865,30 @@ export default defineThreadEndpoint(async (req, state) => {
911
865
 
912
866
  | Parameter | Type | Description |
913
867
  |-----------|------|-------------|
914
- | \`req\` | \`Request\` | The incoming HTTP request |
915
- | \`state\` | \`ThreadState\` | Thread state with messages, identity, file system, etc. |
868
+ | \`thread\` | \`DurableThread\` | The thread's Durable Object instance |
869
+ | \`request\` | \`Request\` | The incoming HTTP request |
870
+ | \`env\` | \`Env\` | Cloudflare Worker environment bindings |
916
871
 
917
- Note: \`state.execution\` is always \`null\` in endpoints since the thread is at rest.
872
+ ## Thread Methods
918
873
 
919
- ## ThreadState Methods
920
-
921
- Access thread data through the state object:
874
+ Access thread data through the instance:
922
875
 
923
876
  \`\`\`typescript
924
- import { defineThreadEndpoint } from '@standardagents/spec';
925
-
926
- export default defineThreadEndpoint(async (req, state) => {
927
- // Thread identity
928
- console.log('Thread ID:', state.threadId);
929
- console.log('Agent ID:', state.agentId);
930
- console.log('User ID:', state.userId);
931
-
877
+ export default defineThreadEndpoint(async (thread, request, env) => {
932
878
  // Message operations
933
- const { messages, total, hasMore } = await state.getMessages({
934
- limit: 100,
935
- offset: 0,
936
- order: 'desc',
937
- });
879
+ const messages = await thread.getMessages({ limit: 100, offset: 0 });
880
+ const count = await thread.getMessageCount();
938
881
 
939
- // File system operations
940
- const files = await state.findFiles('**/*.json');
941
- const data = await state.readFile('/data/config.json');
882
+ // Thread metadata
883
+ const metadata = thread.getMetadata();
942
884
 
943
- // Resource loading
944
- const agent = await state.loadAgent('my-agent');
945
- const prompt = await state.loadPrompt('my-prompt');
885
+ // Execution control
886
+ await thread.stop();
946
887
 
947
- return Response.json({ messages, total });
888
+ // Custom SQL queries
889
+ const result = thread.ctx.storage.sql.exec(\`
890
+ SELECT * FROM messages WHERE role = 'user'
891
+ \`);
948
892
  });
949
893
  \`\`\`
950
894
 
@@ -952,13 +896,13 @@ export default defineThreadEndpoint(async (req, state) => {
952
896
 
953
897
  \`\`\`typescript
954
898
  // agents/api/export.post.ts -> POST /api/threads/:id/export
955
- import { defineThreadEndpoint } from '@standardagents/spec';
899
+ import { defineThreadEndpoint } from '@standardagents/builder';
956
900
 
957
- export default defineThreadEndpoint(async (req, state) => {
958
- const body = await req.json();
901
+ export default defineThreadEndpoint(async (thread, request, env) => {
902
+ const body = await request.json();
959
903
  const { format = 'json' } = body;
960
904
 
961
- const { messages } = await state.getMessages();
905
+ const messages = await thread.getMessages();
962
906
 
963
907
  if (format === 'csv') {
964
908
  const csv = messages.map(m => \`\${m.role},\${m.content}\`).join('\\n');
@@ -967,7 +911,9 @@ export default defineThreadEndpoint(async (req, state) => {
967
911
  });
968
912
  }
969
913
 
970
- return Response.json(messages);
914
+ return new Response(JSON.stringify(messages), {
915
+ headers: { 'Content-Type': 'application/json' },
916
+ });
971
917
  });
972
918
  \`\`\`
973
919
 
@@ -987,38 +933,35 @@ agents/api/
987
933
  ## Error Handling
988
934
 
989
935
  \`\`\`typescript
990
- import { defineThreadEndpoint } from '@standardagents/spec';
991
-
992
- export default defineThreadEndpoint(async (req, state) => {
936
+ export default defineThreadEndpoint(async (thread, request, env) => {
993
937
  try {
994
938
  const data = await riskyOperation();
995
- return Response.json(data);
939
+ return new Response(JSON.stringify(data), {
940
+ headers: { 'Content-Type': 'application/json' },
941
+ });
996
942
  } catch (error) {
997
- return Response.json({ error: error.message }, { status: 500 });
943
+ return new Response(JSON.stringify({
944
+ error: error.message,
945
+ }), {
946
+ status: 500,
947
+ headers: { 'Content-Type': 'application/json' },
948
+ });
998
949
  }
999
950
  });
1000
951
  \`\`\`
1001
952
 
1002
- ## File System Operations
953
+ ## Using Environment Variables
1003
954
 
1004
955
  \`\`\`typescript
1005
- import { defineThreadEndpoint } from '@standardagents/spec';
1006
-
1007
- export default defineThreadEndpoint(async (req, state) => {
1008
- // Read files
1009
- const content = await state.readFile('/data/file.txt');
1010
-
1011
- // Write files
1012
- await state.writeFile('/output/result.json', JSON.stringify(data), 'application/json');
1013
-
1014
- // List directory
1015
- const { entries } = await state.readdirFile('/data');
956
+ export default defineThreadEndpoint(async (thread, request, env) => {
957
+ // Access secrets and bindings
958
+ const apiKey = env.EXTERNAL_API_KEY;
959
+ const kv = env.MY_KV_NAMESPACE;
1016
960
 
1017
- // Search files
1018
- const matches = await state.grepFiles('pattern');
1019
- const paths = await state.findFiles('**/*.ts');
961
+ const data = await fetchExternalAPI(apiKey);
962
+ await kv.put(\`thread:\${thread.id}\`, JSON.stringify(data));
1020
963
 
1021
- return Response.json({ success: true });
964
+ return new Response('OK');
1022
965
  });
1023
966
  \`\`\`
1024
967
 
@@ -1029,7 +972,6 @@ export default defineThreadEndpoint(async (req, state) => {
1029
972
  - **Validate input data** - check request body before processing
1030
973
  - **Use descriptive file names** - \`export.post.ts\` not \`ep1.ts\`
1031
974
  - **Return proper status codes** - 200, 400, 404, 500
1032
- - **Import from spec** - use \`@standardagents/spec\` for \`defineThreadEndpoint\`
1033
975
 
1034
976
  ## Documentation
1035
977
 
@@ -1037,19 +979,17 @@ Full reference: https://docs.standardagentbuilder.com/core-concepts/api
1037
979
  `;
1038
980
 
1039
981
  // src/commands/scaffold.ts
1040
- var WRANGLER_TEMPLATE = (name) => {
1041
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1042
- return `{
982
+ var WRANGLER_TEMPLATE = (name) => `{
1043
983
  "$schema": "node_modules/wrangler/config-schema.json",
1044
984
  "name": "${name}",
1045
985
  "main": "worker/index.ts",
1046
- "compatibility_date": "${today}",
986
+ "compatibility_date": "2025-01-01",
1047
987
  "compatibility_flags": ["nodejs_compat"],
1048
988
  "observability": {
1049
989
  "enabled": true
1050
990
  },
1051
991
  "assets": {
1052
- "directory": "dist/client",
992
+ "directory": "dist",
1053
993
  "not_found_handling": "single-page-application",
1054
994
  "binding": "ASSETS",
1055
995
  "run_worker_first": ["/**"]
@@ -1078,7 +1018,6 @@ var WRANGLER_TEMPLATE = (name) => {
1078
1018
  ]
1079
1019
  }
1080
1020
  `;
1081
- };
1082
1021
  var THREAD_TS = `import { DurableThread } from 'virtual:@standardagents/builder'
1083
1022
 
1084
1023
  export default class Thread extends DurableThread {}
@@ -1104,9 +1043,9 @@ function getProjectName(cwd) {
1104
1043
  const packageJsonPath = path3.join(cwd, "package.json");
1105
1044
  if (fs3.existsSync(packageJsonPath)) {
1106
1045
  try {
1107
- const pkg = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1108
- if (pkg.name) {
1109
- return pkg.name.replace(/^@[^/]+\//, "");
1046
+ const pkg2 = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1047
+ if (pkg2.name) {
1048
+ return pkg2.name.replace(/^@[^/]+\//, "");
1110
1049
  }
1111
1050
  } catch {
1112
1051
  }
@@ -1143,6 +1082,14 @@ async function modifyViteConfig(configPath, force) {
1143
1082
  logger.info("Vite config already includes Standard Agents plugins");
1144
1083
  return true;
1145
1084
  }
1085
+ if (!hasCloudflare || force) {
1086
+ addVitePlugin(mod, {
1087
+ from: "@cloudflare/vite-plugin",
1088
+ imported: "cloudflare",
1089
+ constructor: "cloudflare"
1090
+ });
1091
+ logger.success("Added cloudflare plugin to vite.config");
1092
+ }
1146
1093
  if (!hasAgentBuilder || force) {
1147
1094
  addVitePlugin(mod, {
1148
1095
  from: "@standardagents/builder",
@@ -1152,14 +1099,6 @@ async function modifyViteConfig(configPath, force) {
1152
1099
  });
1153
1100
  logger.success("Added agentbuilder plugin to vite.config");
1154
1101
  }
1155
- if (!hasCloudflare || force) {
1156
- addVitePlugin(mod, {
1157
- from: "@cloudflare/vite-plugin",
1158
- imported: "cloudflare",
1159
- constructor: "cloudflare"
1160
- });
1161
- logger.success("Added cloudflare plugin to vite.config");
1162
- }
1163
1102
  await writeFile(mod, configPath);
1164
1103
  return true;
1165
1104
  } catch (error) {
@@ -1167,10 +1106,10 @@ async function modifyViteConfig(configPath, force) {
1167
1106
  logger.log("");
1168
1107
  logger.log("Please manually add the following to your vite.config.ts:");
1169
1108
  logger.log("");
1170
- logger.log(` import { agentbuilder } from '@standardagents/builder'`);
1171
1109
  logger.log(` import { cloudflare } from '@cloudflare/vite-plugin'`);
1110
+ logger.log(` import { agentbuilder } from '@standardagents/builder'`);
1172
1111
  logger.log("");
1173
- logger.log(` plugins: [agentbuilder({ mountPoint: '/' }), cloudflare()]`);
1112
+ logger.log(` plugins: [cloudflare(), agentbuilder({ mountPoint: '/' })]`);
1174
1113
  logger.log("");
1175
1114
  return false;
1176
1115
  }
@@ -1219,7 +1158,7 @@ function createOrUpdateWranglerConfig(cwd, projectName, force) {
1219
1158
  }
1220
1159
  if (!config.assets) {
1221
1160
  const edits = modify(result, ["assets"], {
1222
- directory: "dist/client",
1161
+ directory: "dist",
1223
1162
  not_found_handling: "single-page-application",
1224
1163
  binding: "ASSETS",
1225
1164
  run_worker_first: ["/**"]
@@ -1491,15 +1430,15 @@ async function prompt(question) {
1491
1430
  input: process.stdin,
1492
1431
  output: process.stdout
1493
1432
  });
1494
- return new Promise((resolve) => {
1433
+ return new Promise((resolve2) => {
1495
1434
  rl.question(question, (answer) => {
1496
1435
  rl.close();
1497
- resolve(answer.trim());
1436
+ resolve2(answer.trim());
1498
1437
  });
1499
1438
  });
1500
1439
  }
1501
1440
  async function promptPassword(question) {
1502
- return new Promise((resolve) => {
1441
+ return new Promise((resolve2) => {
1503
1442
  const stdin = process.stdin;
1504
1443
  const stdout = process.stdout;
1505
1444
  stdout.write(question);
@@ -1520,7 +1459,7 @@ async function promptPassword(question) {
1520
1459
  stdin.pause();
1521
1460
  stdin.removeListener("data", onData);
1522
1461
  stdout.write("\n");
1523
- resolve(password);
1462
+ resolve2(password);
1524
1463
  break;
1525
1464
  case "":
1526
1465
  stdout.write("\n");
@@ -1546,7 +1485,7 @@ async function promptPassword(question) {
1546
1485
  });
1547
1486
  }
1548
1487
  function runCommand(command, args, cwd) {
1549
- return new Promise((resolve, reject) => {
1488
+ return new Promise((resolve2, reject) => {
1550
1489
  const child = spawn(command, args, {
1551
1490
  cwd,
1552
1491
  stdio: "inherit",
@@ -1554,7 +1493,7 @@ function runCommand(command, args, cwd) {
1554
1493
  });
1555
1494
  child.on("close", (code) => {
1556
1495
  if (code === 0) {
1557
- resolve();
1496
+ resolve2();
1558
1497
  } else {
1559
1498
  reject(new Error(`Command failed with exit code ${code}`));
1560
1499
  }
@@ -1578,16 +1517,25 @@ function detectPackageManager() {
1578
1517
  if (fs3.existsSync("package-lock.json")) return "npm";
1579
1518
  return "npm";
1580
1519
  }
1581
- function getPackageVersion() {
1582
- if (process.env.STANDARDAGENTS_WORKSPACE === "1") {
1583
- return "workspace:*";
1520
+ function getBuilderPackageVersion() {
1521
+ try {
1522
+ const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
1523
+ const pkgPath = path3.resolve(__dirname2, "../../package.json");
1524
+ const pkg2 = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
1525
+ const version = pkg2.version;
1526
+ const prereleaseMatch = version.match(/-([a-z]+)\./i);
1527
+ if (prereleaseMatch) {
1528
+ return `@${prereleaseMatch[1]}`;
1529
+ }
1530
+ return `@^${version}`;
1531
+ } catch {
1532
+ return "";
1584
1533
  }
1585
- return "0.11.11";
1586
1534
  }
1587
1535
  async function selectPackageManager(detected) {
1588
1536
  const options = ["npm", "pnpm", "yarn", "bun"];
1589
1537
  const detectedIndex = options.indexOf(detected);
1590
- return new Promise((resolve) => {
1538
+ return new Promise((resolve2) => {
1591
1539
  const stdin = process.stdin;
1592
1540
  const stdout = process.stdout;
1593
1541
  let selectedIndex = detectedIndex;
@@ -1633,7 +1581,7 @@ async function selectPackageManager(detected) {
1633
1581
  renderOptions();
1634
1582
  } else if (key === "\r" || key === "\n") {
1635
1583
  cleanup();
1636
- resolve(options[selectedIndex]);
1584
+ resolve2(options[selectedIndex]);
1637
1585
  } else if (key === "") {
1638
1586
  cleanup();
1639
1587
  stdout.write("\n");
@@ -1719,7 +1667,31 @@ export default defineConfig({
1719
1667
  }
1720
1668
  }
1721
1669
  logger.log("");
1722
- logger.info("Step 2: Configuring environment variables...");
1670
+ logger.info("Step 2: Installing Standard Agents dependencies...");
1671
+ logger.log("");
1672
+ try {
1673
+ const installCmd = pm === "npm" ? "install" : "add";
1674
+ const devFlag = pm === "npm" ? "--save-dev" : "-D";
1675
+ const builderVersion = getBuilderPackageVersion();
1676
+ await runCommand(pm, [
1677
+ installCmd,
1678
+ devFlag,
1679
+ "@cloudflare/vite-plugin",
1680
+ `@standardagents/builder${builderVersion}`,
1681
+ "wrangler",
1682
+ "zod"
1683
+ ], projectPath);
1684
+ } catch (error) {
1685
+ logger.error("Failed to install dependencies");
1686
+ process.exit(1);
1687
+ }
1688
+ logger.log("");
1689
+ logger.info("Step 3: Configuring Standard Agents...");
1690
+ logger.log("");
1691
+ process.chdir(projectPath);
1692
+ await scaffold({ force: true });
1693
+ logger.log("");
1694
+ logger.info("Step 4: Configuring environment variables...");
1723
1695
  logger.log("");
1724
1696
  const encryptionKey = crypto.randomBytes(32).toString("hex");
1725
1697
  let openrouterKey = "";
@@ -1754,44 +1726,6 @@ export default defineConfig({
1754
1726
  if (!adminPassword) {
1755
1727
  adminPassword = "admin";
1756
1728
  }
1757
- logger.log("");
1758
- logger.info("Step 3: Installing Standard Agents dependencies...");
1759
- logger.log("");
1760
- try {
1761
- const installCmd = pm === "npm" ? "install" : "add";
1762
- const devFlag = pm === "npm" ? "--save-dev" : "-D";
1763
- const packageVersion = getPackageVersion();
1764
- await runCommand(pm, [
1765
- installCmd,
1766
- devFlag,
1767
- "@cloudflare/vite-plugin",
1768
- "wrangler"
1769
- ], projectPath);
1770
- const deps = [
1771
- `@standardagents/builder@${packageVersion}`,
1772
- `@standardagents/spec@${packageVersion}`,
1773
- `@standardagents/sip@${packageVersion}`,
1774
- "zod"
1775
- ];
1776
- if (openaiKey) {
1777
- deps.push(`@standardagents/openai@${packageVersion}`);
1778
- }
1779
- if (openrouterKey) {
1780
- deps.push(`@standardagents/openrouter@${packageVersion}`);
1781
- }
1782
- await runCommand(pm, [installCmd, ...deps], projectPath);
1783
- } catch (error) {
1784
- logger.error("Failed to install dependencies");
1785
- process.exit(1);
1786
- }
1787
- logger.log("");
1788
- logger.info("Step 4: Configuring Standard Agents...");
1789
- logger.log("");
1790
- process.chdir(projectPath);
1791
- await scaffold({ force: true });
1792
- logger.log("");
1793
- logger.info("Writing environment configuration...");
1794
- logger.log("");
1795
1729
  const devVarsLines = [
1796
1730
  "# Standard Agents Environment Variables",
1797
1731
  "# This file contains secrets for local development only",
@@ -1848,10 +1782,10 @@ export default defineConfig({
1848
1782
  }
1849
1783
  function getReactPackageVersion() {
1850
1784
  try {
1851
- const __dirname = path3.dirname(fileURLToPath(import.meta.url));
1852
- const pkgPath = path3.resolve(__dirname, "../package.json");
1853
- const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
1854
- const version = pkg.version;
1785
+ const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
1786
+ const pkgPath = path3.resolve(__dirname2, "../package.json");
1787
+ const pkg2 = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
1788
+ const version = pkg2.version;
1855
1789
  const prereleaseMatch = version.match(/-([a-z]+)\./i);
1856
1790
  if (prereleaseMatch) {
1857
1791
  return prereleaseMatch[1];
@@ -1862,23 +1796,23 @@ function getReactPackageVersion() {
1862
1796
  }
1863
1797
  }
1864
1798
  function getChatSourceDir() {
1865
- const __dirname = path3.dirname(fileURLToPath(import.meta.url));
1866
- return path3.resolve(__dirname, "../chat");
1799
+ const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
1800
+ return path3.resolve(__dirname2, "../chat");
1867
1801
  }
1868
1802
  async function prompt2(question) {
1869
1803
  const rl = readline.createInterface({
1870
1804
  input: process.stdin,
1871
1805
  output: process.stdout
1872
1806
  });
1873
- return new Promise((resolve) => {
1807
+ return new Promise((resolve2) => {
1874
1808
  rl.question(question, (answer) => {
1875
1809
  rl.close();
1876
- resolve(answer.trim());
1810
+ resolve2(answer.trim());
1877
1811
  });
1878
1812
  });
1879
1813
  }
1880
1814
  function runCommand2(command, args, cwd) {
1881
- return new Promise((resolve, reject) => {
1815
+ return new Promise((resolve2, reject) => {
1882
1816
  const child = spawn(command, args, {
1883
1817
  cwd,
1884
1818
  stdio: "inherit",
@@ -1886,7 +1820,7 @@ function runCommand2(command, args, cwd) {
1886
1820
  });
1887
1821
  child.on("close", (code) => {
1888
1822
  if (code === 0) {
1889
- resolve();
1823
+ resolve2();
1890
1824
  } else {
1891
1825
  reject(new Error(`Command failed with exit code ${code}`));
1892
1826
  }
@@ -1910,7 +1844,7 @@ function detectPackageManager2() {
1910
1844
  async function selectPackageManager2(detected) {
1911
1845
  const options = ["npm", "pnpm", "yarn", "bun"];
1912
1846
  const detectedIndex = options.indexOf(detected);
1913
- return new Promise((resolve) => {
1847
+ return new Promise((resolve2) => {
1914
1848
  const stdin = process.stdin;
1915
1849
  const stdout = process.stdout;
1916
1850
  let selectedIndex = detectedIndex;
@@ -1956,7 +1890,7 @@ async function selectPackageManager2(detected) {
1956
1890
  renderOptions();
1957
1891
  } else if (key === "\r" || key === "\n") {
1958
1892
  cleanup();
1959
- resolve(options[selectedIndex]);
1893
+ resolve2(options[selectedIndex]);
1960
1894
  } else if (key === "") {
1961
1895
  cleanup();
1962
1896
  stdout.write("\n");
@@ -1971,7 +1905,7 @@ async function selectFramework() {
1971
1905
  { value: "vite", label: "Vite (React + TypeScript)" },
1972
1906
  { value: "nextjs", label: "Next.js (App Router)" }
1973
1907
  ];
1974
- return new Promise((resolve) => {
1908
+ return new Promise((resolve2) => {
1975
1909
  const stdin = process.stdin;
1976
1910
  const stdout = process.stdout;
1977
1911
  let selectedIndex = 0;
@@ -2015,7 +1949,7 @@ async function selectFramework() {
2015
1949
  renderOptions();
2016
1950
  } else if (key === "\r" || key === "\n") {
2017
1951
  cleanup();
2018
- resolve(options[selectedIndex].value);
1952
+ resolve2(options[selectedIndex].value);
2019
1953
  } else if (key === "") {
2020
1954
  cleanup();
2021
1955
  stdout.write("\n");
@@ -2035,20 +1969,20 @@ function isValidUrl(url) {
2035
1969
  }
2036
1970
  async function isPortOpen(port) {
2037
1971
  const tryConnect = (host) => {
2038
- return new Promise((resolve) => {
1972
+ return new Promise((resolve2) => {
2039
1973
  const socket = new net.Socket();
2040
1974
  socket.setTimeout(200);
2041
1975
  socket.on("connect", () => {
2042
1976
  socket.destroy();
2043
- resolve(true);
1977
+ resolve2(true);
2044
1978
  });
2045
1979
  socket.on("timeout", () => {
2046
1980
  socket.destroy();
2047
- resolve(false);
1981
+ resolve2(false);
2048
1982
  });
2049
1983
  socket.on("error", () => {
2050
1984
  socket.destroy();
2051
- resolve(false);
1985
+ resolve2(false);
2052
1986
  });
2053
1987
  socket.connect(port, host);
2054
1988
  });
@@ -2272,21 +2206,21 @@ export default defineConfig({
2272
2206
  fs3.writeFileSync(path3.join(projectPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n", "utf-8");
2273
2207
  logger.success("Created tsconfig.json");
2274
2208
  fs3.copyFileSync(path3.join(chatSourceDir, "package.json"), path3.join(projectPath, "package.json"));
2275
- const pkg = JSON.parse(fs3.readFileSync(path3.join(projectPath, "package.json"), "utf-8"));
2276
- pkg.name = projectName;
2277
- pkg.scripts = {
2209
+ const pkg2 = JSON.parse(fs3.readFileSync(path3.join(projectPath, "package.json"), "utf-8"));
2210
+ pkg2.name = projectName;
2211
+ pkg2.scripts = {
2278
2212
  dev: "vite",
2279
2213
  build: "vite build",
2280
2214
  preview: "vite preview"
2281
2215
  };
2282
- delete pkg.private;
2283
- if (pkg.dependencies?.["@standardagents/react"]) {
2284
- pkg.dependencies["@standardagents/react"] = reactVersion;
2285
- }
2286
- delete pkg.dependencies?.["next"];
2287
- delete pkg.devDependencies?.["@tailwindcss/postcss"];
2288
- delete pkg.devDependencies?.["postcss"];
2289
- fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg, null, 2) + "\n", "utf-8");
2216
+ delete pkg2.private;
2217
+ if (pkg2.dependencies?.["@standardagents/react"]) {
2218
+ pkg2.dependencies["@standardagents/react"] = reactVersion;
2219
+ }
2220
+ delete pkg2.dependencies?.["next"];
2221
+ delete pkg2.devDependencies?.["@tailwindcss/postcss"];
2222
+ delete pkg2.devDependencies?.["postcss"];
2223
+ fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
2290
2224
  logger.success("Created package.json");
2291
2225
  const envContent = `# Agentbuilder connection
2292
2226
  VITE_AGENTBUILDER_URL=${serverUrl}
@@ -2341,21 +2275,21 @@ async function scaffoldNextjs(projectPath, chatSourceDir, projectName, serverUrl
2341
2275
  };
2342
2276
  fs3.writeFileSync(path3.join(projectPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n", "utf-8");
2343
2277
  logger.success("Created tsconfig.json");
2344
- const pkg = JSON.parse(fs3.readFileSync(path3.join(chatSourceDir, "package.json"), "utf-8"));
2345
- pkg.name = projectName;
2346
- pkg.scripts = {
2278
+ const pkg2 = JSON.parse(fs3.readFileSync(path3.join(chatSourceDir, "package.json"), "utf-8"));
2279
+ pkg2.name = projectName;
2280
+ pkg2.scripts = {
2347
2281
  dev: "next dev",
2348
2282
  build: "next build",
2349
2283
  start: "next start"
2350
2284
  };
2351
- delete pkg.private;
2352
- if (pkg.dependencies?.["@standardagents/react"]) {
2353
- pkg.dependencies["@standardagents/react"] = reactVersion;
2354
- }
2355
- delete pkg.devDependencies?.["@tailwindcss/vite"];
2356
- delete pkg.devDependencies?.["@vitejs/plugin-react"];
2357
- delete pkg.devDependencies?.["vite"];
2358
- fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg, null, 2) + "\n", "utf-8");
2285
+ delete pkg2.private;
2286
+ if (pkg2.dependencies?.["@standardagents/react"]) {
2287
+ pkg2.dependencies["@standardagents/react"] = reactVersion;
2288
+ }
2289
+ delete pkg2.devDependencies?.["@tailwindcss/vite"];
2290
+ delete pkg2.devDependencies?.["@vitejs/plugin-react"];
2291
+ delete pkg2.devDependencies?.["vite"];
2292
+ fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
2359
2293
  logger.success("Created package.json");
2360
2294
  const envContent = `# Agentbuilder connection
2361
2295
  NEXT_PUBLIC_AGENTBUILDER_URL=${serverUrl}
@@ -2377,8 +2311,10 @@ out
2377
2311
  }
2378
2312
 
2379
2313
  // src/index.ts
2314
+ var __dirname$1 = dirname(fileURLToPath(import.meta.url));
2315
+ var pkg = JSON.parse(readFileSync(resolve(__dirname$1, "../package.json"), "utf-8"));
2380
2316
  var program = new Command();
2381
- program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version("0.11.11");
2317
+ program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version(pkg.version);
2382
2318
  program.command("init [project-name]").description("Create a new Standard Agents project (runs create vite, then scaffold)").option("-y, --yes", "Skip prompts and use defaults").option("--template <template>", "Vite template to use", "vanilla-ts").action(init);
2383
2319
  program.command("scaffold").description("Add Standard Agents to an existing Vite project").option("--force", "Overwrite existing configuration").action(scaffold);
2384
2320
  program.command("init-chat [project-name]").description("Scaffold a frontend chat application").option("-y, --yes", "Skip prompts and use defaults").option("--framework <framework>", "Framework to use (vite or nextjs)").action(initChat);