@oxygen-agent/cli 1.1011.326 → 1.1011.405
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 +7 -0
- package/dist/connectors-commands.d.ts +4 -1
- package/dist/connectors-commands.js +81 -10
- package/dist/contract-flags.d.ts +2 -0
- package/dist/contract-flags.js +4 -2
- package/dist/crm-support-flags.d.ts +11 -0
- package/dist/crm-support-flags.js +60 -0
- package/dist/help.js +10 -0
- package/dist/index.js +175 -65
- package/dist/settings-commands.d.ts +11 -0
- package/dist/settings-commands.js +72 -0
- package/node_modules/@oxygen/shared/dist/bounded-read-result.d.ts +4 -0
- package/node_modules/@oxygen/shared/dist/bounded-read-result.js +25 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +30 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +277 -16
- package/node_modules/@oxygen/shared/dist/contracts/connectors.d.ts +32 -6
- package/node_modules/@oxygen/shared/dist/contracts/connectors.js +56 -4
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +117 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +43 -0
- package/node_modules/@oxygen/shared/dist/contracts/dashboard-tabs.d.ts +3 -0
- package/node_modules/@oxygen/shared/dist/contracts/dashboard-tabs.js +2 -0
- package/node_modules/@oxygen/shared/dist/contracts/integration-connect.d.ts +4 -0
- package/node_modules/@oxygen/shared/dist/contracts/integration-connect.js +7 -0
- package/node_modules/@oxygen/shared/dist/contracts/operations.js +8 -2
- package/node_modules/@oxygen/shared/dist/contracts/workspace-pages.d.ts +16 -0
- package/node_modules/@oxygen/shared/dist/contracts/workspace-pages.js +37 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger-parser.d.ts +32 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger-parser.js +303 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger.generated.d.ts +2 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger.generated.js +717 -0
- package/node_modules/@oxygen/shared/dist/decision-ledger.js +20 -0
- package/node_modules/@oxygen/shared/dist/mcp-event-contract.d.ts +10 -7
- package/node_modules/@oxygen/shared/dist/mcp-event-contract.js +11 -7
- package/node_modules/@oxygen/shared/dist/mcp-table-widget.d.ts +50 -0
- package/node_modules/@oxygen/shared/dist/mcp-table-widget.js +24 -0
- package/node_modules/@oxygen/shared/dist/plan-band.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/plan-band.js +12 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +21 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.js +41 -0
- package/node_modules/@oxygen/shared/dist/sequences.d.ts +33 -4
- package/node_modules/@oxygen/shared/dist/sequences.js +48 -13
- package/node_modules/@oxygen/shared/dist/user-capability-routing.js +17 -0
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/node_modules/@oxygen/shared/package.json +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/command-manifest.js
CHANGED
|
@@ -173,6 +173,13 @@ const READ_ONLY_COMMANDS = new Set([
|
|
|
173
173
|
// invocation still previews, so machine-readable discovery must not imply that
|
|
174
174
|
// calling the command without its confirmation flag writes anything.
|
|
175
175
|
const PREVIEW_BY_DEFAULT_COMMANDS = new Set([
|
|
176
|
+
// /api/cli/find/run treats an omitted mode as dry_run for every Find capability.
|
|
177
|
+
"find email",
|
|
178
|
+
"find personal-email",
|
|
179
|
+
"find phone",
|
|
180
|
+
"find linkedin",
|
|
181
|
+
"find person",
|
|
182
|
+
"find company",
|
|
176
183
|
"inbox delete-message",
|
|
177
184
|
"inbox forget-whatsapp-chat",
|
|
178
185
|
"tables watcher preview",
|
|
@@ -5,7 +5,10 @@ type JsonOptions = {
|
|
|
5
5
|
};
|
|
6
6
|
type Handle = (command: string, options: JsonOptions, action: () => Promise<unknown>) => Promise<void>;
|
|
7
7
|
export declare const CONNECTORS_FLAG_OVERLAY: ContractFlagOverlay;
|
|
8
|
-
|
|
8
|
+
export declare const CONNECTOR_EVENTS_REVOKE_FLAG_OVERLAY: ContractFlagOverlay;
|
|
9
|
+
/** The revoke body for the flags given; --subscription is required. */
|
|
10
|
+
export declare function buildConnectorEventsRevokeBody(options: Record<string, unknown>): Record<string, unknown>;
|
|
11
|
+
/** The PATCH body for the flags given; a workspace or a credit ceiling flag is required. */
|
|
9
12
|
export declare function buildConnectorUpdateBody(options: Record<string, unknown>): Record<string, unknown>;
|
|
10
13
|
export declare function registerConnectorsCommands(program: Command, handle: Handle): void;
|
|
11
14
|
export {};
|
|
@@ -5,45 +5,114 @@
|
|
|
5
5
|
// disagree about what can be set.
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { OxygenError } from "@oxygen/shared/cli-result";
|
|
8
|
-
import { CONNECTOR_UPDATE_OPERATION } from "@oxygen/shared/contracts/connectors";
|
|
8
|
+
import { CONNECTOR_EVENTS_REVOKE_OPERATION, CONNECTOR_UPDATE_OPERATION } from "@oxygen/shared/contracts/connectors";
|
|
9
9
|
import { operationPath } from "@oxygen/shared/contracts/operations";
|
|
10
10
|
import { addContractFlags, readContractFlags } from "./contract-flags.js";
|
|
11
11
|
import { requestOxygen } from "./http-client.js";
|
|
12
12
|
const update = CONNECTOR_UPDATE_OPERATION;
|
|
13
|
+
const revokeEvents = CONNECTOR_EVENTS_REVOKE_OPERATION;
|
|
13
14
|
export const CONNECTORS_FLAG_OVERLAY = {
|
|
14
15
|
default_workspace: {
|
|
15
16
|
help: "The workspace this app should work in without asking: its id, slug or exact name from `orgs list`. You must be a member.",
|
|
16
17
|
valueName: "<workspace>",
|
|
17
18
|
},
|
|
19
|
+
credit_ceiling: {
|
|
20
|
+
help: "The most credits this app may spend in any 24 hours while it holds OXYGEN event subscriptions (0 = no paid calls then). --clear-credit-ceiling restores the plan default.",
|
|
21
|
+
valueName: "<credits>",
|
|
22
|
+
},
|
|
23
|
+
approve_above_default: {
|
|
24
|
+
help: "Approve a --credit-ceiling above your plan's default.",
|
|
25
|
+
negateHelp: "Do not approve a ceiling above the default (the default behaviour).",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export const CONNECTOR_EVENTS_REVOKE_FLAG_OVERLAY = {
|
|
29
|
+
subscription: {
|
|
30
|
+
help: "The subscription id from `connectors events get <app>`, or `all` for every live one.",
|
|
31
|
+
valueName: "<id|all>",
|
|
32
|
+
},
|
|
33
|
+
workspace: {
|
|
34
|
+
help: "Only this workspace's subscriptions (id, slug or exact name). Omit for all your workspaces.",
|
|
35
|
+
valueName: "<workspace>",
|
|
36
|
+
},
|
|
18
37
|
};
|
|
19
|
-
/** The
|
|
38
|
+
/** The revoke body for the flags given; --subscription is required. */
|
|
39
|
+
export function buildConnectorEventsRevokeBody(options) {
|
|
40
|
+
const body = readContractFlags(options, revokeEvents.contract, CONNECTOR_EVENTS_REVOKE_FLAG_OVERLAY);
|
|
41
|
+
if (typeof body.subscription !== "string") {
|
|
42
|
+
throw new OxygenError("invalid_request", "Pass --subscription <id> (from `connectors events get <app>`), or --subscription all to revoke every live one.", { exitCode: 1 });
|
|
43
|
+
}
|
|
44
|
+
return body;
|
|
45
|
+
}
|
|
46
|
+
/** The PATCH body for the flags given; a workspace or a credit ceiling flag is required. */
|
|
20
47
|
export function buildConnectorUpdateBody(options) {
|
|
21
48
|
const body = readContractFlags(options, update.contract, CONNECTORS_FLAG_OVERLAY);
|
|
22
|
-
if (!("default_workspace" in body)) {
|
|
23
|
-
throw new OxygenError("invalid_request", "Pass --default-workspace <workspace> to set where the app works, or --clear-
|
|
49
|
+
if (!("default_workspace" in body) && !("credit_ceiling" in body)) {
|
|
50
|
+
throw new OxygenError("invalid_request", "Pass --default-workspace <workspace> (or --clear-default-workspace) to set where the app works, or --credit-ceiling <credits> (or --clear-credit-ceiling) to set what it may spend in 24 hours.", { exitCode: 1 });
|
|
24
51
|
}
|
|
25
52
|
return body;
|
|
26
53
|
}
|
|
27
54
|
export function registerConnectorsCommands(program, handle) {
|
|
28
55
|
const connectors = program
|
|
29
56
|
.command("connectors")
|
|
30
|
-
.description("Connected apps
|
|
31
|
-
+ "`connectors list` shows them; `connectors
|
|
32
|
-
+ "
|
|
33
|
-
+ "
|
|
57
|
+
.description("Connected apps (ChatGPT, Claude, Codex… connected to OXYGEN with OAuth): the workspace each one works in, the OXYGEN events it is subscribed to, and what it may spend. "
|
|
58
|
+
+ "`connectors list` shows them; `connectors events get <app>` shows an app's event subscriptions and what OXYGEN sent it, and `connectors events revoke` stops them. "
|
|
59
|
+
+ "`connectors set <app>` changes one app only: --default-workspace (picking a workspace inside the app changes the same setting; latest wins; this CLI keeps its own, `orgs use`) "
|
|
60
|
+
+ "and --credit-ceiling (while it holds event subscriptions, its paid calls stay under this many credits in any 24 hours; the plan default otherwise). "
|
|
61
|
+
+ "Web: the Connected apps page, /settings/connected-apps; every response carries its `web_url`.");
|
|
34
62
|
connectors.addCommand(new Command("list")
|
|
35
|
-
.description("List your connected apps with each one's default workspace, when it was last used, and the workspaces you can choose from. Read-only, 0 credits.")
|
|
63
|
+
.description("List your connected apps with each one's default workspace, its live event subscriptions, its daily credit ceiling and what it spent in the last 24 hours, when it was last used, and the workspaces you can choose from. Read-only, 0 credits.")
|
|
36
64
|
.option("--json", "Print a JSON envelope.")
|
|
37
65
|
.action(async (options) => {
|
|
38
66
|
await handle("connectors list", options, () => requestOxygen("/api/cli/connectors"));
|
|
39
67
|
}));
|
|
40
68
|
connectors.addCommand(new Command("get")
|
|
41
|
-
.description("Show one connected app
|
|
69
|
+
.description("Show one connected app: its default workspace, its daily credit ceiling and what it spent in the last 24 hours in each workspace where it spends, and how many event subscriptions it holds. Read-only, 0 credits.")
|
|
42
70
|
.argument("<connection>", update.cli.argument?.description ?? "The app's id or name.")
|
|
43
71
|
.option("--json", "Print a JSON envelope.")
|
|
44
72
|
.action(async (connection, options) => {
|
|
45
73
|
await handle("connectors get", options, () => requestOxygen(`/api/cli/connectors/${encodeURIComponent(connection)}`));
|
|
46
74
|
}));
|
|
75
|
+
const events = new Command("events")
|
|
76
|
+
.description("The events OXYGEN sends one connected app: what it subscribed to (a reply was classified, a run settled, an approval is waiting…), "
|
|
77
|
+
+ "each subscription's filters, status and expiry, and what OXYGEN delivered to it and how each delivery went (never the content). "
|
|
78
|
+
+ "`get` reads them; `revoke` stops them. Only apps connected with OAuth, such as ChatGPT, subscribe.");
|
|
79
|
+
events.addCommand(new Command("get")
|
|
80
|
+
.description("Show one connected app's event subscriptions (filters, status, granted, renew-by and expiry, workspace) and its recent deliveries (status, attempts, failure category, times; never content). Ended subscriptions stay listed for 7 days; `active_subscriptions` counts the live ones. Read-only, 0 credits.")
|
|
81
|
+
.argument("<connection>", update.cli.argument?.description ?? "The app's id or name.")
|
|
82
|
+
.option("--workspace <workspace>", "Only this workspace (id, slug or exact name). Omit for all your workspaces.")
|
|
83
|
+
.option("--deliveries <n>", "Recent deliveries to show per subscription (0-50, default 10).")
|
|
84
|
+
.option("--json", "Print a JSON envelope.")
|
|
85
|
+
.addHelpText("after", `
|
|
86
|
+
Examples:
|
|
87
|
+
oxygen connectors events get ChatGPT
|
|
88
|
+
oxygen connectors events get ChatGPT --workspace "Acme GTM" --deliveries 20
|
|
89
|
+
`)
|
|
90
|
+
.action(async (connection, options) => {
|
|
91
|
+
const query = new URLSearchParams();
|
|
92
|
+
if (options.workspace?.trim())
|
|
93
|
+
query.set("workspace", options.workspace.trim());
|
|
94
|
+
if (options.deliveries?.trim())
|
|
95
|
+
query.set("deliveries", options.deliveries.trim());
|
|
96
|
+
const queryString = query.toString();
|
|
97
|
+
const suffix = queryString ? `?${queryString}` : "";
|
|
98
|
+
await handle("connectors events get", options, () => requestOxygen(`/api/cli/connectors/${encodeURIComponent(connection)}/events${suffix}`));
|
|
99
|
+
}));
|
|
100
|
+
events.addCommand(addContractFlags(new Command(revokeEvents.cli.path.at(-1) ?? "revoke")
|
|
101
|
+
.description(revokeEvents.cli.summary)
|
|
102
|
+
.argument(`<${revokeEvents.cli.argument?.name ?? "connection"}>`, revokeEvents.cli.argument?.description), revokeEvents.contract, CONNECTOR_EVENTS_REVOKE_FLAG_OVERLAY)
|
|
103
|
+
.option("--json", "Print a JSON envelope.")
|
|
104
|
+
.addHelpText("after", `
|
|
105
|
+
Examples:
|
|
106
|
+
oxygen connectors events revoke ChatGPT --subscription all
|
|
107
|
+
oxygen connectors events revoke ChatGPT --subscription <id> --workspace "Acme GTM"
|
|
108
|
+
`)
|
|
109
|
+
.action(async (connection, options) => {
|
|
110
|
+
await handle("connectors events revoke", options, () => requestOxygen(operationPath(revokeEvents, { connection }), {
|
|
111
|
+
method: revokeEvents.method,
|
|
112
|
+
body: buildConnectorEventsRevokeBody(options),
|
|
113
|
+
}));
|
|
114
|
+
}));
|
|
115
|
+
connectors.addCommand(events);
|
|
47
116
|
connectors.addCommand(addContractFlags(new Command(update.cli.path.at(-1) ?? "set")
|
|
48
117
|
.description(update.cli.summary)
|
|
49
118
|
.argument(`<${update.cli.argument?.name ?? "connection"}>`, update.cli.argument?.description), update.contract, CONNECTORS_FLAG_OVERLAY)
|
|
@@ -53,6 +122,8 @@ Examples:
|
|
|
53
122
|
oxygen connectors list
|
|
54
123
|
oxygen connectors set ChatGPT --default-workspace "Acme GTM"
|
|
55
124
|
oxygen connectors set <id> --clear-default-workspace
|
|
125
|
+
oxygen connectors set ChatGPT --credit-ceiling 300
|
|
126
|
+
oxygen connectors set ChatGPT --credit-ceiling 50000 --approve-above-default
|
|
56
127
|
`)
|
|
57
128
|
.action(async (connection, options) => {
|
|
58
129
|
await handle("connectors set", options, () => requestOxygen(operationPath(update, { connection }), {
|
package/dist/contract-flags.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type ContractFlagOverlayEntry = {
|
|
|
10
10
|
aliases?: readonly string[];
|
|
11
11
|
/** Boolean: help for the `--no-<flag>` form. */
|
|
12
12
|
negateHelp?: string;
|
|
13
|
+
/** Boolean: do not generate the `--no-<flag>` form, for a field whose `false` changes nothing. */
|
|
14
|
+
noNegate?: boolean;
|
|
13
15
|
/**
|
|
14
16
|
* Boolean as two flags, e.g. `--warmup-restart` (true) / `--warmup-disable`
|
|
15
17
|
* (false). When both are given, `off` wins.
|
package/dist/contract-flags.js
CHANGED
|
@@ -84,7 +84,9 @@ export function addContractFlags(command, contract, overlay = {}) {
|
|
|
84
84
|
}
|
|
85
85
|
if (spec.kind === "boolean") {
|
|
86
86
|
command.addOption(new Option(`--${spec.flag}`, helpFor(spec, property)));
|
|
87
|
-
|
|
87
|
+
if (!spec.entry.noNegate) {
|
|
88
|
+
command.addOption(new Option(`--no-${spec.flag}`, spec.entry.negateHelp ?? `Sends ${spec.path.join(".")}: false.`));
|
|
89
|
+
}
|
|
88
90
|
continue;
|
|
89
91
|
}
|
|
90
92
|
const valueName = spec.entry.valueName ?? (spec.kind === "json" ? "<json>" : "<value>");
|
|
@@ -210,7 +212,7 @@ export function contractFlagNames(contract, overlay = {}) {
|
|
|
210
212
|
case "pair":
|
|
211
213
|
return [`--${spec.on}`, `--${spec.off}`];
|
|
212
214
|
case "boolean":
|
|
213
|
-
return [`--${spec.flag}`, `--no-${spec.flag}`];
|
|
215
|
+
return spec.entry.noNegate ? [`--${spec.flag}`] : [`--${spec.flag}`, `--no-${spec.flag}`];
|
|
214
216
|
case "clear":
|
|
215
217
|
return [`--${spec.flag}`];
|
|
216
218
|
default:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/** Existing command names, positional arguments, formatters and actions stay owned by index.ts. */
|
|
3
|
+
export declare function registerCrmSupportFlags(program: Command): void;
|
|
4
|
+
export declare function readCrmNoteEditFields(options: object): Record<string, unknown>;
|
|
5
|
+
export declare function readCrmPhotoFields(options: {
|
|
6
|
+
live?: boolean;
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
}): Record<string, unknown>;
|
|
9
|
+
export declare function readCrmFileLabel(options: object): Record<string, unknown>;
|
|
10
|
+
export declare function buildCrmObjectsPath(options: object): string;
|
|
11
|
+
export declare function buildCrmConnectionsPath(object: string, rowId: string, options: object): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { OxygenError } from "@oxygen/shared/cli-result";
|
|
2
|
+
import { CRM_CONNECTIONS_QUERY_CONTRACT, CRM_NOTE_EDIT_CONTRACT, CRM_OBJECTS_QUERY_CONTRACT, CRM_PHOTOS_CONTRACT, CRM_FILE_COMPLETE_CONTRACT } from "@oxygen/shared/contracts/crm-support";
|
|
3
|
+
import { validateContract } from "@oxygen/shared/contracts/schema";
|
|
4
|
+
import { addContractFlags, readContractFlags } from "./contract-flags.js";
|
|
5
|
+
import { assertModeFlagsExclusive } from "./cli-values.js";
|
|
6
|
+
const NOTE_OVERLAY = { pinned: { pair: { on: "pin", onHelp: "Pin the note.", off: "unpin", offHelp: "Unpin the note." } } };
|
|
7
|
+
function child(parent, name) { return parent?.commands.find((command) => command.name() === name); }
|
|
8
|
+
function replaceFlags(command, attributes, contract, overlay) {
|
|
9
|
+
if (!command)
|
|
10
|
+
throw new Error("Register CRM commands before their shared flags.");
|
|
11
|
+
const retained = command.options.filter((option) => !attributes.includes(option.attributeName()));
|
|
12
|
+
// Commander exposes this mutable runtime collection as readonly in its types.
|
|
13
|
+
// Replace only the flags this leaf owns before parsing the existing commands.
|
|
14
|
+
const options = command.options;
|
|
15
|
+
options.splice(0, options.length, ...retained);
|
|
16
|
+
addContractFlags(command, contract, overlay);
|
|
17
|
+
}
|
|
18
|
+
/** Existing command names, positional arguments, formatters and actions stay owned by index.ts. */
|
|
19
|
+
export function registerCrmSupportFlags(program) {
|
|
20
|
+
const crm = child(program, "crm");
|
|
21
|
+
replaceFlags(child(crm, "objects"), [], CRM_OBJECTS_QUERY_CONTRACT);
|
|
22
|
+
replaceFlags(child(crm, "connections"), ["conversationLimit", "sequenceLimit"], CRM_CONNECTIONS_QUERY_CONTRACT);
|
|
23
|
+
replaceFlags(child(child(crm, "notes"), "update"), ["body", "title", "pin", "unpin"], CRM_NOTE_EDIT_CONTRACT, NOTE_OVERLAY);
|
|
24
|
+
replaceFlags(child(crm, "photos"), ["limit", "live"], CRM_PHOTOS_CONTRACT);
|
|
25
|
+
replaceFlags(child(child(crm, "files"), "attach"), ["label"], CRM_FILE_COMPLETE_CONTRACT);
|
|
26
|
+
}
|
|
27
|
+
function checkedFlags(options, contract, overlay) {
|
|
28
|
+
const value = readContractFlags(options, contract, overlay);
|
|
29
|
+
const checked = validateContract(contract, value, { unknown: "reject", overMax: "reject" });
|
|
30
|
+
if (!checked.ok)
|
|
31
|
+
throw new OxygenError("invalid_request", "Invalid CRM command fields.", { exitCode: 1, details: { fields: checked.issues.map((issue) => issue.path) } });
|
|
32
|
+
return checked.value;
|
|
33
|
+
}
|
|
34
|
+
export function readCrmNoteEditFields(options) {
|
|
35
|
+
const value = checkedFlags(options, CRM_NOTE_EDIT_CONTRACT, NOTE_OVERLAY);
|
|
36
|
+
// Preserve the existing --title "" spelling in addition to --clear-title.
|
|
37
|
+
if (options.title === "")
|
|
38
|
+
value.title = null;
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
export function readCrmPhotoFields(options) {
|
|
42
|
+
assertModeFlagsExclusive(options);
|
|
43
|
+
const value = checkedFlags(options, CRM_PHOTOS_CONTRACT);
|
|
44
|
+
if (options.dryRun)
|
|
45
|
+
value.mode = "dry_run";
|
|
46
|
+
if (value.mode === "dry_run" && value.live === true)
|
|
47
|
+
throw new OxygenError("invalid_request", "Pass either dry_run or live.", { exitCode: 1 });
|
|
48
|
+
if (value.mode === undefined && value.live !== true)
|
|
49
|
+
value.mode = "dry_run";
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
export function readCrmFileLabel(options) { return checkedFlags(options, CRM_FILE_COMPLETE_CONTRACT); }
|
|
53
|
+
function queryPath(path, query) {
|
|
54
|
+
const params = new URLSearchParams(Object.entries(query).map(([key, value]) => [key, String(value)]));
|
|
55
|
+
return params.size ? `${path}?${params}` : path;
|
|
56
|
+
}
|
|
57
|
+
export function buildCrmObjectsPath(options) { return queryPath("/api/cli/crm/objects", checkedFlags(options, CRM_OBJECTS_QUERY_CONTRACT)); }
|
|
58
|
+
export function buildCrmConnectionsPath(object, rowId, options) {
|
|
59
|
+
return queryPath(`/api/cli/crm/objects/${encodeURIComponent(object)}/records/${encodeURIComponent(rowId)}/connections`, checkedFlags(options, CRM_CONNECTIONS_QUERY_CONTRACT));
|
|
60
|
+
}
|
package/dist/help.js
CHANGED
|
@@ -20,6 +20,12 @@ const HELP_GROUPS = [
|
|
|
20
20
|
"status",
|
|
21
21
|
"home",
|
|
22
22
|
"orgs",
|
|
23
|
+
// Where each connected app (ChatGPT, Claude…) works by default: read
|
|
24
|
+
// beside `orgs`, where a founder asking "which workspace" looks first.
|
|
25
|
+
"connectors",
|
|
26
|
+
// Workspace settings (the sidebar pages everyone sees): the 2026-09-30
|
|
27
|
+
// blind baseline typed `oxygen settings --help` before anything else.
|
|
28
|
+
"settings",
|
|
23
29
|
"commands",
|
|
24
30
|
"skills",
|
|
25
31
|
"session",
|
|
@@ -205,6 +211,10 @@ const COMMAND_SYNONYMS = {
|
|
|
205
211
|
exec: ["run", "start", "call"],
|
|
206
212
|
execute: ["run", "start", "call"],
|
|
207
213
|
find: ["search", "query", "list"],
|
|
214
|
+
// The product's own copy calls a Sequence a campaign; a blind agent's first
|
|
215
|
+
// guess was `oxygen campaigns` (Plain T-220 baseline, 2026-09-30).
|
|
216
|
+
campaign: ["sequences"],
|
|
217
|
+
campaigns: ["sequences"],
|
|
208
218
|
};
|
|
209
219
|
/**
|
|
210
220
|
* The extra line printed after `error: unknown command '<x>'`.
|