@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,271 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { agentOutput } from "../output.js";
|
|
4
|
+
export const billingClientCmd = new Command("billing-client")
|
|
5
|
+
.description("naive/billing-client — Stripe-via-Composio: invoice + bill your clients. Distinct from 'naive billing' (Naive platform plan).")
|
|
6
|
+
.addHelpText("after", `
|
|
7
|
+
Subcommands:
|
|
8
|
+
naive billing-client connection Check whether Stripe is connected via Composio
|
|
9
|
+
naive billing-client sync Manually pull latest invoices/subscriptions/customers from Stripe
|
|
10
|
+
naive billing-client invoices ... Manage Stripe invoices for your clients
|
|
11
|
+
naive billing-client subscriptions ... Manage Stripe subscriptions for retainers
|
|
12
|
+
naive billing-client profile <contact-id> Look up a billing profile for a CRM contact
|
|
13
|
+
naive billing-client overdue List overdue invoices (for dunning workflows)
|
|
14
|
+
naive billing-client mrr Net MRR change over a date range
|
|
15
|
+
|
|
16
|
+
Stripe must be connected via Composio first:
|
|
17
|
+
$ naive integrations connect stripe
|
|
18
|
+
|
|
19
|
+
If it isn't connected, every billing-client command returns:
|
|
20
|
+
{ error_code: "stripe_not_connected", connect_url: "..." }
|
|
21
|
+
`);
|
|
22
|
+
billingClientCmd
|
|
23
|
+
.command("connection")
|
|
24
|
+
.description("Check Stripe (Composio) connection status")
|
|
25
|
+
.action(async () => {
|
|
26
|
+
const resp = await apiRequest("GET", "/v1/billing-client/connection");
|
|
27
|
+
handleApiError("billing-client.connection", resp);
|
|
28
|
+
const data = resp.data;
|
|
29
|
+
agentOutput({
|
|
30
|
+
action: "billing-client.connection",
|
|
31
|
+
result: resp.data,
|
|
32
|
+
next_steps: data.connected
|
|
33
|
+
? [{ command: "naive billing-client invoices list", description: "List existing invoices" }]
|
|
34
|
+
: [{ command: "naive integrations connect stripe", description: "Connect Stripe via Composio" }],
|
|
35
|
+
hints: data.connected
|
|
36
|
+
? ["Stripe is connected — billing-client commands will work"]
|
|
37
|
+
: ["Stripe is not connected — connect via Composio before invoicing clients"],
|
|
38
|
+
related_commands: ["naive integrations connect", "naive billing-client invoices list"],
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
billingClientCmd
|
|
42
|
+
.command("sync")
|
|
43
|
+
.description("Manually pull latest invoices/subscriptions/customers from Stripe (usually runs hourly)")
|
|
44
|
+
.action(async () => {
|
|
45
|
+
const resp = await apiRequest("POST", "/v1/billing-client/sync");
|
|
46
|
+
handleApiError("billing-client.sync", resp);
|
|
47
|
+
agentOutput({
|
|
48
|
+
action: "billing-client.sync",
|
|
49
|
+
result: resp.data,
|
|
50
|
+
related_commands: ["naive billing-client invoices list", "naive billing-client subscriptions list"],
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
// ── Invoices ──────────────────────────────────────────────────────────────
|
|
54
|
+
const invoicesCmd = billingClientCmd.command("invoices").description("Stripe invoice management");
|
|
55
|
+
invoicesCmd
|
|
56
|
+
.command("list")
|
|
57
|
+
.description("List invoices (denormalized read model)")
|
|
58
|
+
.option("--crm-contact <id>", "Filter to a CRM contact")
|
|
59
|
+
.option("--crm-company <id>", "Filter to a CRM company")
|
|
60
|
+
.option("--status <status>", "Stripe status (draft|open|paid|void|uncollectible)")
|
|
61
|
+
.option("--limit <n>", "Max results (default 50)", "50")
|
|
62
|
+
.option("--offset <n>", "Pagination offset", "0")
|
|
63
|
+
.action(async (opts) => {
|
|
64
|
+
const params = new URLSearchParams({ limit: opts.limit, offset: opts.offset });
|
|
65
|
+
if (opts.crmContact)
|
|
66
|
+
params.set("crm_contact_id", opts.crmContact);
|
|
67
|
+
if (opts.crmCompany)
|
|
68
|
+
params.set("crm_company_id", opts.crmCompany);
|
|
69
|
+
if (opts.status)
|
|
70
|
+
params.set("status", opts.status);
|
|
71
|
+
const resp = await apiRequest("GET", `/v1/billing-client/invoices?${params}`);
|
|
72
|
+
handleApiError("billing-client.invoices.list", resp);
|
|
73
|
+
const data = resp.data;
|
|
74
|
+
agentOutput({
|
|
75
|
+
action: "billing-client.invoices.list",
|
|
76
|
+
result: resp.data,
|
|
77
|
+
next_steps: data.invoices.length > 0
|
|
78
|
+
? [{ command: `naive billing-client invoices get ${data.invoices[0].id}`, description: "View the most recent invoice" }]
|
|
79
|
+
: [{ command: "naive billing-client invoices create --crm-contact <id> --line-items <json>", description: "Create your first invoice" }],
|
|
80
|
+
hints: [`${data.count} invoice${data.count === 1 ? "" : "s"} returned`],
|
|
81
|
+
related_commands: ["naive billing-client invoices create", "naive billing-client invoices send"],
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
invoicesCmd
|
|
85
|
+
.command("create")
|
|
86
|
+
.description("Create a Stripe invoice for a CRM contact")
|
|
87
|
+
.requiredOption("--crm-contact <id>", "CRM contact UUID")
|
|
88
|
+
.requiredOption("--line-items <json>", "JSON array: [{description, amount_cents, quantity?, currency?}]")
|
|
89
|
+
.option("--memo <text>", "Memo text on the invoice")
|
|
90
|
+
.option("--due-date <iso>", "ISO date string")
|
|
91
|
+
.option("--currency <iso>", "Default currency (usd)")
|
|
92
|
+
.option("--auto-send", "Finalize and send immediately after creation")
|
|
93
|
+
.action(async (opts) => {
|
|
94
|
+
let lineItems;
|
|
95
|
+
try {
|
|
96
|
+
lineItems = JSON.parse(opts.lineItems);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
agentOutput({
|
|
100
|
+
action: "billing-client.invoices.create",
|
|
101
|
+
result: { error: "invalid_input", message: "--line-items must be valid JSON" },
|
|
102
|
+
hints: ["Example: '[{\"description\":\"Audit\",\"amount_cents\":150000}]'"],
|
|
103
|
+
related_commands: ["naive billing-client invoices create"],
|
|
104
|
+
});
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
const resp = await apiRequest("POST", "/v1/billing-client/invoices", {
|
|
108
|
+
crm_contact_id: opts.crmContact,
|
|
109
|
+
line_items: lineItems,
|
|
110
|
+
memo: opts.memo,
|
|
111
|
+
due_date: opts.dueDate,
|
|
112
|
+
currency: opts.currency,
|
|
113
|
+
auto_send: opts.autoSend === true,
|
|
114
|
+
});
|
|
115
|
+
handleApiError("billing-client.invoices.create", resp);
|
|
116
|
+
const data = resp.data;
|
|
117
|
+
agentOutput({
|
|
118
|
+
action: "billing-client.invoices.create",
|
|
119
|
+
result: resp.data,
|
|
120
|
+
next_steps: [
|
|
121
|
+
...(opts.autoSend
|
|
122
|
+
? [{ command: `naive billing-client invoices get ${data.invoice.id}`, description: "Verify invoice was sent" }]
|
|
123
|
+
: [{ command: `naive billing-client invoices send ${data.invoice.id}`, description: "Finalize and send this draft invoice" }]),
|
|
124
|
+
],
|
|
125
|
+
hints: data.invoice.hosted_invoice_url ? [`Hosted: ${data.invoice.hosted_invoice_url}`] : [],
|
|
126
|
+
related_commands: ["naive billing-client invoices send", "naive billing-client invoices void"],
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
invoicesCmd
|
|
130
|
+
.command("get <invoice_id>")
|
|
131
|
+
.description("Get a single invoice")
|
|
132
|
+
.action(async (invoiceId) => {
|
|
133
|
+
const resp = await apiRequest("GET", `/v1/billing-client/invoices/${invoiceId}`);
|
|
134
|
+
handleApiError("billing-client.invoices.get", resp);
|
|
135
|
+
agentOutput({
|
|
136
|
+
action: "billing-client.invoices.get",
|
|
137
|
+
result: resp.data,
|
|
138
|
+
related_commands: ["naive billing-client invoices send", "naive billing-client invoices void"],
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
invoicesCmd
|
|
142
|
+
.command("send <invoice_id>")
|
|
143
|
+
.description("Finalize (if draft) and send a Stripe invoice")
|
|
144
|
+
.action(async (invoiceId) => {
|
|
145
|
+
const resp = await apiRequest("POST", `/v1/billing-client/invoices/${invoiceId}/send`);
|
|
146
|
+
handleApiError("billing-client.invoices.send", resp);
|
|
147
|
+
agentOutput({
|
|
148
|
+
action: "billing-client.invoices.send",
|
|
149
|
+
result: resp.data,
|
|
150
|
+
related_commands: ["naive billing-client invoices get", "naive billing-client invoices list"],
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
invoicesCmd
|
|
154
|
+
.command("void <invoice_id>")
|
|
155
|
+
.description("Void a Stripe invoice")
|
|
156
|
+
.option("--reason <text>", "Why the invoice is being voided")
|
|
157
|
+
.action(async (invoiceId, opts) => {
|
|
158
|
+
const resp = await apiRequest("POST", `/v1/billing-client/invoices/${invoiceId}/void`, {
|
|
159
|
+
reason: opts.reason,
|
|
160
|
+
});
|
|
161
|
+
handleApiError("billing-client.invoices.void", resp);
|
|
162
|
+
agentOutput({
|
|
163
|
+
action: "billing-client.invoices.void",
|
|
164
|
+
result: resp.data,
|
|
165
|
+
related_commands: ["naive billing-client invoices list", "naive billing-client invoices create"],
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
// ── Subscriptions ────────────────────────────────────────────────────────
|
|
169
|
+
const subsCmd = billingClientCmd.command("subscriptions").description("Stripe subscription management (retainers)");
|
|
170
|
+
subsCmd
|
|
171
|
+
.command("list")
|
|
172
|
+
.description("List subscriptions")
|
|
173
|
+
.option("--crm-contact <id>", "Filter to a CRM contact")
|
|
174
|
+
.option("--status <status>", "Stripe status filter")
|
|
175
|
+
.option("--limit <n>", "Max results (default 50)", "50")
|
|
176
|
+
.option("--offset <n>", "Pagination offset", "0")
|
|
177
|
+
.action(async (opts) => {
|
|
178
|
+
const params = new URLSearchParams({ limit: opts.limit, offset: opts.offset });
|
|
179
|
+
if (opts.crmContact)
|
|
180
|
+
params.set("crm_contact_id", opts.crmContact);
|
|
181
|
+
if (opts.status)
|
|
182
|
+
params.set("status", opts.status);
|
|
183
|
+
const resp = await apiRequest("GET", `/v1/billing-client/subscriptions?${params}`);
|
|
184
|
+
handleApiError("billing-client.subscriptions.list", resp);
|
|
185
|
+
agentOutput({
|
|
186
|
+
action: "billing-client.subscriptions.list",
|
|
187
|
+
result: resp.data,
|
|
188
|
+
related_commands: ["naive billing-client subscriptions create", "naive billing-client subscriptions cancel"],
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
subsCmd
|
|
192
|
+
.command("create")
|
|
193
|
+
.description("Create a subscription for a CRM contact")
|
|
194
|
+
.requiredOption("--crm-contact <id>", "CRM contact UUID")
|
|
195
|
+
.requiredOption("--price-id <id>", "Stripe price ID (price_...)")
|
|
196
|
+
.option("--trial-days <n>", "Trial period in days")
|
|
197
|
+
.action(async (opts) => {
|
|
198
|
+
const resp = await apiRequest("POST", "/v1/billing-client/subscriptions", {
|
|
199
|
+
crm_contact_id: opts.crmContact,
|
|
200
|
+
price_id: opts.priceId,
|
|
201
|
+
...(opts.trialDays && { trial_days: parseInt(opts.trialDays, 10) }),
|
|
202
|
+
});
|
|
203
|
+
handleApiError("billing-client.subscriptions.create", resp);
|
|
204
|
+
agentOutput({
|
|
205
|
+
action: "billing-client.subscriptions.create",
|
|
206
|
+
result: resp.data,
|
|
207
|
+
related_commands: ["naive billing-client subscriptions list", "naive billing-client mrr"],
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
subsCmd
|
|
211
|
+
.command("cancel <subscription_id>")
|
|
212
|
+
.description("Cancel a subscription (default: at period end)")
|
|
213
|
+
.option("--immediate", "Cancel immediately rather than at period end")
|
|
214
|
+
.action(async (subscriptionId, opts) => {
|
|
215
|
+
const resp = await apiRequest("POST", `/v1/billing-client/subscriptions/${subscriptionId}/cancel`, {
|
|
216
|
+
at_period_end: !opts.immediate,
|
|
217
|
+
});
|
|
218
|
+
handleApiError("billing-client.subscriptions.cancel", resp);
|
|
219
|
+
agentOutput({
|
|
220
|
+
action: "billing-client.subscriptions.cancel",
|
|
221
|
+
result: resp.data,
|
|
222
|
+
related_commands: ["naive billing-client subscriptions list"],
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
// ── Profiles + aggregates ─────────────────────────────────────────────────
|
|
226
|
+
billingClientCmd
|
|
227
|
+
.command("profile <contact_id>")
|
|
228
|
+
.description("Get the billing profile for a CRM contact (denormalized status, MRR, LTV)")
|
|
229
|
+
.action(async (contactId) => {
|
|
230
|
+
const resp = await apiRequest("GET", `/v1/billing-client/profiles/by-contact/${contactId}`);
|
|
231
|
+
handleApiError("billing-client.profile", resp);
|
|
232
|
+
agentOutput({
|
|
233
|
+
action: "billing-client.profile",
|
|
234
|
+
result: resp.data,
|
|
235
|
+
related_commands: ["naive billing-client invoices list", "naive billing-client subscriptions list"],
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
billingClientCmd
|
|
239
|
+
.command("overdue")
|
|
240
|
+
.description("List overdue invoices (for dunning)")
|
|
241
|
+
.option("--threshold-days <n>", "Only invoices overdue by at least N days", "0")
|
|
242
|
+
.action(async (opts) => {
|
|
243
|
+
const params = new URLSearchParams({ threshold_days: opts.thresholdDays });
|
|
244
|
+
const resp = await apiRequest("GET", `/v1/billing-client/invoices/overdue?${params}`);
|
|
245
|
+
handleApiError("billing-client.overdue", resp);
|
|
246
|
+
agentOutput({
|
|
247
|
+
action: "billing-client.overdue",
|
|
248
|
+
result: resp.data,
|
|
249
|
+
related_commands: ["naive billing-client invoices list", "naive billing-client invoices send"],
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
billingClientCmd
|
|
253
|
+
.command("mrr")
|
|
254
|
+
.description("Compute MRR change over a date range")
|
|
255
|
+
.option("--from <iso>", "Start date (default 30 days ago)")
|
|
256
|
+
.option("--to <iso>", "End date (default now)")
|
|
257
|
+
.action(async (opts) => {
|
|
258
|
+
const params = new URLSearchParams();
|
|
259
|
+
if (opts.from)
|
|
260
|
+
params.set("from", opts.from);
|
|
261
|
+
if (opts.to)
|
|
262
|
+
params.set("to", opts.to);
|
|
263
|
+
const resp = await apiRequest("GET", `/v1/billing-client/mrr?${params}`);
|
|
264
|
+
handleApiError("billing-client.mrr", resp);
|
|
265
|
+
agentOutput({
|
|
266
|
+
action: "billing-client.mrr",
|
|
267
|
+
result: resp.data,
|
|
268
|
+
related_commands: ["naive billing-client subscriptions list"],
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
//# sourceMappingURL=billing-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billing-client.js","sourceRoot":"","sources":["../../src/commands/billing-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { apiRequest, handleApiError } from "../client.js";
|
|
3
|
+
import { loadConfig, getApiKey } from "../config.js";
|
|
4
|
+
import { agentOutput, agentError } from "../output.js";
|
|
5
|
+
export const ceoCmd = new Command("ceo")
|
|
6
|
+
.description("Communicate with the CEO agent — run prompts, send messages, monitor sessions")
|
|
7
|
+
.addHelpText("after", `
|
|
8
|
+
Subcommands:
|
|
9
|
+
naive ceo run <prompt> Start a new CEO run with a prompt
|
|
10
|
+
naive ceo message <text> Send a message to an active CEO session
|
|
11
|
+
naive ceo status Get the CEO agent's current status
|
|
12
|
+
naive ceo sessions List all CEO sessions
|
|
13
|
+
naive ceo stream <runId> Stream real-time output from a CEO run (SSE)
|
|
14
|
+
naive ceo team-approve Approve a CEO-proposed team and provision agents
|
|
15
|
+
|
|
16
|
+
Workflow:
|
|
17
|
+
1. naive ceo run "Launch a new product line" → start a CEO task
|
|
18
|
+
2. naive ceo stream <runId> → watch output in real-time
|
|
19
|
+
3. naive ceo team-approve --team '[...]' → approve the proposed team
|
|
20
|
+
4. naive ceo message "Focus on marketing" → steer the CEO mid-run
|
|
21
|
+
5. naive ceo status → check if the CEO is working
|
|
22
|
+
6. naive ceo sessions → review all past sessions
|
|
23
|
+
|
|
24
|
+
The CEO is a persistent Hermes gateway that orchestrates your company's
|
|
25
|
+
AI workforce. It decomposes objectives into tasks, proposes teams, and
|
|
26
|
+
dispatches work to employees once you approve the team composition.
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
$ naive ceo run "Analyze our competitors and draft a strategy"
|
|
30
|
+
$ naive ceo status
|
|
31
|
+
$ naive ceo sessions
|
|
32
|
+
$ naive ceo stream abc-123
|
|
33
|
+
$ naive ceo message "Prioritize the SEO analysis"
|
|
34
|
+
`);
|
|
35
|
+
ceoCmd
|
|
36
|
+
.command("run <prompt>")
|
|
37
|
+
.description("Start a new CEO run — the CEO will interpret the prompt and begin executing")
|
|
38
|
+
.addHelpText("after", `
|
|
39
|
+
Examples:
|
|
40
|
+
$ naive ceo run "Set up email infrastructure and send welcome emails to our leads"
|
|
41
|
+
$ naive ceo run "Research competitors in the AI space and write a report"
|
|
42
|
+
|
|
43
|
+
What this does:
|
|
44
|
+
1. Sends the prompt to the CEO agent
|
|
45
|
+
2. The CEO decomposes the prompt into objectives and tasks
|
|
46
|
+
3. Tasks are dispatched to available employees
|
|
47
|
+
4. Returns a run ID for tracking progress
|
|
48
|
+
|
|
49
|
+
The CEO operates asynchronously — use 'naive ceo stream <runId>' to
|
|
50
|
+
watch output in real-time, or 'naive ceo status' to check progress.
|
|
51
|
+
`)
|
|
52
|
+
.action(async (prompt) => {
|
|
53
|
+
const config = loadConfig();
|
|
54
|
+
const resp = await apiRequest("POST", `/v1/companies/${config.company_id}/ceo/run`, {
|
|
55
|
+
prompt,
|
|
56
|
+
});
|
|
57
|
+
handleApiError("ceo.run", resp);
|
|
58
|
+
const data = resp.data;
|
|
59
|
+
agentOutput({
|
|
60
|
+
action: "ceo.run",
|
|
61
|
+
result: resp.data,
|
|
62
|
+
next_steps: [
|
|
63
|
+
{ command: `naive ceo stream ${data.run_id}`, description: "Stream real-time output from this run" },
|
|
64
|
+
{ command: "naive ceo status", description: "Check the CEO's current status" },
|
|
65
|
+
{ command: "naive tasks list", description: "See tasks the CEO has created" },
|
|
66
|
+
],
|
|
67
|
+
hints: [
|
|
68
|
+
`CEO run started (id: ${data.run_id})`,
|
|
69
|
+
"The CEO is now decomposing your prompt into actionable tasks",
|
|
70
|
+
"Use 'naive ceo stream' to watch progress in real-time",
|
|
71
|
+
],
|
|
72
|
+
related_commands: ["naive ceo stream", "naive ceo status", "naive ceo message", "naive tasks list"],
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
ceoCmd
|
|
76
|
+
.command("message <text>")
|
|
77
|
+
.description("Send a message to the CEO agent during an active session")
|
|
78
|
+
.addHelpText("after", `
|
|
79
|
+
Examples:
|
|
80
|
+
$ naive ceo message "Focus on the marketing tasks first"
|
|
81
|
+
$ naive ceo message "Pause all work and give me a status update"
|
|
82
|
+
|
|
83
|
+
What this does:
|
|
84
|
+
Sends a real-time message to the active CEO session. Use this to:
|
|
85
|
+
- Steer the CEO's priorities mid-execution
|
|
86
|
+
- Ask for a progress update
|
|
87
|
+
- Provide additional context or constraints
|
|
88
|
+
- Request course corrections
|
|
89
|
+
|
|
90
|
+
The CEO will incorporate your message into its current workflow.
|
|
91
|
+
`)
|
|
92
|
+
.action(async (text) => {
|
|
93
|
+
const config = loadConfig();
|
|
94
|
+
const resp = await apiRequest("POST", `/v1/companies/${config.company_id}/ceo/message`, {
|
|
95
|
+
text,
|
|
96
|
+
});
|
|
97
|
+
handleApiError("ceo.message", resp);
|
|
98
|
+
agentOutput({
|
|
99
|
+
action: "ceo.message",
|
|
100
|
+
result: resp.data,
|
|
101
|
+
next_steps: [
|
|
102
|
+
{ command: "naive ceo status", description: "Check how the CEO is responding to your message" },
|
|
103
|
+
{ command: "naive ceo sessions", description: "View session history" },
|
|
104
|
+
],
|
|
105
|
+
hints: [
|
|
106
|
+
"Message delivered to the CEO agent",
|
|
107
|
+
"The CEO will incorporate this into its current execution plan",
|
|
108
|
+
],
|
|
109
|
+
related_commands: ["naive ceo status", "naive ceo run", "naive ceo sessions"],
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
ceoCmd
|
|
113
|
+
.command("status")
|
|
114
|
+
.description("Get the CEO agent's current status — active run, idle, or error")
|
|
115
|
+
.addHelpText("after", `
|
|
116
|
+
Examples:
|
|
117
|
+
$ naive ceo status
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
- Current state (idle, running, error)
|
|
121
|
+
- Active run ID (if running)
|
|
122
|
+
- Current objective being worked on
|
|
123
|
+
- Number of active tasks dispatched
|
|
124
|
+
- Last activity timestamp
|
|
125
|
+
`)
|
|
126
|
+
.action(async () => {
|
|
127
|
+
const config = loadConfig();
|
|
128
|
+
const resp = await apiRequest("GET", `/v1/companies/${config.company_id}/ceo/status`);
|
|
129
|
+
handleApiError("ceo.status", resp);
|
|
130
|
+
const data = resp.data;
|
|
131
|
+
agentOutput({
|
|
132
|
+
action: "ceo.status",
|
|
133
|
+
result: resp.data,
|
|
134
|
+
next_steps: [
|
|
135
|
+
...(data.state === "running" && data.active_run_id
|
|
136
|
+
? [{ command: `naive ceo stream ${data.active_run_id}`, description: "Stream the active run's output" }]
|
|
137
|
+
: []),
|
|
138
|
+
...(data.state === "idle"
|
|
139
|
+
? [{ command: 'naive ceo run "<prompt>"', description: "Start a new CEO run" }]
|
|
140
|
+
: []),
|
|
141
|
+
{ command: "naive ceo sessions", description: "View all past sessions" },
|
|
142
|
+
{ command: "naive tasks list", description: "See active tasks" },
|
|
143
|
+
],
|
|
144
|
+
hints: [
|
|
145
|
+
`CEO is currently: ${data.state}`,
|
|
146
|
+
...(data.active_run_id ? [`Active run: ${data.active_run_id}`] : []),
|
|
147
|
+
],
|
|
148
|
+
related_commands: ["naive ceo run", "naive ceo stream", "naive ceo sessions", "naive tasks list"],
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
ceoCmd
|
|
152
|
+
.command("sessions")
|
|
153
|
+
.description("List all CEO sessions — past and current runs")
|
|
154
|
+
.addHelpText("after", `
|
|
155
|
+
Examples:
|
|
156
|
+
$ naive ceo sessions
|
|
157
|
+
|
|
158
|
+
Returns a list of all CEO sessions including:
|
|
159
|
+
- Session/run ID
|
|
160
|
+
- Original prompt
|
|
161
|
+
- Status (running, completed, failed)
|
|
162
|
+
- Start and end timestamps
|
|
163
|
+
- Number of tasks created
|
|
164
|
+
- Summary (for completed sessions)
|
|
165
|
+
`)
|
|
166
|
+
.action(async () => {
|
|
167
|
+
const config = loadConfig();
|
|
168
|
+
const resp = await apiRequest("GET", `/v1/companies/${config.company_id}/ceo/sessions`);
|
|
169
|
+
handleApiError("ceo.sessions", resp);
|
|
170
|
+
const data = resp.data;
|
|
171
|
+
const count = data.sessions?.length ?? 0;
|
|
172
|
+
agentOutput({
|
|
173
|
+
action: "ceo.sessions",
|
|
174
|
+
result: resp.data,
|
|
175
|
+
next_steps: [
|
|
176
|
+
...(count > 0
|
|
177
|
+
? [{ command: `naive ceo stream ${data.sessions[0].id}`, description: "Stream the most recent session" }]
|
|
178
|
+
: []),
|
|
179
|
+
{ command: 'naive ceo run "<prompt>"', description: "Start a new CEO session" },
|
|
180
|
+
],
|
|
181
|
+
hints: [
|
|
182
|
+
`${count} session${count !== 1 ? "s" : ""} found`,
|
|
183
|
+
"Each session represents a CEO run with its tasks and results",
|
|
184
|
+
],
|
|
185
|
+
related_commands: ["naive ceo run", "naive ceo stream", "naive ceo status"],
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
ceoCmd
|
|
189
|
+
.command("team-approve")
|
|
190
|
+
.description("Approve a CEO-proposed team — provisions agent profiles and begins task assignment")
|
|
191
|
+
.requiredOption("--team <json>", "JSON array of team members (each with name, title, template, optional skills/context)")
|
|
192
|
+
.option("--tasks <json>", "JSON array of pre-defined tasks (each with title, description, assignee, optional priority/phase)")
|
|
193
|
+
.option("--objective-id <id>", "Link the team to an objective")
|
|
194
|
+
.addHelpText("after", `
|
|
195
|
+
Examples:
|
|
196
|
+
$ naive ceo team-approve --team '[{"name":"Landing Page Engineer","title":"Engineer","template":"engineer"}]'
|
|
197
|
+
$ naive ceo team-approve --team '[{"name":"Growth Marketer","title":"Marketer","template":"writer"}]' --tasks '[{"title":"Create GTM Plan","description":"Develop go-to-market plan","assignee":"Growth Marketer","priority":"high"}]'
|
|
198
|
+
|
|
199
|
+
What this does:
|
|
200
|
+
1. Creates agent records in the database
|
|
201
|
+
2. Provisions Hermes profiles on the container (with template specialization)
|
|
202
|
+
3. Creates and assigns any pre-defined tasks
|
|
203
|
+
4. Notifies the CEO that the team is ready
|
|
204
|
+
5. Workers are spawned automatically when tasks are dispatched
|
|
205
|
+
|
|
206
|
+
Team member fields:
|
|
207
|
+
name (required) — Display name (use role-based names, e.g. "Landing Page Engineer")
|
|
208
|
+
title (required) — Role/title (Engineer, Marketer, Writer, etc.)
|
|
209
|
+
template (optional) — Specialization: engineer, writer, hunter, or legal
|
|
210
|
+
skills (optional) — Array of skill tags for task routing
|
|
211
|
+
context (optional) — What this agent works on (e.g. "Build the company landing page")
|
|
212
|
+
persona (optional) — Custom persona/system prompt
|
|
213
|
+
|
|
214
|
+
Task fields:
|
|
215
|
+
title (required) — Task title
|
|
216
|
+
description (required) — Detailed description of the deliverable
|
|
217
|
+
assignee (required) — Agent name to assign to (must match a team member name)
|
|
218
|
+
priority (optional) — low, medium, high, or critical (default: medium)
|
|
219
|
+
phase (optional) — 1 or 2. Phase 1 runs immediately, phase 2 is delegated later.
|
|
220
|
+
`)
|
|
221
|
+
.action(async (opts) => {
|
|
222
|
+
const config = loadConfig();
|
|
223
|
+
let team;
|
|
224
|
+
try {
|
|
225
|
+
team = JSON.parse(opts.team);
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
agentError({
|
|
229
|
+
action: "ceo.team-approve",
|
|
230
|
+
error: { code: "invalid_json", message: "The --team flag must be valid JSON" },
|
|
231
|
+
recovery_steps: [
|
|
232
|
+
{ command: `naive ceo team-approve --team '[{"name":"Alice","title":"Engineer"}]'`, description: "Example with valid JSON" },
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
let tasks;
|
|
238
|
+
if (opts.tasks) {
|
|
239
|
+
try {
|
|
240
|
+
tasks = JSON.parse(opts.tasks);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
agentError({
|
|
244
|
+
action: "ceo.team-approve",
|
|
245
|
+
error: { code: "invalid_json", message: "The --tasks flag must be valid JSON" },
|
|
246
|
+
recovery_steps: [
|
|
247
|
+
{ command: `naive ceo team-approve --team '[...]' --tasks '[{"title":"Build Page","description":"...","assignee":"Engineer"}]'`, description: "Example with valid JSON" },
|
|
248
|
+
],
|
|
249
|
+
});
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const body = { team };
|
|
254
|
+
if (tasks)
|
|
255
|
+
body.tasks = tasks;
|
|
256
|
+
if (opts.objectiveId)
|
|
257
|
+
body.objective_id = opts.objectiveId;
|
|
258
|
+
const resp = await apiRequest("POST", `/v1/companies/${config.company_id}/ceo/team/approve`, body);
|
|
259
|
+
handleApiError("ceo.team-approve", resp);
|
|
260
|
+
const data = resp.data;
|
|
261
|
+
agentOutput({
|
|
262
|
+
action: "ceo.team-approve",
|
|
263
|
+
result: resp.data,
|
|
264
|
+
next_steps: [
|
|
265
|
+
{ command: "naive employees list", description: "View your provisioned team" },
|
|
266
|
+
{ command: "naive tasks list", description: "See tasks being assigned to the team" },
|
|
267
|
+
{ command: "naive ceo status", description: "Check if the CEO is dispatching work" },
|
|
268
|
+
],
|
|
269
|
+
hints: [
|
|
270
|
+
`Team approved: ${data.count ?? data.agents_created?.length ?? 0} agent(s) provisioned`,
|
|
271
|
+
...(data.agents_created?.length
|
|
272
|
+
? [`Agents: ${data.agents_created.map((a) => a.name).join(", ")}`]
|
|
273
|
+
: []),
|
|
274
|
+
"The CEO will begin assigning tasks to the new team members",
|
|
275
|
+
],
|
|
276
|
+
related_commands: ["naive employees list", "naive tasks list", "naive ceo run"],
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
ceoCmd
|
|
280
|
+
.command("stream <runId>")
|
|
281
|
+
.description("Stream real-time output from a CEO run via Server-Sent Events")
|
|
282
|
+
.addHelpText("after", `
|
|
283
|
+
Examples:
|
|
284
|
+
$ naive ceo stream abc-123-run-id
|
|
285
|
+
|
|
286
|
+
What this does:
|
|
287
|
+
Opens an SSE (Server-Sent Events) connection to stream the CEO's
|
|
288
|
+
real-time output. Events include:
|
|
289
|
+
- thought: CEO's reasoning steps
|
|
290
|
+
- task_created: new task dispatched
|
|
291
|
+
- task_completed: employee finished a task
|
|
292
|
+
- message: CEO status updates
|
|
293
|
+
- done: run completed
|
|
294
|
+
- error: something went wrong
|
|
295
|
+
|
|
296
|
+
Press Ctrl+C to stop streaming (the run continues in the background).
|
|
297
|
+
`)
|
|
298
|
+
.action(async (runId) => {
|
|
299
|
+
const config = loadConfig();
|
|
300
|
+
const apiKey = getApiKey();
|
|
301
|
+
const url = `${config.base_url}/v1/companies/${config.company_id}/ceo/runs/${runId}/stream`;
|
|
302
|
+
console.error(`Connecting to CEO stream for run ${runId}...`);
|
|
303
|
+
try {
|
|
304
|
+
const resp = await fetch(url, {
|
|
305
|
+
headers: {
|
|
306
|
+
Authorization: `Bearer ${apiKey}`,
|
|
307
|
+
Accept: "text/event-stream",
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
if (!resp.ok || !resp.body) {
|
|
311
|
+
agentError({
|
|
312
|
+
action: "ceo.stream",
|
|
313
|
+
error: { code: "stream_failed", message: `HTTP ${resp.status}: Failed to connect to stream` },
|
|
314
|
+
recovery_steps: [
|
|
315
|
+
{ command: `naive ceo stream ${runId}`, description: "Retry the stream connection" },
|
|
316
|
+
{ command: "naive ceo status", description: "Check if the run is still active" },
|
|
317
|
+
],
|
|
318
|
+
});
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const reader = resp.body.getReader();
|
|
322
|
+
const decoder = new TextDecoder();
|
|
323
|
+
let buffer = "";
|
|
324
|
+
while (true) {
|
|
325
|
+
const { done, value } = await reader.read();
|
|
326
|
+
if (done)
|
|
327
|
+
break;
|
|
328
|
+
buffer += decoder.decode(value, { stream: true });
|
|
329
|
+
const lines = buffer.split("\n");
|
|
330
|
+
buffer = lines.pop() ?? "";
|
|
331
|
+
for (const line of lines) {
|
|
332
|
+
if (line.startsWith("data: ")) {
|
|
333
|
+
const payload = line.slice(6);
|
|
334
|
+
if (payload === "[DONE]") {
|
|
335
|
+
agentOutput({
|
|
336
|
+
action: "ceo.stream",
|
|
337
|
+
result: { status: "completed", run_id: runId },
|
|
338
|
+
next_steps: [
|
|
339
|
+
{ command: "naive tasks list", description: "View tasks created during this run" },
|
|
340
|
+
{ command: "naive ceo sessions", description: "View all sessions" },
|
|
341
|
+
],
|
|
342
|
+
hints: ["CEO run completed — stream ended"],
|
|
343
|
+
related_commands: ["naive ceo status", "naive tasks list"],
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
try {
|
|
348
|
+
const event = JSON.parse(payload);
|
|
349
|
+
console.log(JSON.stringify(event));
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
console.log(payload);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
agentError({
|
|
360
|
+
action: "ceo.stream",
|
|
361
|
+
error: { code: "stream_error", message: String(err) },
|
|
362
|
+
recovery_steps: [
|
|
363
|
+
{ command: `naive ceo stream ${runId}`, description: "Retry the stream" },
|
|
364
|
+
{ command: "naive ceo status", description: "Check CEO status" },
|
|
365
|
+
],
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
//# sourceMappingURL=ceo.js.map
|