struere 0.9.7 → 0.9.9
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 +235 -103
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/org.d.ts +5 -0
- package/dist/cli/commands/org.d.ts.map +1 -0
- package/dist/cli/index.js +675 -539
- package/dist/cli/utils/__tests__/plugin.test.d.ts +2 -0
- package/dist/cli/utils/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/cli/utils/config.d.ts +2 -2
- package/dist/cli/utils/config.d.ts.map +1 -1
- package/dist/cli/utils/convex.d.ts +6 -1
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/entities.d.ts.map +1 -1
- package/dist/cli/utils/evals.d.ts.map +1 -1
- package/dist/cli/utils/extractor.d.ts +1 -0
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/integrations.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/cli/utils/whatsapp.d.ts +4 -4
- package/dist/cli/utils/whatsapp.d.ts.map +1 -1
- package/dist/define/__tests__/agent.test.d.ts +2 -0
- package/dist/define/__tests__/agent.test.d.ts.map +1 -0
- package/dist/define/__tests__/entityType.test.d.ts +2 -0
- package/dist/define/__tests__/entityType.test.d.ts.map +1 -0
- package/dist/define/__tests__/role.test.d.ts +2 -0
- package/dist/define/__tests__/role.test.d.ts.map +1 -0
- package/dist/define/__tests__/trigger.test.d.ts +2 -0
- package/dist/define/__tests__/trigger.test.d.ts.map +1 -0
- package/dist/define/index.d.ts +0 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/tools.d.ts +1 -0
- package/dist/define/tools.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -29
- package/dist/types.d.ts +56 -21
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -19463,11 +19463,13 @@ function getApiKey() {
|
|
|
19463
19463
|
return process.env.STRUERE_API_KEY || null;
|
|
19464
19464
|
}
|
|
19465
19465
|
|
|
19466
|
-
// src/cli/utils/
|
|
19466
|
+
// src/cli/utils/config.ts
|
|
19467
19467
|
var CONVEX_URL = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
19468
19468
|
function getSiteUrl() {
|
|
19469
19469
|
return CONVEX_URL.replace(".cloud", ".site");
|
|
19470
19470
|
}
|
|
19471
|
+
|
|
19472
|
+
// src/cli/utils/convex.ts
|
|
19471
19473
|
async function refreshToken() {
|
|
19472
19474
|
const credentials = loadCredentials();
|
|
19473
19475
|
if (!credentials?.sessionId)
|
|
@@ -19492,6 +19494,38 @@ async function refreshToken() {
|
|
|
19492
19494
|
return null;
|
|
19493
19495
|
}
|
|
19494
19496
|
}
|
|
19497
|
+
async function createOrganization(token, name, slug) {
|
|
19498
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
19499
|
+
method: "POST",
|
|
19500
|
+
headers: {
|
|
19501
|
+
"Content-Type": "application/json",
|
|
19502
|
+
Authorization: `Bearer ${token}`
|
|
19503
|
+
},
|
|
19504
|
+
body: JSON.stringify({
|
|
19505
|
+
path: "organizations:createFromCli",
|
|
19506
|
+
args: { name, slug }
|
|
19507
|
+
}),
|
|
19508
|
+
signal: AbortSignal.timeout(30000)
|
|
19509
|
+
});
|
|
19510
|
+
const text = await response.text();
|
|
19511
|
+
let json;
|
|
19512
|
+
try {
|
|
19513
|
+
json = JSON.parse(text);
|
|
19514
|
+
} catch {
|
|
19515
|
+
return { error: text || `HTTP ${response.status}` };
|
|
19516
|
+
}
|
|
19517
|
+
if (!response.ok) {
|
|
19518
|
+
const msg = json.errorData?.message || json.errorMessage || text;
|
|
19519
|
+
return { error: msg };
|
|
19520
|
+
}
|
|
19521
|
+
if (json.status === "success" && json.value) {
|
|
19522
|
+
return { organization: json.value };
|
|
19523
|
+
}
|
|
19524
|
+
if (json.status === "error") {
|
|
19525
|
+
return { error: json.errorData?.message || json.errorMessage || "Unknown error" };
|
|
19526
|
+
}
|
|
19527
|
+
return { error: `Unexpected response: ${text}` };
|
|
19528
|
+
}
|
|
19495
19529
|
async function listMyOrganizations(token) {
|
|
19496
19530
|
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
19497
19531
|
method: "POST",
|
|
@@ -19980,7 +20014,7 @@ async function browserLoginInternal(spinner) {
|
|
|
19980
20014
|
if (organizations.length > 0) {
|
|
19981
20015
|
console.log(source_default.gray("Organizations:"), organizations.map((o) => o.name).join(", "));
|
|
19982
20016
|
} else {
|
|
19983
|
-
console.log(source_default.yellow("No organizations found.
|
|
20017
|
+
console.log(source_default.yellow("No organizations found. Run"), source_default.cyan("struere org create"), source_default.yellow("to create one."));
|
|
19984
20018
|
}
|
|
19985
20019
|
console.log();
|
|
19986
20020
|
return credentials;
|
|
@@ -20292,7 +20326,7 @@ export default defineTools([
|
|
|
20292
20326
|
},
|
|
20293
20327
|
},
|
|
20294
20328
|
},
|
|
20295
|
-
handler: async (args, context, fetch) => {
|
|
20329
|
+
handler: async (args, context, struere, fetch) => {
|
|
20296
20330
|
const timezone = (args.timezone as string) || 'UTC'
|
|
20297
20331
|
const now = new Date()
|
|
20298
20332
|
return {
|
|
@@ -20321,7 +20355,7 @@ export default defineTools([
|
|
|
20321
20355
|
},
|
|
20322
20356
|
required: ['message'],
|
|
20323
20357
|
},
|
|
20324
|
-
handler: async (args, context, fetch) => {
|
|
20358
|
+
handler: async (args, context, struere, fetch) => {
|
|
20325
20359
|
const webhookUrl = process.env.SLACK_WEBHOOK_URL
|
|
20326
20360
|
if (!webhookUrl) {
|
|
20327
20361
|
return { success: false, error: 'SLACK_WEBHOOK_URL not configured' }
|
|
@@ -20662,6 +20696,15 @@ function defineTrigger(config) {
|
|
|
20662
20696
|
if (!action.tool) throw new Error('Trigger action tool is required')
|
|
20663
20697
|
if (!action.args || typeof action.args !== 'object') throw new Error('Trigger action args must be an object')
|
|
20664
20698
|
}
|
|
20699
|
+
if (config.schedule) {
|
|
20700
|
+
if (config.schedule.delay !== undefined && config.schedule.at !== undefined) throw new Error('Trigger schedule cannot have both "delay" and "at"')
|
|
20701
|
+
if (config.schedule.delay !== undefined && typeof config.schedule.delay !== 'number') throw new Error('Trigger schedule.delay must be a number')
|
|
20702
|
+
if (config.schedule.at !== undefined && typeof config.schedule.at !== 'string') throw new Error('Trigger schedule.at must be a string')
|
|
20703
|
+
}
|
|
20704
|
+
if (config.retry) {
|
|
20705
|
+
if (config.retry.maxAttempts !== undefined && (typeof config.retry.maxAttempts !== 'number' || config.retry.maxAttempts < 1)) throw new Error('Trigger retry.maxAttempts must be a positive number')
|
|
20706
|
+
if (config.retry.backoffMs !== undefined && (typeof config.retry.backoffMs !== 'number' || config.retry.backoffMs < 0)) throw new Error('Trigger retry.backoffMs must be a non-negative number')
|
|
20707
|
+
}
|
|
20665
20708
|
return config
|
|
20666
20709
|
}
|
|
20667
20710
|
|
|
@@ -20692,24 +20735,7 @@ function defineTools(tools) {
|
|
|
20692
20735
|
})
|
|
20693
20736
|
}
|
|
20694
20737
|
|
|
20695
|
-
|
|
20696
|
-
const defaultConfig = {
|
|
20697
|
-
port: 3000,
|
|
20698
|
-
host: 'localhost',
|
|
20699
|
-
cors: { origins: ['http://localhost:3000'], credentials: true },
|
|
20700
|
-
logging: { level: 'info', format: 'pretty' },
|
|
20701
|
-
auth: { type: 'none' },
|
|
20702
|
-
}
|
|
20703
|
-
return {
|
|
20704
|
-
...defaultConfig,
|
|
20705
|
-
...config,
|
|
20706
|
-
cors: config.cors ? { ...defaultConfig.cors, ...config.cors } : defaultConfig.cors,
|
|
20707
|
-
logging: config.logging ? { ...defaultConfig.logging, ...config.logging } : defaultConfig.logging,
|
|
20708
|
-
auth: config.auth ? { ...defaultConfig.auth, ...config.auth } : defaultConfig.auth,
|
|
20709
|
-
}
|
|
20710
|
-
}
|
|
20711
|
-
|
|
20712
|
-
export { defineAgent, defineRole, defineData, defineTrigger, defineTools, defineConfig }
|
|
20738
|
+
export { defineAgent, defineRole, defineData, defineTrigger, defineTools }
|
|
20713
20739
|
`;
|
|
20714
20740
|
function registerStruerePlugin() {
|
|
20715
20741
|
if (registered)
|
|
@@ -20755,11 +20781,6 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20755
20781
|
export interface ToolContext {
|
|
20756
20782
|
conversationId: string
|
|
20757
20783
|
userId?: string
|
|
20758
|
-
state: {
|
|
20759
|
-
get<T>(key: string): Promise<T | undefined>
|
|
20760
|
-
set<T>(key: string, value: T): Promise<void>
|
|
20761
|
-
delete(key: string): Promise<void>
|
|
20762
|
-
}
|
|
20763
20784
|
}
|
|
20764
20785
|
|
|
20765
20786
|
export type ToolHandler = (params: Record<string, unknown>, context: ToolContext) => Promise<unknown>
|
|
@@ -20788,6 +20809,12 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20788
20809
|
model?: ModelConfig
|
|
20789
20810
|
tools?: string[]
|
|
20790
20811
|
firstMessageSuggestions?: string[]
|
|
20812
|
+
threadContextParams?: Array<{
|
|
20813
|
+
name: string
|
|
20814
|
+
type: 'string' | 'number' | 'boolean'
|
|
20815
|
+
required?: boolean
|
|
20816
|
+
description?: string
|
|
20817
|
+
}>
|
|
20791
20818
|
}
|
|
20792
20819
|
|
|
20793
20820
|
export interface JSONSchemaProperty {
|
|
@@ -20824,13 +20851,12 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20824
20851
|
resource: string
|
|
20825
20852
|
actions: string[]
|
|
20826
20853
|
effect: 'allow' | 'deny'
|
|
20827
|
-
priority?: number
|
|
20828
20854
|
}
|
|
20829
20855
|
|
|
20830
20856
|
export interface ScopeRuleConfig {
|
|
20831
20857
|
entityType: string
|
|
20832
20858
|
field: string
|
|
20833
|
-
operator: 'eq' | '
|
|
20859
|
+
operator: 'eq' | 'neq' | 'in' | 'contains'
|
|
20834
20860
|
value: string
|
|
20835
20861
|
}
|
|
20836
20862
|
|
|
@@ -20865,22 +20891,15 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20865
20891
|
condition?: Record<string, unknown>
|
|
20866
20892
|
}
|
|
20867
20893
|
actions: TriggerAction[]
|
|
20868
|
-
|
|
20869
|
-
|
|
20870
|
-
|
|
20871
|
-
|
|
20872
|
-
|
|
20873
|
-
cors?: {
|
|
20874
|
-
origins: string[]
|
|
20875
|
-
credentials?: boolean
|
|
20876
|
-
}
|
|
20877
|
-
logging?: {
|
|
20878
|
-
level: 'debug' | 'info' | 'warn' | 'error'
|
|
20879
|
-
format?: 'json' | 'pretty'
|
|
20894
|
+
schedule?: {
|
|
20895
|
+
delay?: number
|
|
20896
|
+
at?: string
|
|
20897
|
+
offset?: number
|
|
20898
|
+
cancelPrevious?: boolean
|
|
20880
20899
|
}
|
|
20881
|
-
|
|
20882
|
-
|
|
20883
|
-
|
|
20900
|
+
retry?: {
|
|
20901
|
+
maxAttempts?: number
|
|
20902
|
+
backoffMs?: number
|
|
20884
20903
|
}
|
|
20885
20904
|
}
|
|
20886
20905
|
|
|
@@ -20889,7 +20908,6 @@ var TYPE_DECLARATIONS = `declare module 'struere' {
|
|
|
20889
20908
|
export function defineData(config: EntityTypeConfig): EntityTypeConfig
|
|
20890
20909
|
export function defineTrigger(config: TriggerConfig): TriggerConfig
|
|
20891
20910
|
export function defineTools(tools: ToolDefinition[]): ToolReference[]
|
|
20892
|
-
export function defineConfig(config?: Partial<FrameworkConfig>): FrameworkConfig
|
|
20893
20911
|
}
|
|
20894
20912
|
`;
|
|
20895
20913
|
function generateTypeDeclarations(cwd) {
|
|
@@ -21445,6 +21463,112 @@ function isOrgAccessError(error) {
|
|
|
21445
21463
|
return message.includes("Access denied") || message.includes("not a member") || message.includes("Organization not found");
|
|
21446
21464
|
}
|
|
21447
21465
|
|
|
21466
|
+
// src/cli/commands/org.ts
|
|
21467
|
+
async function promptCreateOrg(token) {
|
|
21468
|
+
if (!isInteractive2()) {
|
|
21469
|
+
console.log(source_default.red("No organizations found. Run struere org create to create one."));
|
|
21470
|
+
return null;
|
|
21471
|
+
}
|
|
21472
|
+
const shouldCreate = await esm_default2({
|
|
21473
|
+
message: "No organizations found. Create one now?",
|
|
21474
|
+
default: true
|
|
21475
|
+
});
|
|
21476
|
+
if (!shouldCreate)
|
|
21477
|
+
return null;
|
|
21478
|
+
const name = await esm_default3({
|
|
21479
|
+
message: "Organization name:",
|
|
21480
|
+
validate: (v) => v.trim().length > 0 || "Name is required"
|
|
21481
|
+
});
|
|
21482
|
+
const slug = slugify(name.trim());
|
|
21483
|
+
const spinner = ora();
|
|
21484
|
+
spinner.start("Creating organization");
|
|
21485
|
+
const { organization, error } = await createOrganization(token, name.trim(), slug);
|
|
21486
|
+
if (error || !organization) {
|
|
21487
|
+
spinner.fail("Failed to create organization");
|
|
21488
|
+
console.log(source_default.red(error || "Unknown error"));
|
|
21489
|
+
return null;
|
|
21490
|
+
}
|
|
21491
|
+
spinner.succeed(`Created organization ${source_default.cyan(organization.name)} (${organization.slug})`);
|
|
21492
|
+
return organization;
|
|
21493
|
+
}
|
|
21494
|
+
var orgCommand = new Command("org").description("Manage organizations");
|
|
21495
|
+
orgCommand.command("list").description("List your organizations").option("--json", "Output as JSON").action(async (options) => {
|
|
21496
|
+
const credentials = loadCredentials();
|
|
21497
|
+
if (!credentials) {
|
|
21498
|
+
console.log(source_default.red("Not authenticated. Run struere login first."));
|
|
21499
|
+
process.exit(1);
|
|
21500
|
+
}
|
|
21501
|
+
await refreshToken();
|
|
21502
|
+
const fresh = loadCredentials();
|
|
21503
|
+
const token = fresh?.token || credentials.token;
|
|
21504
|
+
const spinner = ora();
|
|
21505
|
+
spinner.start("Fetching organizations");
|
|
21506
|
+
const { organizations, error } = await listMyOrganizations(token);
|
|
21507
|
+
if (error) {
|
|
21508
|
+
spinner.fail("Failed to fetch organizations");
|
|
21509
|
+
console.log(source_default.red(error));
|
|
21510
|
+
process.exit(1);
|
|
21511
|
+
}
|
|
21512
|
+
spinner.stop();
|
|
21513
|
+
if (options.json) {
|
|
21514
|
+
console.log(JSON.stringify(organizations, null, 2));
|
|
21515
|
+
return;
|
|
21516
|
+
}
|
|
21517
|
+
if (organizations.length === 0) {
|
|
21518
|
+
console.log(source_default.yellow("No organizations found."));
|
|
21519
|
+
console.log(source_default.gray("Run"), source_default.cyan("struere org create"), source_default.gray("to create one."));
|
|
21520
|
+
return;
|
|
21521
|
+
}
|
|
21522
|
+
console.log();
|
|
21523
|
+
console.log(source_default.bold("Organizations"));
|
|
21524
|
+
console.log();
|
|
21525
|
+
for (const org of organizations) {
|
|
21526
|
+
console.log(` ${source_default.cyan(org.name)} ${source_default.gray(`(${org.slug})`)} ${source_default.gray(`- ${org.role}`)}`);
|
|
21527
|
+
}
|
|
21528
|
+
console.log();
|
|
21529
|
+
});
|
|
21530
|
+
orgCommand.command("create").argument("[name]", "Organization name").description("Create a new organization").option("--slug <slug>", "Custom slug").option("--json", "Output as JSON").action(async (nameArg, options) => {
|
|
21531
|
+
const credentials = loadCredentials();
|
|
21532
|
+
if (!credentials) {
|
|
21533
|
+
console.log(source_default.red("Not authenticated. Run struere login first."));
|
|
21534
|
+
process.exit(1);
|
|
21535
|
+
}
|
|
21536
|
+
await refreshToken();
|
|
21537
|
+
const fresh = loadCredentials();
|
|
21538
|
+
const token = fresh?.token || credentials.token;
|
|
21539
|
+
let name = nameArg;
|
|
21540
|
+
if (!name) {
|
|
21541
|
+
if (!isInteractive2()) {
|
|
21542
|
+
console.log(source_default.red("Organization name is required in non-interactive mode."));
|
|
21543
|
+
process.exit(1);
|
|
21544
|
+
}
|
|
21545
|
+
name = await esm_default3({
|
|
21546
|
+
message: "Organization name:",
|
|
21547
|
+
validate: (v) => v.trim().length > 0 || "Name is required"
|
|
21548
|
+
});
|
|
21549
|
+
}
|
|
21550
|
+
name = name.trim();
|
|
21551
|
+
const slug = options.slug || slugify(name);
|
|
21552
|
+
const spinner = ora();
|
|
21553
|
+
spinner.start("Creating organization");
|
|
21554
|
+
const { organization, error } = await createOrganization(token, name, slug);
|
|
21555
|
+
if (error || !organization) {
|
|
21556
|
+
spinner.fail("Failed to create organization");
|
|
21557
|
+
console.log(source_default.red(error || "Unknown error"));
|
|
21558
|
+
process.exit(1);
|
|
21559
|
+
}
|
|
21560
|
+
spinner.stop();
|
|
21561
|
+
if (options.json) {
|
|
21562
|
+
console.log(JSON.stringify(organization, null, 2));
|
|
21563
|
+
return;
|
|
21564
|
+
}
|
|
21565
|
+
console.log(source_default.green("\u2713"), `Created organization ${source_default.cyan(organization.name)} (${organization.slug})`);
|
|
21566
|
+
console.log();
|
|
21567
|
+
console.log(source_default.gray("Next steps:"));
|
|
21568
|
+
console.log(source_default.gray(" \u2022"), source_default.cyan("struere init"), source_default.gray("- Initialize a project"));
|
|
21569
|
+
console.log();
|
|
21570
|
+
});
|
|
21571
|
+
|
|
21448
21572
|
// src/cli/commands/init.ts
|
|
21449
21573
|
async function runInit(cwd, selectedOrg) {
|
|
21450
21574
|
const spinner = ora();
|
|
@@ -21473,10 +21597,11 @@ async function runInit(cwd, selectedOrg) {
|
|
|
21473
21597
|
return false;
|
|
21474
21598
|
}
|
|
21475
21599
|
if (organizations.length === 0) {
|
|
21476
|
-
|
|
21477
|
-
|
|
21478
|
-
|
|
21479
|
-
|
|
21600
|
+
const created = await promptCreateOrg(credentials.token);
|
|
21601
|
+
if (!created)
|
|
21602
|
+
return false;
|
|
21603
|
+
org = created;
|
|
21604
|
+
} else if (organizations.length === 1) {
|
|
21480
21605
|
org = organizations[0];
|
|
21481
21606
|
} else {
|
|
21482
21607
|
org = await esm_default4({
|
|
@@ -21554,12 +21679,17 @@ var initCommand = new Command("init").description("Initialize a new Struere orga
|
|
|
21554
21679
|
console.log(source_default.red("Failed to fetch organizations:"), error);
|
|
21555
21680
|
process.exit(1);
|
|
21556
21681
|
}
|
|
21557
|
-
if (organizations.length === 0) {
|
|
21558
|
-
console.log(source_default.red("No organizations found. Please create one in the dashboard first."));
|
|
21559
|
-
process.exit(1);
|
|
21560
|
-
}
|
|
21561
21682
|
let selectedOrg;
|
|
21562
|
-
if (
|
|
21683
|
+
if (organizations.length === 0) {
|
|
21684
|
+
if (nonInteractive) {
|
|
21685
|
+
console.log(source_default.red("No organizations found. Run struere org create to create one."));
|
|
21686
|
+
process.exit(1);
|
|
21687
|
+
}
|
|
21688
|
+
const created = await promptCreateOrg(credentials?.token || "");
|
|
21689
|
+
if (!created)
|
|
21690
|
+
process.exit(1);
|
|
21691
|
+
selectedOrg = created;
|
|
21692
|
+
} else if (options.org) {
|
|
21563
21693
|
const found = organizations.find((o) => o.slug === options.org);
|
|
21564
21694
|
if (!found) {
|
|
21565
21695
|
console.log(source_default.red(`Organization "${options.org}" not found.`));
|
|
@@ -21797,7 +21927,8 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
21797
21927
|
name: customTool.name,
|
|
21798
21928
|
description: customTool.description,
|
|
21799
21929
|
parameters: customTool.parameters || { type: "object", properties: {} },
|
|
21800
|
-
handlerCode: extractHandlerCode(customTool._originalHandler || customTool.handler)
|
|
21930
|
+
handlerCode: extractHandlerCode(customTool._originalHandler || customTool.handler),
|
|
21931
|
+
...customTool.templateOnly && { templateOnly: true }
|
|
21801
21932
|
};
|
|
21802
21933
|
});
|
|
21803
21934
|
return {
|
|
@@ -22658,9 +22789,15 @@ var devCommand = new Command("dev").description("Watch files and sync to develop
|
|
|
22658
22789
|
persistent: true,
|
|
22659
22790
|
usePolling: false
|
|
22660
22791
|
});
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22792
|
+
let debounceTimer = null;
|
|
22793
|
+
let pendingChanges = [];
|
|
22794
|
+
const triggerSync = async () => {
|
|
22795
|
+
const changes = [...pendingChanges];
|
|
22796
|
+
pendingChanges = [];
|
|
22797
|
+
for (const { path, action } of changes) {
|
|
22798
|
+
const relativePath = path.replace(cwd, ".");
|
|
22799
|
+
console.log(source_default.gray(`${action}: ${relativePath}`));
|
|
22800
|
+
}
|
|
22664
22801
|
const syncSpinner = ora("Syncing...").start();
|
|
22665
22802
|
try {
|
|
22666
22803
|
await performDevSync(cwd, project.organization.id);
|
|
@@ -22688,6 +22825,15 @@ var devCommand = new Command("dev").description("Watch files and sync to develop
|
|
|
22688
22825
|
}
|
|
22689
22826
|
}
|
|
22690
22827
|
};
|
|
22828
|
+
const handleFileChange = (path, action) => {
|
|
22829
|
+
pendingChanges.push({ path, action });
|
|
22830
|
+
if (debounceTimer)
|
|
22831
|
+
clearTimeout(debounceTimer);
|
|
22832
|
+
debounceTimer = setTimeout(() => {
|
|
22833
|
+
debounceTimer = null;
|
|
22834
|
+
triggerSync();
|
|
22835
|
+
}, 300);
|
|
22836
|
+
};
|
|
22691
22837
|
watcher.on("change", (path) => handleFileChange(path, "Changed"));
|
|
22692
22838
|
watcher.on("add", (path) => handleFileChange(path, "Added"));
|
|
22693
22839
|
watcher.on("unlink", (path) => handleFileChange(path, "Removed"));
|
|
@@ -23616,13 +23762,13 @@ export default defineTools([])
|
|
|
23616
23762
|
` parameters: ${stringifyValue(tool.parameters, 4)}`
|
|
23617
23763
|
];
|
|
23618
23764
|
if (tool.handlerCode) {
|
|
23619
|
-
parts.push(` handler: async (args, context, fetch) => {
|
|
23765
|
+
parts.push(` handler: async (args, context, struere, fetch) => {
|
|
23620
23766
|
${tool.handlerCode.split(`
|
|
23621
23767
|
`).join(`
|
|
23622
23768
|
`)}
|
|
23623
23769
|
}`);
|
|
23624
23770
|
} else {
|
|
23625
|
-
parts.push(` handler: async (args, context, fetch) => {
|
|
23771
|
+
parts.push(` handler: async (args, context, struere, fetch) => {
|
|
23626
23772
|
throw new Error("TODO: implement handler")
|
|
23627
23773
|
}`);
|
|
23628
23774
|
}
|
|
@@ -23912,7 +24058,6 @@ var pullCommand = new Command("pull").description("Pull remote resources to loca
|
|
|
23912
24058
|
});
|
|
23913
24059
|
|
|
23914
24060
|
// src/cli/utils/entities.ts
|
|
23915
|
-
var CONVEX_URL2 = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
23916
24061
|
function getToken() {
|
|
23917
24062
|
const credentials = loadCredentials();
|
|
23918
24063
|
const apiKey = getApiKey();
|
|
@@ -23922,7 +24067,7 @@ async function convexQuery(path, args) {
|
|
|
23922
24067
|
const token = getToken();
|
|
23923
24068
|
if (!token)
|
|
23924
24069
|
return { error: "Not authenticated" };
|
|
23925
|
-
const response = await fetch(`${
|
|
24070
|
+
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
23926
24071
|
method: "POST",
|
|
23927
24072
|
headers: {
|
|
23928
24073
|
"Content-Type": "application/json",
|
|
@@ -23951,7 +24096,7 @@ async function convexMutation(path, args) {
|
|
|
23951
24096
|
const token = getToken();
|
|
23952
24097
|
if (!token)
|
|
23953
24098
|
return { error: "Not authenticated" };
|
|
23954
|
-
const response = await fetch(`${
|
|
24099
|
+
const response = await fetch(`${CONVEX_URL}/api/mutation`, {
|
|
23955
24100
|
method: "POST",
|
|
23956
24101
|
headers: {
|
|
23957
24102
|
"Content-Type": "application/json",
|
|
@@ -24481,7 +24626,6 @@ import { join as join9 } from "path";
|
|
|
24481
24626
|
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
24482
24627
|
|
|
24483
24628
|
// src/cli/utils/evals.ts
|
|
24484
|
-
var CONVEX_URL3 = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
24485
24629
|
function getToken2() {
|
|
24486
24630
|
const credentials = loadCredentials();
|
|
24487
24631
|
const apiKey = getApiKey();
|
|
@@ -24492,7 +24636,7 @@ function getToken2() {
|
|
|
24492
24636
|
}
|
|
24493
24637
|
async function convexQuery2(path, args) {
|
|
24494
24638
|
const token = getToken2();
|
|
24495
|
-
const response = await fetch(`${
|
|
24639
|
+
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
24496
24640
|
method: "POST",
|
|
24497
24641
|
headers: {
|
|
24498
24642
|
"Content-Type": "application/json",
|
|
@@ -24517,7 +24661,7 @@ async function convexQuery2(path, args) {
|
|
|
24517
24661
|
}
|
|
24518
24662
|
async function convexMutation2(path, args) {
|
|
24519
24663
|
const token = getToken2();
|
|
24520
|
-
const response = await fetch(`${
|
|
24664
|
+
const response = await fetch(`${CONVEX_URL}/api/mutation`, {
|
|
24521
24665
|
method: "POST",
|
|
24522
24666
|
headers: {
|
|
24523
24667
|
"Content-Type": "application/json",
|
|
@@ -24934,10 +25078,6 @@ evalCommand.addCommand(runCommand);
|
|
|
24934
25078
|
import { readFileSync as readFileSync4 } from "fs";
|
|
24935
25079
|
|
|
24936
25080
|
// src/cli/utils/whatsapp.ts
|
|
24937
|
-
var CONVEX_URL4 = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
24938
|
-
function getSiteUrl2() {
|
|
24939
|
-
return CONVEX_URL4.replace(".cloud", ".site");
|
|
24940
|
-
}
|
|
24941
25081
|
function getToken3() {
|
|
24942
25082
|
const credentials = loadCredentials();
|
|
24943
25083
|
const apiKey = getApiKey();
|
|
@@ -24947,7 +25087,7 @@ async function httpPost(path, body) {
|
|
|
24947
25087
|
const apiKey = getApiKey();
|
|
24948
25088
|
if (!apiKey)
|
|
24949
25089
|
return { error: "Not authenticated" };
|
|
24950
|
-
const siteUrl =
|
|
25090
|
+
const siteUrl = getSiteUrl();
|
|
24951
25091
|
try {
|
|
24952
25092
|
const response = await fetch(`${siteUrl}${path}`, {
|
|
24953
25093
|
method: "POST",
|
|
@@ -24980,7 +25120,7 @@ async function convexAction(path, args) {
|
|
|
24980
25120
|
const token = getToken3();
|
|
24981
25121
|
if (!token)
|
|
24982
25122
|
return { error: "Not authenticated" };
|
|
24983
|
-
const response = await fetch(`${
|
|
25123
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
24984
25124
|
method: "POST",
|
|
24985
25125
|
headers: {
|
|
24986
25126
|
"Content-Type": "application/json",
|
|
@@ -25009,7 +25149,7 @@ async function convexQuery3(path, args) {
|
|
|
25009
25149
|
const token = getToken3();
|
|
25010
25150
|
if (!token)
|
|
25011
25151
|
return { error: "Not authenticated" };
|
|
25012
|
-
const response = await fetch(`${
|
|
25152
|
+
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
25013
25153
|
method: "POST",
|
|
25014
25154
|
headers: {
|
|
25015
25155
|
"Content-Type": "application/json",
|
|
@@ -25043,16 +25183,15 @@ async function listWhatsAppConnections(env2) {
|
|
|
25043
25183
|
}
|
|
25044
25184
|
return convexQuery3("whatsapp:listConnections", { environment: env2 });
|
|
25045
25185
|
}
|
|
25046
|
-
async function listTemplates(connectionId
|
|
25186
|
+
async function listTemplates(connectionId) {
|
|
25047
25187
|
if (getApiKey()) {
|
|
25048
25188
|
return httpPost("/v1/templates/list", { connectionId });
|
|
25049
25189
|
}
|
|
25050
25190
|
return convexAction("whatsappActions:listTemplates", {
|
|
25051
|
-
connectionId
|
|
25052
|
-
environment: env2
|
|
25191
|
+
connectionId
|
|
25053
25192
|
});
|
|
25054
25193
|
}
|
|
25055
|
-
async function createTemplate(connectionId,
|
|
25194
|
+
async function createTemplate(connectionId, name, language, category, components, allowCategoryChange) {
|
|
25056
25195
|
if (getApiKey()) {
|
|
25057
25196
|
return httpPost("/v1/templates/create", {
|
|
25058
25197
|
connectionId,
|
|
@@ -25065,7 +25204,6 @@ async function createTemplate(connectionId, env2, name, language, category, comp
|
|
|
25065
25204
|
}
|
|
25066
25205
|
return convexAction("whatsappActions:createTemplate", {
|
|
25067
25206
|
connectionId,
|
|
25068
|
-
environment: env2,
|
|
25069
25207
|
name,
|
|
25070
25208
|
language,
|
|
25071
25209
|
category,
|
|
@@ -25073,23 +25211,21 @@ async function createTemplate(connectionId, env2, name, language, category, comp
|
|
|
25073
25211
|
...allowCategoryChange !== undefined && { allowCategoryChange }
|
|
25074
25212
|
});
|
|
25075
25213
|
}
|
|
25076
|
-
async function deleteTemplate(connectionId,
|
|
25214
|
+
async function deleteTemplate(connectionId, name) {
|
|
25077
25215
|
if (getApiKey()) {
|
|
25078
25216
|
return httpPost("/v1/templates/delete", { connectionId, name });
|
|
25079
25217
|
}
|
|
25080
25218
|
return convexAction("whatsappActions:deleteTemplate", {
|
|
25081
25219
|
connectionId,
|
|
25082
|
-
environment: env2,
|
|
25083
25220
|
name
|
|
25084
25221
|
});
|
|
25085
25222
|
}
|
|
25086
|
-
async function getTemplateStatus(connectionId,
|
|
25223
|
+
async function getTemplateStatus(connectionId, name) {
|
|
25087
25224
|
if (getApiKey()) {
|
|
25088
25225
|
return httpPost("/v1/templates/status", { connectionId, name });
|
|
25089
25226
|
}
|
|
25090
25227
|
return convexAction("whatsappActions:getTemplateStatus", {
|
|
25091
25228
|
connectionId,
|
|
25092
|
-
environment: env2,
|
|
25093
25229
|
name
|
|
25094
25230
|
});
|
|
25095
25231
|
}
|
|
@@ -25185,13 +25321,12 @@ function statusColor2(status) {
|
|
|
25185
25321
|
}
|
|
25186
25322
|
}
|
|
25187
25323
|
var templatesCommand = new Command("templates").description("Manage WhatsApp message templates");
|
|
25188
|
-
templatesCommand.command("list").description("List all message templates").option("--
|
|
25324
|
+
templatesCommand.command("list").description("List all message templates").option("--connection <id>", "WhatsApp connection ID").option("--json", "Output raw JSON").action(async (opts) => {
|
|
25189
25325
|
await ensureAuth2();
|
|
25190
|
-
const
|
|
25191
|
-
const connectionId = await resolveConnectionId(env2, opts.connection);
|
|
25326
|
+
const connectionId = await resolveConnectionId("development", opts.connection);
|
|
25192
25327
|
const out = createOutput();
|
|
25193
25328
|
out.start("Fetching templates");
|
|
25194
|
-
const { data, error } = await listTemplates(connectionId
|
|
25329
|
+
const { data, error } = await listTemplates(connectionId);
|
|
25195
25330
|
if (error) {
|
|
25196
25331
|
out.fail("Failed to fetch templates");
|
|
25197
25332
|
out.error(error);
|
|
@@ -25223,10 +25358,9 @@ templatesCommand.command("list").description("List all message templates").optio
|
|
|
25223
25358
|
})));
|
|
25224
25359
|
console.log();
|
|
25225
25360
|
});
|
|
25226
|
-
templatesCommand.command("create <name>").description("Create a new message template").option("--
|
|
25361
|
+
templatesCommand.command("create <name>").description("Create a new message template").option("--connection <id>", "WhatsApp connection ID").option("--language <code>", "Language code", "en_US").option("--category <cat>", "Category (UTILITY|MARKETING|AUTHENTICATION)", "UTILITY").option("--components <json>", "Components as JSON string").option("--file <path>", "Read components from a JSON file").option("--allow-category-change", "Allow Meta to reassign category").option("--json", "Output raw JSON").action(async (name, opts) => {
|
|
25227
25362
|
await ensureAuth2();
|
|
25228
|
-
const
|
|
25229
|
-
const connectionId = await resolveConnectionId(env2, opts.connection);
|
|
25363
|
+
const connectionId = await resolveConnectionId("development", opts.connection);
|
|
25230
25364
|
let components;
|
|
25231
25365
|
if (opts.file) {
|
|
25232
25366
|
try {
|
|
@@ -25254,7 +25388,7 @@ templatesCommand.command("create <name>").description("Create a new message temp
|
|
|
25254
25388
|
}
|
|
25255
25389
|
const out = createOutput();
|
|
25256
25390
|
out.start(`Creating template "${name}"`);
|
|
25257
|
-
const { data, error } = await createTemplate(connectionId,
|
|
25391
|
+
const { data, error } = await createTemplate(connectionId, name, opts.language, opts.category.toUpperCase(), components, opts.allowCategoryChange);
|
|
25258
25392
|
if (error) {
|
|
25259
25393
|
out.fail("Failed to create template");
|
|
25260
25394
|
out.error(error);
|
|
@@ -25272,10 +25406,9 @@ templatesCommand.command("create <name>").description("Create a new message temp
|
|
|
25272
25406
|
console.log();
|
|
25273
25407
|
}
|
|
25274
25408
|
});
|
|
25275
|
-
templatesCommand.command("delete <name>").description("Delete a message template").option("--
|
|
25409
|
+
templatesCommand.command("delete <name>").description("Delete a message template").option("--connection <id>", "WhatsApp connection ID").option("--yes", "Skip confirmation").action(async (name, opts) => {
|
|
25276
25410
|
await ensureAuth2();
|
|
25277
|
-
const
|
|
25278
|
-
const connectionId = await resolveConnectionId(env2, opts.connection);
|
|
25411
|
+
const connectionId = await resolveConnectionId("development", opts.connection);
|
|
25279
25412
|
if (!opts.yes && isInteractive2()) {
|
|
25280
25413
|
const confirmed = await esm_default2({
|
|
25281
25414
|
message: `Delete template "${name}"? This cannot be undone.`,
|
|
@@ -25288,7 +25421,7 @@ templatesCommand.command("delete <name>").description("Delete a message template
|
|
|
25288
25421
|
}
|
|
25289
25422
|
const out = createOutput();
|
|
25290
25423
|
out.start(`Deleting template "${name}"`);
|
|
25291
|
-
const { error } = await deleteTemplate(connectionId,
|
|
25424
|
+
const { error } = await deleteTemplate(connectionId, name);
|
|
25292
25425
|
if (error) {
|
|
25293
25426
|
out.fail("Failed to delete template");
|
|
25294
25427
|
out.error(error);
|
|
@@ -25297,13 +25430,12 @@ templatesCommand.command("delete <name>").description("Delete a message template
|
|
|
25297
25430
|
out.succeed(`Template "${name}" deleted`);
|
|
25298
25431
|
console.log();
|
|
25299
25432
|
});
|
|
25300
|
-
templatesCommand.command("status <name>").description("Check template approval status").option("--
|
|
25433
|
+
templatesCommand.command("status <name>").description("Check template approval status").option("--connection <id>", "WhatsApp connection ID").option("--json", "Output raw JSON").action(async (name, opts) => {
|
|
25301
25434
|
await ensureAuth2();
|
|
25302
|
-
const
|
|
25303
|
-
const connectionId = await resolveConnectionId(env2, opts.connection);
|
|
25435
|
+
const connectionId = await resolveConnectionId("development", opts.connection);
|
|
25304
25436
|
const out = createOutput();
|
|
25305
25437
|
out.start(`Checking status for "${name}"`);
|
|
25306
|
-
const { data, error } = await getTemplateStatus(connectionId,
|
|
25438
|
+
const { data, error } = await getTemplateStatus(connectionId, name);
|
|
25307
25439
|
if (error) {
|
|
25308
25440
|
out.fail("Failed to fetch template status");
|
|
25309
25441
|
out.error(error);
|
|
@@ -25336,7 +25468,6 @@ templatesCommand.command("status <name>").description("Check template approval s
|
|
|
25336
25468
|
});
|
|
25337
25469
|
|
|
25338
25470
|
// src/cli/utils/integrations.ts
|
|
25339
|
-
var CONVEX_URL5 = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
25340
25471
|
function getToken4() {
|
|
25341
25472
|
const credentials = loadCredentials();
|
|
25342
25473
|
const apiKey = getApiKey();
|
|
@@ -25346,7 +25477,7 @@ async function convexQuery4(path, args) {
|
|
|
25346
25477
|
const token = getToken4();
|
|
25347
25478
|
if (!token)
|
|
25348
25479
|
return { error: "Not authenticated" };
|
|
25349
|
-
const response = await fetch(`${
|
|
25480
|
+
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
25350
25481
|
method: "POST",
|
|
25351
25482
|
headers: {
|
|
25352
25483
|
"Content-Type": "application/json",
|
|
@@ -25375,7 +25506,7 @@ async function convexMutation3(path, args) {
|
|
|
25375
25506
|
const token = getToken4();
|
|
25376
25507
|
if (!token)
|
|
25377
25508
|
return { error: "Not authenticated" };
|
|
25378
|
-
const response = await fetch(`${
|
|
25509
|
+
const response = await fetch(`${CONVEX_URL}/api/mutation`, {
|
|
25379
25510
|
method: "POST",
|
|
25380
25511
|
headers: {
|
|
25381
25512
|
"Content-Type": "application/json",
|
|
@@ -25404,7 +25535,7 @@ async function convexAction2(path, args) {
|
|
|
25404
25535
|
const token = getToken4();
|
|
25405
25536
|
if (!token)
|
|
25406
25537
|
return { error: "Not authenticated" };
|
|
25407
|
-
const response = await fetch(`${
|
|
25538
|
+
const response = await fetch(`${CONVEX_URL}/api/action`, {
|
|
25408
25539
|
method: "POST",
|
|
25409
25540
|
headers: {
|
|
25410
25541
|
"Content-Type": "application/json",
|
|
@@ -25869,7 +26000,7 @@ var compilePromptCommand = new Command("compile-prompt").description("Compile an
|
|
|
25869
26000
|
// package.json
|
|
25870
26001
|
var package_default = {
|
|
25871
26002
|
name: "struere",
|
|
25872
|
-
version: "0.9.
|
|
26003
|
+
version: "0.9.9",
|
|
25873
26004
|
description: "Build, test, and deploy AI agents",
|
|
25874
26005
|
keywords: [
|
|
25875
26006
|
"ai",
|
|
@@ -25973,6 +26104,7 @@ program.addCommand(initCommand);
|
|
|
25973
26104
|
program.addCommand(loginCommand);
|
|
25974
26105
|
program.addCommand(logoutCommand);
|
|
25975
26106
|
program.addCommand(whoamiCommand);
|
|
26107
|
+
program.addCommand(orgCommand);
|
|
25976
26108
|
program.addCommand(syncCommand);
|
|
25977
26109
|
program.addCommand(devCommand);
|
|
25978
26110
|
program.addCommand(deployCommand);
|