struere 0.3.5 → 0.3.7
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/bin/struere.js
CHANGED
|
@@ -17480,6 +17480,332 @@ function getEnvLocal(deploymentUrl) {
|
|
|
17480
17480
|
return `STRUERE_DEPLOYMENT_URL=${deploymentUrl}
|
|
17481
17481
|
`;
|
|
17482
17482
|
}
|
|
17483
|
+
function getClaudeMd(name) {
|
|
17484
|
+
const displayName = name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
17485
|
+
return `# ${displayName} Agent
|
|
17486
|
+
|
|
17487
|
+
This is a Struere AI agent project. Struere is a framework for building production AI agents with built-in data management, event tracking, and job scheduling.
|
|
17488
|
+
|
|
17489
|
+
## Project Structure
|
|
17490
|
+
|
|
17491
|
+
\`\`\`
|
|
17492
|
+
src/
|
|
17493
|
+
\u251C\u2500\u2500 agent.ts # Agent definition (system prompt, model, tools)
|
|
17494
|
+
\u251C\u2500\u2500 context.ts # Dynamic context injection per request
|
|
17495
|
+
\u251C\u2500\u2500 tools.ts # Custom tool definitions
|
|
17496
|
+
\u2514\u2500\u2500 workflows/ # Multi-step workflow definitions
|
|
17497
|
+
tests/
|
|
17498
|
+
\u2514\u2500\u2500 *.test.yaml # YAML-based conversation tests
|
|
17499
|
+
struere.json # Project configuration (agentId, team, slug)
|
|
17500
|
+
struere.config.ts # Framework settings (port, CORS, logging)
|
|
17501
|
+
\`\`\`
|
|
17502
|
+
|
|
17503
|
+
## Agent Definition
|
|
17504
|
+
|
|
17505
|
+
Define your agent in \`src/agent.ts\`:
|
|
17506
|
+
|
|
17507
|
+
\`\`\`typescript
|
|
17508
|
+
import { defineAgent } from 'struere'
|
|
17509
|
+
import { tools } from './tools'
|
|
17510
|
+
import { context } from './context'
|
|
17511
|
+
|
|
17512
|
+
export default defineAgent({
|
|
17513
|
+
name: 'my-agent',
|
|
17514
|
+
version: '0.1.0',
|
|
17515
|
+
description: 'My AI Agent',
|
|
17516
|
+
model: {
|
|
17517
|
+
provider: 'anthropic',
|
|
17518
|
+
name: 'claude-sonnet-4-20250514',
|
|
17519
|
+
temperature: 0.7,
|
|
17520
|
+
maxTokens: 4096,
|
|
17521
|
+
},
|
|
17522
|
+
systemPrompt: \\\`You are a helpful assistant.
|
|
17523
|
+
|
|
17524
|
+
Current time: {{datetime}}
|
|
17525
|
+
Customer: {{entity.get({"id": "{{thread.metadata.customerId}}"})}}\\\`,
|
|
17526
|
+
tools,
|
|
17527
|
+
context,
|
|
17528
|
+
state: {
|
|
17529
|
+
storage: 'memory',
|
|
17530
|
+
ttl: 3600,
|
|
17531
|
+
},
|
|
17532
|
+
})
|
|
17533
|
+
\`\`\`
|
|
17534
|
+
|
|
17535
|
+
## System Prompt Templates
|
|
17536
|
+
|
|
17537
|
+
System prompts support dynamic \`{{...}}\` templates that are resolved at runtime before the LLM call.
|
|
17538
|
+
|
|
17539
|
+
### Available Variables
|
|
17540
|
+
|
|
17541
|
+
| Variable | Description |
|
|
17542
|
+
|----------|-------------|
|
|
17543
|
+
| \`{{organizationId}}\` | Current organization ID |
|
|
17544
|
+
| \`{{userId}}\` | Current user ID |
|
|
17545
|
+
| \`{{threadId}}\` | Conversation thread ID |
|
|
17546
|
+
| \`{{agentId}}\` | Agent ID |
|
|
17547
|
+
| \`{{agent.name}}\` | Agent name |
|
|
17548
|
+
| \`{{agent.slug}}\` | Agent slug |
|
|
17549
|
+
| \`{{thread.metadata.X}}\` | Thread metadata field X |
|
|
17550
|
+
| \`{{message}}\` | Current user message |
|
|
17551
|
+
| \`{{timestamp}}\` | Unix timestamp (ms) |
|
|
17552
|
+
| \`{{datetime}}\` | ISO 8601 datetime |
|
|
17553
|
+
|
|
17554
|
+
### Function Calls
|
|
17555
|
+
|
|
17556
|
+
Call any agent tool directly in the system prompt:
|
|
17557
|
+
|
|
17558
|
+
\`\`\`
|
|
17559
|
+
{{entity.get({"id": "ent_123"})}}
|
|
17560
|
+
{{entity.query({"type": "customer", "limit": 5})}}
|
|
17561
|
+
{{event.query({"entityId": "ent_123", "limit": 10})}}
|
|
17562
|
+
\`\`\`
|
|
17563
|
+
|
|
17564
|
+
### Nested Templates
|
|
17565
|
+
|
|
17566
|
+
Variables can be used inside function arguments:
|
|
17567
|
+
|
|
17568
|
+
\`\`\`
|
|
17569
|
+
{{entity.get({"id": "{{thread.metadata.customerId}}"})}}
|
|
17570
|
+
\`\`\`
|
|
17571
|
+
|
|
17572
|
+
### Error Handling
|
|
17573
|
+
|
|
17574
|
+
Failed templates are replaced with inline errors:
|
|
17575
|
+
\`\`\`
|
|
17576
|
+
[TEMPLATE_ERROR: variableName not found]
|
|
17577
|
+
[TEMPLATE_ERROR: toolName - error message]
|
|
17578
|
+
\`\`\`
|
|
17579
|
+
|
|
17580
|
+
## Custom Tools
|
|
17581
|
+
|
|
17582
|
+
Define tools in \`src/tools.ts\`:
|
|
17583
|
+
|
|
17584
|
+
\`\`\`typescript
|
|
17585
|
+
import { defineTools } from 'struere'
|
|
17586
|
+
|
|
17587
|
+
export const tools = defineTools([
|
|
17588
|
+
{
|
|
17589
|
+
name: 'search_products',
|
|
17590
|
+
description: 'Search the product catalog',
|
|
17591
|
+
parameters: {
|
|
17592
|
+
type: 'object',
|
|
17593
|
+
properties: {
|
|
17594
|
+
query: { type: 'string', description: 'Search query' },
|
|
17595
|
+
limit: { type: 'number', description: 'Max results' },
|
|
17596
|
+
},
|
|
17597
|
+
required: ['query'],
|
|
17598
|
+
},
|
|
17599
|
+
handler: async (params) => {
|
|
17600
|
+
const results = await searchProducts(params.query, params.limit ?? 10)
|
|
17601
|
+
return { products: results }
|
|
17602
|
+
},
|
|
17603
|
+
},
|
|
17604
|
+
])
|
|
17605
|
+
\`\`\`
|
|
17606
|
+
|
|
17607
|
+
Custom tool handlers are executed in a sandboxed Cloudflare Worker environment. They can make HTTP requests to allowlisted domains:
|
|
17608
|
+
- api.openai.com, api.anthropic.com, api.stripe.com
|
|
17609
|
+
- api.sendgrid.com, api.twilio.com, hooks.slack.com
|
|
17610
|
+
- discord.com, api.github.com
|
|
17611
|
+
|
|
17612
|
+
## Built-in Tools
|
|
17613
|
+
|
|
17614
|
+
Agents have access to these built-in tools for data management:
|
|
17615
|
+
|
|
17616
|
+
### Entity Tools
|
|
17617
|
+
|
|
17618
|
+
| Tool | Description |
|
|
17619
|
+
|------|-------------|
|
|
17620
|
+
| \`entity.create\` | Create a new entity |
|
|
17621
|
+
| \`entity.get\` | Get entity by ID |
|
|
17622
|
+
| \`entity.query\` | Query entities by type/filters |
|
|
17623
|
+
| \`entity.update\` | Update entity data |
|
|
17624
|
+
| \`entity.delete\` | Soft-delete entity |
|
|
17625
|
+
| \`entity.link\` | Create entity relation |
|
|
17626
|
+
| \`entity.unlink\` | Remove entity relation |
|
|
17627
|
+
|
|
17628
|
+
Example entity operations:
|
|
17629
|
+
\`\`\`json
|
|
17630
|
+
// entity.create
|
|
17631
|
+
{ "type": "customer", "data": { "name": "John", "email": "john@example.com" } }
|
|
17632
|
+
|
|
17633
|
+
// entity.query
|
|
17634
|
+
{ "type": "customer", "filters": { "status": "active" }, "limit": 10 }
|
|
17635
|
+
|
|
17636
|
+
// entity.update
|
|
17637
|
+
{ "id": "ent_123", "data": { "status": "vip" } }
|
|
17638
|
+
\`\`\`
|
|
17639
|
+
|
|
17640
|
+
### Event Tools
|
|
17641
|
+
|
|
17642
|
+
| Tool | Description |
|
|
17643
|
+
|------|-------------|
|
|
17644
|
+
| \`event.emit\` | Emit a custom event |
|
|
17645
|
+
| \`event.query\` | Query event history |
|
|
17646
|
+
|
|
17647
|
+
Example event operations:
|
|
17648
|
+
\`\`\`json
|
|
17649
|
+
// event.emit
|
|
17650
|
+
{ "entityId": "ent_123", "eventType": "order.placed", "payload": { "amount": 99.99 } }
|
|
17651
|
+
|
|
17652
|
+
// event.query
|
|
17653
|
+
{ "entityId": "ent_123", "eventType": "order.*", "limit": 20 }
|
|
17654
|
+
\`\`\`
|
|
17655
|
+
|
|
17656
|
+
### Job Tools
|
|
17657
|
+
|
|
17658
|
+
| Tool | Description |
|
|
17659
|
+
|------|-------------|
|
|
17660
|
+
| \`job.enqueue\` | Schedule a background job |
|
|
17661
|
+
| \`job.status\` | Get job status |
|
|
17662
|
+
|
|
17663
|
+
Example job operations:
|
|
17664
|
+
\`\`\`json
|
|
17665
|
+
// job.enqueue
|
|
17666
|
+
{ "jobType": "send_email", "payload": { "to": "user@example.com" }, "scheduledFor": 1706745600000 }
|
|
17667
|
+
|
|
17668
|
+
// job.status
|
|
17669
|
+
{ "id": "job_abc123" }
|
|
17670
|
+
\`\`\`
|
|
17671
|
+
|
|
17672
|
+
## Context Function
|
|
17673
|
+
|
|
17674
|
+
Inject dynamic context per request in \`src/context.ts\`:
|
|
17675
|
+
|
|
17676
|
+
\`\`\`typescript
|
|
17677
|
+
import { defineContext } from 'struere'
|
|
17678
|
+
|
|
17679
|
+
export const context = defineContext(async (request) => {
|
|
17680
|
+
const { conversationId, userId, channel, state } = request
|
|
17681
|
+
|
|
17682
|
+
const userProfile = await fetchUserProfile(userId)
|
|
17683
|
+
|
|
17684
|
+
return {
|
|
17685
|
+
additionalContext: \\\`
|
|
17686
|
+
User: \${userProfile.name} (\${userProfile.tier} tier)
|
|
17687
|
+
Conversation: \${conversationId}
|
|
17688
|
+
Channel: \${channel}
|
|
17689
|
+
\\\`,
|
|
17690
|
+
variables: {
|
|
17691
|
+
userId,
|
|
17692
|
+
userTier: userProfile.tier,
|
|
17693
|
+
timestamp: new Date().toISOString(),
|
|
17694
|
+
},
|
|
17695
|
+
}
|
|
17696
|
+
})
|
|
17697
|
+
\`\`\`
|
|
17698
|
+
|
|
17699
|
+
## Testing
|
|
17700
|
+
|
|
17701
|
+
Write YAML-based conversation tests in \`tests/\`:
|
|
17702
|
+
|
|
17703
|
+
\`\`\`yaml
|
|
17704
|
+
name: Order flow test
|
|
17705
|
+
description: Test the complete order flow
|
|
17706
|
+
|
|
17707
|
+
conversation:
|
|
17708
|
+
- role: user
|
|
17709
|
+
content: I want to order a pizza
|
|
17710
|
+
- role: assistant
|
|
17711
|
+
assertions:
|
|
17712
|
+
- type: contains
|
|
17713
|
+
value: size
|
|
17714
|
+
- type: toolCalled
|
|
17715
|
+
value: get_menu
|
|
17716
|
+
|
|
17717
|
+
- role: user
|
|
17718
|
+
content: Large pepperoni please
|
|
17719
|
+
- role: assistant
|
|
17720
|
+
assertions:
|
|
17721
|
+
- type: toolCalled
|
|
17722
|
+
value: entity.create
|
|
17723
|
+
\`\`\`
|
|
17724
|
+
|
|
17725
|
+
### Assertion Types
|
|
17726
|
+
|
|
17727
|
+
| Type | Description |
|
|
17728
|
+
|------|-------------|
|
|
17729
|
+
| \`contains\` | Response contains substring |
|
|
17730
|
+
| \`matches\` | Response matches regex |
|
|
17731
|
+
| \`toolCalled\` | Specific tool was called |
|
|
17732
|
+
| \`noToolCalled\` | No tools were called |
|
|
17733
|
+
|
|
17734
|
+
Run tests with:
|
|
17735
|
+
\`\`\`bash
|
|
17736
|
+
bun run test
|
|
17737
|
+
\`\`\`
|
|
17738
|
+
|
|
17739
|
+
## CLI Commands
|
|
17740
|
+
|
|
17741
|
+
| Command | Description |
|
|
17742
|
+
|---------|-------------|
|
|
17743
|
+
| \`struere dev\` | Start development mode (live sync to Convex) |
|
|
17744
|
+
| \`struere build\` | Validate agent configuration |
|
|
17745
|
+
| \`struere deploy\` | Deploy agent to production |
|
|
17746
|
+
| \`struere test\` | Run YAML conversation tests |
|
|
17747
|
+
| \`struere logs\` | View recent execution logs |
|
|
17748
|
+
| \`struere state\` | Inspect conversation thread state |
|
|
17749
|
+
|
|
17750
|
+
## Thread Metadata
|
|
17751
|
+
|
|
17752
|
+
Set thread metadata when creating conversations to provide context:
|
|
17753
|
+
|
|
17754
|
+
\`\`\`typescript
|
|
17755
|
+
// Via API
|
|
17756
|
+
POST /v1/chat
|
|
17757
|
+
{
|
|
17758
|
+
"agentId": "agent_123",
|
|
17759
|
+
"message": "Hello",
|
|
17760
|
+
"metadata": {
|
|
17761
|
+
"customerId": "ent_customer_456",
|
|
17762
|
+
"channel": "web",
|
|
17763
|
+
"language": "en"
|
|
17764
|
+
}
|
|
17765
|
+
}
|
|
17766
|
+
\`\`\`
|
|
17767
|
+
|
|
17768
|
+
Access in system prompt:
|
|
17769
|
+
\`\`\`
|
|
17770
|
+
Customer: {{entity.get({"id": "{{thread.metadata.customerId}}"})}}
|
|
17771
|
+
Channel: {{thread.metadata.channel}}
|
|
17772
|
+
\`\`\`
|
|
17773
|
+
|
|
17774
|
+
## Development Workflow
|
|
17775
|
+
|
|
17776
|
+
1. **Edit agent configuration** in \`src/agent.ts\`
|
|
17777
|
+
2. **Run \`bun run dev\`** to sync changes to Convex
|
|
17778
|
+
3. **Test via API** or dashboard chat interface
|
|
17779
|
+
4. **Write tests** in \`tests/*.test.yaml\`
|
|
17780
|
+
5. **Deploy** with \`bun run deploy\`
|
|
17781
|
+
|
|
17782
|
+
## API Endpoints
|
|
17783
|
+
|
|
17784
|
+
| Endpoint | Method | Description |
|
|
17785
|
+
|----------|--------|-------------|
|
|
17786
|
+
| \`/v1/chat\` | POST | Chat by agent ID |
|
|
17787
|
+
| \`/v1/agents/:slug/chat\` | POST | Chat by agent slug |
|
|
17788
|
+
|
|
17789
|
+
Authentication: Bearer token (API key from dashboard)
|
|
17790
|
+
|
|
17791
|
+
\`\`\`bash
|
|
17792
|
+
curl -X POST https://your-deployment.convex.cloud/v1/chat \\
|
|
17793
|
+
-H "Authorization: Bearer sk_live_..." \\
|
|
17794
|
+
-H "Content-Type: application/json" \\
|
|
17795
|
+
-d '{"agentId": "...", "message": "Hello"}'
|
|
17796
|
+
\`\`\`
|
|
17797
|
+
|
|
17798
|
+
## Best Practices
|
|
17799
|
+
|
|
17800
|
+
1. **System Prompts**: Use templates for dynamic data instead of hardcoding
|
|
17801
|
+
2. **Tools**: Keep tool handlers focused and stateless
|
|
17802
|
+
3. **Entities**: Model your domain data as entity types
|
|
17803
|
+
4. **Events**: Emit events for audit trails and analytics
|
|
17804
|
+
5. **Jobs**: Use jobs for async operations (emails, notifications)
|
|
17805
|
+
6. **Testing**: Write tests for critical conversation flows
|
|
17806
|
+
7. **Context**: Use context for user-specific personalization
|
|
17807
|
+
`;
|
|
17808
|
+
}
|
|
17483
17809
|
|
|
17484
17810
|
// src/cli/utils/scaffold.ts
|
|
17485
17811
|
function ensureDir(filePath) {
|
|
@@ -17519,7 +17845,8 @@ function scaffoldAgentFiles(cwd, projectName) {
|
|
|
17519
17845
|
"src/tools.ts": getToolsTs(),
|
|
17520
17846
|
"src/workflows/.gitkeep": "",
|
|
17521
17847
|
"tests/basic.test.yaml": getBasicTestYaml(),
|
|
17522
|
-
".env.example": getEnvExample()
|
|
17848
|
+
".env.example": getEnvExample(),
|
|
17849
|
+
".claude.md": getClaudeMd(projectName)
|
|
17523
17850
|
};
|
|
17524
17851
|
for (const [relativePath, content] of Object.entries(files)) {
|
|
17525
17852
|
const fullPath = join3(cwd, relativePath);
|
|
@@ -17627,12 +17954,12 @@ var initCommand = new Command("init").description("Initialize a new Struere proj
|
|
|
17627
17954
|
}
|
|
17628
17955
|
}
|
|
17629
17956
|
if (!selectedAgent) {
|
|
17630
|
-
const
|
|
17957
|
+
const displayName2 = projectName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
17631
17958
|
spinner.start("Creating agent");
|
|
17632
17959
|
const { agentId, error: createError } = await createAgent({
|
|
17633
|
-
name:
|
|
17960
|
+
name: displayName2,
|
|
17634
17961
|
slug: projectName,
|
|
17635
|
-
description: `${
|
|
17962
|
+
description: `${displayName2} Agent`
|
|
17636
17963
|
});
|
|
17637
17964
|
if (createError || !agentId) {
|
|
17638
17965
|
spinner.fail("Failed to create agent");
|
|
@@ -17640,7 +17967,7 @@ var initCommand = new Command("init").description("Initialize a new Struere proj
|
|
|
17640
17967
|
console.log(source_default.red("Error:"), createError || "Unknown error");
|
|
17641
17968
|
process.exit(1);
|
|
17642
17969
|
}
|
|
17643
|
-
selectedAgent = { id: agentId, name:
|
|
17970
|
+
selectedAgent = { id: agentId, name: displayName2, slug: projectName };
|
|
17644
17971
|
deploymentUrl = `https://${projectName}-dev.struere.dev`;
|
|
17645
17972
|
spinner.succeed(`Created agent "${projectName}"`);
|
|
17646
17973
|
} else {
|
|
@@ -17691,10 +18018,43 @@ var initCommand = new Command("init").description("Initialize a new Struere proj
|
|
|
17691
18018
|
}
|
|
17692
18019
|
}
|
|
17693
18020
|
console.log();
|
|
18021
|
+
spinner.start("Installing dependencies");
|
|
18022
|
+
const installResult = Bun.spawnSync(["bun", "install"], {
|
|
18023
|
+
cwd,
|
|
18024
|
+
stdout: "pipe",
|
|
18025
|
+
stderr: "pipe"
|
|
18026
|
+
});
|
|
18027
|
+
if (installResult.exitCode === 0) {
|
|
18028
|
+
spinner.succeed("Dependencies installed");
|
|
18029
|
+
} else {
|
|
18030
|
+
spinner.warn("Could not install dependencies automatically");
|
|
18031
|
+
console.log(source_default.gray(" Run"), source_default.cyan("bun install"), source_default.gray("manually"));
|
|
18032
|
+
}
|
|
18033
|
+
spinner.start("Syncing initial config to Convex");
|
|
18034
|
+
const displayName = projectName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
18035
|
+
const defaultConfig = {
|
|
18036
|
+
name: displayName,
|
|
18037
|
+
version: "0.1.0",
|
|
18038
|
+
systemPrompt: `You are ${displayName}, a helpful AI assistant. You help users with their questions and tasks.`,
|
|
18039
|
+
model: {
|
|
18040
|
+
provider: "anthropic",
|
|
18041
|
+
name: "claude-sonnet-4-20250514",
|
|
18042
|
+
temperature: 0.7,
|
|
18043
|
+
maxTokens: 4096
|
|
18044
|
+
},
|
|
18045
|
+
tools: []
|
|
18046
|
+
};
|
|
18047
|
+
const syncResult = await syncToConvex(selectedAgent.id, defaultConfig);
|
|
18048
|
+
if (syncResult.success) {
|
|
18049
|
+
spinner.succeed("Initial config synced");
|
|
18050
|
+
} else {
|
|
18051
|
+
spinner.warn("Could not sync initial config");
|
|
18052
|
+
console.log(source_default.gray(" Run"), source_default.cyan("struere dev"), source_default.gray("to sync manually"));
|
|
18053
|
+
}
|
|
18054
|
+
console.log();
|
|
17694
18055
|
console.log(source_default.green("Success!"), "Project initialized");
|
|
17695
18056
|
console.log();
|
|
17696
18057
|
console.log(source_default.gray("Next steps:"));
|
|
17697
|
-
console.log(source_default.gray(" $"), source_default.cyan("bun install"));
|
|
17698
18058
|
console.log(source_default.gray(" $"), source_default.cyan("struere dev"));
|
|
17699
18059
|
console.log();
|
|
17700
18060
|
});
|
|
@@ -18735,9 +19095,17 @@ var whoamiCommand = new Command("whoami").description("Show current logged in us
|
|
|
18735
19095
|
// package.json
|
|
18736
19096
|
var package_default = {
|
|
18737
19097
|
name: "struere",
|
|
18738
|
-
version: "0.3.
|
|
19098
|
+
version: "0.3.7",
|
|
18739
19099
|
description: "Build, test, and deploy AI agents",
|
|
18740
|
-
keywords: [
|
|
19100
|
+
keywords: [
|
|
19101
|
+
"ai",
|
|
19102
|
+
"agents",
|
|
19103
|
+
"llm",
|
|
19104
|
+
"anthropic",
|
|
19105
|
+
"openai",
|
|
19106
|
+
"framework",
|
|
19107
|
+
"cli"
|
|
19108
|
+
],
|
|
18741
19109
|
author: "struere",
|
|
18742
19110
|
license: "MIT",
|
|
18743
19111
|
publishConfig: {
|
|
@@ -18764,7 +19132,9 @@ var package_default = {
|
|
|
18764
19132
|
types: "./dist/index.d.ts"
|
|
18765
19133
|
}
|
|
18766
19134
|
},
|
|
18767
|
-
files: [
|
|
19135
|
+
files: [
|
|
19136
|
+
"dist"
|
|
19137
|
+
],
|
|
18768
19138
|
scripts: {
|
|
18769
19139
|
build: "bun build ./src/cli/index.ts --outdir ./dist/cli --target bun --external commander --external chalk --external ora --external chokidar --external yaml && bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/bin/struere.ts --outdir ./dist/bin --target bun && tsc --emitDeclarationOnly && chmod +x ./dist/bin/struere.js",
|
|
18770
19140
|
dev: "tsc --watch",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC,eAAO,MAAM,WAAW,SA4NpB,CAAA;AAEJ,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C"}
|
package/dist/cli/index.js
CHANGED
|
@@ -819,6 +819,332 @@ function getEnvLocal(deploymentUrl) {
|
|
|
819
819
|
return `STRUERE_DEPLOYMENT_URL=${deploymentUrl}
|
|
820
820
|
`;
|
|
821
821
|
}
|
|
822
|
+
function getClaudeMd(name) {
|
|
823
|
+
const displayName = name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
824
|
+
return `# ${displayName} Agent
|
|
825
|
+
|
|
826
|
+
This is a Struere AI agent project. Struere is a framework for building production AI agents with built-in data management, event tracking, and job scheduling.
|
|
827
|
+
|
|
828
|
+
## Project Structure
|
|
829
|
+
|
|
830
|
+
\`\`\`
|
|
831
|
+
src/
|
|
832
|
+
\u251C\u2500\u2500 agent.ts # Agent definition (system prompt, model, tools)
|
|
833
|
+
\u251C\u2500\u2500 context.ts # Dynamic context injection per request
|
|
834
|
+
\u251C\u2500\u2500 tools.ts # Custom tool definitions
|
|
835
|
+
\u2514\u2500\u2500 workflows/ # Multi-step workflow definitions
|
|
836
|
+
tests/
|
|
837
|
+
\u2514\u2500\u2500 *.test.yaml # YAML-based conversation tests
|
|
838
|
+
struere.json # Project configuration (agentId, team, slug)
|
|
839
|
+
struere.config.ts # Framework settings (port, CORS, logging)
|
|
840
|
+
\`\`\`
|
|
841
|
+
|
|
842
|
+
## Agent Definition
|
|
843
|
+
|
|
844
|
+
Define your agent in \`src/agent.ts\`:
|
|
845
|
+
|
|
846
|
+
\`\`\`typescript
|
|
847
|
+
import { defineAgent } from 'struere'
|
|
848
|
+
import { tools } from './tools'
|
|
849
|
+
import { context } from './context'
|
|
850
|
+
|
|
851
|
+
export default defineAgent({
|
|
852
|
+
name: 'my-agent',
|
|
853
|
+
version: '0.1.0',
|
|
854
|
+
description: 'My AI Agent',
|
|
855
|
+
model: {
|
|
856
|
+
provider: 'anthropic',
|
|
857
|
+
name: 'claude-sonnet-4-20250514',
|
|
858
|
+
temperature: 0.7,
|
|
859
|
+
maxTokens: 4096,
|
|
860
|
+
},
|
|
861
|
+
systemPrompt: \\\`You are a helpful assistant.
|
|
862
|
+
|
|
863
|
+
Current time: {{datetime}}
|
|
864
|
+
Customer: {{entity.get({"id": "{{thread.metadata.customerId}}"})}}\\\`,
|
|
865
|
+
tools,
|
|
866
|
+
context,
|
|
867
|
+
state: {
|
|
868
|
+
storage: 'memory',
|
|
869
|
+
ttl: 3600,
|
|
870
|
+
},
|
|
871
|
+
})
|
|
872
|
+
\`\`\`
|
|
873
|
+
|
|
874
|
+
## System Prompt Templates
|
|
875
|
+
|
|
876
|
+
System prompts support dynamic \`{{...}}\` templates that are resolved at runtime before the LLM call.
|
|
877
|
+
|
|
878
|
+
### Available Variables
|
|
879
|
+
|
|
880
|
+
| Variable | Description |
|
|
881
|
+
|----------|-------------|
|
|
882
|
+
| \`{{organizationId}}\` | Current organization ID |
|
|
883
|
+
| \`{{userId}}\` | Current user ID |
|
|
884
|
+
| \`{{threadId}}\` | Conversation thread ID |
|
|
885
|
+
| \`{{agentId}}\` | Agent ID |
|
|
886
|
+
| \`{{agent.name}}\` | Agent name |
|
|
887
|
+
| \`{{agent.slug}}\` | Agent slug |
|
|
888
|
+
| \`{{thread.metadata.X}}\` | Thread metadata field X |
|
|
889
|
+
| \`{{message}}\` | Current user message |
|
|
890
|
+
| \`{{timestamp}}\` | Unix timestamp (ms) |
|
|
891
|
+
| \`{{datetime}}\` | ISO 8601 datetime |
|
|
892
|
+
|
|
893
|
+
### Function Calls
|
|
894
|
+
|
|
895
|
+
Call any agent tool directly in the system prompt:
|
|
896
|
+
|
|
897
|
+
\`\`\`
|
|
898
|
+
{{entity.get({"id": "ent_123"})}}
|
|
899
|
+
{{entity.query({"type": "customer", "limit": 5})}}
|
|
900
|
+
{{event.query({"entityId": "ent_123", "limit": 10})}}
|
|
901
|
+
\`\`\`
|
|
902
|
+
|
|
903
|
+
### Nested Templates
|
|
904
|
+
|
|
905
|
+
Variables can be used inside function arguments:
|
|
906
|
+
|
|
907
|
+
\`\`\`
|
|
908
|
+
{{entity.get({"id": "{{thread.metadata.customerId}}"})}}
|
|
909
|
+
\`\`\`
|
|
910
|
+
|
|
911
|
+
### Error Handling
|
|
912
|
+
|
|
913
|
+
Failed templates are replaced with inline errors:
|
|
914
|
+
\`\`\`
|
|
915
|
+
[TEMPLATE_ERROR: variableName not found]
|
|
916
|
+
[TEMPLATE_ERROR: toolName - error message]
|
|
917
|
+
\`\`\`
|
|
918
|
+
|
|
919
|
+
## Custom Tools
|
|
920
|
+
|
|
921
|
+
Define tools in \`src/tools.ts\`:
|
|
922
|
+
|
|
923
|
+
\`\`\`typescript
|
|
924
|
+
import { defineTools } from 'struere'
|
|
925
|
+
|
|
926
|
+
export const tools = defineTools([
|
|
927
|
+
{
|
|
928
|
+
name: 'search_products',
|
|
929
|
+
description: 'Search the product catalog',
|
|
930
|
+
parameters: {
|
|
931
|
+
type: 'object',
|
|
932
|
+
properties: {
|
|
933
|
+
query: { type: 'string', description: 'Search query' },
|
|
934
|
+
limit: { type: 'number', description: 'Max results' },
|
|
935
|
+
},
|
|
936
|
+
required: ['query'],
|
|
937
|
+
},
|
|
938
|
+
handler: async (params) => {
|
|
939
|
+
const results = await searchProducts(params.query, params.limit ?? 10)
|
|
940
|
+
return { products: results }
|
|
941
|
+
},
|
|
942
|
+
},
|
|
943
|
+
])
|
|
944
|
+
\`\`\`
|
|
945
|
+
|
|
946
|
+
Custom tool handlers are executed in a sandboxed Cloudflare Worker environment. They can make HTTP requests to allowlisted domains:
|
|
947
|
+
- api.openai.com, api.anthropic.com, api.stripe.com
|
|
948
|
+
- api.sendgrid.com, api.twilio.com, hooks.slack.com
|
|
949
|
+
- discord.com, api.github.com
|
|
950
|
+
|
|
951
|
+
## Built-in Tools
|
|
952
|
+
|
|
953
|
+
Agents have access to these built-in tools for data management:
|
|
954
|
+
|
|
955
|
+
### Entity Tools
|
|
956
|
+
|
|
957
|
+
| Tool | Description |
|
|
958
|
+
|------|-------------|
|
|
959
|
+
| \`entity.create\` | Create a new entity |
|
|
960
|
+
| \`entity.get\` | Get entity by ID |
|
|
961
|
+
| \`entity.query\` | Query entities by type/filters |
|
|
962
|
+
| \`entity.update\` | Update entity data |
|
|
963
|
+
| \`entity.delete\` | Soft-delete entity |
|
|
964
|
+
| \`entity.link\` | Create entity relation |
|
|
965
|
+
| \`entity.unlink\` | Remove entity relation |
|
|
966
|
+
|
|
967
|
+
Example entity operations:
|
|
968
|
+
\`\`\`json
|
|
969
|
+
// entity.create
|
|
970
|
+
{ "type": "customer", "data": { "name": "John", "email": "john@example.com" } }
|
|
971
|
+
|
|
972
|
+
// entity.query
|
|
973
|
+
{ "type": "customer", "filters": { "status": "active" }, "limit": 10 }
|
|
974
|
+
|
|
975
|
+
// entity.update
|
|
976
|
+
{ "id": "ent_123", "data": { "status": "vip" } }
|
|
977
|
+
\`\`\`
|
|
978
|
+
|
|
979
|
+
### Event Tools
|
|
980
|
+
|
|
981
|
+
| Tool | Description |
|
|
982
|
+
|------|-------------|
|
|
983
|
+
| \`event.emit\` | Emit a custom event |
|
|
984
|
+
| \`event.query\` | Query event history |
|
|
985
|
+
|
|
986
|
+
Example event operations:
|
|
987
|
+
\`\`\`json
|
|
988
|
+
// event.emit
|
|
989
|
+
{ "entityId": "ent_123", "eventType": "order.placed", "payload": { "amount": 99.99 } }
|
|
990
|
+
|
|
991
|
+
// event.query
|
|
992
|
+
{ "entityId": "ent_123", "eventType": "order.*", "limit": 20 }
|
|
993
|
+
\`\`\`
|
|
994
|
+
|
|
995
|
+
### Job Tools
|
|
996
|
+
|
|
997
|
+
| Tool | Description |
|
|
998
|
+
|------|-------------|
|
|
999
|
+
| \`job.enqueue\` | Schedule a background job |
|
|
1000
|
+
| \`job.status\` | Get job status |
|
|
1001
|
+
|
|
1002
|
+
Example job operations:
|
|
1003
|
+
\`\`\`json
|
|
1004
|
+
// job.enqueue
|
|
1005
|
+
{ "jobType": "send_email", "payload": { "to": "user@example.com" }, "scheduledFor": 1706745600000 }
|
|
1006
|
+
|
|
1007
|
+
// job.status
|
|
1008
|
+
{ "id": "job_abc123" }
|
|
1009
|
+
\`\`\`
|
|
1010
|
+
|
|
1011
|
+
## Context Function
|
|
1012
|
+
|
|
1013
|
+
Inject dynamic context per request in \`src/context.ts\`:
|
|
1014
|
+
|
|
1015
|
+
\`\`\`typescript
|
|
1016
|
+
import { defineContext } from 'struere'
|
|
1017
|
+
|
|
1018
|
+
export const context = defineContext(async (request) => {
|
|
1019
|
+
const { conversationId, userId, channel, state } = request
|
|
1020
|
+
|
|
1021
|
+
const userProfile = await fetchUserProfile(userId)
|
|
1022
|
+
|
|
1023
|
+
return {
|
|
1024
|
+
additionalContext: \\\`
|
|
1025
|
+
User: \${userProfile.name} (\${userProfile.tier} tier)
|
|
1026
|
+
Conversation: \${conversationId}
|
|
1027
|
+
Channel: \${channel}
|
|
1028
|
+
\\\`,
|
|
1029
|
+
variables: {
|
|
1030
|
+
userId,
|
|
1031
|
+
userTier: userProfile.tier,
|
|
1032
|
+
timestamp: new Date().toISOString(),
|
|
1033
|
+
},
|
|
1034
|
+
}
|
|
1035
|
+
})
|
|
1036
|
+
\`\`\`
|
|
1037
|
+
|
|
1038
|
+
## Testing
|
|
1039
|
+
|
|
1040
|
+
Write YAML-based conversation tests in \`tests/\`:
|
|
1041
|
+
|
|
1042
|
+
\`\`\`yaml
|
|
1043
|
+
name: Order flow test
|
|
1044
|
+
description: Test the complete order flow
|
|
1045
|
+
|
|
1046
|
+
conversation:
|
|
1047
|
+
- role: user
|
|
1048
|
+
content: I want to order a pizza
|
|
1049
|
+
- role: assistant
|
|
1050
|
+
assertions:
|
|
1051
|
+
- type: contains
|
|
1052
|
+
value: size
|
|
1053
|
+
- type: toolCalled
|
|
1054
|
+
value: get_menu
|
|
1055
|
+
|
|
1056
|
+
- role: user
|
|
1057
|
+
content: Large pepperoni please
|
|
1058
|
+
- role: assistant
|
|
1059
|
+
assertions:
|
|
1060
|
+
- type: toolCalled
|
|
1061
|
+
value: entity.create
|
|
1062
|
+
\`\`\`
|
|
1063
|
+
|
|
1064
|
+
### Assertion Types
|
|
1065
|
+
|
|
1066
|
+
| Type | Description |
|
|
1067
|
+
|------|-------------|
|
|
1068
|
+
| \`contains\` | Response contains substring |
|
|
1069
|
+
| \`matches\` | Response matches regex |
|
|
1070
|
+
| \`toolCalled\` | Specific tool was called |
|
|
1071
|
+
| \`noToolCalled\` | No tools were called |
|
|
1072
|
+
|
|
1073
|
+
Run tests with:
|
|
1074
|
+
\`\`\`bash
|
|
1075
|
+
bun run test
|
|
1076
|
+
\`\`\`
|
|
1077
|
+
|
|
1078
|
+
## CLI Commands
|
|
1079
|
+
|
|
1080
|
+
| Command | Description |
|
|
1081
|
+
|---------|-------------|
|
|
1082
|
+
| \`struere dev\` | Start development mode (live sync to Convex) |
|
|
1083
|
+
| \`struere build\` | Validate agent configuration |
|
|
1084
|
+
| \`struere deploy\` | Deploy agent to production |
|
|
1085
|
+
| \`struere test\` | Run YAML conversation tests |
|
|
1086
|
+
| \`struere logs\` | View recent execution logs |
|
|
1087
|
+
| \`struere state\` | Inspect conversation thread state |
|
|
1088
|
+
|
|
1089
|
+
## Thread Metadata
|
|
1090
|
+
|
|
1091
|
+
Set thread metadata when creating conversations to provide context:
|
|
1092
|
+
|
|
1093
|
+
\`\`\`typescript
|
|
1094
|
+
// Via API
|
|
1095
|
+
POST /v1/chat
|
|
1096
|
+
{
|
|
1097
|
+
"agentId": "agent_123",
|
|
1098
|
+
"message": "Hello",
|
|
1099
|
+
"metadata": {
|
|
1100
|
+
"customerId": "ent_customer_456",
|
|
1101
|
+
"channel": "web",
|
|
1102
|
+
"language": "en"
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
\`\`\`
|
|
1106
|
+
|
|
1107
|
+
Access in system prompt:
|
|
1108
|
+
\`\`\`
|
|
1109
|
+
Customer: {{entity.get({"id": "{{thread.metadata.customerId}}"})}}
|
|
1110
|
+
Channel: {{thread.metadata.channel}}
|
|
1111
|
+
\`\`\`
|
|
1112
|
+
|
|
1113
|
+
## Development Workflow
|
|
1114
|
+
|
|
1115
|
+
1. **Edit agent configuration** in \`src/agent.ts\`
|
|
1116
|
+
2. **Run \`bun run dev\`** to sync changes to Convex
|
|
1117
|
+
3. **Test via API** or dashboard chat interface
|
|
1118
|
+
4. **Write tests** in \`tests/*.test.yaml\`
|
|
1119
|
+
5. **Deploy** with \`bun run deploy\`
|
|
1120
|
+
|
|
1121
|
+
## API Endpoints
|
|
1122
|
+
|
|
1123
|
+
| Endpoint | Method | Description |
|
|
1124
|
+
|----------|--------|-------------|
|
|
1125
|
+
| \`/v1/chat\` | POST | Chat by agent ID |
|
|
1126
|
+
| \`/v1/agents/:slug/chat\` | POST | Chat by agent slug |
|
|
1127
|
+
|
|
1128
|
+
Authentication: Bearer token (API key from dashboard)
|
|
1129
|
+
|
|
1130
|
+
\`\`\`bash
|
|
1131
|
+
curl -X POST https://your-deployment.convex.cloud/v1/chat \\
|
|
1132
|
+
-H "Authorization: Bearer sk_live_..." \\
|
|
1133
|
+
-H "Content-Type: application/json" \\
|
|
1134
|
+
-d '{"agentId": "...", "message": "Hello"}'
|
|
1135
|
+
\`\`\`
|
|
1136
|
+
|
|
1137
|
+
## Best Practices
|
|
1138
|
+
|
|
1139
|
+
1. **System Prompts**: Use templates for dynamic data instead of hardcoding
|
|
1140
|
+
2. **Tools**: Keep tool handlers focused and stateless
|
|
1141
|
+
3. **Entities**: Model your domain data as entity types
|
|
1142
|
+
4. **Events**: Emit events for audit trails and analytics
|
|
1143
|
+
5. **Jobs**: Use jobs for async operations (emails, notifications)
|
|
1144
|
+
6. **Testing**: Write tests for critical conversation flows
|
|
1145
|
+
7. **Context**: Use context for user-specific personalization
|
|
1146
|
+
`;
|
|
1147
|
+
}
|
|
822
1148
|
|
|
823
1149
|
// src/cli/utils/scaffold.ts
|
|
824
1150
|
function ensureDir(filePath) {
|
|
@@ -858,7 +1184,8 @@ function scaffoldAgentFiles(cwd, projectName) {
|
|
|
858
1184
|
"src/tools.ts": getToolsTs(),
|
|
859
1185
|
"src/workflows/.gitkeep": "",
|
|
860
1186
|
"tests/basic.test.yaml": getBasicTestYaml(),
|
|
861
|
-
".env.example": getEnvExample()
|
|
1187
|
+
".env.example": getEnvExample(),
|
|
1188
|
+
".claude.md": getClaudeMd(projectName)
|
|
862
1189
|
};
|
|
863
1190
|
for (const [relativePath, content] of Object.entries(files)) {
|
|
864
1191
|
const fullPath = join3(cwd, relativePath);
|
|
@@ -966,12 +1293,12 @@ var initCommand = new Command2("init").description("Initialize a new Struere pro
|
|
|
966
1293
|
}
|
|
967
1294
|
}
|
|
968
1295
|
if (!selectedAgent) {
|
|
969
|
-
const
|
|
1296
|
+
const displayName2 = projectName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
970
1297
|
spinner.start("Creating agent");
|
|
971
1298
|
const { agentId, error: createError } = await createAgent({
|
|
972
|
-
name:
|
|
1299
|
+
name: displayName2,
|
|
973
1300
|
slug: projectName,
|
|
974
|
-
description: `${
|
|
1301
|
+
description: `${displayName2} Agent`
|
|
975
1302
|
});
|
|
976
1303
|
if (createError || !agentId) {
|
|
977
1304
|
spinner.fail("Failed to create agent");
|
|
@@ -979,7 +1306,7 @@ var initCommand = new Command2("init").description("Initialize a new Struere pro
|
|
|
979
1306
|
console.log(chalk2.red("Error:"), createError || "Unknown error");
|
|
980
1307
|
process.exit(1);
|
|
981
1308
|
}
|
|
982
|
-
selectedAgent = { id: agentId, name:
|
|
1309
|
+
selectedAgent = { id: agentId, name: displayName2, slug: projectName };
|
|
983
1310
|
deploymentUrl = `https://${projectName}-dev.struere.dev`;
|
|
984
1311
|
spinner.succeed(`Created agent "${projectName}"`);
|
|
985
1312
|
} else {
|
|
@@ -1030,10 +1357,43 @@ var initCommand = new Command2("init").description("Initialize a new Struere pro
|
|
|
1030
1357
|
}
|
|
1031
1358
|
}
|
|
1032
1359
|
console.log();
|
|
1360
|
+
spinner.start("Installing dependencies");
|
|
1361
|
+
const installResult = Bun.spawnSync(["bun", "install"], {
|
|
1362
|
+
cwd,
|
|
1363
|
+
stdout: "pipe",
|
|
1364
|
+
stderr: "pipe"
|
|
1365
|
+
});
|
|
1366
|
+
if (installResult.exitCode === 0) {
|
|
1367
|
+
spinner.succeed("Dependencies installed");
|
|
1368
|
+
} else {
|
|
1369
|
+
spinner.warn("Could not install dependencies automatically");
|
|
1370
|
+
console.log(chalk2.gray(" Run"), chalk2.cyan("bun install"), chalk2.gray("manually"));
|
|
1371
|
+
}
|
|
1372
|
+
spinner.start("Syncing initial config to Convex");
|
|
1373
|
+
const displayName = projectName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
1374
|
+
const defaultConfig = {
|
|
1375
|
+
name: displayName,
|
|
1376
|
+
version: "0.1.0",
|
|
1377
|
+
systemPrompt: `You are ${displayName}, a helpful AI assistant. You help users with their questions and tasks.`,
|
|
1378
|
+
model: {
|
|
1379
|
+
provider: "anthropic",
|
|
1380
|
+
name: "claude-sonnet-4-20250514",
|
|
1381
|
+
temperature: 0.7,
|
|
1382
|
+
maxTokens: 4096
|
|
1383
|
+
},
|
|
1384
|
+
tools: []
|
|
1385
|
+
};
|
|
1386
|
+
const syncResult = await syncToConvex(selectedAgent.id, defaultConfig);
|
|
1387
|
+
if (syncResult.success) {
|
|
1388
|
+
spinner.succeed("Initial config synced");
|
|
1389
|
+
} else {
|
|
1390
|
+
spinner.warn("Could not sync initial config");
|
|
1391
|
+
console.log(chalk2.gray(" Run"), chalk2.cyan("struere dev"), chalk2.gray("to sync manually"));
|
|
1392
|
+
}
|
|
1393
|
+
console.log();
|
|
1033
1394
|
console.log(chalk2.green("Success!"), "Project initialized");
|
|
1034
1395
|
console.log();
|
|
1035
1396
|
console.log(chalk2.gray("Next steps:"));
|
|
1036
|
-
console.log(chalk2.gray(" $"), chalk2.cyan("bun install"));
|
|
1037
1397
|
console.log(chalk2.gray(" $"), chalk2.cyan("struere dev"));
|
|
1038
1398
|
console.log();
|
|
1039
1399
|
});
|
|
@@ -2100,9 +2460,17 @@ var whoamiCommand = new Command11("whoami").description("Show current logged in
|
|
|
2100
2460
|
// package.json
|
|
2101
2461
|
var package_default = {
|
|
2102
2462
|
name: "struere",
|
|
2103
|
-
version: "0.3.
|
|
2463
|
+
version: "0.3.7",
|
|
2104
2464
|
description: "Build, test, and deploy AI agents",
|
|
2105
|
-
keywords: [
|
|
2465
|
+
keywords: [
|
|
2466
|
+
"ai",
|
|
2467
|
+
"agents",
|
|
2468
|
+
"llm",
|
|
2469
|
+
"anthropic",
|
|
2470
|
+
"openai",
|
|
2471
|
+
"framework",
|
|
2472
|
+
"cli"
|
|
2473
|
+
],
|
|
2106
2474
|
author: "struere",
|
|
2107
2475
|
license: "MIT",
|
|
2108
2476
|
publishConfig: {
|
|
@@ -2129,7 +2497,9 @@ var package_default = {
|
|
|
2129
2497
|
types: "./dist/index.d.ts"
|
|
2130
2498
|
}
|
|
2131
2499
|
},
|
|
2132
|
-
files: [
|
|
2500
|
+
files: [
|
|
2501
|
+
"dist"
|
|
2502
|
+
],
|
|
2133
2503
|
scripts: {
|
|
2134
2504
|
build: "bun build ./src/cli/index.ts --outdir ./dist/cli --target bun --external commander --external chalk --external ora --external chokidar --external yaml && bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/bin/struere.ts --outdir ./dist/bin --target bun && tsc --emitDeclarationOnly && chmod +x ./dist/bin/struere.js",
|
|
2135
2505
|
dev: "tsc --watch",
|
|
@@ -9,4 +9,5 @@ export declare function getEnvExample(): string;
|
|
|
9
9
|
export declare function getGitignore(): string;
|
|
10
10
|
export declare function getStruereJson(agentId: string, team: string, slug: string, name: string): string;
|
|
11
11
|
export declare function getEnvLocal(deploymentUrl: string): string;
|
|
12
|
+
export declare function getClaudeMd(name: string): string;
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBnD;AAED,wBAAgB,WAAW,IAAI,MAAM,CAsBpC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoC/C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAkBrC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAoDnC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAmBzC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAgBrC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAahG;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzD"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBnD;AAED,wBAAgB,WAAW,IAAI,MAAM,CAsBpC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoC/C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAkBrC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAoDnC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAmBzC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAgBrC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAahG;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyUhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/scaffold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/scaffold.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAeD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,cAAc,CAexF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,cAAc,CAgCrF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CA+BnF;AAsBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "struere",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Build, test, and deploy AI agents",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"agents",
|
|
8
|
+
"llm",
|
|
9
|
+
"anthropic",
|
|
10
|
+
"openai",
|
|
11
|
+
"framework",
|
|
12
|
+
"cli"
|
|
13
|
+
],
|
|
6
14
|
"author": "struere",
|
|
7
15
|
"license": "MIT",
|
|
8
16
|
"publishConfig": {
|
|
@@ -29,7 +37,9 @@
|
|
|
29
37
|
"types": "./dist/index.d.ts"
|
|
30
38
|
}
|
|
31
39
|
},
|
|
32
|
-
"files": [
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
33
43
|
"scripts": {
|
|
34
44
|
"build": "bun build ./src/cli/index.ts --outdir ./dist/cli --target bun --external commander --external chalk --external ora --external chokidar --external yaml && bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/bin/struere.ts --outdir ./dist/bin --target bun && tsc --emitDeclarationOnly && chmod +x ./dist/bin/struere.js",
|
|
35
45
|
"dev": "tsc --watch",
|