@usenaive-sdk/cli 0.3.1 → 0.4.1
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/README.md +53 -6
- package/dist/commands/apps.d.ts +2 -0
- package/dist/commands/apps.js +424 -0
- package/dist/commands/apps.js.map +1 -0
- package/dist/commands/billing-client.d.ts +2 -0
- package/dist/commands/billing-client.js +271 -0
- package/dist/commands/billing-client.js.map +1 -0
- package/dist/commands/ceo.d.ts +2 -0
- package/dist/commands/ceo.js +369 -0
- package/dist/commands/ceo.js.map +1 -0
- package/dist/commands/companies.js +105 -0
- package/dist/commands/companies.js.map +1 -1
- package/dist/commands/crm-app.d.ts +2 -0
- package/dist/commands/crm-app.js +306 -0
- package/dist/commands/crm-app.js.map +1 -0
- package/dist/commands/crm.d.ts +2 -0
- package/dist/commands/crm.js +319 -0
- package/dist/commands/crm.js.map +1 -0
- package/dist/commands/cron-jobs.d.ts +2 -0
- package/dist/commands/cron-jobs.js +208 -0
- package/dist/commands/cron-jobs.js.map +1 -0
- package/dist/commands/employees.d.ts +2 -0
- package/dist/commands/employees.js +190 -0
- package/dist/commands/employees.js.map +1 -0
- package/dist/commands/integrations.d.ts +2 -0
- package/dist/commands/integrations.js +199 -0
- package/dist/commands/integrations.js.map +1 -0
- package/dist/commands/media.d.ts +2 -0
- package/dist/commands/media.js +183 -0
- package/dist/commands/media.js.map +1 -0
- package/dist/commands/memory.d.ts +2 -0
- package/dist/commands/memory.js +151 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/objectives.d.ts +2 -0
- package/dist/commands/objectives.js +243 -0
- package/dist/commands/objectives.js.map +1 -0
- package/dist/commands/register.js +5 -6
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/social.js +3 -0
- package/dist/commands/social.js.map +1 -1
- package/dist/commands/tasks.d.ts +2 -0
- package/dist/commands/tasks.js +400 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/usage.js +5 -5
- package/dist/commands/video.js +259 -11
- package/dist/commands/video.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +30 -6
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const employeesCmd = new Command("employees")
|
|
5
|
+
.description("Manage AI employees — hire, fire, configure, and list your workforce")
|
|
6
|
+
.addHelpText("after", `
|
|
7
|
+
Subcommands:
|
|
8
|
+
naive employees list List all employees in your company
|
|
9
|
+
naive employees hire Hire a new AI employee
|
|
10
|
+
naive employees fire <id> Terminate an employee
|
|
11
|
+
naive employees configure <id> Update an employee's model, skills, or settings
|
|
12
|
+
|
|
13
|
+
Workflow:
|
|
14
|
+
1. naive employees hire --role engineer --name "Alice" → hire an employee
|
|
15
|
+
2. naive employees list → see your workforce
|
|
16
|
+
3. naive employees configure <id> --model gpt-4o --skills "coding,devops"
|
|
17
|
+
4. naive tasks dispatch → dispatch tasks to employees
|
|
18
|
+
5. naive employees fire <id> → terminate if no longer needed
|
|
19
|
+
|
|
20
|
+
Employees are AI agents that execute tasks on the kanban board. Each employee
|
|
21
|
+
has a role (engineer, marketer, writer, etc.), a model configuration, and
|
|
22
|
+
a set of skills that determine which tasks they can handle.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
$ naive employees list
|
|
26
|
+
$ naive employees hire --role marketer --name "Marketing Max"
|
|
27
|
+
$ naive employees hire --role engineer --name "Dev Diana" --skills "typescript,react,devops"
|
|
28
|
+
$ naive employees configure emp-123 --model claude-sonnet-4-20250514
|
|
29
|
+
$ naive employees fire emp-123
|
|
30
|
+
`);
|
|
31
|
+
employeesCmd
|
|
32
|
+
.command("list")
|
|
33
|
+
.description("List all AI employees in your company")
|
|
34
|
+
.addHelpText("after", `
|
|
35
|
+
Examples:
|
|
36
|
+
$ naive employees list
|
|
37
|
+
|
|
38
|
+
Returns employee details:
|
|
39
|
+
- id, name, role
|
|
40
|
+
- Model configuration
|
|
41
|
+
- Skills list
|
|
42
|
+
- Current status (idle, working, offline)
|
|
43
|
+
- Active task (if working)
|
|
44
|
+
- Tasks completed count
|
|
45
|
+
`)
|
|
46
|
+
.action(async () => {
|
|
47
|
+
const resp = await apiRequest("GET", "/v1/employees");
|
|
48
|
+
handleApiError("employees.list", resp);
|
|
49
|
+
const data = resp.data;
|
|
50
|
+
const count = data.employees?.length ?? 0;
|
|
51
|
+
const working = data.employees?.filter((e) => e.status === "working") ?? [];
|
|
52
|
+
agentOutput({
|
|
53
|
+
action: "employees.list",
|
|
54
|
+
result: resp.data,
|
|
55
|
+
next_steps: [
|
|
56
|
+
{ command: "naive employees hire --role <role> --name <name>", description: "Hire a new employee" },
|
|
57
|
+
...(count > 0
|
|
58
|
+
? [{ command: `naive employees configure ${data.employees[0].id} --model <model>`, description: "Configure an employee" }]
|
|
59
|
+
: []),
|
|
60
|
+
{ command: "naive tasks dispatch", description: "Dispatch tasks to available employees" },
|
|
61
|
+
],
|
|
62
|
+
hints: [
|
|
63
|
+
`${count} employee${count !== 1 ? "s" : ""} in your company`,
|
|
64
|
+
`${working.length} currently working on tasks`,
|
|
65
|
+
],
|
|
66
|
+
related_commands: ["naive employees hire", "naive employees configure", "naive tasks dispatch"],
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
employeesCmd
|
|
70
|
+
.command("hire")
|
|
71
|
+
.description("Hire a new AI employee for your company")
|
|
72
|
+
.requiredOption("--role <role>", "Employee role: engineer | marketer | writer | sales | designer | researcher | support")
|
|
73
|
+
.requiredOption("--name <name>", "Display name for the employee")
|
|
74
|
+
.option("--skills <skills>", "Comma-separated skill tags (e.g., 'typescript,react,seo')")
|
|
75
|
+
.option("--model <model>", "AI model to use (default: auto-selected based on role)")
|
|
76
|
+
.addHelpText("after", `
|
|
77
|
+
Examples:
|
|
78
|
+
$ naive employees hire --role engineer --name "Dev Diana"
|
|
79
|
+
$ naive employees hire --role marketer --name "Marketing Max" --skills "seo,content,social"
|
|
80
|
+
$ naive employees hire --role writer --name "Content Casey" --model gpt-4o
|
|
81
|
+
|
|
82
|
+
Available roles:
|
|
83
|
+
engineer — coding, deployment, infrastructure
|
|
84
|
+
marketer — SEO, social media, content marketing, ads
|
|
85
|
+
writer — blog posts, copy, documentation, emails
|
|
86
|
+
sales — outreach, lead generation, proposals
|
|
87
|
+
designer — branding, visual assets, UI mockups
|
|
88
|
+
researcher — market research, competitive analysis, reports
|
|
89
|
+
support — customer service, ticket handling, FAQ management
|
|
90
|
+
|
|
91
|
+
Skills help the task dispatcher match employees to appropriate tasks.
|
|
92
|
+
`)
|
|
93
|
+
.action(async (opts) => {
|
|
94
|
+
const resp = await apiRequest("POST", "/v1/employees", {
|
|
95
|
+
role: opts.role,
|
|
96
|
+
name: opts.name,
|
|
97
|
+
...(opts.skills && { skills: opts.skills.split(",").map((s) => s.trim()) }),
|
|
98
|
+
...(opts.model && { model: opts.model }),
|
|
99
|
+
});
|
|
100
|
+
handleApiError("employees.hire", resp);
|
|
101
|
+
const data = resp.data;
|
|
102
|
+
agentOutput({
|
|
103
|
+
action: "employees.hire",
|
|
104
|
+
result: resp.data,
|
|
105
|
+
next_steps: [
|
|
106
|
+
{ command: `naive employees configure ${data.id} --skills <skills>`, description: "Fine-tune skills" },
|
|
107
|
+
{ command: "naive employees list", description: "View your full team" },
|
|
108
|
+
{ command: "naive tasks dispatch", description: "Dispatch tasks to the new employee" },
|
|
109
|
+
],
|
|
110
|
+
hints: [
|
|
111
|
+
`Employee hired: ${data.name} (${data.role}, id: ${data.id})`,
|
|
112
|
+
"New employees start in 'idle' status and can receive tasks immediately",
|
|
113
|
+
],
|
|
114
|
+
related_commands: ["naive employees list", "naive employees configure", "naive tasks dispatch"],
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
employeesCmd
|
|
118
|
+
.command("fire <id>")
|
|
119
|
+
.description("Terminate an AI employee — reassigns their active tasks")
|
|
120
|
+
.addHelpText("after", `
|
|
121
|
+
Examples:
|
|
122
|
+
$ naive employees fire emp-abc-123
|
|
123
|
+
|
|
124
|
+
What this does:
|
|
125
|
+
1. Marks the employee as terminated
|
|
126
|
+
2. Any active tasks are returned to 'pending' status
|
|
127
|
+
3. The employee can no longer receive new tasks
|
|
128
|
+
4. Historical task completions are preserved
|
|
129
|
+
|
|
130
|
+
Note: This does not delete the employee record — it remains in history.
|
|
131
|
+
`)
|
|
132
|
+
.action(async (id) => {
|
|
133
|
+
const resp = await apiRequest("DELETE", `/v1/employees/${id}`);
|
|
134
|
+
handleApiError("employees.fire", resp);
|
|
135
|
+
agentOutput({
|
|
136
|
+
action: "employees.fire",
|
|
137
|
+
result: resp.data,
|
|
138
|
+
next_steps: [
|
|
139
|
+
{ command: "naive employees list", description: "View remaining employees" },
|
|
140
|
+
{ command: "naive tasks list --status pending", description: "Check for reassigned tasks" },
|
|
141
|
+
{ command: "naive tasks dispatch", description: "Redistribute orphaned tasks" },
|
|
142
|
+
],
|
|
143
|
+
hints: [
|
|
144
|
+
`Employee ${id} terminated`,
|
|
145
|
+
"Active tasks have been returned to pending status",
|
|
146
|
+
],
|
|
147
|
+
related_commands: ["naive employees list", "naive employees hire", "naive tasks dispatch"],
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
employeesCmd
|
|
151
|
+
.command("configure <id>")
|
|
152
|
+
.description("Update an employee's model, skills, or other configuration")
|
|
153
|
+
.option("--model <model>", "Change the AI model (e.g., gpt-4o, claude-sonnet-4-20250514)")
|
|
154
|
+
.option("--skills <skills>", "Replace skill tags (comma-separated)")
|
|
155
|
+
.option("--name <name>", "Update display name")
|
|
156
|
+
.addHelpText("after", `
|
|
157
|
+
Examples:
|
|
158
|
+
$ naive employees configure emp-123 --model gpt-4o
|
|
159
|
+
$ naive employees configure emp-123 --skills "typescript,react,nextjs,devops"
|
|
160
|
+
$ naive employees configure emp-123 --name "Senior Dev Diana" --model claude-sonnet-4-20250514
|
|
161
|
+
|
|
162
|
+
Changes take effect for the next task the employee picks up.
|
|
163
|
+
Active tasks continue with the previous configuration.
|
|
164
|
+
`)
|
|
165
|
+
.action(async (id, opts) => {
|
|
166
|
+
const body = {};
|
|
167
|
+
if (opts.model)
|
|
168
|
+
body.model = opts.model;
|
|
169
|
+
if (opts.skills)
|
|
170
|
+
body.skills = opts.skills.split(",").map((s) => s.trim());
|
|
171
|
+
if (opts.name)
|
|
172
|
+
body.name = opts.name;
|
|
173
|
+
const resp = await apiRequest("PATCH", `/v1/employees/${id}`, body);
|
|
174
|
+
handleApiError("employees.configure", resp);
|
|
175
|
+
agentOutput({
|
|
176
|
+
action: "employees.configure",
|
|
177
|
+
result: resp.data,
|
|
178
|
+
next_steps: [
|
|
179
|
+
{ command: `naive employees list`, description: "View updated employee roster" },
|
|
180
|
+
{ command: "naive tasks dispatch", description: "Dispatch tasks with updated skills matching" },
|
|
181
|
+
],
|
|
182
|
+
hints: [
|
|
183
|
+
`Employee ${id} configuration updated`,
|
|
184
|
+
...(opts.model ? [`Model → ${opts.model}`] : []),
|
|
185
|
+
...(opts.skills ? [`Skills → ${opts.skills}`] : []),
|
|
186
|
+
],
|
|
187
|
+
related_commands: ["naive employees list", "naive employees hire"],
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=employees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"employees.js","sourceRoot":"","sources":["../../src/commands/employees.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const integrationsCmd = new Command("integrations")
|
|
5
|
+
.alias("integration")
|
|
6
|
+
.description("3rd-party integrations — connect 250+ Composio toolkits (Gmail, GitHub, Linear, Notion, ...) and invoke their tools")
|
|
7
|
+
.addHelpText("after", `
|
|
8
|
+
Subcommands:
|
|
9
|
+
naive integrations list List toolkits + connection state
|
|
10
|
+
naive integrations connected List only connected toolkits
|
|
11
|
+
naive integrations connect <toolkit> Start OAuth/API-key flow → returns a redirect URL
|
|
12
|
+
naive integrations disconnect <toolkit> [--purge] Disable (default) or permanently delete connection
|
|
13
|
+
naive integrations tools <toolkit> List the tools exposed by a toolkit
|
|
14
|
+
naive integrations execute <toolkit> <tool> [--args] Invoke a Composio tool (costs 1 credit on success)
|
|
15
|
+
|
|
16
|
+
Common Toolkits:
|
|
17
|
+
gmail, googlecalendar, googledrive, github, linear, notion, slack,
|
|
18
|
+
airtable, hubspot, salesforce, stripe, shopify, calendly, twilio, zoom
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
$ naive integrations connect gmail
|
|
22
|
+
# Open the redirect_url, finish OAuth, then:
|
|
23
|
+
$ naive integrations execute gmail GMAIL_SEND_EMAIL \\
|
|
24
|
+
--args '{"recipient_email":"me@example.com","subject":"hi","body":"hello"}'
|
|
25
|
+
|
|
26
|
+
Cost:
|
|
27
|
+
- listing toolkits / tools / connecting / disconnecting: free
|
|
28
|
+
- executing a tool: 1 credit per successful call
|
|
29
|
+
`);
|
|
30
|
+
integrationsCmd
|
|
31
|
+
.command("list")
|
|
32
|
+
.description("List 3rd-party toolkits available via Composio (paged)")
|
|
33
|
+
.option("--search <q>", "Filter by name or slug substring")
|
|
34
|
+
.option("--cursor <c>", "Opaque cursor from previous response")
|
|
35
|
+
.option("--limit <n>", "Page size (max 50)")
|
|
36
|
+
.option("--connected", "Only show connected toolkits")
|
|
37
|
+
.action(async (opts) => {
|
|
38
|
+
const params = new URLSearchParams();
|
|
39
|
+
if (opts.search)
|
|
40
|
+
params.set("search", opts.search);
|
|
41
|
+
if (opts.cursor)
|
|
42
|
+
params.set("cursor", opts.cursor);
|
|
43
|
+
if (opts.limit)
|
|
44
|
+
params.set("limit", opts.limit);
|
|
45
|
+
if (opts.connected)
|
|
46
|
+
params.set("connected", "true");
|
|
47
|
+
const qs = params.toString();
|
|
48
|
+
const resp = await apiRequest("GET", `/v1/integrations${qs ? `?${qs}` : ""}`);
|
|
49
|
+
handleApiError("integrations.list", resp);
|
|
50
|
+
const data = resp.data;
|
|
51
|
+
agentOutput({
|
|
52
|
+
action: "integrations.list",
|
|
53
|
+
result: resp.data,
|
|
54
|
+
next_steps: [
|
|
55
|
+
{ command: "naive integrations connect <toolkit>", description: "Connect a toolkit by slug" },
|
|
56
|
+
...(data.nextCursor
|
|
57
|
+
? [{ command: `naive integrations list --cursor ${data.nextCursor}`, description: "Fetch the next page" }]
|
|
58
|
+
: []),
|
|
59
|
+
],
|
|
60
|
+
hints: [`${data.toolkits?.length ?? 0} toolkit(s) on this page`],
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
integrationsCmd
|
|
64
|
+
.command("connected")
|
|
65
|
+
.description("List only the toolkits this company has connected")
|
|
66
|
+
.option("--cursor <c>", "Opaque cursor from previous response")
|
|
67
|
+
.option("--limit <n>", "Page size (max 50)")
|
|
68
|
+
.action(async (opts) => {
|
|
69
|
+
const params = new URLSearchParams();
|
|
70
|
+
if (opts.cursor)
|
|
71
|
+
params.set("cursor", opts.cursor);
|
|
72
|
+
if (opts.limit)
|
|
73
|
+
params.set("limit", opts.limit);
|
|
74
|
+
const qs = params.toString();
|
|
75
|
+
const resp = await apiRequest("GET", `/v1/integrations/connected${qs ? `?${qs}` : ""}`);
|
|
76
|
+
handleApiError("integrations.connected", resp);
|
|
77
|
+
const data = resp.data;
|
|
78
|
+
agentOutput({
|
|
79
|
+
action: "integrations.connected",
|
|
80
|
+
result: resp.data,
|
|
81
|
+
next_steps: [
|
|
82
|
+
{ command: "naive integrations tools <toolkit>", description: "Inspect a connected toolkit's tools" },
|
|
83
|
+
{ command: "naive integrations execute <toolkit> <tool>", description: "Invoke a tool" },
|
|
84
|
+
],
|
|
85
|
+
hints: [`${data.toolkits?.length ?? 0} connected toolkit(s)`],
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
integrationsCmd
|
|
89
|
+
.command("connect <toolkit>")
|
|
90
|
+
.description("Start an OAuth/API-key flow for a toolkit (returns a redirect URL)")
|
|
91
|
+
.option("--callback-url <url>", "Where Composio should send the user back after auth")
|
|
92
|
+
.action(async (toolkit, opts) => {
|
|
93
|
+
const body = { toolkit };
|
|
94
|
+
if (opts.callbackUrl)
|
|
95
|
+
body.callback_url = opts.callbackUrl;
|
|
96
|
+
const resp = await apiRequest("POST", "/v1/integrations/connect", body);
|
|
97
|
+
handleApiError("integrations.connect", resp);
|
|
98
|
+
const data = resp.data;
|
|
99
|
+
agentOutput({
|
|
100
|
+
action: "integrations.connect",
|
|
101
|
+
result: resp.data,
|
|
102
|
+
next_steps: [
|
|
103
|
+
{ command: `naive integrations connected`, description: "Check connection status after finishing in-browser" },
|
|
104
|
+
{ command: `naive integrations tools ${toolkit}`, description: "List tools once the connection is ACTIVE" },
|
|
105
|
+
],
|
|
106
|
+
hints: [
|
|
107
|
+
data.redirectUrl
|
|
108
|
+
? `Open this URL to finish connecting ${toolkit}:`
|
|
109
|
+
: `Connection initiated for ${toolkit} (no redirect needed — credentials supplied via API).`,
|
|
110
|
+
...(data.redirectUrl ? [data.redirectUrl] : []),
|
|
111
|
+
`connected_account_id: ${data.connectedAccountId} · status: ${data.status}`,
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
integrationsCmd
|
|
116
|
+
.command("disconnect <toolkit>")
|
|
117
|
+
.description("Disconnect a toolkit (soft-disable by default; --purge for permanent delete)")
|
|
118
|
+
.option("--purge", "Permanently delete the connection and revoke tokens")
|
|
119
|
+
.action(async (toolkit, opts) => {
|
|
120
|
+
const qs = opts.purge ? "?purge=true" : "";
|
|
121
|
+
const resp = await apiRequest("DELETE", `/v1/integrations/${encodeURIComponent(toolkit)}${qs}`);
|
|
122
|
+
handleApiError("integrations.disconnect", resp);
|
|
123
|
+
agentOutput({
|
|
124
|
+
action: "integrations.disconnect",
|
|
125
|
+
result: resp.data,
|
|
126
|
+
next_steps: [
|
|
127
|
+
{ command: `naive integrations connect ${toolkit}`, description: "Reconnect this toolkit later" },
|
|
128
|
+
{ command: "naive integrations connected", description: "List remaining connected toolkits" },
|
|
129
|
+
],
|
|
130
|
+
hints: [opts.purge ? `Toolkit ${toolkit} permanently deleted.` : `Toolkit ${toolkit} disabled (reversible).`],
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
integrationsCmd
|
|
134
|
+
.command("tools <toolkit>")
|
|
135
|
+
.description("List the individual tools exposed by a toolkit")
|
|
136
|
+
.option("--search <q>", "Semantic search across tool descriptions")
|
|
137
|
+
.option("--limit <n>", "Max tools to return (default 100, max 200)")
|
|
138
|
+
.action(async (toolkit, opts) => {
|
|
139
|
+
const params = new URLSearchParams();
|
|
140
|
+
if (opts.search)
|
|
141
|
+
params.set("search", opts.search);
|
|
142
|
+
if (opts.limit)
|
|
143
|
+
params.set("limit", opts.limit);
|
|
144
|
+
const qs = params.toString();
|
|
145
|
+
const resp = await apiRequest("GET", `/v1/integrations/${encodeURIComponent(toolkit)}/tools${qs ? `?${qs}` : ""}`);
|
|
146
|
+
handleApiError("integrations.tools", resp);
|
|
147
|
+
const data = resp.data;
|
|
148
|
+
agentOutput({
|
|
149
|
+
action: "integrations.tools",
|
|
150
|
+
result: resp.data,
|
|
151
|
+
next_steps: [
|
|
152
|
+
{ command: `naive integrations execute ${toolkit} <tool>`, description: "Invoke one of these tools" },
|
|
153
|
+
],
|
|
154
|
+
hints: [`${data.tools?.length ?? 0} tool(s) returned for ${toolkit}`],
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
integrationsCmd
|
|
158
|
+
.command("execute <toolkit> <tool>")
|
|
159
|
+
.description("Invoke a Composio tool. Costs 1 credit on success.")
|
|
160
|
+
.option("--args <json>", "Tool arguments as JSON object", "{}")
|
|
161
|
+
.option("--connected-account-id <id>", "Override which connected account to use")
|
|
162
|
+
.action(async (toolkit, tool, opts) => {
|
|
163
|
+
let args = {};
|
|
164
|
+
try {
|
|
165
|
+
args = JSON.parse(opts.args ?? "{}");
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
console.error(JSON.stringify({
|
|
169
|
+
success: false,
|
|
170
|
+
action: "integrations.execute",
|
|
171
|
+
error: { code: "invalid_input", message: `--args must be valid JSON: ${err.message}` },
|
|
172
|
+
recovery_steps: [
|
|
173
|
+
{ command: `naive integrations execute ${toolkit} ${tool} --args '{"key":"value"}'`, description: "Retry with valid JSON" },
|
|
174
|
+
],
|
|
175
|
+
}, null, 2));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
const body = { tool, arguments: args };
|
|
179
|
+
if (opts.connectedAccountId)
|
|
180
|
+
body.connected_account_id = opts.connectedAccountId;
|
|
181
|
+
const resp = await apiRequest("POST", `/v1/integrations/${encodeURIComponent(toolkit)}/execute`, body);
|
|
182
|
+
handleApiError("integrations.execute", resp);
|
|
183
|
+
const data = resp.data;
|
|
184
|
+
const credits = typeof data.creditsRemaining === "number" ? data.creditsRemaining.toFixed(2) : "?";
|
|
185
|
+
agentOutput({
|
|
186
|
+
action: "integrations.execute",
|
|
187
|
+
result: resp.data,
|
|
188
|
+
next_steps: data.successful
|
|
189
|
+
? [{ command: `naive integrations tools ${toolkit}`, description: "Discover related tools" }]
|
|
190
|
+
: [
|
|
191
|
+
{ command: `naive integrations connected`, description: "Confirm the toolkit is connected" },
|
|
192
|
+
{ command: `naive integrations connect ${toolkit}`, description: "Reconnect if the auth lapsed" },
|
|
193
|
+
],
|
|
194
|
+
hints: data.successful
|
|
195
|
+
? [`Executed ${tool} successfully. Credits remaining: ${credits}.`]
|
|
196
|
+
: [`Tool returned an error: ${data.error ?? "unknown"}`],
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
//# sourceMappingURL=integrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrations.js","sourceRoot":"","sources":["../../src/commands/integrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { basename } from "path";
|
|
4
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
5
|
+
import { loadConfig, getApiKey } from "../config.js";
|
|
6
|
+
import { agentOutput, formatApiError } from "../output.js";
|
|
7
|
+
export const mediaCmd = new Command("media")
|
|
8
|
+
.description("Manage media assets — upload, list, update, delete files in your Media Asset Manager")
|
|
9
|
+
.addHelpText("after", `
|
|
10
|
+
Subcommands:
|
|
11
|
+
naive media list List media assets
|
|
12
|
+
naive media get <id> Get a single asset by ID
|
|
13
|
+
naive media upload --url <url> Upload from a URL
|
|
14
|
+
naive media upload --file <path> Upload a local file
|
|
15
|
+
naive media update <id> --title ... --tags ... Update asset metadata
|
|
16
|
+
naive media delete <id> Delete an asset
|
|
17
|
+
|
|
18
|
+
Assets are auto-populated when video clipping or video generation jobs complete.
|
|
19
|
+
`);
|
|
20
|
+
// ── List ──────────────────────────────────────────────────────────────────
|
|
21
|
+
mediaCmd
|
|
22
|
+
.command("list")
|
|
23
|
+
.description("List media assets with optional filters")
|
|
24
|
+
.option("--source <type>", "Filter by source: manual, video_clipping, video_generation, url_import")
|
|
25
|
+
.option("--search <query>", "Search by title or filename")
|
|
26
|
+
.option("--limit <n>", "Max results (default 50, max 100)")
|
|
27
|
+
.option("--offset <n>", "Pagination offset")
|
|
28
|
+
.action(async (opts) => {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (opts.source)
|
|
31
|
+
params.set("source_type", opts.source);
|
|
32
|
+
if (opts.search)
|
|
33
|
+
params.set("search", opts.search);
|
|
34
|
+
if (opts.limit)
|
|
35
|
+
params.set("limit", opts.limit);
|
|
36
|
+
if (opts.offset)
|
|
37
|
+
params.set("offset", opts.offset);
|
|
38
|
+
const qs = params.toString();
|
|
39
|
+
const resp = await apiRequest("GET", `/v1/media${qs ? `?${qs}` : ""}`);
|
|
40
|
+
handleApiError("media.list", resp);
|
|
41
|
+
agentOutput({
|
|
42
|
+
action: "media.list",
|
|
43
|
+
result: resp.data,
|
|
44
|
+
next_steps: [
|
|
45
|
+
{ command: "naive media get <id>", description: "View a specific asset" },
|
|
46
|
+
{ command: "naive media upload --url <url>", description: "Upload a new asset from URL" },
|
|
47
|
+
],
|
|
48
|
+
hints: ["Use --source to filter by origin (video_clipping, video_generation, manual, url_import)."],
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
// ── Get ───────────────────────────────────────────────────────────────────
|
|
52
|
+
mediaCmd
|
|
53
|
+
.command("get <id>")
|
|
54
|
+
.description("Get details of a single media asset")
|
|
55
|
+
.action(async (id) => {
|
|
56
|
+
const resp = await apiRequest("GET", `/v1/media/${id}`);
|
|
57
|
+
handleApiError("media.get", resp);
|
|
58
|
+
agentOutput({
|
|
59
|
+
action: "media.get",
|
|
60
|
+
result: resp.data,
|
|
61
|
+
next_steps: [
|
|
62
|
+
{ command: `naive media update ${id} --title "New Title"`, description: "Update this asset" },
|
|
63
|
+
{ command: `naive media delete ${id}`, description: "Delete this asset" },
|
|
64
|
+
],
|
|
65
|
+
hints: ["Asset details include source_type, source_job_id, and tags."],
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
// ── Upload ────────────────────────────────────────────────────────────────
|
|
69
|
+
mediaCmd
|
|
70
|
+
.command("upload")
|
|
71
|
+
.description("Upload a media asset from a URL or local file")
|
|
72
|
+
.option("--url <url>", "Public URL of the media file")
|
|
73
|
+
.option("--file <path>", "Path to a local file to upload")
|
|
74
|
+
.option("--title <title>", "Asset title")
|
|
75
|
+
.option("--description <desc>", "Asset description")
|
|
76
|
+
.option("--tags <tags>", "Comma-separated tags")
|
|
77
|
+
.action(async (opts) => {
|
|
78
|
+
if (!opts.url && !opts.file) {
|
|
79
|
+
console.error("Error: provide --url or --file");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()) : undefined;
|
|
83
|
+
if (opts.url) {
|
|
84
|
+
const body = { url: opts.url };
|
|
85
|
+
if (opts.title)
|
|
86
|
+
body.title = opts.title;
|
|
87
|
+
if (opts.description)
|
|
88
|
+
body.description = opts.description;
|
|
89
|
+
if (tags)
|
|
90
|
+
body.tags = tags;
|
|
91
|
+
const resp = await apiRequest("POST", "/v1/media/upload/url", body);
|
|
92
|
+
handleApiError("media.upload", resp);
|
|
93
|
+
agentOutput({
|
|
94
|
+
action: "media.upload",
|
|
95
|
+
result: resp.data,
|
|
96
|
+
next_steps: [
|
|
97
|
+
{ command: "naive media list", description: "View all assets" },
|
|
98
|
+
],
|
|
99
|
+
hints: ["Asset uploaded from URL and added to your Media Asset Manager."],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const filePath = opts.file;
|
|
104
|
+
const fileBuffer = readFileSync(filePath);
|
|
105
|
+
const filename = basename(filePath);
|
|
106
|
+
const config = loadConfig();
|
|
107
|
+
const url = `${config.base_url}/v1/media/upload/file`;
|
|
108
|
+
const formData = new FormData();
|
|
109
|
+
formData.append("file", new Blob([fileBuffer]), filename);
|
|
110
|
+
if (opts.title)
|
|
111
|
+
formData.append("title", opts.title);
|
|
112
|
+
if (opts.description)
|
|
113
|
+
formData.append("description", opts.description);
|
|
114
|
+
if (tags)
|
|
115
|
+
formData.append("tags", JSON.stringify(tags));
|
|
116
|
+
const resp = await fetch(url, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: { Authorization: `Bearer ${getApiKey()}` },
|
|
119
|
+
body: formData,
|
|
120
|
+
});
|
|
121
|
+
const data = await resp.json();
|
|
122
|
+
if (resp.status >= 400) {
|
|
123
|
+
formatApiError("media.upload", data);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
agentOutput({
|
|
127
|
+
action: "media.upload",
|
|
128
|
+
result: data,
|
|
129
|
+
next_steps: [
|
|
130
|
+
{ command: "naive media list", description: "View all assets" },
|
|
131
|
+
],
|
|
132
|
+
hints: [`File "${filename}" uploaded to your Media Asset Manager.`],
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
// ── Update ────────────────────────────────────────────────────────────────
|
|
138
|
+
mediaCmd
|
|
139
|
+
.command("update <id>")
|
|
140
|
+
.description("Update media asset metadata (title, description, tags)")
|
|
141
|
+
.option("--title <title>", "New title")
|
|
142
|
+
.option("--description <desc>", "New description")
|
|
143
|
+
.option("--tags <tags>", "Comma-separated tags (replaces existing)")
|
|
144
|
+
.action(async (id, opts) => {
|
|
145
|
+
const body = {};
|
|
146
|
+
if (opts.title !== undefined)
|
|
147
|
+
body.title = opts.title;
|
|
148
|
+
if (opts.description !== undefined)
|
|
149
|
+
body.description = opts.description;
|
|
150
|
+
if (opts.tags !== undefined)
|
|
151
|
+
body.tags = opts.tags.split(",").map((t) => t.trim());
|
|
152
|
+
if (Object.keys(body).length === 0) {
|
|
153
|
+
console.error("Error: provide at least one of --title, --description, or --tags");
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
const resp = await apiRequest("PATCH", `/v1/media/${id}`, body);
|
|
157
|
+
handleApiError("media.update", resp);
|
|
158
|
+
agentOutput({
|
|
159
|
+
action: "media.update",
|
|
160
|
+
result: resp.data,
|
|
161
|
+
next_steps: [
|
|
162
|
+
{ command: `naive media get ${id}`, description: "View updated asset" },
|
|
163
|
+
],
|
|
164
|
+
hints: ["Asset metadata updated."],
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// ── Delete ────────────────────────────────────────────────────────────────
|
|
168
|
+
mediaCmd
|
|
169
|
+
.command("delete <id>")
|
|
170
|
+
.description("Delete a media asset")
|
|
171
|
+
.action(async (id) => {
|
|
172
|
+
const resp = await apiRequest("DELETE", `/v1/media/${id}`);
|
|
173
|
+
handleApiError("media.delete", resp);
|
|
174
|
+
agentOutput({
|
|
175
|
+
action: "media.delete",
|
|
176
|
+
result: resp.data,
|
|
177
|
+
next_steps: [
|
|
178
|
+
{ command: "naive media list", description: "View remaining assets" },
|
|
179
|
+
],
|
|
180
|
+
hints: ["Asset permanently deleted."],
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"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"}
|