struere 0.9.6 → 0.9.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 +390 -93
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/compile-prompt.d.ts +3 -0
- package/dist/cli/commands/compile-prompt.d.ts.map +1 -0
- package/dist/cli/commands/entities.d.ts.map +1 -1
- package/dist/cli/commands/integration.d.ts.map +1 -1
- package/dist/cli/index.js +393 -93
- package/dist/cli/utils/convex.d.ts +18 -0
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/extractor.d.ts +2 -0
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/plugin.d.ts +1 -1
- package/dist/cli/utils/plugin.d.ts.map +1 -1
- package/dist/define/entityType.d.ts +1 -1
- package/dist/define/entityType.d.ts.map +1 -1
- package/dist/define/index.d.ts +1 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -19710,6 +19710,115 @@ async function getSyncState(organizationId, environment) {
|
|
|
19710
19710
|
}
|
|
19711
19711
|
return { error: `Unexpected response: ${JSON.stringify(result)}` };
|
|
19712
19712
|
}
|
|
19713
|
+
async function compilePrompt(options) {
|
|
19714
|
+
const credentials = loadCredentials();
|
|
19715
|
+
const apiKey = getApiKey();
|
|
19716
|
+
if (apiKey && !credentials?.token) {
|
|
19717
|
+
const siteUrl = getSiteUrl();
|
|
19718
|
+
try {
|
|
19719
|
+
const response2 = await fetch(`${siteUrl}/v1/compile-prompt`, {
|
|
19720
|
+
method: "POST",
|
|
19721
|
+
headers: {
|
|
19722
|
+
"Content-Type": "application/json",
|
|
19723
|
+
Authorization: `Bearer ${apiKey}`
|
|
19724
|
+
},
|
|
19725
|
+
body: JSON.stringify({
|
|
19726
|
+
slug: options.slug,
|
|
19727
|
+
message: options.message,
|
|
19728
|
+
channel: options.channel,
|
|
19729
|
+
threadMetadata: options.threadMetadata
|
|
19730
|
+
}),
|
|
19731
|
+
signal: AbortSignal.timeout(30000)
|
|
19732
|
+
});
|
|
19733
|
+
const text2 = await response2.text();
|
|
19734
|
+
let json2;
|
|
19735
|
+
try {
|
|
19736
|
+
json2 = JSON.parse(text2);
|
|
19737
|
+
} catch {
|
|
19738
|
+
return { error: text2 || `HTTP ${response2.status}` };
|
|
19739
|
+
}
|
|
19740
|
+
if (!response2.ok) {
|
|
19741
|
+
return { error: json2.error || text2 };
|
|
19742
|
+
}
|
|
19743
|
+
return { result: json2 };
|
|
19744
|
+
} catch (err) {
|
|
19745
|
+
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
19746
|
+
return { error: "Request timed out after 30s" };
|
|
19747
|
+
}
|
|
19748
|
+
return { error: `Network error: ${err instanceof Error ? err.message : String(err)}` };
|
|
19749
|
+
}
|
|
19750
|
+
}
|
|
19751
|
+
if (credentials?.sessionId) {
|
|
19752
|
+
await refreshToken();
|
|
19753
|
+
}
|
|
19754
|
+
const freshCredentials = loadCredentials();
|
|
19755
|
+
const token = apiKey || freshCredentials?.token;
|
|
19756
|
+
if (!token) {
|
|
19757
|
+
return { error: "Not authenticated" };
|
|
19758
|
+
}
|
|
19759
|
+
const agentResponse = await fetch(`${CONVEX_URL}/api/query`, {
|
|
19760
|
+
method: "POST",
|
|
19761
|
+
headers: {
|
|
19762
|
+
"Content-Type": "application/json",
|
|
19763
|
+
Authorization: `Bearer ${token}`
|
|
19764
|
+
},
|
|
19765
|
+
body: JSON.stringify({
|
|
19766
|
+
path: "agents:getBySlug",
|
|
19767
|
+
args: { slug: options.slug }
|
|
19768
|
+
})
|
|
19769
|
+
});
|
|
19770
|
+
if (!agentResponse.ok) {
|
|
19771
|
+
return { error: await agentResponse.text() };
|
|
19772
|
+
}
|
|
19773
|
+
const agentResult = await agentResponse.json();
|
|
19774
|
+
if (agentResult.status === "error") {
|
|
19775
|
+
return { error: agentResult.errorMessage || "Failed to look up agent" };
|
|
19776
|
+
}
|
|
19777
|
+
if (!agentResult.value) {
|
|
19778
|
+
return { error: `Agent not found: ${options.slug}` };
|
|
19779
|
+
}
|
|
19780
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
19781
|
+
method: "POST",
|
|
19782
|
+
headers: {
|
|
19783
|
+
"Content-Type": "application/json",
|
|
19784
|
+
Authorization: `Bearer ${token}`
|
|
19785
|
+
},
|
|
19786
|
+
body: JSON.stringify({
|
|
19787
|
+
path: "agents:compileSystemPrompt",
|
|
19788
|
+
args: {
|
|
19789
|
+
agentId: agentResult.value._id,
|
|
19790
|
+
environment: options.environment,
|
|
19791
|
+
sampleContext: {
|
|
19792
|
+
message: options.message,
|
|
19793
|
+
channel: options.channel,
|
|
19794
|
+
threadMetadata: options.threadMetadata
|
|
19795
|
+
}
|
|
19796
|
+
}
|
|
19797
|
+
}),
|
|
19798
|
+
signal: AbortSignal.timeout(30000)
|
|
19799
|
+
});
|
|
19800
|
+
const text = await response.text();
|
|
19801
|
+
let json;
|
|
19802
|
+
try {
|
|
19803
|
+
json = JSON.parse(text);
|
|
19804
|
+
} catch {
|
|
19805
|
+
return { error: text || `HTTP ${response.status}` };
|
|
19806
|
+
}
|
|
19807
|
+
if (!response.ok) {
|
|
19808
|
+
const msg = json.errorData?.message || json.errorMessage || text;
|
|
19809
|
+
return { error: msg };
|
|
19810
|
+
}
|
|
19811
|
+
if (json.status === "success" && json.value) {
|
|
19812
|
+
return { result: json.value };
|
|
19813
|
+
}
|
|
19814
|
+
if (json.status === "success" && json.value === null) {
|
|
19815
|
+
return { error: `Agent not found or no config for environment: ${options.environment}` };
|
|
19816
|
+
}
|
|
19817
|
+
if (json.status === "error") {
|
|
19818
|
+
return { error: json.errorData?.message || json.errorMessage || "Unknown error from Convex" };
|
|
19819
|
+
}
|
|
19820
|
+
return { error: `Unexpected response: ${text}` };
|
|
19821
|
+
}
|
|
19713
19822
|
async function getPullState(organizationId, environment = "development") {
|
|
19714
19823
|
const credentials = loadCredentials();
|
|
19715
19824
|
const apiKey = getApiKey();
|
|
@@ -19802,6 +19911,7 @@ async function browserLoginInternal(spinner) {
|
|
|
19802
19911
|
const authPromise = new Promise((resolve, reject) => {
|
|
19803
19912
|
const server = Bun.serve({
|
|
19804
19913
|
port: AUTH_CALLBACK_PORT,
|
|
19914
|
+
hostname: "127.0.0.1",
|
|
19805
19915
|
async fetch(req) {
|
|
19806
19916
|
const url = new URL(req.url);
|
|
19807
19917
|
if (url.pathname === "/callback") {
|
|
@@ -20102,9 +20212,9 @@ logs/
|
|
|
20102
20212
|
}
|
|
20103
20213
|
function getEntityTypeTs(name, slug) {
|
|
20104
20214
|
const displayName = name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
20105
|
-
return `import {
|
|
20215
|
+
return `import { defineData } from 'struere'
|
|
20106
20216
|
|
|
20107
|
-
export default
|
|
20217
|
+
export default defineData({
|
|
20108
20218
|
name: "${displayName}",
|
|
20109
20219
|
slug: "${slug}",
|
|
20110
20220
|
schema: {
|
|
@@ -20520,11 +20630,11 @@ function validateObjectProperties(schema, path) {
|
|
|
20520
20630
|
}
|
|
20521
20631
|
}
|
|
20522
20632
|
|
|
20523
|
-
function
|
|
20524
|
-
if (!config.name) throw new Error('
|
|
20525
|
-
if (!config.slug) throw new Error('
|
|
20526
|
-
if (!config.schema) throw new Error('
|
|
20527
|
-
if (config.schema.type !== 'object') throw new Error('
|
|
20633
|
+
function defineData(config) {
|
|
20634
|
+
if (!config.name) throw new Error('Data type name is required')
|
|
20635
|
+
if (!config.slug) throw new Error('Data type slug is required')
|
|
20636
|
+
if (!config.schema) throw new Error('Data type schema is required')
|
|
20637
|
+
if (config.schema.type !== 'object') throw new Error('Data type schema must be an object type')
|
|
20528
20638
|
if (config.schema.properties) {
|
|
20529
20639
|
for (const [key, value] of Object.entries(config.schema.properties)) {
|
|
20530
20640
|
validateObjectProperties(value, key)
|
|
@@ -20599,7 +20709,7 @@ function defineConfig(config) {
|
|
|
20599
20709
|
}
|
|
20600
20710
|
}
|
|
20601
20711
|
|
|
20602
|
-
export { defineAgent, defineRole,
|
|
20712
|
+
export { defineAgent, defineRole, defineData, defineTrigger, defineTools, defineConfig }
|
|
20603
20713
|
`;
|
|
20604
20714
|
function registerStruerePlugin() {
|
|
20605
20715
|
if (registered)
|
|
@@ -20776,7 +20886,7 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20776
20886
|
|
|
20777
20887
|
export function defineAgent(config: AgentConfig): AgentConfig
|
|
20778
20888
|
export function defineRole(config: RoleConfig): RoleConfig
|
|
20779
|
-
export function
|
|
20889
|
+
export function defineData(config: EntityTypeConfig): EntityTypeConfig
|
|
20780
20890
|
export function defineTrigger(config: TriggerConfig): TriggerConfig
|
|
20781
20891
|
export function defineTools(tools: ToolDefinition[]): ToolReference[]
|
|
20782
20892
|
export function defineConfig(config?: Partial<FrameworkConfig>): FrameworkConfig
|
|
@@ -20950,7 +21060,7 @@ function buildProjectContext(orgName, resources) {
|
|
|
20950
21060
|
}
|
|
20951
21061
|
if (resources.entityTypes.length > 0) {
|
|
20952
21062
|
lines.push("");
|
|
20953
|
-
lines.push(`###
|
|
21063
|
+
lines.push(`### Data Types (${resources.entityTypes.length})`);
|
|
20954
21064
|
for (const et of resources.entityTypes) {
|
|
20955
21065
|
const fields = et.schema?.properties ? Object.keys(et.schema.properties).join(", ") : "";
|
|
20956
21066
|
const fieldStr = fields ? ` \u2014 fields: ${fields}` : "";
|
|
@@ -20986,7 +21096,7 @@ function buildDocument(projectContext) {
|
|
|
20986
21096
|
const lines = [];
|
|
20987
21097
|
lines.push(`# Struere Workspace`);
|
|
20988
21098
|
lines.push("");
|
|
20989
|
-
lines.push(`> This is a Struere workspace project. You define agents,
|
|
21099
|
+
lines.push(`> This is a Struere workspace project. You define agents, data types, roles, triggers, and custom tools here. The CLI syncs them to the Convex backend.`);
|
|
20990
21100
|
lines.push("");
|
|
20991
21101
|
lines.push(`## Agent Usage`);
|
|
20992
21102
|
lines.push("");
|
|
@@ -21006,7 +21116,7 @@ function buildDocument(projectContext) {
|
|
|
21006
21116
|
lines.push("");
|
|
21007
21117
|
lines.push("**JSON output**: Most commands support `--json` for structured output:");
|
|
21008
21118
|
lines.push("```bash");
|
|
21009
|
-
lines.push("struere
|
|
21119
|
+
lines.push("struere data list <type> --json");
|
|
21010
21120
|
lines.push("struere status --json");
|
|
21011
21121
|
lines.push("struere deploy --json --force");
|
|
21012
21122
|
lines.push("```");
|
|
@@ -21023,7 +21133,7 @@ function buildDocument(projectContext) {
|
|
|
21023
21133
|
lines.push("");
|
|
21024
21134
|
lines.push("```");
|
|
21025
21135
|
lines.push("agents/ # Agent definitions (one file per agent)");
|
|
21026
|
-
lines.push("entity-types/ #
|
|
21136
|
+
lines.push("entity-types/ # Data type schemas (like DB tables)");
|
|
21027
21137
|
lines.push("roles/ # RBAC roles with policies, scope rules, field masks");
|
|
21028
21138
|
lines.push("triggers/ # Automation rules (react to entity changes)");
|
|
21029
21139
|
lines.push("tools/index.ts # Custom tools shared by all agents");
|
|
@@ -21039,16 +21149,16 @@ function buildDocument(projectContext) {
|
|
|
21039
21149
|
lines.push("| `struere sync` | One-shot sync to Convex and exit (agent-friendly) |");
|
|
21040
21150
|
lines.push("| `struere dev` | Watch files and sync to Convex on save |");
|
|
21041
21151
|
lines.push("| `struere deploy` | Push development config to production |");
|
|
21042
|
-
lines.push("| `struere add agent\\|
|
|
21152
|
+
lines.push("| `struere add agent\\|data-type\\|role\\|trigger\\|eval\\|fixture <name>` | Scaffold a new resource |");
|
|
21043
21153
|
lines.push("| `struere status` | Compare local vs remote state |");
|
|
21044
21154
|
lines.push("| `struere pull` | Download remote resources to local files |");
|
|
21045
|
-
lines.push("| `struere
|
|
21046
|
-
lines.push("| `struere
|
|
21047
|
-
lines.push("| `struere
|
|
21048
|
-
lines.push("| `struere
|
|
21049
|
-
lines.push("| `struere
|
|
21050
|
-
lines.push("| `struere
|
|
21051
|
-
lines.push("| `struere
|
|
21155
|
+
lines.push("| `struere data types` | List data types in an environment |");
|
|
21156
|
+
lines.push("| `struere data list <type>` | List records (supports `--status`, `--limit`, `--json`) |");
|
|
21157
|
+
lines.push("| `struere data get <id>` | Get record details |");
|
|
21158
|
+
lines.push("| `struere data create <type>` | Create record (interactive or `--data <json>`) |");
|
|
21159
|
+
lines.push("| `struere data update <id>` | Update record (`--data <json>`, `--status`) |");
|
|
21160
|
+
lines.push("| `struere data delete <id>` | Delete record (with confirmation) |");
|
|
21161
|
+
lines.push("| `struere data search <type> <query>` | Search records by text |");
|
|
21052
21162
|
lines.push("| `struere eval run <suite>` | Run an eval suite and write Markdown results |");
|
|
21053
21163
|
lines.push("| `struere eval run <suite> --case <name>` | Run specific case(s) by name |");
|
|
21054
21164
|
lines.push("| `struere eval run <suite> --tag <tag>` | Run cases matching a tag |");
|
|
@@ -21060,7 +21170,7 @@ function buildDocument(projectContext) {
|
|
|
21060
21170
|
lines.push("");
|
|
21061
21171
|
lines.push(`## Key Patterns`);
|
|
21062
21172
|
lines.push("");
|
|
21063
|
-
lines.push("- **Imports**: `import { defineAgent,
|
|
21173
|
+
lines.push("- **Imports**: `import { defineAgent, defineData, defineRole, defineTrigger, defineTools } from 'struere'`");
|
|
21064
21174
|
lines.push("- **Default model**: `grok-4-1-fast` (provider: `xai`). Also supports `anthropic`, `openai` and `google`");
|
|
21065
21175
|
lines.push("- **Scope rule values**: `actor.userId`, `actor.entityId`, `actor.organizationId`, `actor.relatedIds:TYPE`, `literal:VALUE`");
|
|
21066
21176
|
lines.push("- **Policy actions**: `create`, `read`, `update`, `delete`, `list` (deny overrides allow)");
|
|
@@ -21157,7 +21267,7 @@ function buildDocument(projectContext) {
|
|
|
21157
21267
|
lines.push("### SDK");
|
|
21158
21268
|
lines.push(`- [SDK Overview](${DOCS_BASE}/sdk/overview.md)`);
|
|
21159
21269
|
lines.push(`- [defineAgent](${DOCS_BASE}/sdk/define-agent.md)`);
|
|
21160
|
-
lines.push(`- [
|
|
21270
|
+
lines.push(`- [defineData](${DOCS_BASE}/sdk/define-data.md)`);
|
|
21161
21271
|
lines.push(`- [defineRole](${DOCS_BASE}/sdk/define-role.md)`);
|
|
21162
21272
|
lines.push(`- [defineTrigger](${DOCS_BASE}/sdk/define-trigger.md)`);
|
|
21163
21273
|
lines.push(`- [defineTools](${DOCS_BASE}/sdk/define-tools.md)`);
|
|
@@ -21168,7 +21278,7 @@ function buildDocument(projectContext) {
|
|
|
21168
21278
|
lines.push(`- [System Prompt Templates](${DOCS_BASE}/tools/system-prompt-templates.md)`);
|
|
21169
21279
|
lines.push("");
|
|
21170
21280
|
lines.push("### Platform");
|
|
21171
|
-
lines.push(`- [
|
|
21281
|
+
lines.push(`- [Data](${DOCS_BASE}/platform/data.md)`);
|
|
21172
21282
|
lines.push(`- [Permissions](${DOCS_BASE}/platform/permissions.md)`);
|
|
21173
21283
|
lines.push(`- [Agents](${DOCS_BASE}/platform/agents.md)`);
|
|
21174
21284
|
lines.push(`- [Events](${DOCS_BASE}/platform/events.md)`);
|
|
@@ -21505,7 +21615,7 @@ var initCommand = new Command("init").description("Initialize a new Struere orga
|
|
|
21505
21615
|
console.log();
|
|
21506
21616
|
console.log(source_default.gray("Project structure:"));
|
|
21507
21617
|
console.log(source_default.gray(" agents/ "), source_default.cyan("Agent definitions"));
|
|
21508
|
-
console.log(source_default.gray(" entity-types/ "), source_default.cyan("
|
|
21618
|
+
console.log(source_default.gray(" entity-types/ "), source_default.cyan("Data type schemas"));
|
|
21509
21619
|
console.log(source_default.gray(" roles/ "), source_default.cyan("Role + permission definitions"));
|
|
21510
21620
|
console.log(source_default.gray(" tools/ "), source_default.cyan("Shared custom tools"));
|
|
21511
21621
|
console.log();
|
|
@@ -21563,7 +21673,9 @@ var BUILTIN_TOOLS = [
|
|
|
21563
21673
|
"airtable.createRecords",
|
|
21564
21674
|
"airtable.updateRecords",
|
|
21565
21675
|
"airtable.deleteRecords",
|
|
21566
|
-
"email.send"
|
|
21676
|
+
"email.send",
|
|
21677
|
+
"payment.create",
|
|
21678
|
+
"payment.getStatus"
|
|
21567
21679
|
];
|
|
21568
21680
|
function extractSyncPayload(resources) {
|
|
21569
21681
|
const customToolsMap = new Map;
|
|
@@ -21618,7 +21730,9 @@ function extractSyncPayload(resources) {
|
|
|
21618
21730
|
userMessage: t.user,
|
|
21619
21731
|
assertions: t.assertions
|
|
21620
21732
|
})),
|
|
21621
|
-
finalAssertions: c.finalAssertions
|
|
21733
|
+
finalAssertions: c.finalAssertions,
|
|
21734
|
+
channel: c.channel,
|
|
21735
|
+
contextParams: c.contextParams
|
|
21622
21736
|
}))
|
|
21623
21737
|
})) : undefined;
|
|
21624
21738
|
const triggers = resources.triggers.length > 0 ? resources.triggers.map((t) => ({
|
|
@@ -21734,7 +21848,9 @@ function getBuiltinToolDescription(name) {
|
|
|
21734
21848
|
"airtable.createRecords": "Create up to 10 records in an Airtable table",
|
|
21735
21849
|
"airtable.updateRecords": "Update up to 10 records in an Airtable table",
|
|
21736
21850
|
"airtable.deleteRecords": "Delete up to 10 records from an Airtable table",
|
|
21737
|
-
"email.send": "Send an email via Resend"
|
|
21851
|
+
"email.send": "Send an email via Resend",
|
|
21852
|
+
"payment.create": "Create a payment link via Flow.cl and return the URL",
|
|
21853
|
+
"payment.getStatus": "Check the current status of a payment"
|
|
21738
21854
|
};
|
|
21739
21855
|
return descriptions[name] || name;
|
|
21740
21856
|
}
|
|
@@ -22042,6 +22158,24 @@ function getBuiltinToolParameters(name) {
|
|
|
22042
22158
|
replyTo: { type: "string", description: "Reply-to email address" }
|
|
22043
22159
|
},
|
|
22044
22160
|
required: ["to", "subject"]
|
|
22161
|
+
},
|
|
22162
|
+
"payment.create": {
|
|
22163
|
+
type: "object",
|
|
22164
|
+
properties: {
|
|
22165
|
+
amount: { type: "number", description: "Payment amount in the smallest currency unit" },
|
|
22166
|
+
description: { type: "string", description: "Description of the payment" },
|
|
22167
|
+
currency: { type: "string", description: "Currency code (defaults to CLP)" },
|
|
22168
|
+
customerEmail: { type: "string", description: "Customer email address" },
|
|
22169
|
+
entityId: { type: "string", description: "Optional entity ID to link the payment to" }
|
|
22170
|
+
},
|
|
22171
|
+
required: ["amount", "description"]
|
|
22172
|
+
},
|
|
22173
|
+
"payment.getStatus": {
|
|
22174
|
+
type: "object",
|
|
22175
|
+
properties: {
|
|
22176
|
+
entityId: { type: "string", description: "Payment entity ID to check status for" }
|
|
22177
|
+
},
|
|
22178
|
+
required: ["entityId"]
|
|
22045
22179
|
}
|
|
22046
22180
|
};
|
|
22047
22181
|
return schemas[name] || { type: "object", properties: {} };
|
|
@@ -22118,7 +22252,7 @@ async function checkForDeletions(resources, organizationId, environment) {
|
|
|
22118
22252
|
deletions.push({ type: "Agents", remote: remoteState.agents.length, local: payload.agents.length, deleted: deletedAgents });
|
|
22119
22253
|
const deletedEntityTypes = remoteState.entityTypes.filter((et) => !localSlugs.entityTypes.has(et.slug)).map((et) => et.name);
|
|
22120
22254
|
if (deletedEntityTypes.length > 0)
|
|
22121
|
-
deletions.push({ type: "
|
|
22255
|
+
deletions.push({ type: "Data types", remote: remoteState.entityTypes.length, local: payload.entityTypes.length, deleted: deletedEntityTypes });
|
|
22122
22256
|
const deletedRoles = remoteState.roles.filter((r) => !localSlugs.roles.has(r.name)).map((r) => r.name);
|
|
22123
22257
|
if (deletedRoles.length > 0)
|
|
22124
22258
|
deletions.push({ type: "Roles", remote: remoteState.roles.length, local: payload.roles.length, deleted: deletedRoles });
|
|
@@ -22223,7 +22357,7 @@ var syncCommand = new Command("sync").description("Sync resources to Convex and
|
|
|
22223
22357
|
process.exit(1);
|
|
22224
22358
|
}
|
|
22225
22359
|
if (!jsonMode && !options.dryRun)
|
|
22226
|
-
output.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length}
|
|
22360
|
+
output.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length} data types, ${resources.roles.length} roles`);
|
|
22227
22361
|
} catch (error) {
|
|
22228
22362
|
if (jsonMode) {
|
|
22229
22363
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }));
|
|
@@ -22255,7 +22389,7 @@ var syncCommand = new Command("sync").description("Sync resources to Convex and
|
|
|
22255
22389
|
console.log(source_default.bold("Dry run \u2014 nothing will be synced"));
|
|
22256
22390
|
console.log();
|
|
22257
22391
|
console.log(source_default.gray(" Agents:"), payload.agents.map((a) => a.slug).join(", ") || "none");
|
|
22258
|
-
console.log(source_default.gray("
|
|
22392
|
+
console.log(source_default.gray(" Data types:"), payload.entityTypes.map((et) => et.slug).join(", ") || "none");
|
|
22259
22393
|
console.log(source_default.gray(" Roles:"), payload.roles.map((r) => r.name).join(", ") || "none");
|
|
22260
22394
|
console.log(source_default.gray(" Triggers:"), (payload.triggers || []).map((t) => t.slug).join(", ") || "none");
|
|
22261
22395
|
if (deletions.length > 0) {
|
|
@@ -22421,7 +22555,7 @@ var devCommand = new Command("dev").description("Watch files and sync to develop
|
|
|
22421
22555
|
spinner.start("Loading resources");
|
|
22422
22556
|
try {
|
|
22423
22557
|
loadedResources = await loadAllResources(cwd);
|
|
22424
|
-
spinner.succeed(`Loaded ${loadedResources.agents.length} agents, ${loadedResources.entityTypes.length}
|
|
22558
|
+
spinner.succeed(`Loaded ${loadedResources.agents.length} agents, ${loadedResources.entityTypes.length} data types, ${loadedResources.roles.length} roles, ${loadedResources.customTools.length} custom tools, ${loadedResources.evalSuites.length} eval suites, ${loadedResources.triggers.length} triggers, ${loadedResources.fixtures.length} fixtures`);
|
|
22425
22559
|
for (const err of loadedResources.errors) {
|
|
22426
22560
|
console.log(source_default.red(" \u2716"), err);
|
|
22427
22561
|
}
|
|
@@ -22634,7 +22768,7 @@ var deployCommand = new Command("deploy").description("Deploy all resources to p
|
|
|
22634
22768
|
try {
|
|
22635
22769
|
resources = await loadAllResources(cwd);
|
|
22636
22770
|
if (!jsonMode)
|
|
22637
|
-
spinner.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length}
|
|
22771
|
+
spinner.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length} data types, ${resources.roles.length} roles, ${resources.customTools.length} custom tools, ${resources.evalSuites.length} eval suites`);
|
|
22638
22772
|
for (const err of resources.errors) {
|
|
22639
22773
|
if (!jsonMode)
|
|
22640
22774
|
console.log(source_default.red(" \u2716"), err);
|
|
@@ -22698,7 +22832,7 @@ var deployCommand = new Command("deploy").description("Deploy all resources to p
|
|
|
22698
22832
|
console.log(source_default.gray(" -"), `${source_default.cyan(agent.name)} (${agent.slug}) v${agent.version}`);
|
|
22699
22833
|
}
|
|
22700
22834
|
console.log();
|
|
22701
|
-
console.log("
|
|
22835
|
+
console.log("Data types:");
|
|
22702
22836
|
for (const et of resources.entityTypes) {
|
|
22703
22837
|
console.log(source_default.gray(" -"), source_default.cyan(et.name), `(${et.slug})`);
|
|
22704
22838
|
}
|
|
@@ -22976,7 +23110,7 @@ var whoamiCommand = new Command("whoami").description("Show current logged in us
|
|
|
22976
23110
|
});
|
|
22977
23111
|
|
|
22978
23112
|
// src/cli/commands/add.ts
|
|
22979
|
-
var addCommand = new Command("add").description("Scaffold a new resource").argument("<type>", "Resource type: agent,
|
|
23113
|
+
var addCommand = new Command("add").description("Scaffold a new resource").argument("<type>", "Resource type: agent, data-type, role, eval, trigger, or fixture").argument("<name>", "Resource name").action(async (type, name) => {
|
|
22980
23114
|
const cwd = process.cwd();
|
|
22981
23115
|
console.log();
|
|
22982
23116
|
if (!hasProject(cwd)) {
|
|
@@ -23003,17 +23137,19 @@ var addCommand = new Command("add").description("Scaffold a new resource").argum
|
|
|
23003
23137
|
console.log(source_default.yellow("Agent already exists:"), `agents/${slug}.ts`);
|
|
23004
23138
|
}
|
|
23005
23139
|
break;
|
|
23140
|
+
case "data-type":
|
|
23141
|
+
case "datatype":
|
|
23006
23142
|
case "entity-type":
|
|
23007
23143
|
case "entitytype":
|
|
23008
23144
|
case "type":
|
|
23009
23145
|
result = scaffoldEntityType(cwd, displayName, slug);
|
|
23010
23146
|
if (result.createdFiles.length > 0) {
|
|
23011
|
-
console.log(source_default.green("\u2713"), `Created
|
|
23147
|
+
console.log(source_default.green("\u2713"), `Created data type "${displayName}"`);
|
|
23012
23148
|
for (const file of result.createdFiles) {
|
|
23013
23149
|
console.log(source_default.gray(" \u2192"), file);
|
|
23014
23150
|
}
|
|
23015
23151
|
} else {
|
|
23016
|
-
console.log(source_default.yellow("
|
|
23152
|
+
console.log(source_default.yellow("Data type already exists:"), `entity-types/${slug}.ts`);
|
|
23017
23153
|
}
|
|
23018
23154
|
break;
|
|
23019
23155
|
case "role":
|
|
@@ -23070,10 +23206,10 @@ var addCommand = new Command("add").description("Scaffold a new resource").argum
|
|
|
23070
23206
|
console.log();
|
|
23071
23207
|
console.log("Available types:");
|
|
23072
23208
|
console.log(source_default.gray(" -"), source_default.cyan("agent"), "- Create an AI agent");
|
|
23073
|
-
console.log(source_default.gray(" -"), source_default.cyan("
|
|
23209
|
+
console.log(source_default.gray(" -"), source_default.cyan("data-type"), "- Create a data type schema");
|
|
23074
23210
|
console.log(source_default.gray(" -"), source_default.cyan("role"), "- Create a role with permissions");
|
|
23075
23211
|
console.log(source_default.gray(" -"), source_default.cyan("eval"), "- Create an eval suite (YAML)");
|
|
23076
|
-
console.log(source_default.gray(" -"), source_default.cyan("trigger"), "- Create
|
|
23212
|
+
console.log(source_default.gray(" -"), source_default.cyan("trigger"), "- Create a data trigger");
|
|
23077
23213
|
console.log(source_default.gray(" -"), source_default.cyan("fixture"), "- Create a test data fixture (YAML)");
|
|
23078
23214
|
console.log();
|
|
23079
23215
|
process.exit(1);
|
|
@@ -23153,7 +23289,7 @@ var statusCommand = new Command("status").description("Compare local vs remote s
|
|
|
23153
23289
|
try {
|
|
23154
23290
|
localResources = await loadAllResources(cwd);
|
|
23155
23291
|
if (!jsonMode) {
|
|
23156
|
-
spinner.succeed(`Loaded ${localResources.agents.length} agents, ${localResources.entityTypes.length}
|
|
23292
|
+
spinner.succeed(`Loaded ${localResources.agents.length} agents, ${localResources.entityTypes.length} data types, ${localResources.roles.length} roles, ${localResources.customTools.length} custom tools, ${localResources.evalSuites.length} eval suites`);
|
|
23157
23293
|
for (const err of localResources.errors) {
|
|
23158
23294
|
console.log(source_default.red(" \u2716"), err);
|
|
23159
23295
|
}
|
|
@@ -23241,10 +23377,10 @@ var statusCommand = new Command("status").description("Compare local vs remote s
|
|
|
23241
23377
|
}
|
|
23242
23378
|
}
|
|
23243
23379
|
console.log();
|
|
23244
|
-
console.log(source_default.bold("
|
|
23380
|
+
console.log(source_default.bold("Data Types"));
|
|
23245
23381
|
console.log(source_default.gray("\u2500".repeat(60)));
|
|
23246
23382
|
if (localResources.entityTypes.length === 0 && devState.entityTypes.length === 0) {
|
|
23247
|
-
console.log(source_default.gray(" No
|
|
23383
|
+
console.log(source_default.gray(" No data types"));
|
|
23248
23384
|
} else {
|
|
23249
23385
|
for (const et of localResources.entityTypes) {
|
|
23250
23386
|
const remote = devState.entityTypes.find((r) => r.slug === et.slug);
|
|
@@ -23390,9 +23526,9 @@ function generateEntityTypeFile(entityType) {
|
|
|
23390
23526
|
if (entityType.displayConfig) {
|
|
23391
23527
|
parts.push(` displayConfig: ${stringifyValue(entityType.displayConfig, 2)}`);
|
|
23392
23528
|
}
|
|
23393
|
-
return `import {
|
|
23529
|
+
return `import { defineData } from 'struere'
|
|
23394
23530
|
|
|
23395
|
-
export default
|
|
23531
|
+
export default defineData({
|
|
23396
23532
|
${parts.join(`,
|
|
23397
23533
|
`)},
|
|
23398
23534
|
})
|
|
@@ -24001,20 +24137,20 @@ function flattenEntityForTable(entity) {
|
|
|
24001
24137
|
status: entity.status
|
|
24002
24138
|
};
|
|
24003
24139
|
}
|
|
24004
|
-
var entitiesCommand = new Command("
|
|
24005
|
-
entitiesCommand.command("types").description("List available
|
|
24140
|
+
var entitiesCommand = new Command("data").description("Manage data records");
|
|
24141
|
+
entitiesCommand.command("types").description("List available data types").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (opts) => {
|
|
24006
24142
|
await ensureAuth();
|
|
24007
24143
|
const spinner = ora();
|
|
24008
24144
|
const env2 = opts.env;
|
|
24009
24145
|
const orgId = getOrgId();
|
|
24010
|
-
spinner.start("Fetching
|
|
24146
|
+
spinner.start("Fetching data types");
|
|
24011
24147
|
const { data, error } = await queryEntityTypes(env2, orgId);
|
|
24012
24148
|
if (error || !data) {
|
|
24013
|
-
spinner.fail("Failed to fetch
|
|
24149
|
+
spinner.fail("Failed to fetch data types");
|
|
24014
24150
|
console.log(source_default.red("Error:"), error);
|
|
24015
24151
|
process.exit(1);
|
|
24016
24152
|
}
|
|
24017
|
-
spinner.succeed("
|
|
24153
|
+
spinner.succeed("Data types loaded");
|
|
24018
24154
|
const types = data;
|
|
24019
24155
|
if (opts.json) {
|
|
24020
24156
|
console.log(JSON.stringify(types, null, 2));
|
|
@@ -24037,12 +24173,12 @@ entitiesCommand.command("types").description("List available entity types").opti
|
|
|
24037
24173
|
}));
|
|
24038
24174
|
console.log();
|
|
24039
24175
|
});
|
|
24040
|
-
entitiesCommand.command("list <type>").description("List
|
|
24176
|
+
entitiesCommand.command("list <type>").description("List records of a type").option("--env <environment>", "Environment (development|production)", "development").option("--status <status>", "Filter by status").option("--limit <n>", "Maximum results", "50").option("--json", "Output raw JSON").action(async (type, opts) => {
|
|
24041
24177
|
await ensureAuth();
|
|
24042
24178
|
const spinner = ora();
|
|
24043
24179
|
const env2 = opts.env;
|
|
24044
24180
|
const orgId = getOrgId();
|
|
24045
|
-
spinner.start(`Fetching ${type}
|
|
24181
|
+
spinner.start(`Fetching ${type} records`);
|
|
24046
24182
|
const [entitiesResult, typeResult] = await Promise.all([
|
|
24047
24183
|
queryEntities(type, env2, {
|
|
24048
24184
|
status: opts.status,
|
|
@@ -24051,12 +24187,12 @@ entitiesCommand.command("list <type>").description("List entities of a type").op
|
|
|
24051
24187
|
queryEntityTypeBySlug(type, env2, orgId)
|
|
24052
24188
|
]);
|
|
24053
24189
|
if (entitiesResult.error || !entitiesResult.data) {
|
|
24054
|
-
spinner.fail(`Failed to fetch ${type}
|
|
24190
|
+
spinner.fail(`Failed to fetch ${type} records`);
|
|
24055
24191
|
console.log(source_default.red("Error:"), entitiesResult.error);
|
|
24056
24192
|
process.exit(1);
|
|
24057
24193
|
}
|
|
24058
24194
|
const entities = entitiesResult.data;
|
|
24059
|
-
spinner.succeed(`Found ${entities.length} ${type}
|
|
24195
|
+
spinner.succeed(`Found ${entities.length} ${type} records`);
|
|
24060
24196
|
if (opts.json) {
|
|
24061
24197
|
console.log(JSON.stringify(entities, null, 2));
|
|
24062
24198
|
return;
|
|
@@ -24069,27 +24205,27 @@ entitiesCommand.command("list <type>").description("List entities of a type").op
|
|
|
24069
24205
|
renderTable(columns, entities.map(flattenEntityForTable));
|
|
24070
24206
|
console.log();
|
|
24071
24207
|
});
|
|
24072
|
-
entitiesCommand.command("get <id>").description("Get
|
|
24208
|
+
entitiesCommand.command("get <id>").description("Get record details").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
24073
24209
|
await ensureAuth();
|
|
24074
24210
|
const spinner = ora();
|
|
24075
24211
|
const env2 = opts.env;
|
|
24076
24212
|
const orgId = getOrgId();
|
|
24077
|
-
spinner.start("Resolving
|
|
24213
|
+
spinner.start("Resolving record ID");
|
|
24078
24214
|
const resolved = await resolveEntityId(rawId, env2, orgId);
|
|
24079
24215
|
if (resolved.error || !resolved.data) {
|
|
24080
|
-
spinner.fail("
|
|
24081
|
-
console.log(source_default.red("Error:"), resolved.error || `No
|
|
24216
|
+
spinner.fail("Record not found");
|
|
24217
|
+
console.log(source_default.red("Error:"), resolved.error || `No record matched "${rawId}"`);
|
|
24082
24218
|
process.exit(1);
|
|
24083
24219
|
}
|
|
24084
24220
|
const id = resolved.data;
|
|
24085
|
-
spinner.text = "Fetching
|
|
24221
|
+
spinner.text = "Fetching record";
|
|
24086
24222
|
const { data, error } = await queryEntity(id, env2, orgId);
|
|
24087
24223
|
if (error || !data) {
|
|
24088
|
-
spinner.fail("Failed to fetch
|
|
24089
|
-
console.log(source_default.red("Error:"), error || "
|
|
24224
|
+
spinner.fail("Failed to fetch record");
|
|
24225
|
+
console.log(source_default.red("Error:"), error || "Record not found");
|
|
24090
24226
|
process.exit(1);
|
|
24091
24227
|
}
|
|
24092
|
-
spinner.succeed("
|
|
24228
|
+
spinner.succeed("Record loaded");
|
|
24093
24229
|
const result = data;
|
|
24094
24230
|
if (opts.json) {
|
|
24095
24231
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -24117,7 +24253,7 @@ entitiesCommand.command("get <id>").description("Get entity details").option("--
|
|
|
24117
24253
|
}
|
|
24118
24254
|
console.log();
|
|
24119
24255
|
});
|
|
24120
|
-
entitiesCommand.command("create <type>").description("Create a new
|
|
24256
|
+
entitiesCommand.command("create <type>").description("Create a new record").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Record data as JSON").option("--status <status>", "Initial status").option("--json", "Output raw JSON").action(async (type, opts) => {
|
|
24121
24257
|
await ensureAuth();
|
|
24122
24258
|
const spinner = ora();
|
|
24123
24259
|
const env2 = opts.env;
|
|
@@ -24137,7 +24273,7 @@ entitiesCommand.command("create <type>").description("Create a new entity").opti
|
|
|
24137
24273
|
spinner.start(`Fetching ${type} schema`);
|
|
24138
24274
|
const { data: typeData, error: error2 } = await queryEntityTypeBySlug(type, env2, orgId);
|
|
24139
24275
|
if (error2 || !typeData) {
|
|
24140
|
-
spinner.fail(`
|
|
24276
|
+
spinner.fail(`Data type not found: ${type}`);
|
|
24141
24277
|
console.log(source_default.red("Error:"), error2 || "Not found");
|
|
24142
24278
|
process.exit(1);
|
|
24143
24279
|
}
|
|
@@ -24146,7 +24282,7 @@ entitiesCommand.command("create <type>").description("Create a new entity").opti
|
|
|
24146
24282
|
const entityType = typeData;
|
|
24147
24283
|
const schema = entityType.schema;
|
|
24148
24284
|
if (!schema?.properties) {
|
|
24149
|
-
console.log(source_default.red("
|
|
24285
|
+
console.log(source_default.red("Data type has no schema properties defined"));
|
|
24150
24286
|
process.exit(1);
|
|
24151
24287
|
}
|
|
24152
24288
|
data = {};
|
|
@@ -24175,14 +24311,14 @@ entitiesCommand.command("create <type>").description("Create a new entity").opti
|
|
|
24175
24311
|
}
|
|
24176
24312
|
console.log();
|
|
24177
24313
|
}
|
|
24178
|
-
spinner.start(`Creating ${type}
|
|
24314
|
+
spinner.start(`Creating ${type} record`);
|
|
24179
24315
|
const { data: result, error } = await createEntity(type, data, env2, opts.status, orgId);
|
|
24180
24316
|
if (error) {
|
|
24181
|
-
spinner.fail("Failed to create
|
|
24317
|
+
spinner.fail("Failed to create record");
|
|
24182
24318
|
console.log(source_default.red("Error:"), error);
|
|
24183
24319
|
process.exit(1);
|
|
24184
24320
|
}
|
|
24185
|
-
spinner.succeed(`
|
|
24321
|
+
spinner.succeed(`Record created`);
|
|
24186
24322
|
if (opts.json) {
|
|
24187
24323
|
console.log(JSON.stringify({ id: result }, null, 2));
|
|
24188
24324
|
} else {
|
|
@@ -24191,7 +24327,7 @@ entitiesCommand.command("create <type>").description("Create a new entity").opti
|
|
|
24191
24327
|
console.log();
|
|
24192
24328
|
}
|
|
24193
24329
|
});
|
|
24194
|
-
entitiesCommand.command("update <id>").description("Update
|
|
24330
|
+
entitiesCommand.command("update <id>").description("Update a record").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Update data as JSON").option("--status <status>", "New status").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
24195
24331
|
await ensureAuth();
|
|
24196
24332
|
const spinner = ora();
|
|
24197
24333
|
const env2 = opts.env;
|
|
@@ -24209,63 +24345,63 @@ entitiesCommand.command("update <id>").description("Update an entity").option("-
|
|
|
24209
24345
|
process.exit(1);
|
|
24210
24346
|
}
|
|
24211
24347
|
}
|
|
24212
|
-
spinner.start("Resolving
|
|
24348
|
+
spinner.start("Resolving record ID");
|
|
24213
24349
|
const resolved = await resolveEntityId(rawId, env2, orgId);
|
|
24214
24350
|
if (resolved.error || !resolved.data) {
|
|
24215
|
-
spinner.fail("
|
|
24216
|
-
console.log(source_default.red("Error:"), resolved.error || `No
|
|
24351
|
+
spinner.fail("Record not found");
|
|
24352
|
+
console.log(source_default.red("Error:"), resolved.error || `No record matched "${rawId}"`);
|
|
24217
24353
|
process.exit(1);
|
|
24218
24354
|
}
|
|
24219
24355
|
const id = resolved.data;
|
|
24220
|
-
spinner.text = "Updating
|
|
24356
|
+
spinner.text = "Updating record";
|
|
24221
24357
|
const { data: result, error } = await updateEntity(id, data, env2, opts.status, orgId);
|
|
24222
24358
|
if (error) {
|
|
24223
|
-
spinner.fail("Failed to update
|
|
24359
|
+
spinner.fail("Failed to update record");
|
|
24224
24360
|
console.log(source_default.red("Error:"), error);
|
|
24225
24361
|
process.exit(1);
|
|
24226
24362
|
}
|
|
24227
|
-
spinner.succeed("
|
|
24363
|
+
spinner.succeed("Record updated");
|
|
24228
24364
|
if (opts.json) {
|
|
24229
24365
|
console.log(JSON.stringify(result, null, 2));
|
|
24230
24366
|
} else {
|
|
24231
24367
|
console.log();
|
|
24232
|
-
console.log(source_default.green("
|
|
24368
|
+
console.log(source_default.green(" Record updated successfully"));
|
|
24233
24369
|
console.log();
|
|
24234
24370
|
}
|
|
24235
24371
|
});
|
|
24236
|
-
entitiesCommand.command("delete <id>").description("Delete
|
|
24372
|
+
entitiesCommand.command("delete <id>").description("Delete a record").option("--env <environment>", "Environment (development|production)", "development").option("--yes", "Skip confirmation").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
24237
24373
|
await ensureAuth();
|
|
24238
24374
|
const spinner = ora();
|
|
24239
24375
|
const env2 = opts.env;
|
|
24240
24376
|
const orgId = getOrgId();
|
|
24241
24377
|
const jsonMode = !!opts.json;
|
|
24242
24378
|
if (!jsonMode)
|
|
24243
|
-
spinner.start("Resolving
|
|
24379
|
+
spinner.start("Resolving record ID");
|
|
24244
24380
|
const resolved = await resolveEntityId(rawId, env2, orgId);
|
|
24245
24381
|
if (resolved.error || !resolved.data) {
|
|
24246
24382
|
if (jsonMode) {
|
|
24247
|
-
console.log(JSON.stringify({ success: false, error: resolved.error || `No
|
|
24383
|
+
console.log(JSON.stringify({ success: false, error: resolved.error || `No record matched "${rawId}"` }));
|
|
24248
24384
|
} else {
|
|
24249
|
-
spinner.fail("
|
|
24250
|
-
console.log(source_default.red("Error:"), resolved.error || `No
|
|
24385
|
+
spinner.fail("Record not found");
|
|
24386
|
+
console.log(source_default.red("Error:"), resolved.error || `No record matched "${rawId}"`);
|
|
24251
24387
|
}
|
|
24252
24388
|
process.exit(1);
|
|
24253
24389
|
}
|
|
24254
24390
|
const id = resolved.data;
|
|
24255
24391
|
if (!jsonMode)
|
|
24256
|
-
spinner.text = "Fetching
|
|
24392
|
+
spinner.text = "Fetching record";
|
|
24257
24393
|
const { data, error: fetchError } = await queryEntity(id, env2, orgId);
|
|
24258
24394
|
if (fetchError || !data) {
|
|
24259
24395
|
if (jsonMode) {
|
|
24260
|
-
console.log(JSON.stringify({ success: false, error: fetchError || "
|
|
24396
|
+
console.log(JSON.stringify({ success: false, error: fetchError || "Record not found" }));
|
|
24261
24397
|
} else {
|
|
24262
|
-
spinner.fail("Failed to fetch
|
|
24263
|
-
console.log(source_default.red("Error:"), fetchError || "
|
|
24398
|
+
spinner.fail("Failed to fetch record");
|
|
24399
|
+
console.log(source_default.red("Error:"), fetchError || "Record not found");
|
|
24264
24400
|
}
|
|
24265
24401
|
process.exit(1);
|
|
24266
24402
|
}
|
|
24267
24403
|
if (!jsonMode)
|
|
24268
|
-
spinner.succeed("
|
|
24404
|
+
spinner.succeed("Record loaded");
|
|
24269
24405
|
const result = data;
|
|
24270
24406
|
const entity = result.entity;
|
|
24271
24407
|
const entityType = result.entityType;
|
|
@@ -24283,7 +24419,7 @@ entitiesCommand.command("delete <id>").description("Delete an entity").option("-
|
|
|
24283
24419
|
}
|
|
24284
24420
|
if (!opts.yes && !jsonMode && isInteractive2()) {
|
|
24285
24421
|
const confirmed = await esm_default2({
|
|
24286
|
-
message: "Are you sure you want to delete this
|
|
24422
|
+
message: "Are you sure you want to delete this record?",
|
|
24287
24423
|
default: false
|
|
24288
24424
|
});
|
|
24289
24425
|
if (!confirmed) {
|
|
@@ -24292,13 +24428,13 @@ entitiesCommand.command("delete <id>").description("Delete an entity").option("-
|
|
|
24292
24428
|
}
|
|
24293
24429
|
}
|
|
24294
24430
|
if (!jsonMode)
|
|
24295
|
-
spinner.start("Deleting
|
|
24431
|
+
spinner.start("Deleting record");
|
|
24296
24432
|
const { error } = await removeEntity(id, env2, orgId);
|
|
24297
24433
|
if (error) {
|
|
24298
24434
|
if (jsonMode) {
|
|
24299
24435
|
console.log(JSON.stringify({ success: false, error }));
|
|
24300
24436
|
} else {
|
|
24301
|
-
spinner.fail("Failed to delete
|
|
24437
|
+
spinner.fail("Failed to delete record");
|
|
24302
24438
|
console.log(source_default.red("Error:"), error);
|
|
24303
24439
|
}
|
|
24304
24440
|
process.exit(1);
|
|
@@ -24306,11 +24442,11 @@ entitiesCommand.command("delete <id>").description("Delete an entity").option("-
|
|
|
24306
24442
|
if (jsonMode) {
|
|
24307
24443
|
console.log(JSON.stringify({ success: true, id }));
|
|
24308
24444
|
} else {
|
|
24309
|
-
spinner.succeed("
|
|
24445
|
+
spinner.succeed("Record deleted");
|
|
24310
24446
|
console.log();
|
|
24311
24447
|
}
|
|
24312
24448
|
});
|
|
24313
|
-
entitiesCommand.command("search <type> <query>").description("Search
|
|
24449
|
+
entitiesCommand.command("search <type> <query>").description("Search records").option("--env <environment>", "Environment (development|production)", "development").option("--limit <n>", "Maximum results", "25").option("--json", "Output raw JSON").action(async (type, query, opts) => {
|
|
24314
24450
|
await ensureAuth();
|
|
24315
24451
|
const spinner = ora();
|
|
24316
24452
|
const env2 = opts.env;
|
|
@@ -25313,7 +25449,7 @@ async function setIntegrationStatus(provider, env2, status) {
|
|
|
25313
25449
|
}
|
|
25314
25450
|
|
|
25315
25451
|
// src/cli/commands/integration.ts
|
|
25316
|
-
var VALID_PROVIDERS = ["airtable", "resend"];
|
|
25452
|
+
var VALID_PROVIDERS = ["airtable", "resend", "flow"];
|
|
25317
25453
|
async function ensureAuth3() {
|
|
25318
25454
|
const cwd = process.cwd();
|
|
25319
25455
|
const nonInteractive = !isInteractive2();
|
|
@@ -25366,6 +25502,8 @@ function getProviderHelp(provider) {
|
|
|
25366
25502
|
return `Usage: struere integration airtable --token <pat> [--base-id <id>] [--test]`;
|
|
25367
25503
|
case "resend":
|
|
25368
25504
|
return `Usage: struere integration resend --from-email <email> [--from-name <name>] [--reply-to <email>]`;
|
|
25505
|
+
case "flow":
|
|
25506
|
+
return `Usage: struere integration flow --api-url <url> --api-key <key> --secret-key <secret> [--return-url <url>]`;
|
|
25369
25507
|
default:
|
|
25370
25508
|
return "";
|
|
25371
25509
|
}
|
|
@@ -25393,9 +25531,23 @@ function buildConfigFromOpts(provider, opts) {
|
|
|
25393
25531
|
return null;
|
|
25394
25532
|
return config;
|
|
25395
25533
|
}
|
|
25534
|
+
if (provider === "flow") {
|
|
25535
|
+
const config = {};
|
|
25536
|
+
if (opts.apiUrl)
|
|
25537
|
+
config.apiUrl = opts.apiUrl;
|
|
25538
|
+
if (opts.apiKey)
|
|
25539
|
+
config.apiKey = opts.apiKey;
|
|
25540
|
+
if (opts.secretKey)
|
|
25541
|
+
config.secretKey = opts.secretKey;
|
|
25542
|
+
if (opts.returnUrl)
|
|
25543
|
+
config.returnUrl = opts.returnUrl;
|
|
25544
|
+
if (Object.keys(config).length === 0)
|
|
25545
|
+
return null;
|
|
25546
|
+
return config;
|
|
25547
|
+
}
|
|
25396
25548
|
return null;
|
|
25397
25549
|
}
|
|
25398
|
-
var integrationCommand = new Command("integration").description("Manage integrations").argument("[provider]", "Integration provider (airtable, resend)").option("--env <environment>", "Environment (development|production)", "development").option("--token <pat>", "Personal access token (airtable)").option("--base-id <id>", "Default base ID (airtable)").option("--from-email <email>", "From email address (resend)").option("--from-name <name>", "From display name (resend)").option("--reply-to <email>", "Reply-to address (resend)").option("--test", "Test the connection after saving").option("--remove", "Remove integration config").option("--enable", "Enable integration").option("--disable", "Disable integration").option("--status", "Show current config status").option("--yes", "Skip confirmation prompts").option("--json", "Output raw JSON").action(async (provider, opts) => {
|
|
25550
|
+
var integrationCommand = new Command("integration").description("Manage integrations").argument("[provider]", "Integration provider (airtable, resend, flow)").option("--env <environment>", "Environment (development|production)", "development").option("--token <pat>", "Personal access token (airtable)").option("--base-id <id>", "Default base ID (airtable)").option("--from-email <email>", "From email address (resend)").option("--from-name <name>", "From display name (resend)").option("--reply-to <email>", "Reply-to address (resend)").option("--api-url <url>", "API URL (flow)").option("--api-key <key>", "API key (flow)").option("--secret-key <secret>", "Secret key (flow)").option("--return-url <url>", "Return URL after payment (flow)").option("--test", "Test the connection after saving").option("--remove", "Remove integration config").option("--enable", "Enable integration").option("--disable", "Disable integration").option("--status", "Show current config status").option("--yes", "Skip confirmation prompts").option("--json", "Output raw JSON").action(async (provider, opts) => {
|
|
25399
25551
|
await ensureAuth3();
|
|
25400
25552
|
const env2 = opts.env;
|
|
25401
25553
|
const out = createOutput();
|
|
@@ -25570,10 +25722,154 @@ var integrationCommand = new Command("integration").description("Manage integrat
|
|
|
25570
25722
|
}
|
|
25571
25723
|
console.log();
|
|
25572
25724
|
});
|
|
25725
|
+
|
|
25726
|
+
// src/cli/commands/compile-prompt.ts
|
|
25727
|
+
var compilePromptCommand = new Command("compile-prompt").description("Compile and preview an agent's system prompt after template processing").argument("<agent-slug>", "Agent slug to compile prompt for").option("--env <env>", "Environment: development | production", "development").option("--message <msg>", "Sample message for template context").option("--channel <channel>", "Sample channel (whatsapp, widget, api, dashboard)").option("--param <key=value...>", "Custom thread param (repeatable)", (val, acc) => {
|
|
25728
|
+
acc.push(val);
|
|
25729
|
+
return acc;
|
|
25730
|
+
}, []).option("--json", "Output full JSON (raw + compiled + context)").option("--raw", "Show raw uncompiled template instead of compiled").action(async (agentSlug, options) => {
|
|
25731
|
+
const spinner = ora();
|
|
25732
|
+
const cwd = process.cwd();
|
|
25733
|
+
const nonInteractive = !isInteractive2();
|
|
25734
|
+
const jsonMode = !!options.json;
|
|
25735
|
+
if (!hasProject(cwd)) {
|
|
25736
|
+
if (nonInteractive) {
|
|
25737
|
+
if (jsonMode) {
|
|
25738
|
+
console.log(JSON.stringify({ success: false, error: "No struere.json found" }));
|
|
25739
|
+
} else {
|
|
25740
|
+
console.log(source_default.red("No struere.json found. Run struere init first."));
|
|
25741
|
+
}
|
|
25742
|
+
process.exit(1);
|
|
25743
|
+
}
|
|
25744
|
+
console.log(source_default.yellow("No struere.json found - initializing project..."));
|
|
25745
|
+
console.log();
|
|
25746
|
+
const success = await runInit(cwd);
|
|
25747
|
+
if (!success) {
|
|
25748
|
+
process.exit(1);
|
|
25749
|
+
}
|
|
25750
|
+
console.log();
|
|
25751
|
+
}
|
|
25752
|
+
const project = loadProject(cwd);
|
|
25753
|
+
if (!project) {
|
|
25754
|
+
if (jsonMode) {
|
|
25755
|
+
console.log(JSON.stringify({ success: false, error: "Failed to load struere.json" }));
|
|
25756
|
+
} else {
|
|
25757
|
+
console.log(source_default.red("Failed to load struere.json"));
|
|
25758
|
+
}
|
|
25759
|
+
process.exit(1);
|
|
25760
|
+
}
|
|
25761
|
+
let credentials = loadCredentials();
|
|
25762
|
+
const apiKey = getApiKey();
|
|
25763
|
+
if (!credentials && !apiKey) {
|
|
25764
|
+
if (nonInteractive) {
|
|
25765
|
+
if (jsonMode) {
|
|
25766
|
+
console.log(JSON.stringify({ success: false, error: "Not authenticated. Set STRUERE_API_KEY or run struere login." }));
|
|
25767
|
+
} else {
|
|
25768
|
+
console.log(source_default.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
|
|
25769
|
+
}
|
|
25770
|
+
process.exit(1);
|
|
25771
|
+
}
|
|
25772
|
+
console.log(source_default.yellow("Not logged in - authenticating..."));
|
|
25773
|
+
console.log();
|
|
25774
|
+
credentials = await performLogin();
|
|
25775
|
+
if (!credentials) {
|
|
25776
|
+
console.log(source_default.red("Authentication failed"));
|
|
25777
|
+
process.exit(1);
|
|
25778
|
+
}
|
|
25779
|
+
console.log();
|
|
25780
|
+
}
|
|
25781
|
+
const threadMetadata = {};
|
|
25782
|
+
for (const param of options.param) {
|
|
25783
|
+
const eqIndex = param.indexOf("=");
|
|
25784
|
+
if (eqIndex === -1) {
|
|
25785
|
+
if (jsonMode) {
|
|
25786
|
+
console.log(JSON.stringify({ success: false, error: `Invalid param format: ${param}. Use key=value.` }));
|
|
25787
|
+
} else {
|
|
25788
|
+
console.log(source_default.red(`Invalid param format: ${param}. Use key=value.`));
|
|
25789
|
+
}
|
|
25790
|
+
process.exit(1);
|
|
25791
|
+
}
|
|
25792
|
+
const key = param.slice(0, eqIndex);
|
|
25793
|
+
const value = param.slice(eqIndex + 1);
|
|
25794
|
+
threadMetadata[key] = value;
|
|
25795
|
+
}
|
|
25796
|
+
const environment = options.env;
|
|
25797
|
+
if (!jsonMode) {
|
|
25798
|
+
spinner.start(`Compiling prompt for ${source_default.cyan(agentSlug)} (${environment})`);
|
|
25799
|
+
}
|
|
25800
|
+
const doCompile = async () => {
|
|
25801
|
+
return compilePrompt({
|
|
25802
|
+
slug: agentSlug,
|
|
25803
|
+
environment,
|
|
25804
|
+
message: options.message,
|
|
25805
|
+
channel: options.channel,
|
|
25806
|
+
threadMetadata: Object.keys(threadMetadata).length > 0 ? threadMetadata : undefined
|
|
25807
|
+
});
|
|
25808
|
+
};
|
|
25809
|
+
let { result, error } = await doCompile();
|
|
25810
|
+
if (error && isAuthError(error) && !nonInteractive) {
|
|
25811
|
+
if (!jsonMode)
|
|
25812
|
+
spinner.fail("Session expired - re-authenticating...");
|
|
25813
|
+
clearCredentials();
|
|
25814
|
+
credentials = await performLogin();
|
|
25815
|
+
if (!credentials) {
|
|
25816
|
+
if (jsonMode) {
|
|
25817
|
+
console.log(JSON.stringify({ success: false, error: "Authentication failed" }));
|
|
25818
|
+
} else {
|
|
25819
|
+
console.log(source_default.red("Authentication failed"));
|
|
25820
|
+
}
|
|
25821
|
+
process.exit(1);
|
|
25822
|
+
}
|
|
25823
|
+
const retry = await doCompile();
|
|
25824
|
+
result = retry.result;
|
|
25825
|
+
error = retry.error;
|
|
25826
|
+
if (!jsonMode && !error)
|
|
25827
|
+
spinner.succeed("Compiled prompt");
|
|
25828
|
+
}
|
|
25829
|
+
if (error) {
|
|
25830
|
+
if (jsonMode) {
|
|
25831
|
+
console.log(JSON.stringify({ success: false, error }));
|
|
25832
|
+
} else {
|
|
25833
|
+
spinner.fail("Failed to compile prompt");
|
|
25834
|
+
console.log(source_default.red("Error:"), error);
|
|
25835
|
+
}
|
|
25836
|
+
process.exit(1);
|
|
25837
|
+
}
|
|
25838
|
+
if (!result) {
|
|
25839
|
+
if (jsonMode) {
|
|
25840
|
+
console.log(JSON.stringify({ success: false, error: "No result returned" }));
|
|
25841
|
+
} else {
|
|
25842
|
+
spinner.fail("No result returned");
|
|
25843
|
+
}
|
|
25844
|
+
process.exit(1);
|
|
25845
|
+
}
|
|
25846
|
+
if (!jsonMode)
|
|
25847
|
+
spinner.succeed("Compiled prompt");
|
|
25848
|
+
if (jsonMode) {
|
|
25849
|
+
console.log(JSON.stringify({
|
|
25850
|
+
success: true,
|
|
25851
|
+
raw: result.raw,
|
|
25852
|
+
compiled: result.compiled,
|
|
25853
|
+
context: result.context
|
|
25854
|
+
}, null, 2));
|
|
25855
|
+
} else if (options.raw) {
|
|
25856
|
+
console.log();
|
|
25857
|
+
console.log(source_default.bold("Raw System Prompt"));
|
|
25858
|
+
console.log(source_default.gray("\u2500".repeat(60)));
|
|
25859
|
+
console.log(result.raw);
|
|
25860
|
+
console.log(source_default.gray("\u2500".repeat(60)));
|
|
25861
|
+
} else {
|
|
25862
|
+
console.log();
|
|
25863
|
+
console.log(source_default.bold("Compiled System Prompt"));
|
|
25864
|
+
console.log(source_default.gray("\u2500".repeat(60)));
|
|
25865
|
+
console.log(result.compiled);
|
|
25866
|
+
console.log(source_default.gray("\u2500".repeat(60)));
|
|
25867
|
+
}
|
|
25868
|
+
});
|
|
25573
25869
|
// package.json
|
|
25574
25870
|
var package_default = {
|
|
25575
25871
|
name: "struere",
|
|
25576
|
-
version: "0.9.
|
|
25872
|
+
version: "0.9.7",
|
|
25577
25873
|
description: "Build, test, and deploy AI agents",
|
|
25578
25874
|
keywords: [
|
|
25579
25875
|
"ai",
|
|
@@ -25688,4 +25984,5 @@ program.addCommand(docsCommand);
|
|
|
25688
25984
|
program.addCommand(evalCommand);
|
|
25689
25985
|
program.addCommand(templatesCommand);
|
|
25690
25986
|
program.addCommand(integrationCommand);
|
|
25987
|
+
program.addCommand(compilePromptCommand);
|
|
25691
25988
|
program.parse();
|