@pixelml/agenticflow-cli 0.1.0 → 1.0.0

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 CHANGED
@@ -1,71 +1,273 @@
1
1
  # AgenticFlow CLI
2
2
 
3
- Agent-native CLI for AgenticFlow public APIs.
3
+ A command-line interface for the [AgenticFlow](https://agenticflow.ai) platform.
4
+ Manage agents, workflows, connections, and more — directly from your terminal.
4
5
 
5
- ## Features
6
+ Built on the `@pixelml/agenticflow-sdk`.
6
7
 
7
- - OpenAPI-backed operation discovery and invocation.
8
- - High-level commands for workflows, agents, node types, and connections.
9
- - API-key-based auth profiles (`AGENTICFLOW_PUBLIC_API_KEY`).
10
- - Preflight checks (`doctor`) and capability catalog (`catalog`).
11
- - Local guardrails (`policy`) and audit log support.
12
- - Built-in CLI playbooks (no MCP required).
8
+ ## Installation
13
9
 
14
- ## Install (Python)
10
+ ```bash
11
+ npm install -g @pixelml/agenticflow-cli
12
+ ```
13
+
14
+ Or run directly via `npx`:
15
+
16
+ ```bash
17
+ npx @pixelml/agenticflow-cli --help
18
+ ```
19
+
20
+ ## Authentication
21
+
22
+ ### Option 1: Environment variables
15
23
 
16
24
  ```bash
17
- pip install agenticflow-cli
25
+ export AGENTICFLOW_API_KEY="sk-..."
26
+ export AGENTICFLOW_WORKSPACE_ID="ws-..."
27
+ export AGENTICFLOW_PROJECT_ID="proj-..."
18
28
  ```
19
29
 
20
- Then run:
30
+ ### Option 2: Import from `.env` file
21
31
 
22
32
  ```bash
23
- agenticflow --help
33
+ agenticflow auth import-env --file .env
24
34
  ```
25
35
 
26
- ## Install (from source)
36
+ This writes credentials to `~/.agenticflow/auth.json` and they are used
37
+ automatically for all commands.
38
+
39
+ ### Option 3: CLI flags
27
40
 
28
41
  ```bash
29
- python -m pip install -e .
30
- agenticflow --help
42
+ agenticflow --api-key sk-... --workspace-id ws-... agent list
31
43
  ```
32
44
 
33
- ## Auth
45
+ **Priority order**: CLI flag → environment variable → `~/.agenticflow/auth.json`
34
46
 
35
- Use API key only:
47
+ ### Verify credentials
36
48
 
37
49
  ```bash
38
- export AGENTICFLOW_PUBLIC_API_KEY=...
39
- agenticflow doctor --json
50
+ agenticflow auth whoami
51
+ ```
52
+
53
+ ```
54
+ Profile: default
55
+ API Key: present
56
+ Workspace ID: ws-abc123
57
+ Project ID: proj-xyz789
58
+ Config: ~/.agenticflow/auth.json
40
59
  ```
41
60
 
42
- Or import from env file:
61
+ ## Usage
62
+
63
+ ### Agents
43
64
 
44
65
  ```bash
45
- agenticflow auth import-env --file ./.env --profile default
46
- agenticflow auth whoami --json
66
+ # List agents
67
+ agenticflow agent list
68
+
69
+ # Get agent details
70
+ agenticflow agent get <agent-id>
71
+
72
+ # Create an agent
73
+ agenticflow agent create --body '{"name": "My Agent"}'
74
+
75
+ # Update an agent
76
+ agenticflow agent update <agent-id> --body '{"name": "Updated"}'
77
+
78
+ # Delete an agent
79
+ agenticflow agent delete <agent-id>
80
+
81
+ # Stream a message to an agent
82
+ agenticflow agent stream <agent-id> --body '{"input": "Hello"}'
83
+
84
+ # Publishing
85
+ agenticflow agent publish-info <agent-id>
86
+ agenticflow agent publish <agent-id> --body '{"platform": "web"}'
87
+ agenticflow agent unpublish <agent-id> --body '{"platform": "web"}'
88
+
89
+ # Reference impact
90
+ agenticflow agent reference-impact <agent-id>
91
+
92
+ # Save as template
93
+ agenticflow agent save-as-template <agent-id> --body '{...}'
47
94
  ```
48
95
 
49
- `--token` bearer override is intentionally unsupported.
96
+ ### Workflows
97
+
98
+ ```bash
99
+ # List workflows
100
+ agenticflow workflow list
101
+
102
+ # Get workflow details
103
+ agenticflow workflow get <workflow-id>
104
+
105
+ # Create / update / delete
106
+ agenticflow workflow create --body '{...}'
107
+ agenticflow workflow update <workflow-id> --body '{...}'
108
+ agenticflow workflow delete <workflow-id>
109
+
110
+ # Run a workflow
111
+ agenticflow workflow run --body '{"workflow_id": "wf-123", "input": {}}'
112
+
113
+ # Check run status
114
+ agenticflow workflow run-status <run-id>
115
+
116
+ # List runs for a workflow
117
+ agenticflow workflow list-runs <workflow-id>
118
+
119
+ # Run history
120
+ agenticflow workflow run-history <workflow-id>
121
+
122
+ # Validate a workflow definition
123
+ agenticflow workflow validate --body '{...}'
50
124
 
51
- ## Node Wrapper (npm)
125
+ # Like / unlike
126
+ agenticflow workflow like <workflow-id>
127
+ agenticflow workflow unlike <workflow-id>
128
+ agenticflow workflow like-status <workflow-id>
129
+ ```
52
130
 
53
- This repo also ships a thin npm wrapper package (`@pixelml/agenticflow-cli`) that invokes the Python CLI.
131
+ ### Connections
54
132
 
55
133
  ```bash
56
- npm i -g @pixelml/agenticflow-cli
57
- agenticflow --help
134
+ # List connections
135
+ agenticflow connections list
136
+
137
+ # Create a connection
138
+ agenticflow connections create --body '{...}'
139
+
140
+ # Get default connection for a category
141
+ agenticflow connections get-default --category <name>
142
+
143
+ # Update / delete
144
+ agenticflow connections update <connection-id> --body '{...}'
145
+ agenticflow connections delete <connection-id>
146
+
147
+ # List connection categories
148
+ agenticflow connections categories
149
+
150
+ # Health checks
151
+ agenticflow connections health-check-pre --body '{...}'
152
+ agenticflow connections health-check-post <connection-id>
58
153
  ```
59
154
 
60
- The wrapper requires Python 3.10+ with `agenticflow-cli` installed or importable.
155
+ ### Node Types
156
+
157
+ ```bash
158
+ # List all node types
159
+ agenticflow node-types list
61
160
 
62
- ## Release Tags
161
+ # Get a specific node type
162
+ agenticflow node-types get <name>
63
163
 
64
- - Python release: `py-vX.Y.Z`
65
- - npm wrapper release: `npm-vX.Y.Z`
164
+ # Search node types
165
+ agenticflow node-types search <query>
166
+
167
+ # Get dynamic options
168
+ agenticflow node-types dynamic-options --name <name> --field-name <field>
169
+ ```
170
+
171
+ ### Uploads
172
+
173
+ ```bash
174
+ # Create an upload session
175
+ agenticflow uploads create --body '{...}'
176
+
177
+ # Check upload session status
178
+ agenticflow uploads status <session-id>
179
+ ```
180
+
181
+ ### Generic API Calls
182
+
183
+ For any API endpoint not covered by resource commands:
184
+
185
+ ```bash
186
+ # By operation ID
187
+ agenticflow call --operation-id getAgentModel
188
+
189
+ # By method + path
190
+ agenticflow call --method GET --path /v1/agents/
191
+
192
+ # With parameters
193
+ agenticflow call --operation-id updateAgent \
194
+ -P agent_id=abc123 \
195
+ --body '{"name": "Updated"}'
196
+
197
+ # With query parameters
198
+ agenticflow call --method GET --path /v1/agents/ \
199
+ -Q limit=10 -Q offset=0
200
+
201
+ # Dry run (show request without executing)
202
+ agenticflow call --operation-id listAgents --dry-run
203
+ ```
204
+
205
+ ### Operations Discovery
206
+
207
+ ```bash
208
+ # List all available operations
209
+ agenticflow ops list
210
+
211
+ # Show details of an operation
212
+ agenticflow ops show <operation-id>
213
+ ```
214
+
215
+ ### Preflight Check
216
+
217
+ ```bash
218
+ agenticflow doctor
219
+ ```
220
+
221
+ Runs connectivity checks, validates API key, and verifies the OpenAPI spec.
222
+
223
+ ### Other Commands
224
+
225
+ ```bash
226
+ # Catalog management
227
+ agenticflow catalog export
228
+ agenticflow catalog rank
229
+
230
+ # Policy management
231
+ agenticflow policy show
232
+ agenticflow policy init
233
+
234
+ # Playbook management
235
+ agenticflow playbook list
236
+ agenticflow playbook export
237
+ ```
238
+
239
+ ## Global Options
240
+
241
+ | Flag | Description |
242
+ |---|---|
243
+ | `--api-key <key>` | API key for authentication |
244
+ | `--workspace-id <id>` | Default workspace ID |
245
+ | `--project-id <id>` | Default project ID |
246
+ | `--spec-file <path>` | Path to OpenAPI spec JSON file |
247
+ | `--json` | Force JSON output |
248
+ | `--version` | Show version |
249
+ | `--help` | Show help |
250
+
251
+ ## Output
252
+
253
+ All commands output JSON by default:
254
+
255
+ ```json
256
+ {
257
+ "status": 200,
258
+ "body": { ... }
259
+ }
260
+ ```
261
+
262
+ Error responses set a non-zero exit code:
263
+
264
+ ```json
265
+ {
266
+ "status": 404,
267
+ "body": { "detail": "Not found" }
268
+ }
269
+ ```
66
270
 
67
- ## OSS Hygiene
271
+ ## License
68
272
 
69
- - No hardcoded secrets in CLI code path.
70
- - `.env*` and `.agenticflow/` are ignored.
71
- - Users provide their own `AGENTICFLOW_PUBLIC_API_KEY`.
273
+ Apache-2.0
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AgenticFlow CLI entry point.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=agenticflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agenticflow.d.ts","sourceRoot":"","sources":["../../src/bin/agenticflow.ts"],"names":[],"mappings":";AAEA;;GAEG"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AgenticFlow CLI entry point.
4
+ */
5
+ import { runCli } from "../cli/main.js";
6
+ runCli().catch((err) => {
7
+ console.error(err instanceof Error ? err.message : err);
8
+ process.exit(1);
9
+ });
10
+ //# sourceMappingURL=agenticflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agenticflow.js","sourceRoot":"","sources":["../../src/bin/agenticflow.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * HTTP request builder helpers for AgenticFlow CLI commands.
3
+ */
4
+ import type { Operation } from "./spec.js";
5
+ export interface RequestSpec {
6
+ method: string;
7
+ url: string;
8
+ params: Record<string, string>;
9
+ headers: Record<string, string>;
10
+ body?: unknown;
11
+ json?: unknown;
12
+ }
13
+ export declare function parseKeyValuePairs(rawValues: string[]): Record<string, string>;
14
+ export declare function loadJsonPayload(raw: string): unknown;
15
+ export declare function resolveApiKey(explicitKey?: string | null): string | null;
16
+ export declare function buildRequestSpec(operation: Operation, baseUrl: string, pathParams: Record<string, string>, queryParams: Record<string, string>, extraHeaders: Record<string, string>, token?: string | null, body?: unknown): RequestSpec;
17
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa9E;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBpD;AAED,wBAAgB,aAAa,CAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAC1B,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,CAAC,EAAE,OAAO,GACb,WAAW,CA4Bb"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * HTTP request builder helpers for AgenticFlow CLI commands.
3
+ */
4
+ import { readFileSync } from "node:fs";
5
+ export function parseKeyValuePairs(rawValues) {
6
+ const parsed = {};
7
+ for (const raw of rawValues) {
8
+ if (!raw.includes("=")) {
9
+ throw new Error(`Invalid key-value pair: ${raw}`);
10
+ }
11
+ const idx = raw.indexOf("=");
12
+ const key = raw.slice(0, idx);
13
+ const value = raw.slice(idx + 1);
14
+ if (!key)
15
+ throw new Error(`Invalid key-value pair: ${raw}`);
16
+ parsed[key] = value;
17
+ }
18
+ return parsed;
19
+ }
20
+ export function loadJsonPayload(raw) {
21
+ let payloadText;
22
+ if (raw.startsWith("@")) {
23
+ const filePath = raw.slice(1).trim();
24
+ if (!filePath)
25
+ throw new Error(`Unable to read body file: ${raw}`);
26
+ try {
27
+ payloadText = readFileSync(filePath, "utf-8");
28
+ }
29
+ catch {
30
+ throw new Error(`Unable to read body file: ${raw}`);
31
+ }
32
+ }
33
+ else {
34
+ payloadText = raw;
35
+ }
36
+ try {
37
+ return JSON.parse(payloadText);
38
+ }
39
+ catch {
40
+ throw new Error(`Invalid JSON payload: ${raw}`);
41
+ }
42
+ }
43
+ export function resolveApiKey(explicitKey) {
44
+ if (explicitKey)
45
+ return explicitKey;
46
+ return process.env["AGENTICFLOW_PUBLIC_API_KEY"] ?? null;
47
+ }
48
+ export function buildRequestSpec(operation, baseUrl, pathParams, queryParams, extraHeaders, token, body) {
49
+ const normalizedUrl = baseUrl.replace(/\/+$/, "");
50
+ const formattedPath = formatPath(operation.path, pathParams);
51
+ const normalizedPath = formattedPath.startsWith("/") ? formattedPath : `/${formattedPath}`;
52
+ const url = `${normalizedUrl}${normalizedPath}`;
53
+ const headers = { ...extraHeaders };
54
+ if (token) {
55
+ headers["Authorization"] = `Bearer ${token}`;
56
+ }
57
+ if (body != null) {
58
+ const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
59
+ if (!hasContentType) {
60
+ headers["Content-Type"] = "application/json";
61
+ }
62
+ }
63
+ return {
64
+ method: operation.method.toUpperCase(),
65
+ url,
66
+ params: { ...queryParams },
67
+ headers,
68
+ body,
69
+ json: body,
70
+ };
71
+ }
72
+ function formatPath(path, pathParams) {
73
+ if (!path.includes("{"))
74
+ return path;
75
+ const required = extractPathParameterNames(path);
76
+ const missing = required.filter((name) => !(name in pathParams));
77
+ if (missing.length > 0) {
78
+ throw new Error(`Missing required path parameters: ${missing.sort().join(", ")}`);
79
+ }
80
+ let formatted = path;
81
+ for (const name of required) {
82
+ formatted = formatted.replace(`{${name}}`, encodeURIComponent(pathParams[name]));
83
+ }
84
+ return formatted;
85
+ }
86
+ function extractPathParameterNames(path) {
87
+ const names = [];
88
+ let inBraces = false;
89
+ let start = 0;
90
+ for (let i = 0; i < path.length; i++) {
91
+ if (path[i] === "{") {
92
+ inBraces = true;
93
+ start = i + 1;
94
+ }
95
+ else if (path[i] === "}" && inBraces) {
96
+ names.push(path.slice(start, i));
97
+ inBraces = false;
98
+ }
99
+ }
100
+ return names;
101
+ }
102
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"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"}