@oxygen-agent/cli 1.936.1 → 1.948.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 +1 -1
- package/dist/command-manifest.js +24 -2
- package/dist/help.js +1 -0
- package/dist/index.js +342 -54
- package/dist/ugc-commands.js +353 -12
- package/node_modules/@oxygen/shared/dist/byok-connect.d.ts +11 -6
- package/node_modules/@oxygen/shared/dist/byok-connect.js +14 -6
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +53 -5
- package/node_modules/@oxygen/shared/dist/email-dsn.d.ts +60 -0
- package/node_modules/@oxygen/shared/dist/email-dsn.js +120 -0
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.d.ts +64 -0
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.js +90 -0
- package/node_modules/@oxygen/shared/dist/index.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/index.js +6 -0
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +50 -21
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.js +47 -21
- package/node_modules/@oxygen/shared/dist/langfuse.d.ts +8 -3
- package/node_modules/@oxygen/shared/dist/langfuse.js +177 -130
- package/node_modules/@oxygen/shared/dist/llm-payload.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/llm-payload.js +54 -0
- package/node_modules/@oxygen/shared/dist/llm-usage.d.ts +11 -0
- package/node_modules/@oxygen/shared/dist/llm-usage.js +30 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-core.d.ts +98 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-core.js +159 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-environment.d.ts +18 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-environment.js +46 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +92 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-events.js +96 -0
- package/node_modules/@oxygen/shared/dist/ugc.d.ts +21 -1
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +1 -1
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +22 -0
- package/package.json +1 -1
package/dist/ugc-commands.js
CHANGED
|
@@ -28,20 +28,36 @@ export function registerUgcCommands(program, handle) {
|
|
|
28
28
|
const ugc = program
|
|
29
29
|
.command("ugc")
|
|
30
30
|
.description("Manage UGC programs and independent creator participations: briefs, voice, posts, approvals, sponsorship and bounded amplification. Requires UGC availability.");
|
|
31
|
+
const groupDescriptions = {
|
|
32
|
+
programs: "Programs you operate or joined. Lifecycle: create, update, duplicate (settings + briefs), archive (stops future work, keeps shared history, reversible with restore) and delete (permanent; only while no creator has ever joined).",
|
|
33
|
+
creators: "Creator participations: invite, revoke an invite, accept in the creator workspace, connect a sender, change approval authority, or revoke.",
|
|
34
|
+
briefs: "Program briefs with ordered questions for creators.",
|
|
35
|
+
posts: "Enrolled program posts: enroll existing posts, draft from briefs, edit, schedule, and record creator or brand approval.",
|
|
36
|
+
analytics: "Stored daily program and creator performance.",
|
|
37
|
+
knowledge: "Master Knowledge pages shared live with a program.",
|
|
38
|
+
voice: "Creator voice profiles and imports.",
|
|
39
|
+
sponsorship: "Seat and credit sponsorship per participation.",
|
|
40
|
+
amplification: "Bounded, approval-gated amplification of enrolled posts.",
|
|
41
|
+
calendar: "Bounded enrolled-post calendar reads.",
|
|
42
|
+
};
|
|
31
43
|
const groups = new Map();
|
|
32
44
|
const group = (name) => {
|
|
33
45
|
let command = groups.get(name);
|
|
34
46
|
if (!command) {
|
|
35
47
|
command = ugc.command(name);
|
|
48
|
+
const description = groupDescriptions[name];
|
|
49
|
+
if (description)
|
|
50
|
+
command.description(description);
|
|
36
51
|
groups.set(name, command);
|
|
37
52
|
}
|
|
38
53
|
return command;
|
|
39
54
|
};
|
|
40
55
|
group("programs")
|
|
41
56
|
.command("list")
|
|
42
|
-
.description("Read UGC programs in the active workspace. Read-only.")
|
|
57
|
+
.description("Read UGC programs in the active workspace, archived ones included unless --status filters. Read-only.")
|
|
43
58
|
.option("--program-id <id>", "Program ID.")
|
|
44
59
|
.option("--participation-id <id>", "Creator participation ID.")
|
|
60
|
+
.option("--status <active|archived>", "Only programs in this status.")
|
|
45
61
|
.option("--json", "Print a JSON envelope.")
|
|
46
62
|
.action((options) => handle("ugc programs list", options, () => {
|
|
47
63
|
const query = new URLSearchParams({ view: "programs" });
|
|
@@ -49,6 +65,8 @@ export function registerUgcCommands(program, handle) {
|
|
|
49
65
|
query.set("program_id", String(options.programId));
|
|
50
66
|
if (options.participationId)
|
|
51
67
|
query.set("participation_id", String(options.participationId));
|
|
68
|
+
if (options.status)
|
|
69
|
+
query.set("status", String(options.status));
|
|
52
70
|
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
53
71
|
}));
|
|
54
72
|
group("programs")
|
|
@@ -67,7 +85,7 @@ export function registerUgcCommands(program, handle) {
|
|
|
67
85
|
}));
|
|
68
86
|
group("creators")
|
|
69
87
|
.command("list")
|
|
70
|
-
.description("Read
|
|
88
|
+
.description("Read creators and invitations, including persisted email delivery status. Read-only.")
|
|
71
89
|
.option("--program-id <id>", "Program ID.")
|
|
72
90
|
.option("--participation-id <id>", "Creator participation ID.")
|
|
73
91
|
.option("--json", "Print a JSON envelope.")
|
|
@@ -119,6 +137,8 @@ export function registerUgcCommands(program, handle) {
|
|
|
119
137
|
.description("Read UGC analytics in the active workspace. Read-only.")
|
|
120
138
|
.requiredOption("--program-id <id>", "Program ID.")
|
|
121
139
|
.option("--participation-id <id>", "Creator participation ID.")
|
|
140
|
+
.option("--post-cursor <cursor>", "Next post_performance page from next_post_cursor; totals still cover all enrolled posts.")
|
|
141
|
+
.option("--limit <count>", "Post performance rows per page, up to 100.")
|
|
122
142
|
.option("--json", "Print a JSON envelope.")
|
|
123
143
|
.action((options) => handle("ugc analytics get", options, () => {
|
|
124
144
|
const query = new URLSearchParams({ view: "analytics" });
|
|
@@ -126,6 +146,10 @@ export function registerUgcCommands(program, handle) {
|
|
|
126
146
|
query.set("program_id", String(options.programId));
|
|
127
147
|
if (options.participationId)
|
|
128
148
|
query.set("participation_id", String(options.participationId));
|
|
149
|
+
if (options.postCursor)
|
|
150
|
+
query.set("post_cursor", String(options.postCursor));
|
|
151
|
+
if (options.limit)
|
|
152
|
+
query.set("limit", String(options.limit));
|
|
129
153
|
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
130
154
|
}));
|
|
131
155
|
group("knowledge")
|
|
@@ -156,9 +180,23 @@ export function registerUgcCommands(program, handle) {
|
|
|
156
180
|
query.set("participation_id", String(options.participationId));
|
|
157
181
|
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
158
182
|
}));
|
|
183
|
+
group("posts")
|
|
184
|
+
.command("draft-status")
|
|
185
|
+
.description("Read the original paid draft request and saved result without generating again. Creator workspace only, 0 credits.")
|
|
186
|
+
.requiredOption("--participation-id <id>", "Creator participation ID.")
|
|
187
|
+
.requiredOption("--request-id <id>", "Original draft request ID.")
|
|
188
|
+
.option("--json", "Print a JSON envelope.")
|
|
189
|
+
.action((options) => handle("ugc posts draft-status", options, () => {
|
|
190
|
+
const query = new URLSearchParams({
|
|
191
|
+
view: "draft_run",
|
|
192
|
+
participation_id: String(options.participationId),
|
|
193
|
+
request_id: String(options.requestId),
|
|
194
|
+
});
|
|
195
|
+
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
196
|
+
}));
|
|
159
197
|
group("sponsorship")
|
|
160
198
|
.command("get")
|
|
161
|
-
.description("Read
|
|
199
|
+
.description("Read sponsorship in the active workspace. Creators see their remaining credits and exact organizer access; masters see program payment status. Read-only.")
|
|
162
200
|
.requiredOption("--program-id <id>", "Program ID.")
|
|
163
201
|
.option("--participation-id <id>", "Creator participation ID.")
|
|
164
202
|
.option("--json", "Print a JSON envelope.")
|
|
@@ -170,6 +208,66 @@ export function registerUgcCommands(program, handle) {
|
|
|
170
208
|
query.set("participation_id", String(options.participationId));
|
|
171
209
|
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
172
210
|
}));
|
|
211
|
+
for (const spec of [
|
|
212
|
+
{
|
|
213
|
+
group: "calendar",
|
|
214
|
+
command: "list",
|
|
215
|
+
view: "calendar",
|
|
216
|
+
description: "Read the program's enrolled post calendar in a bounded UTC date range (up to 42 days). Stored data only, 0 credits.",
|
|
217
|
+
fields: [
|
|
218
|
+
["date_from", "Start ISO instant, inclusive.", true],
|
|
219
|
+
["date_to", "End ISO instant, exclusive.", true],
|
|
220
|
+
[
|
|
221
|
+
"calendar_cursor",
|
|
222
|
+
"Calendar next_cursor from the previous page.",
|
|
223
|
+
false,
|
|
224
|
+
],
|
|
225
|
+
["participation_id", "Filter to one creator participation.", false],
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
group: "posts",
|
|
230
|
+
command: "history",
|
|
231
|
+
view: "post_history",
|
|
232
|
+
description: "Read retained public comments, metrics, and publication receipts for one enrolled post. Stored data only, 0 credits.",
|
|
233
|
+
fields: [
|
|
234
|
+
["post_id", "Enrolled source post UUID.", true],
|
|
235
|
+
["cursor", "next_comments_cursor from the previous page.", false],
|
|
236
|
+
["metric_cursor", "next_metrics_cursor from the previous page.", false],
|
|
237
|
+
["action_cursor", "next_actions_cursor from the previous page.", false],
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
group: "amplification",
|
|
242
|
+
command: "get",
|
|
243
|
+
view: "amplification",
|
|
244
|
+
description: "Read this program's current amplification authority and immutable action history. Master workspace only; 0 credits, no provider call.",
|
|
245
|
+
fields: [["cursor", "next_cursor from the previous action page.", false]],
|
|
246
|
+
},
|
|
247
|
+
]) {
|
|
248
|
+
const command = group(spec.group)
|
|
249
|
+
.command(spec.command)
|
|
250
|
+
.description(spec.description)
|
|
251
|
+
.requiredOption("--program-id <id>", "Program ID.")
|
|
252
|
+
.option("--limit <count>", "Rows per page, up to 100.")
|
|
253
|
+
.option("--json", "Print a JSON envelope.");
|
|
254
|
+
for (const [name, description, required] of spec.fields)
|
|
255
|
+
command[required ? "requiredOption" : "option"](`--${name.replaceAll("_", "-")} <value>`, description);
|
|
256
|
+
command.action((options) => handle(`ugc ${spec.group} ${spec.command}`, options, () => {
|
|
257
|
+
const query = new URLSearchParams({
|
|
258
|
+
view: spec.view,
|
|
259
|
+
program_id: String(options.programId),
|
|
260
|
+
});
|
|
261
|
+
for (const [name] of spec.fields) {
|
|
262
|
+
const key = name.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
263
|
+
if (options[key] !== undefined)
|
|
264
|
+
query.set(name, String(options[key]));
|
|
265
|
+
}
|
|
266
|
+
if (options.limit)
|
|
267
|
+
query.set("limit", String(options.limit));
|
|
268
|
+
return requestOxygen(`/api/cli/ugc?${query}`);
|
|
269
|
+
}));
|
|
270
|
+
}
|
|
173
271
|
const writes = [
|
|
174
272
|
{
|
|
175
273
|
action: "program_create",
|
|
@@ -252,7 +350,79 @@ export function registerUgcCommands(program, handle) {
|
|
|
252
350
|
{
|
|
253
351
|
name: "status",
|
|
254
352
|
kind: "string",
|
|
255
|
-
description: "
|
|
353
|
+
description: "active or archived; prefer `programs archive` / `programs restore`.",
|
|
354
|
+
required: false,
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
action: "program_update",
|
|
360
|
+
command: "programs archive",
|
|
361
|
+
description: "Archive a program: stop future access, publishing, tracking and amplification, revoke pending invitations and request cancellation of sponsorship renewals. Shared history is retained; `programs restore` re-activates it.",
|
|
362
|
+
fixed: { status: "archived" },
|
|
363
|
+
fields: [
|
|
364
|
+
{
|
|
365
|
+
name: "program_id",
|
|
366
|
+
kind: "string",
|
|
367
|
+
description: "Program ID.",
|
|
368
|
+
required: true,
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
action: "program_update",
|
|
374
|
+
command: "programs restore",
|
|
375
|
+
description: "Restore an archived program. Creators removed earlier stay removed, revoked invitations stay revoked, and cancelled sponsorships need a new preview and confirmation.",
|
|
376
|
+
fixed: { status: "active" },
|
|
377
|
+
fields: [
|
|
378
|
+
{
|
|
379
|
+
name: "program_id",
|
|
380
|
+
kind: "string",
|
|
381
|
+
description: "Program ID.",
|
|
382
|
+
required: true,
|
|
383
|
+
},
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
action: "program_duplicate",
|
|
388
|
+
command: "programs duplicate",
|
|
389
|
+
description: "Copy a program's settings, shared knowledge and brand review into a new active program, with its briefs by default. Free: 0 credits. Never copies creators, invitations, posts or sponsorship.",
|
|
390
|
+
fields: [
|
|
391
|
+
{
|
|
392
|
+
name: "program_id",
|
|
393
|
+
kind: "string",
|
|
394
|
+
description: "Source program ID.",
|
|
395
|
+
required: true,
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: "name",
|
|
399
|
+
kind: "string",
|
|
400
|
+
description: 'Name of the copy; defaults to "<name> (copy)".',
|
|
401
|
+
required: false,
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: "include_briefs",
|
|
405
|
+
kind: "boolean",
|
|
406
|
+
description: "Copy the program's briefs (default true).",
|
|
407
|
+
required: false,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
action: "program_delete",
|
|
413
|
+
command: "programs delete",
|
|
414
|
+
description: "Permanently delete a program with its briefs and pending invitations. A bare call previews the counts and whether it is deletable; pass --approved to delete. Allowed only while no creator has ever joined; otherwise use `programs archive`.",
|
|
415
|
+
fields: [
|
|
416
|
+
{
|
|
417
|
+
name: "program_id",
|
|
418
|
+
kind: "string",
|
|
419
|
+
description: "Program ID.",
|
|
420
|
+
required: true,
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
name: "approved",
|
|
424
|
+
kind: "boolean",
|
|
425
|
+
description: "Confirm the previewed permanent deletion.",
|
|
256
426
|
required: false,
|
|
257
427
|
},
|
|
258
428
|
],
|
|
@@ -260,7 +430,7 @@ export function registerUgcCommands(program, handle) {
|
|
|
260
430
|
{
|
|
261
431
|
action: "invite_create",
|
|
262
432
|
command: "creators invite",
|
|
263
|
-
description: "
|
|
433
|
+
description: "Preview an invitation email (0 credits); send with --approved --preview-token from that preview. Use --link-only to create a link without email.",
|
|
264
434
|
fields: [
|
|
265
435
|
{
|
|
266
436
|
name: "program_id",
|
|
@@ -271,9 +441,52 @@ export function registerUgcCommands(program, handle) {
|
|
|
271
441
|
{
|
|
272
442
|
name: "email",
|
|
273
443
|
kind: "string",
|
|
274
|
-
description: "
|
|
444
|
+
description: "Exact creator email to receive the invitation.",
|
|
445
|
+
required: true,
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
name: "approved",
|
|
449
|
+
kind: "boolean",
|
|
450
|
+
description: "Authorize sending the exact previewed invitation email.",
|
|
451
|
+
required: false,
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: "preview_token",
|
|
455
|
+
kind: "string",
|
|
456
|
+
description: "Exact token from the invitation email preview.",
|
|
457
|
+
required: false,
|
|
458
|
+
},
|
|
459
|
+
],
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
action: "invite_send",
|
|
463
|
+
command: "creators send-invite",
|
|
464
|
+
description: "Preview email for an existing pending invitation; send or resend with --approved --preview-token. Replaces the old link, keeps its expiry. Sent means provider accepted, not inbox delivery.",
|
|
465
|
+
fields: [
|
|
466
|
+
{
|
|
467
|
+
name: "program_id",
|
|
468
|
+
kind: "string",
|
|
469
|
+
description: "Program ID.",
|
|
470
|
+
required: true,
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
name: "invitation_id",
|
|
474
|
+
kind: "string",
|
|
475
|
+
description: "Exact pending invitation ID from creators list.",
|
|
275
476
|
required: true,
|
|
276
477
|
},
|
|
478
|
+
{
|
|
479
|
+
name: "approved",
|
|
480
|
+
kind: "boolean",
|
|
481
|
+
description: "Authorize the exact previewed email send or resend.",
|
|
482
|
+
required: false,
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
name: "preview_token",
|
|
486
|
+
kind: "string",
|
|
487
|
+
description: "Exact token from this invitation email preview.",
|
|
488
|
+
required: false,
|
|
489
|
+
},
|
|
277
490
|
],
|
|
278
491
|
},
|
|
279
492
|
{
|
|
@@ -453,8 +666,14 @@ export function registerUgcCommands(program, handle) {
|
|
|
453
666
|
{
|
|
454
667
|
action: "draft_create",
|
|
455
668
|
command: "posts draft",
|
|
456
|
-
description: "Preview AI drafting from brief answers
|
|
669
|
+
description: "Preview AI drafting from brief answers. Execute only in the creator workspace with approved and a credit ceiling; publishing delegation does not grant authority to spend creator credits.",
|
|
457
670
|
fields: [
|
|
671
|
+
{
|
|
672
|
+
name: "request_id",
|
|
673
|
+
kind: "string",
|
|
674
|
+
description: "Request ID from preview. Reuse it after a timeout; a new ID is a new paid draft.",
|
|
675
|
+
required: false,
|
|
676
|
+
},
|
|
458
677
|
{
|
|
459
678
|
name: "participation_id",
|
|
460
679
|
kind: "string",
|
|
@@ -589,7 +808,7 @@ export function registerUgcCommands(program, handle) {
|
|
|
589
808
|
{
|
|
590
809
|
action: "voice_import",
|
|
591
810
|
command: "voice import",
|
|
592
|
-
description: "Preview LinkedIn voice
|
|
811
|
+
description: "Preview all retrievable LinkedIn history and voice inference; approve a total credit ceiling to start. Use --import-id to resume a safely interrupted import with its saved progress and spend.",
|
|
593
812
|
fields: [
|
|
594
813
|
{
|
|
595
814
|
name: "participation_id",
|
|
@@ -597,6 +816,12 @@ export function registerUgcCommands(program, handle) {
|
|
|
597
816
|
description: "Creator participation ID.",
|
|
598
817
|
required: true,
|
|
599
818
|
},
|
|
819
|
+
{
|
|
820
|
+
name: "import_id",
|
|
821
|
+
kind: "string",
|
|
822
|
+
description: "Existing safely interrupted import to resume; max-credits is its total ceiling including credits already used.",
|
|
823
|
+
required: false,
|
|
824
|
+
},
|
|
600
825
|
{
|
|
601
826
|
name: "approved",
|
|
602
827
|
kind: "boolean",
|
|
@@ -611,10 +836,66 @@ export function registerUgcCommands(program, handle) {
|
|
|
611
836
|
},
|
|
612
837
|
],
|
|
613
838
|
},
|
|
839
|
+
{
|
|
840
|
+
action: "voice_save",
|
|
841
|
+
command: "voice save",
|
|
842
|
+
description: "Save your own writing preferences and examples as a private provisional Knowledge voice. Free: 0 credits, no provider call or connected account required. Existing voice edits require its current revision.",
|
|
843
|
+
fields: [
|
|
844
|
+
{
|
|
845
|
+
name: "participation_id",
|
|
846
|
+
kind: "string",
|
|
847
|
+
description: "Your creator participation ID.",
|
|
848
|
+
required: true,
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
name: "body",
|
|
852
|
+
kind: "string",
|
|
853
|
+
description: "Your own writing preferences or voice guide (Markdown).",
|
|
854
|
+
required: true,
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
name: "writing_examples",
|
|
858
|
+
kind: "array",
|
|
859
|
+
description: "JSON array of up to five examples you actually wrote; do not invent personal experiences.",
|
|
860
|
+
required: false,
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
name: "expected_revision",
|
|
864
|
+
kind: "number",
|
|
865
|
+
description: "Current profile revision returned by voice get, required when editing it.",
|
|
866
|
+
required: false,
|
|
867
|
+
},
|
|
868
|
+
],
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
action: "sponsorship_cancel",
|
|
872
|
+
command: "sponsorship cancel",
|
|
873
|
+
description: "Preview stopping renewal for one program sponsorship. Confirm with --approved and a signed-in master admin. Participation and credits through the paid period remain available.",
|
|
874
|
+
fields: [
|
|
875
|
+
{
|
|
876
|
+
name: "program_id",
|
|
877
|
+
kind: "string",
|
|
878
|
+
description: "Master program ID.",
|
|
879
|
+
required: true,
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
name: "participation_id",
|
|
883
|
+
kind: "string",
|
|
884
|
+
description: "Exact creator participation ID.",
|
|
885
|
+
required: true,
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
name: "approved",
|
|
889
|
+
kind: "boolean",
|
|
890
|
+
description: "Approve the exact cancellation preview. Omit for a free preview.",
|
|
891
|
+
required: false,
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
},
|
|
614
895
|
{
|
|
615
896
|
action: "sponsorship_preview",
|
|
616
897
|
command: "sponsorship preview",
|
|
617
|
-
description: "Preview seat charges and monthly 10,000-credit creator grants
|
|
898
|
+
description: "Preview seat charges and monthly 10,000-credit creator grants as a signed-in master workspace admin. Org API keys cannot create this quote.",
|
|
618
899
|
fields: [
|
|
619
900
|
{
|
|
620
901
|
name: "program_id",
|
|
@@ -633,7 +914,7 @@ export function registerUgcCommands(program, handle) {
|
|
|
633
914
|
{
|
|
634
915
|
action: "sponsorship_confirm",
|
|
635
916
|
command: "sponsorship confirm",
|
|
636
|
-
description: "
|
|
917
|
+
description: "Confirm the exact sponsorship quote as the same signed-in master workspace admin. Each program pays separately, even for the same account.",
|
|
637
918
|
fields: [
|
|
638
919
|
{
|
|
639
920
|
name: "program_id",
|
|
@@ -661,11 +942,54 @@ export function registerUgcCommands(program, handle) {
|
|
|
661
942
|
},
|
|
662
943
|
],
|
|
663
944
|
},
|
|
945
|
+
{
|
|
946
|
+
action: "amplification_reconcile",
|
|
947
|
+
command: "amplification reconcile",
|
|
948
|
+
description: "Preview recording a provider observation for an uncertain program action. Confirmation needs a signed-in operator and --approved; it never contacts the provider or authorizes a retry.",
|
|
949
|
+
fields: [
|
|
950
|
+
{
|
|
951
|
+
name: "program_id",
|
|
952
|
+
kind: "string",
|
|
953
|
+
description: "Program ID in the master workspace.",
|
|
954
|
+
required: true,
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
name: "action_id",
|
|
958
|
+
kind: "string",
|
|
959
|
+
description: "Unresolved effect_unknown action ID.",
|
|
960
|
+
required: true,
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
name: "outcome",
|
|
964
|
+
kind: "string",
|
|
965
|
+
description: "Observed applied or not_applied outcome.",
|
|
966
|
+
required: true,
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
name: "evidence",
|
|
970
|
+
kind: "object",
|
|
971
|
+
description: "JSON object: provider_post_id, evidence_ref, observed_at ISO instant; applied needs provider_object_id and comments/reposts need exact observed_text. Optional note.",
|
|
972
|
+
required: true,
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
name: "approved",
|
|
976
|
+
kind: "boolean",
|
|
977
|
+
description: "Explicitly confirm this immutable observation. No retry is authorized.",
|
|
978
|
+
required: false,
|
|
979
|
+
},
|
|
980
|
+
],
|
|
981
|
+
},
|
|
664
982
|
{
|
|
665
983
|
action: "amplification_save",
|
|
666
984
|
command: "amplification save",
|
|
667
985
|
description: "Save exact opted-in sender scope and bounded post-specific amplification. Enabling needs explicit approval.",
|
|
668
986
|
fields: [
|
|
987
|
+
{
|
|
988
|
+
name: "sender_voice_pages",
|
|
989
|
+
kind: "object",
|
|
990
|
+
description: "JSON map from each acting sender UUID to its selected active Knowledge voice page UUID. Required for comments or reposts; the exact mapping is approved with the policy.",
|
|
991
|
+
required: false,
|
|
992
|
+
},
|
|
669
993
|
{
|
|
670
994
|
name: "program_id",
|
|
671
995
|
kind: "string",
|
|
@@ -733,16 +1057,33 @@ export function registerUgcCommands(program, handle) {
|
|
|
733
1057
|
else
|
|
734
1058
|
command.option(flag, field.description);
|
|
735
1059
|
}
|
|
1060
|
+
if (spec.action === "invite_create")
|
|
1061
|
+
command.option("--link-only", "Create a shareable link without sending email.");
|
|
736
1062
|
command
|
|
737
1063
|
.option("--json", "Print a JSON envelope.")
|
|
738
1064
|
.action((options) => handle(`ugc ${spec.command}`, options, () => {
|
|
739
|
-
const body = {
|
|
1065
|
+
const body = {
|
|
1066
|
+
action: spec.action,
|
|
1067
|
+
...(spec.fixed ?? {}),
|
|
1068
|
+
};
|
|
740
1069
|
for (const field of spec.fields) {
|
|
741
1070
|
const key = field.name.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
742
1071
|
if (options[key] !== undefined)
|
|
743
1072
|
body[field.name] = parseField(options[key], field);
|
|
744
1073
|
}
|
|
745
|
-
|
|
1074
|
+
if (spec.action === "invite_create") {
|
|
1075
|
+
body.send_email = options.linkOnly !== true;
|
|
1076
|
+
if (options.linkOnly && (body.approved || body.preview_token))
|
|
1077
|
+
throw new Error("--link-only cannot be combined with --approved or --preview-token.");
|
|
1078
|
+
}
|
|
1079
|
+
return requestOxygen("/api/cli/ugc", {
|
|
1080
|
+
method: "POST",
|
|
1081
|
+
body,
|
|
1082
|
+
...(spec.action === "draft_create" &&
|
|
1083
|
+
typeof body.request_id === "string"
|
|
1084
|
+
? { idempotencyKey: body.request_id }
|
|
1085
|
+
: {}),
|
|
1086
|
+
});
|
|
746
1087
|
}));
|
|
747
1088
|
}
|
|
748
1089
|
}
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* WHY THIS EXISTS. `native_provider.execution.supports_byok` says a TOOL can run on
|
|
6
6
|
* a customer's own key. It does not say the customer has any way to give us one.
|
|
7
|
-
* Those are two different facts, and
|
|
7
|
+
* Those are two different facts, and 9 of the 42 byok-capable native providers
|
|
8
8
|
* have the first without the second:
|
|
9
9
|
*
|
|
10
|
-
* apify builtwith dropleads lusha openwebninja
|
|
10
|
+
* apify builtwith dropleads lusha openwebninja peopledatalabs
|
|
11
11
|
* rocketreach theirstack wiza
|
|
12
12
|
*
|
|
13
13
|
* For those, `oxygen integrations connect <id> --api-key` does not reach
|
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
* tool is native generic-REST and `shouldRouteStaticToolThroughComposio` is false, so
|
|
18
18
|
* `resolveOptionalApiKeyCredentials` finds nothing and the call falls back to the
|
|
19
19
|
* MANAGED key — the very key that was out of credits. The command appears to work,
|
|
20
|
-
* changes nothing, and the customer is back where they started with no error.
|
|
20
|
+
* changes nothing, and the customer is back where they started with no error. The
|
|
21
|
+
* connect route now refuses each of those nine with a typed `byok_connect_unavailable`
|
|
22
|
+
* rather than a silent Composio "success"; they stay OFF this list until one gains a
|
|
23
|
+
* real native connect form.
|
|
21
24
|
*
|
|
22
|
-
* That is precisely the failure Plain T-104
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
+
* That is precisely the failure Plain T-104 hit: `parallel.search` was one of the
|
|
26
|
+
* refused tools, and a refusal message that told Mentcape to connect their own Parallel
|
|
27
|
+
* key would once have sent them down a path that silently does nothing. Parallel now has
|
|
28
|
+
* a native api-key connect (catalog.ts) and IS on this list, so that message is finally
|
|
29
|
+
* true for it — the nine above are the ones it must still never name.
|
|
25
30
|
*
|
|
26
31
|
* So a message may only offer BYOK when BOTH halves hold, and this list is the second
|
|
27
32
|
* half. It lives in @oxygen/shared because the two sides that need it cannot see each
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* WHY THIS EXISTS. `native_provider.execution.supports_byok` says a TOOL can run on
|
|
6
6
|
* a customer's own key. It does not say the customer has any way to give us one.
|
|
7
|
-
* Those are two different facts, and
|
|
7
|
+
* Those are two different facts, and 9 of the 42 byok-capable native providers
|
|
8
8
|
* have the first without the second:
|
|
9
9
|
*
|
|
10
|
-
* apify builtwith dropleads lusha openwebninja
|
|
10
|
+
* apify builtwith dropleads lusha openwebninja peopledatalabs
|
|
11
11
|
* rocketreach theirstack wiza
|
|
12
12
|
*
|
|
13
13
|
* For those, `oxygen integrations connect <id> --api-key` does not reach
|
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
* tool is native generic-REST and `shouldRouteStaticToolThroughComposio` is false, so
|
|
18
18
|
* `resolveOptionalApiKeyCredentials` finds nothing and the call falls back to the
|
|
19
19
|
* MANAGED key — the very key that was out of credits. The command appears to work,
|
|
20
|
-
* changes nothing, and the customer is back where they started with no error.
|
|
20
|
+
* changes nothing, and the customer is back where they started with no error. The
|
|
21
|
+
* connect route now refuses each of those nine with a typed `byok_connect_unavailable`
|
|
22
|
+
* rather than a silent Composio "success"; they stay OFF this list until one gains a
|
|
23
|
+
* real native connect form.
|
|
21
24
|
*
|
|
22
|
-
* That is precisely the failure Plain T-104
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
+
* That is precisely the failure Plain T-104 hit: `parallel.search` was one of the
|
|
26
|
+
* refused tools, and a refusal message that told Mentcape to connect their own Parallel
|
|
27
|
+
* key would once have sent them down a path that silently does nothing. Parallel now has
|
|
28
|
+
* a native api-key connect (catalog.ts) and IS on this list, so that message is finally
|
|
29
|
+
* true for it — the nine above are the ones it must still never name.
|
|
25
30
|
*
|
|
26
31
|
* So a message may only offer BYOK when BOTH halves hold, and this list is the second
|
|
27
32
|
* half. It lives in @oxygen/shared because the two sides that need it cannot see each
|
|
@@ -64,6 +69,9 @@ export const NATIVE_API_KEY_CONNECT_INTEGRATION_IDS = new Set([
|
|
|
64
69
|
// rest — so the native runner does find the key.
|
|
65
70
|
"moltsets",
|
|
66
71
|
"ocean",
|
|
72
|
+
// Native api-key connect added in catalog.ts (2026-09-10): connect writes an
|
|
73
|
+
// integration_secrets api_key row the native parallel.* runner reads. T-104.
|
|
74
|
+
"parallel",
|
|
67
75
|
"predictleads",
|
|
68
76
|
"prospeo",
|
|
69
77
|
"scalelist",
|