struere 0.7.1 → 0.7.3

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.
@@ -20657,34 +20657,13 @@ function getResourceDirectories(cwd) {
20657
20657
  }
20658
20658
 
20659
20659
  // src/cli/commands/docs.ts
20660
- var DOCS_URL = "https://docs.struere.dev/llms-full.txt";
20660
+ var DOCS_BASE = "https://docs.struere.dev";
20661
20661
  var ALL_TARGETS = ["claude", "cursor", "copilot"];
20662
20662
  var TARGET_FILES = {
20663
20663
  claude: "CLAUDE.md",
20664
20664
  cursor: ".cursorrules",
20665
20665
  copilot: ".github/copilot-instructions.md"
20666
20666
  };
20667
- var TARGET_HEADERS = {
20668
- claude: `# Struere Workspace
20669
-
20670
- > This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
20671
- `,
20672
- cursor: `# Struere Workspace
20673
-
20674
- This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
20675
- `,
20676
- copilot: `# Struere Workspace
20677
-
20678
- This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
20679
- `
20680
- };
20681
- async function fetchFrameworkDocs() {
20682
- const response = await fetch(DOCS_URL, { signal: AbortSignal.timeout(15000) });
20683
- if (!response.ok) {
20684
- throw new Error(`Failed to fetch docs: ${response.status} ${response.statusText}`);
20685
- }
20686
- return await response.text();
20687
- }
20688
20667
  function buildProjectContext(orgName, resources) {
20689
20668
  const lines = [];
20690
20669
  lines.push(`## This Project`);
@@ -20695,7 +20674,7 @@ function buildProjectContext(orgName, resources) {
20695
20674
  lines.push(`### Agents (${resources.agents.length})`);
20696
20675
  for (const agent of resources.agents) {
20697
20676
  const tools = agent.tools?.length ? ` \u2014 tools: ${agent.tools.join(", ")}` : "";
20698
- lines.push(`- ${agent.name} (${agent.slug}) - v${agent.version}${tools}`);
20677
+ lines.push(`- **${agent.name}** (\`${agent.slug}\`) v${agent.version}${tools}`);
20699
20678
  }
20700
20679
  }
20701
20680
  if (resources.entityTypes.length > 0) {
@@ -20704,7 +20683,7 @@ function buildProjectContext(orgName, resources) {
20704
20683
  for (const et of resources.entityTypes) {
20705
20684
  const fields = et.schema?.properties ? Object.keys(et.schema.properties).join(", ") : "";
20706
20685
  const fieldStr = fields ? ` \u2014 fields: ${fields}` : "";
20707
- lines.push(`- ${et.name} (${et.slug})${fieldStr}`);
20686
+ lines.push(`- **${et.name}** (\`${et.slug}\`)${fieldStr}`);
20708
20687
  }
20709
20688
  }
20710
20689
  if (resources.roles.length > 0) {
@@ -20712,37 +20691,167 @@ function buildProjectContext(orgName, resources) {
20712
20691
  lines.push(`### Roles (${resources.roles.length})`);
20713
20692
  for (const role of resources.roles) {
20714
20693
  const policyCount = role.policies?.length || 0;
20715
- lines.push(`- ${role.name} \u2014 ${policyCount} ${policyCount === 1 ? "policy" : "policies"}`);
20694
+ lines.push(`- **${role.name}** \u2014 ${policyCount} ${policyCount === 1 ? "policy" : "policies"}`);
20716
20695
  }
20717
20696
  }
20718
20697
  if (resources.triggers.length > 0) {
20719
20698
  lines.push("");
20720
20699
  lines.push(`### Triggers (${resources.triggers.length})`);
20721
20700
  for (const trigger of resources.triggers) {
20722
- lines.push(`- ${trigger.name} (${trigger.slug}) \u2014 on ${trigger.on.entityType}.${trigger.on.action}`);
20701
+ lines.push(`- **${trigger.name}** (\`${trigger.slug}\`) \u2014 on \`${trigger.on.entityType}.${trigger.on.action}\``);
20723
20702
  }
20724
20703
  }
20725
20704
  if (resources.customTools.length > 0) {
20726
20705
  lines.push("");
20727
20706
  lines.push(`### Custom Tools (${resources.customTools.length})`);
20728
20707
  for (const tool of resources.customTools) {
20729
- lines.push(`- ${tool.name} \u2014 ${tool.description}`);
20708
+ lines.push(`- **${tool.name}** \u2014 ${tool.description}`);
20730
20709
  }
20731
20710
  }
20732
- lines.push("");
20733
20711
  return lines.join(`
20734
20712
  `);
20735
20713
  }
20736
- function assembleDocument(target, projectContext, frameworkDocs) {
20737
- const parts = [];
20738
- parts.push(TARGET_HEADERS[target]);
20714
+ function buildDocument(projectContext) {
20715
+ const lines = [];
20716
+ lines.push(`# Struere Workspace`);
20717
+ lines.push("");
20718
+ lines.push(`> This is a Struere workspace project. You define agents, entity types, roles, triggers, and custom tools here. The CLI syncs them to the Convex backend.`);
20719
+ lines.push("");
20739
20720
  if (projectContext) {
20740
- parts.push(projectContext);
20721
+ lines.push(projectContext);
20722
+ lines.push("");
20741
20723
  }
20742
- parts.push(`---
20743
- `);
20744
- parts.push(frameworkDocs);
20745
- return parts.join(`
20724
+ lines.push(`## Project Structure`);
20725
+ lines.push("");
20726
+ lines.push("```");
20727
+ lines.push("agents/ # Agent definitions (one file per agent)");
20728
+ lines.push("entity-types/ # Entity type schemas (like DB tables)");
20729
+ lines.push("roles/ # RBAC roles with policies, scope rules, field masks");
20730
+ lines.push("triggers/ # Automation rules (react to entity changes)");
20731
+ lines.push("tools/index.ts # Custom tools shared by all agents");
20732
+ lines.push("evals/*.eval.yaml # Test suites for agent evaluation");
20733
+ lines.push("struere.json # Organization config (auto-generated)");
20734
+ lines.push("```");
20735
+ lines.push("");
20736
+ lines.push(`## CLI Commands`);
20737
+ lines.push("");
20738
+ lines.push("| Command | Description |");
20739
+ lines.push("|---------|-------------|");
20740
+ lines.push("| `struere dev` | Watch files and sync to Convex on save |");
20741
+ lines.push("| `struere deploy` | Push development config to production |");
20742
+ lines.push("| `struere add agent\\|entity-type\\|role\\|trigger\\|eval <name>` | Scaffold a new resource |");
20743
+ lines.push("| `struere status` | Compare local vs remote state |");
20744
+ lines.push("| `struere pull` | Download remote resources to local files |");
20745
+ lines.push("| `struere entities types` | List entity types in an environment |");
20746
+ lines.push("| `struere entities list <type>` | List entities (supports `--status`, `--limit`, `--json`) |");
20747
+ lines.push("| `struere entities get <id>` | Get entity details |");
20748
+ lines.push("| `struere entities create <type>` | Create entity (interactive or `--data <json>`) |");
20749
+ lines.push("| `struere entities update <id>` | Update entity (`--data <json>`, `--status`) |");
20750
+ lines.push("| `struere entities delete <id>` | Delete entity (with confirmation) |");
20751
+ lines.push("| `struere entities search <type> <query>` | Search entities by text |");
20752
+ lines.push("| `struere docs` | Regenerate this file |");
20753
+ lines.push("");
20754
+ lines.push(`## Key Patterns`);
20755
+ lines.push("");
20756
+ lines.push("- **Imports**: `import { defineAgent, defineEntityType, defineRole, defineTrigger, defineTools } from 'struere'`");
20757
+ lines.push("- **Default model**: `claude-sonnet-4` (provider: `anthropic`). Also supports `openai` and `google`");
20758
+ lines.push("- **Scope rule values**: `actor.userId`, `actor.entityId`, `actor.organizationId`, `actor.relatedIds:TYPE`, `literal:VALUE`");
20759
+ lines.push("- **Policy actions**: `create`, `read`, `update`, `delete`, `list` (deny overrides allow)");
20760
+ lines.push("- **Entity link/unlink params**: `fromId`, `toId`, `relationType`");
20761
+ lines.push("- **Trigger template vars**: `{{trigger.entityId}}`, `{{trigger.data.X}}`, `{{steps.NAME.X}}`");
20762
+ lines.push("");
20763
+ lines.push(`## Dynamic System Prompts`);
20764
+ lines.push("");
20765
+ lines.push("System prompts are **not static strings** \u2014 they are templates evaluated at runtime before every LLM call. This is one of the most powerful features in Struere because it enables completely different agent behavior depending on conditions, live data, and even other agents' responses.");
20766
+ lines.push("");
20767
+ lines.push("### Template Variables");
20768
+ lines.push("Simple variable substitution: `{{agentName}}`, `{{organizationName}}`, `{{currentTime}}`, `{{entityTypes}}`, `{{roles}}`, `{{message}}`, `{{thread.metadata.X}}`");
20769
+ lines.push("");
20770
+ lines.push("### Embedded Queries (Function Calls)");
20771
+ lines.push("Pull live data from the database directly into the system prompt:");
20772
+ lines.push("```");
20773
+ lines.push('{{entity.query({"type": "customer", "limit": 5})}}');
20774
+ lines.push('{{entity.get({"id": "ent_123"})}}');
20775
+ lines.push("```");
20776
+ lines.push("This means the agent always sees the latest data \u2014 no stale context.");
20777
+ lines.push("");
20778
+ lines.push("### Custom Tools in Prompts");
20779
+ lines.push("Since custom tools can run arbitrary logic, you can create tools specifically to generate dynamic prompt sections. A custom tool can fetch external APIs, compute conditions, aggregate data, or format context \u2014 and its output gets embedded into the system prompt at runtime.");
20780
+ lines.push("");
20781
+ lines.push("### Agent-to-Agent in Prompts");
20782
+ lines.push('You can even use `agent.chat` in the template to have another agent\'s response injected into the system prompt. This enables patterns like a "context agent" that summarizes relevant info before the main agent starts reasoning.');
20783
+ lines.push("");
20784
+ lines.push(`For full template syntax: [System Prompt Templates](${DOCS_BASE}/tools/system-prompt-templates.md)`);
20785
+ lines.push("");
20786
+ lines.push(`## Multi-Agent Communication (agent.chat)`);
20787
+ lines.push("");
20788
+ lines.push("The `agent.chat` tool lets agents delegate work to other agents. This is a core building block for complex systems:");
20789
+ lines.push("");
20790
+ lines.push("- **Orchestrator pattern**: A coordinator agent routes tasks to specialist agents based on the request");
20791
+ lines.push("- **Trigger actions**: Use `agent.chat` inside trigger action pipelines to have an agent reason about entity changes");
20792
+ lines.push("- **Chained delegation**: Agents can call other agents up to 3 levels deep (A\u2192B\u2192C), with cycle detection");
20793
+ lines.push("- **Isolated execution**: Each agent runs its own LLM loop with its own system prompt, tools, and permissions");
20794
+ lines.push("");
20795
+ lines.push("```typescript");
20796
+ lines.push("// Orchestrator that delegates to specialists");
20797
+ lines.push('tools: ["agent.chat", "entity.query"]');
20798
+ lines.push("// In trigger actions:");
20799
+ lines.push('{ tool: "agent.chat", args: { agent: "billing-agent", message: "Process refund for {{trigger.data.orderId}}" } }');
20800
+ lines.push("```");
20801
+ lines.push("");
20802
+ lines.push(`For details: [Agents](${DOCS_BASE}/platform/agents.md)`);
20803
+ lines.push("");
20804
+ lines.push(`## Best Practices`);
20805
+ lines.push("");
20806
+ lines.push("- **Keep tools under 10 per agent.** Agents perform significantly worse when they have too many tools to choose from. If an agent needs more, split it into specialist agents and use `agent.chat` to orchestrate");
20807
+ lines.push("- **Always ask the user before making assumptions.** The user may not be technical \u2014 help them accomplish what they want by asking the right questions and offering clear options");
20808
+ lines.push("- **Always check the documentation before making changes.** Fetch the relevant doc link below to verify the correct API, field names, and patterns. Do not guess \u2014 wrong field names or patterns will cause silent failures");
20809
+ lines.push("- **Use `struere dev` to validate changes.** Every save triggers a sync \u2014 check the terminal for errors before testing");
20810
+ lines.push("- **Test with evals.** Write eval suites to catch regressions in agent behavior (`struere add eval <name>`)");
20811
+ lines.push("");
20812
+ lines.push(`## Documentation`);
20813
+ lines.push("");
20814
+ lines.push(`Fetch these URLs for detailed documentation on each topic:`);
20815
+ lines.push("");
20816
+ lines.push("### SDK");
20817
+ lines.push(`- [SDK Overview](${DOCS_BASE}/sdk/overview.md)`);
20818
+ lines.push(`- [defineAgent](${DOCS_BASE}/sdk/define-agent.md)`);
20819
+ lines.push(`- [defineEntityType](${DOCS_BASE}/sdk/define-entity-type.md)`);
20820
+ lines.push(`- [defineRole](${DOCS_BASE}/sdk/define-role.md)`);
20821
+ lines.push(`- [defineTrigger](${DOCS_BASE}/sdk/define-trigger.md)`);
20822
+ lines.push(`- [defineTools](${DOCS_BASE}/sdk/define-tools.md)`);
20823
+ lines.push("");
20824
+ lines.push("### Tools");
20825
+ lines.push(`- [Built-in Tools](${DOCS_BASE}/tools/built-in-tools.md)`);
20826
+ lines.push(`- [Custom Tools](${DOCS_BASE}/tools/custom-tools.md)`);
20827
+ lines.push(`- [System Prompt Templates](${DOCS_BASE}/tools/system-prompt-templates.md)`);
20828
+ lines.push("");
20829
+ lines.push("### Platform");
20830
+ lines.push(`- [Entities](${DOCS_BASE}/platform/entities.md)`);
20831
+ lines.push(`- [Permissions](${DOCS_BASE}/platform/permissions.md)`);
20832
+ lines.push(`- [Agents](${DOCS_BASE}/platform/agents.md)`);
20833
+ lines.push(`- [Events](${DOCS_BASE}/platform/events.md)`);
20834
+ lines.push(`- [Triggers](${DOCS_BASE}/platform/triggers.md)`);
20835
+ lines.push(`- [Environment Isolation](${DOCS_BASE}/platform/environment-isolation.md)`);
20836
+ lines.push("");
20837
+ lines.push("### CLI");
20838
+ lines.push(`- [CLI Overview](${DOCS_BASE}/cli/overview.md)`);
20839
+ lines.push(`- [struere init](${DOCS_BASE}/cli/init.md)`);
20840
+ lines.push(`- [struere dev](${DOCS_BASE}/cli/dev.md)`);
20841
+ lines.push(`- [struere add](${DOCS_BASE}/cli/add.md)`);
20842
+ lines.push(`- [struere deploy](${DOCS_BASE}/cli/deploy.md)`);
20843
+ lines.push("");
20844
+ lines.push("### API & Integrations");
20845
+ lines.push(`- [Chat API](${DOCS_BASE}/api/chat.md)`);
20846
+ lines.push(`- [Webhooks](${DOCS_BASE}/api/webhooks.md)`);
20847
+ lines.push(`- [WhatsApp Integration](${DOCS_BASE}/integrations/whatsapp.md)`);
20848
+ lines.push("");
20849
+ lines.push("### Reference");
20850
+ lines.push(`- [Project Structure](${DOCS_BASE}/reference/project-structure.md)`);
20851
+ lines.push(`- [Model Configuration](${DOCS_BASE}/reference/model-configuration.md)`);
20852
+ lines.push("");
20853
+ lines.push(`Full docs: ${DOCS_BASE}/llms-full.txt`);
20854
+ return lines.join(`
20746
20855
  `);
20747
20856
  }
20748
20857
  function writeTarget(cwd, target, content) {
@@ -20755,12 +20864,6 @@ function writeTarget(cwd, target, content) {
20755
20864
  }
20756
20865
  async function generateDocs(cwd, targets) {
20757
20866
  const generated = [];
20758
- let frameworkDocs;
20759
- try {
20760
- frameworkDocs = await fetchFrameworkDocs();
20761
- } catch (err) {
20762
- return { generated, error: err instanceof Error ? err.message : String(err) };
20763
- }
20764
20867
  let projectContext = null;
20765
20868
  const project = loadProject(cwd);
20766
20869
  if (project) {
@@ -20779,8 +20882,8 @@ async function generateDocs(cwd, targets) {
20779
20882
  });
20780
20883
  }
20781
20884
  }
20885
+ const content = buildDocument(projectContext);
20782
20886
  for (const target of targets) {
20783
- const content = assembleDocument(target, projectContext, frameworkDocs);
20784
20887
  writeTarget(cwd, target, content);
20785
20888
  generated.push(TARGET_FILES[target]);
20786
20889
  }
@@ -20804,10 +20907,10 @@ var docsCommand = new Command("docs").description("Generate AI context files (CL
20804
20907
  } else {
20805
20908
  targets = [...ALL_TARGETS];
20806
20909
  }
20807
- spinner.start("Fetching docs and generating context files");
20910
+ spinner.start("Generating context files");
20808
20911
  const { generated, error } = await generateDocs(cwd, targets);
20809
20912
  if (error) {
20810
- spinner.fail("Failed to fetch docs");
20913
+ spinner.fail("Failed to generate docs");
20811
20914
  console.log(source_default.red("Error:"), error);
20812
20915
  process.exit(1);
20813
20916
  }
@@ -23160,7 +23263,7 @@ entitiesCommand.command("search <type> <query>").description("Search entities").
23160
23263
  // package.json
23161
23264
  var package_default = {
23162
23265
  name: "struere",
23163
- version: "0.7.1",
23266
+ version: "0.7.3",
23164
23267
  description: "Build, test, and deploy AI agents",
23165
23268
  keywords: [
23166
23269
  "ai",
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAUnC,KAAK,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;AAkG7C,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BnH;AAED,eAAO,MAAM,WAAW,SAsCpB,CAAA"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAUnC,KAAK,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;AAiO7C,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBnH;AAED,eAAO,MAAM,WAAW,SAsCpB,CAAA"}
package/dist/cli/index.js CHANGED
@@ -1323,34 +1323,13 @@ function getResourceDirectories(cwd) {
1323
1323
  }
1324
1324
 
1325
1325
  // src/cli/commands/docs.ts
1326
- var DOCS_URL = "https://docs.struere.dev/llms-full.txt";
1326
+ var DOCS_BASE = "https://docs.struere.dev";
1327
1327
  var ALL_TARGETS = ["claude", "cursor", "copilot"];
1328
1328
  var TARGET_FILES = {
1329
1329
  claude: "CLAUDE.md",
1330
1330
  cursor: ".cursorrules",
1331
1331
  copilot: ".github/copilot-instructions.md"
1332
1332
  };
1333
- var TARGET_HEADERS = {
1334
- claude: `# Struere Workspace
1335
-
1336
- > This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
1337
- `,
1338
- cursor: `# Struere Workspace
1339
-
1340
- This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
1341
- `,
1342
- copilot: `# Struere Workspace
1343
-
1344
- This is a Struere workspace project. You define agents, entity types, roles, and custom tools here. The CLI syncs them to Convex.
1345
- `
1346
- };
1347
- async function fetchFrameworkDocs() {
1348
- const response = await fetch(DOCS_URL, { signal: AbortSignal.timeout(15000) });
1349
- if (!response.ok) {
1350
- throw new Error(`Failed to fetch docs: ${response.status} ${response.statusText}`);
1351
- }
1352
- return await response.text();
1353
- }
1354
1333
  function buildProjectContext(orgName, resources) {
1355
1334
  const lines = [];
1356
1335
  lines.push(`## This Project`);
@@ -1361,7 +1340,7 @@ function buildProjectContext(orgName, resources) {
1361
1340
  lines.push(`### Agents (${resources.agents.length})`);
1362
1341
  for (const agent of resources.agents) {
1363
1342
  const tools = agent.tools?.length ? ` \u2014 tools: ${agent.tools.join(", ")}` : "";
1364
- lines.push(`- ${agent.name} (${agent.slug}) - v${agent.version}${tools}`);
1343
+ lines.push(`- **${agent.name}** (\`${agent.slug}\`) v${agent.version}${tools}`);
1365
1344
  }
1366
1345
  }
1367
1346
  if (resources.entityTypes.length > 0) {
@@ -1370,7 +1349,7 @@ function buildProjectContext(orgName, resources) {
1370
1349
  for (const et of resources.entityTypes) {
1371
1350
  const fields = et.schema?.properties ? Object.keys(et.schema.properties).join(", ") : "";
1372
1351
  const fieldStr = fields ? ` \u2014 fields: ${fields}` : "";
1373
- lines.push(`- ${et.name} (${et.slug})${fieldStr}`);
1352
+ lines.push(`- **${et.name}** (\`${et.slug}\`)${fieldStr}`);
1374
1353
  }
1375
1354
  }
1376
1355
  if (resources.roles.length > 0) {
@@ -1378,37 +1357,167 @@ function buildProjectContext(orgName, resources) {
1378
1357
  lines.push(`### Roles (${resources.roles.length})`);
1379
1358
  for (const role of resources.roles) {
1380
1359
  const policyCount = role.policies?.length || 0;
1381
- lines.push(`- ${role.name} \u2014 ${policyCount} ${policyCount === 1 ? "policy" : "policies"}`);
1360
+ lines.push(`- **${role.name}** \u2014 ${policyCount} ${policyCount === 1 ? "policy" : "policies"}`);
1382
1361
  }
1383
1362
  }
1384
1363
  if (resources.triggers.length > 0) {
1385
1364
  lines.push("");
1386
1365
  lines.push(`### Triggers (${resources.triggers.length})`);
1387
1366
  for (const trigger of resources.triggers) {
1388
- lines.push(`- ${trigger.name} (${trigger.slug}) \u2014 on ${trigger.on.entityType}.${trigger.on.action}`);
1367
+ lines.push(`- **${trigger.name}** (\`${trigger.slug}\`) \u2014 on \`${trigger.on.entityType}.${trigger.on.action}\``);
1389
1368
  }
1390
1369
  }
1391
1370
  if (resources.customTools.length > 0) {
1392
1371
  lines.push("");
1393
1372
  lines.push(`### Custom Tools (${resources.customTools.length})`);
1394
1373
  for (const tool of resources.customTools) {
1395
- lines.push(`- ${tool.name} \u2014 ${tool.description}`);
1374
+ lines.push(`- **${tool.name}** \u2014 ${tool.description}`);
1396
1375
  }
1397
1376
  }
1398
- lines.push("");
1399
1377
  return lines.join(`
1400
1378
  `);
1401
1379
  }
1402
- function assembleDocument(target, projectContext, frameworkDocs) {
1403
- const parts = [];
1404
- parts.push(TARGET_HEADERS[target]);
1380
+ function buildDocument(projectContext) {
1381
+ const lines = [];
1382
+ lines.push(`# Struere Workspace`);
1383
+ lines.push("");
1384
+ lines.push(`> This is a Struere workspace project. You define agents, entity types, roles, triggers, and custom tools here. The CLI syncs them to the Convex backend.`);
1385
+ lines.push("");
1405
1386
  if (projectContext) {
1406
- parts.push(projectContext);
1387
+ lines.push(projectContext);
1388
+ lines.push("");
1407
1389
  }
1408
- parts.push(`---
1409
- `);
1410
- parts.push(frameworkDocs);
1411
- return parts.join(`
1390
+ lines.push(`## Project Structure`);
1391
+ lines.push("");
1392
+ lines.push("```");
1393
+ lines.push("agents/ # Agent definitions (one file per agent)");
1394
+ lines.push("entity-types/ # Entity type schemas (like DB tables)");
1395
+ lines.push("roles/ # RBAC roles with policies, scope rules, field masks");
1396
+ lines.push("triggers/ # Automation rules (react to entity changes)");
1397
+ lines.push("tools/index.ts # Custom tools shared by all agents");
1398
+ lines.push("evals/*.eval.yaml # Test suites for agent evaluation");
1399
+ lines.push("struere.json # Organization config (auto-generated)");
1400
+ lines.push("```");
1401
+ lines.push("");
1402
+ lines.push(`## CLI Commands`);
1403
+ lines.push("");
1404
+ lines.push("| Command | Description |");
1405
+ lines.push("|---------|-------------|");
1406
+ lines.push("| `struere dev` | Watch files and sync to Convex on save |");
1407
+ lines.push("| `struere deploy` | Push development config to production |");
1408
+ lines.push("| `struere add agent\\|entity-type\\|role\\|trigger\\|eval <name>` | Scaffold a new resource |");
1409
+ lines.push("| `struere status` | Compare local vs remote state |");
1410
+ lines.push("| `struere pull` | Download remote resources to local files |");
1411
+ lines.push("| `struere entities types` | List entity types in an environment |");
1412
+ lines.push("| `struere entities list <type>` | List entities (supports `--status`, `--limit`, `--json`) |");
1413
+ lines.push("| `struere entities get <id>` | Get entity details |");
1414
+ lines.push("| `struere entities create <type>` | Create entity (interactive or `--data <json>`) |");
1415
+ lines.push("| `struere entities update <id>` | Update entity (`--data <json>`, `--status`) |");
1416
+ lines.push("| `struere entities delete <id>` | Delete entity (with confirmation) |");
1417
+ lines.push("| `struere entities search <type> <query>` | Search entities by text |");
1418
+ lines.push("| `struere docs` | Regenerate this file |");
1419
+ lines.push("");
1420
+ lines.push(`## Key Patterns`);
1421
+ lines.push("");
1422
+ lines.push("- **Imports**: `import { defineAgent, defineEntityType, defineRole, defineTrigger, defineTools } from 'struere'`");
1423
+ lines.push("- **Default model**: `claude-sonnet-4` (provider: `anthropic`). Also supports `openai` and `google`");
1424
+ lines.push("- **Scope rule values**: `actor.userId`, `actor.entityId`, `actor.organizationId`, `actor.relatedIds:TYPE`, `literal:VALUE`");
1425
+ lines.push("- **Policy actions**: `create`, `read`, `update`, `delete`, `list` (deny overrides allow)");
1426
+ lines.push("- **Entity link/unlink params**: `fromId`, `toId`, `relationType`");
1427
+ lines.push("- **Trigger template vars**: `{{trigger.entityId}}`, `{{trigger.data.X}}`, `{{steps.NAME.X}}`");
1428
+ lines.push("");
1429
+ lines.push(`## Dynamic System Prompts`);
1430
+ lines.push("");
1431
+ lines.push("System prompts are **not static strings** \u2014 they are templates evaluated at runtime before every LLM call. This is one of the most powerful features in Struere because it enables completely different agent behavior depending on conditions, live data, and even other agents' responses.");
1432
+ lines.push("");
1433
+ lines.push("### Template Variables");
1434
+ lines.push("Simple variable substitution: `{{agentName}}`, `{{organizationName}}`, `{{currentTime}}`, `{{entityTypes}}`, `{{roles}}`, `{{message}}`, `{{thread.metadata.X}}`");
1435
+ lines.push("");
1436
+ lines.push("### Embedded Queries (Function Calls)");
1437
+ lines.push("Pull live data from the database directly into the system prompt:");
1438
+ lines.push("```");
1439
+ lines.push('{{entity.query({"type": "customer", "limit": 5})}}');
1440
+ lines.push('{{entity.get({"id": "ent_123"})}}');
1441
+ lines.push("```");
1442
+ lines.push("This means the agent always sees the latest data \u2014 no stale context.");
1443
+ lines.push("");
1444
+ lines.push("### Custom Tools in Prompts");
1445
+ lines.push("Since custom tools can run arbitrary logic, you can create tools specifically to generate dynamic prompt sections. A custom tool can fetch external APIs, compute conditions, aggregate data, or format context \u2014 and its output gets embedded into the system prompt at runtime.");
1446
+ lines.push("");
1447
+ lines.push("### Agent-to-Agent in Prompts");
1448
+ lines.push('You can even use `agent.chat` in the template to have another agent\'s response injected into the system prompt. This enables patterns like a "context agent" that summarizes relevant info before the main agent starts reasoning.');
1449
+ lines.push("");
1450
+ lines.push(`For full template syntax: [System Prompt Templates](${DOCS_BASE}/tools/system-prompt-templates.md)`);
1451
+ lines.push("");
1452
+ lines.push(`## Multi-Agent Communication (agent.chat)`);
1453
+ lines.push("");
1454
+ lines.push("The `agent.chat` tool lets agents delegate work to other agents. This is a core building block for complex systems:");
1455
+ lines.push("");
1456
+ lines.push("- **Orchestrator pattern**: A coordinator agent routes tasks to specialist agents based on the request");
1457
+ lines.push("- **Trigger actions**: Use `agent.chat` inside trigger action pipelines to have an agent reason about entity changes");
1458
+ lines.push("- **Chained delegation**: Agents can call other agents up to 3 levels deep (A\u2192B\u2192C), with cycle detection");
1459
+ lines.push("- **Isolated execution**: Each agent runs its own LLM loop with its own system prompt, tools, and permissions");
1460
+ lines.push("");
1461
+ lines.push("```typescript");
1462
+ lines.push("// Orchestrator that delegates to specialists");
1463
+ lines.push('tools: ["agent.chat", "entity.query"]');
1464
+ lines.push("// In trigger actions:");
1465
+ lines.push('{ tool: "agent.chat", args: { agent: "billing-agent", message: "Process refund for {{trigger.data.orderId}}" } }');
1466
+ lines.push("```");
1467
+ lines.push("");
1468
+ lines.push(`For details: [Agents](${DOCS_BASE}/platform/agents.md)`);
1469
+ lines.push("");
1470
+ lines.push(`## Best Practices`);
1471
+ lines.push("");
1472
+ lines.push("- **Keep tools under 10 per agent.** Agents perform significantly worse when they have too many tools to choose from. If an agent needs more, split it into specialist agents and use `agent.chat` to orchestrate");
1473
+ lines.push("- **Always ask the user before making assumptions.** The user may not be technical \u2014 help them accomplish what they want by asking the right questions and offering clear options");
1474
+ lines.push("- **Always check the documentation before making changes.** Fetch the relevant doc link below to verify the correct API, field names, and patterns. Do not guess \u2014 wrong field names or patterns will cause silent failures");
1475
+ lines.push("- **Use `struere dev` to validate changes.** Every save triggers a sync \u2014 check the terminal for errors before testing");
1476
+ lines.push("- **Test with evals.** Write eval suites to catch regressions in agent behavior (`struere add eval <name>`)");
1477
+ lines.push("");
1478
+ lines.push(`## Documentation`);
1479
+ lines.push("");
1480
+ lines.push(`Fetch these URLs for detailed documentation on each topic:`);
1481
+ lines.push("");
1482
+ lines.push("### SDK");
1483
+ lines.push(`- [SDK Overview](${DOCS_BASE}/sdk/overview.md)`);
1484
+ lines.push(`- [defineAgent](${DOCS_BASE}/sdk/define-agent.md)`);
1485
+ lines.push(`- [defineEntityType](${DOCS_BASE}/sdk/define-entity-type.md)`);
1486
+ lines.push(`- [defineRole](${DOCS_BASE}/sdk/define-role.md)`);
1487
+ lines.push(`- [defineTrigger](${DOCS_BASE}/sdk/define-trigger.md)`);
1488
+ lines.push(`- [defineTools](${DOCS_BASE}/sdk/define-tools.md)`);
1489
+ lines.push("");
1490
+ lines.push("### Tools");
1491
+ lines.push(`- [Built-in Tools](${DOCS_BASE}/tools/built-in-tools.md)`);
1492
+ lines.push(`- [Custom Tools](${DOCS_BASE}/tools/custom-tools.md)`);
1493
+ lines.push(`- [System Prompt Templates](${DOCS_BASE}/tools/system-prompt-templates.md)`);
1494
+ lines.push("");
1495
+ lines.push("### Platform");
1496
+ lines.push(`- [Entities](${DOCS_BASE}/platform/entities.md)`);
1497
+ lines.push(`- [Permissions](${DOCS_BASE}/platform/permissions.md)`);
1498
+ lines.push(`- [Agents](${DOCS_BASE}/platform/agents.md)`);
1499
+ lines.push(`- [Events](${DOCS_BASE}/platform/events.md)`);
1500
+ lines.push(`- [Triggers](${DOCS_BASE}/platform/triggers.md)`);
1501
+ lines.push(`- [Environment Isolation](${DOCS_BASE}/platform/environment-isolation.md)`);
1502
+ lines.push("");
1503
+ lines.push("### CLI");
1504
+ lines.push(`- [CLI Overview](${DOCS_BASE}/cli/overview.md)`);
1505
+ lines.push(`- [struere init](${DOCS_BASE}/cli/init.md)`);
1506
+ lines.push(`- [struere dev](${DOCS_BASE}/cli/dev.md)`);
1507
+ lines.push(`- [struere add](${DOCS_BASE}/cli/add.md)`);
1508
+ lines.push(`- [struere deploy](${DOCS_BASE}/cli/deploy.md)`);
1509
+ lines.push("");
1510
+ lines.push("### API & Integrations");
1511
+ lines.push(`- [Chat API](${DOCS_BASE}/api/chat.md)`);
1512
+ lines.push(`- [Webhooks](${DOCS_BASE}/api/webhooks.md)`);
1513
+ lines.push(`- [WhatsApp Integration](${DOCS_BASE}/integrations/whatsapp.md)`);
1514
+ lines.push("");
1515
+ lines.push("### Reference");
1516
+ lines.push(`- [Project Structure](${DOCS_BASE}/reference/project-structure.md)`);
1517
+ lines.push(`- [Model Configuration](${DOCS_BASE}/reference/model-configuration.md)`);
1518
+ lines.push("");
1519
+ lines.push(`Full docs: ${DOCS_BASE}/llms-full.txt`);
1520
+ return lines.join(`
1412
1521
  `);
1413
1522
  }
1414
1523
  function writeTarget(cwd, target, content) {
@@ -1421,12 +1530,6 @@ function writeTarget(cwd, target, content) {
1421
1530
  }
1422
1531
  async function generateDocs(cwd, targets) {
1423
1532
  const generated = [];
1424
- let frameworkDocs;
1425
- try {
1426
- frameworkDocs = await fetchFrameworkDocs();
1427
- } catch (err) {
1428
- return { generated, error: err instanceof Error ? err.message : String(err) };
1429
- }
1430
1533
  let projectContext = null;
1431
1534
  const project = loadProject(cwd);
1432
1535
  if (project) {
@@ -1445,8 +1548,8 @@ async function generateDocs(cwd, targets) {
1445
1548
  });
1446
1549
  }
1447
1550
  }
1551
+ const content = buildDocument(projectContext);
1448
1552
  for (const target of targets) {
1449
- const content = assembleDocument(target, projectContext, frameworkDocs);
1450
1553
  writeTarget(cwd, target, content);
1451
1554
  generated.push(TARGET_FILES[target]);
1452
1555
  }
@@ -1470,10 +1573,10 @@ var docsCommand = new Command2("docs").description("Generate AI context files (C
1470
1573
  } else {
1471
1574
  targets = [...ALL_TARGETS];
1472
1575
  }
1473
- spinner.start("Fetching docs and generating context files");
1576
+ spinner.start("Generating context files");
1474
1577
  const { generated, error } = await generateDocs(cwd, targets);
1475
1578
  if (error) {
1476
- spinner.fail("Failed to fetch docs");
1579
+ spinner.fail("Failed to generate docs");
1477
1580
  console.log(chalk2.red("Error:"), error);
1478
1581
  process.exit(1);
1479
1582
  }
@@ -3854,7 +3957,7 @@ entitiesCommand.command("search <type> <query>").description("Search entities").
3854
3957
  // package.json
3855
3958
  var package_default = {
3856
3959
  name: "struere",
3857
- version: "0.7.1",
3960
+ version: "0.7.3",
3858
3961
  description: "Build, test, and deploy AI agents",
3859
3962
  keywords: [
3860
3963
  "ai",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "struere",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "Build, test, and deploy AI agents",
5
5
  "keywords": [
6
6
  "ai",