@pixelml/agenticflow-cli 1.0.7 → 1.1.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.
Files changed (48) hide show
  1. package/README.md +85 -167
  2. package/dist/cli/gateway/connector.d.ts +51 -0
  3. package/dist/cli/gateway/connector.d.ts.map +1 -0
  4. package/dist/cli/gateway/connector.js +11 -0
  5. package/dist/cli/gateway/connector.js.map +1 -0
  6. package/dist/cli/gateway/connectors/index.d.ts +4 -0
  7. package/dist/cli/gateway/connectors/index.d.ts.map +1 -0
  8. package/dist/cli/gateway/connectors/index.js +4 -0
  9. package/dist/cli/gateway/connectors/index.js.map +1 -0
  10. package/dist/cli/gateway/connectors/linear.d.ts +27 -0
  11. package/dist/cli/gateway/connectors/linear.d.ts.map +1 -0
  12. package/dist/cli/gateway/connectors/linear.js +122 -0
  13. package/dist/cli/gateway/connectors/linear.js.map +1 -0
  14. package/dist/cli/gateway/connectors/paperclip.d.ts +22 -0
  15. package/dist/cli/gateway/connectors/paperclip.d.ts.map +1 -0
  16. package/dist/cli/gateway/connectors/paperclip.js +108 -0
  17. package/dist/cli/gateway/connectors/paperclip.js.map +1 -0
  18. package/dist/cli/gateway/connectors/webhook.d.ts +17 -0
  19. package/dist/cli/gateway/connectors/webhook.d.ts.map +1 -0
  20. package/dist/cli/gateway/connectors/webhook.js +49 -0
  21. package/dist/cli/gateway/connectors/webhook.js.map +1 -0
  22. package/dist/cli/gateway/server.d.ts +26 -0
  23. package/dist/cli/gateway/server.d.ts.map +1 -0
  24. package/dist/cli/gateway/server.js +164 -0
  25. package/dist/cli/gateway/server.js.map +1 -0
  26. package/dist/cli/main.d.ts.map +1 -1
  27. package/dist/cli/main.js +1973 -108
  28. package/dist/cli/main.js.map +1 -1
  29. package/dist/cli/pack-registry.d.ts +92 -0
  30. package/dist/cli/pack-registry.d.ts.map +1 -0
  31. package/dist/cli/pack-registry.js +417 -0
  32. package/dist/cli/pack-registry.js.map +1 -0
  33. package/dist/cli/pack.d.ts +70 -0
  34. package/dist/cli/pack.d.ts.map +1 -0
  35. package/dist/cli/pack.js +371 -0
  36. package/dist/cli/pack.js.map +1 -0
  37. package/dist/cli/paperclip-bridge.d.ts +15 -0
  38. package/dist/cli/paperclip-bridge.d.ts.map +1 -0
  39. package/dist/cli/paperclip-bridge.js +244 -0
  40. package/dist/cli/paperclip-bridge.js.map +1 -0
  41. package/dist/cli/playbooks.d.ts.map +1 -1
  42. package/dist/cli/playbooks.js +331 -0
  43. package/dist/cli/playbooks.js.map +1 -1
  44. package/dist/cli/skill.d.ts +69 -0
  45. package/dist/cli/skill.d.ts.map +1 -0
  46. package/dist/cli/skill.js +297 -0
  47. package/dist/cli/skill.js.map +1 -0
  48. package/package.json +3 -2
package/README.md CHANGED
@@ -1,232 +1,150 @@
1
1
  # @pixelml/agenticflow-cli
2
2
 
3
- Command-line interface for the [AgenticFlow](https://agenticflow.ai) platform.
4
- Manage agents, workflows, connections and more — directly from your terminal.
3
+ Command-line interface for the [AgenticFlow](https://agenticflow.ai) platform — build agents, deploy them to external platforms, and receive tasks from any webhook source.
5
4
 
6
5
  Built on [`@pixelml/agenticflow-sdk`](https://www.npmjs.com/package/@pixelml/agenticflow-sdk).
7
6
 
8
- ## Installation
7
+ ## Install
9
8
 
10
9
  ```bash
11
10
  npm install -g @pixelml/agenticflow-cli
12
11
  ```
13
12
 
14
- Or run directly via `npx`:
13
+ Available as both `agenticflow` and `af` (short alias). Requires Node.js 18+.
15
14
 
16
- ```bash
17
- npx @pixelml/agenticflow-cli --help
18
- ```
19
-
20
- ## Authentication
21
-
22
- ### Interactive login
15
+ ## Quick Start
23
16
 
24
17
  ```bash
25
- agenticflow login
18
+ af login # Authenticate
19
+ af doctor --json # Verify setup
20
+ af agent list --fields id,name,model --json # List agents
21
+ af agent stream --agent-id <id> --body '{"messages":[{"content":"Hello!"}]}'
26
22
  ```
27
23
 
28
- Prompts for API key, workspace ID and project ID, then saves them to
29
- `~/.agenticflow/auth.json`.
24
+ > **AI agents**: Run `af context --json` for a machine-readable bootstrap guide.
30
25
 
31
- ### Environment variables
26
+ ## Authentication
32
27
 
33
28
  ```bash
34
- export AGENTICFLOW_API_KEY="sk-..."
35
- export AGENTICFLOW_WORKSPACE_ID="ws-..."
36
- export AGENTICFLOW_PROJECT_ID="proj-..."
29
+ af login # Interactive (saves to ~/.agenticflow/auth.json)
30
+ export AGENTICFLOW_API_KEY=<key> # Environment variable
31
+ af --api-key <key> agent list # CLI flag
32
+ af auth import-env --file .env # Import from .env
33
+ af whoami --json # Verify
37
34
  ```
38
35
 
39
- ### Import from `.env` file
40
-
41
- ```bash
42
- agenticflow auth import-env --file .env
43
- ```
36
+ ## Core Commands
44
37
 
45
- ### CLI flags
38
+ ### Agents
46
39
 
47
40
  ```bash
48
- agenticflow --api-key sk-... --workspace-id ws-... agent list
41
+ af agent list --fields id,name,model --json
42
+ af agent get --agent-id <id> --json
43
+ af agent create --body @agent.json --dry-run # Validate first
44
+ af agent create --body @agent.json
45
+ af agent stream --agent-id <id> --body @stream.json
46
+ af agent update --agent-id <id> --body @update.json
47
+ af agent delete --agent-id <id>
49
48
  ```
50
49
 
51
- **Resolution order:** CLI flag → environment variable → `~/.agenticflow/auth.json`
52
-
53
- ### Verify
50
+ ### Workflows
54
51
 
55
52
  ```bash
56
- agenticflow whoami
53
+ af workflow list --fields id,name,status --json
54
+ af workflow create --body @wf.json --dry-run
55
+ af workflow create --body @wf.json
56
+ af workflow run --workflow-id <id> --input @input.json
57
+ af workflow run-status --workflow-run-id <run_id> --json
58
+ af workflow validate --body @wf.json --local-only
57
59
  ```
58
60
 
59
- ```
60
- Profile: default
61
- API Key: present
62
- Workspace ID: ws-abc123
63
- Project ID: proj-xyz789
64
- Config: ~/.agenticflow/auth.json
65
- ```
61
+ ### Webhook Gateway
66
62
 
67
- ### Logout
63
+ Receive tasks from any platform and route them to AgenticFlow agents:
68
64
 
69
65
  ```bash
70
- agenticflow logout # remove all credentials
71
- agenticflow logout --profile staging # remove a single profile
66
+ af gateway serve --channels paperclip,linear,webhook --verbose
67
+ af gateway channels # List available channels
72
68
  ```
73
69
 
74
- ## Commands
75
-
76
- ### Cold start
77
-
70
+ **Generic webhook** — any system can send tasks:
78
71
  ```bash
79
- # Machine-discoverable first-touch path
80
- agenticflow discover --json
81
- agenticflow playbook first-touch
82
-
83
- # Prime local template cache for workflow/agent/workforce examples
84
- agenticflow templates sync --json
85
- agenticflow templates index --json
72
+ curl -X POST http://localhost:4100/webhook/webhook \
73
+ -H "Content-Type: application/json" \
74
+ -d '{"agent_id":"<id>","message":"Summarize Q4 report"}'
86
75
  ```
87
76
 
88
- ### agent
89
-
77
+ **Paperclip** — AI company orchestration:
90
78
  ```bash
91
- agenticflow agent list [--project-id <id>] [--search <q>] [--limit <n>] [--offset <n>]
92
- agenticflow agent get --agent-id <id>
93
- agenticflow agent create --body <json|@file>
94
- agenticflow agent update --agent-id <id> --body <json|@file>
95
- agenticflow agent delete --agent-id <id>
96
- agenticflow agent stream --agent-id <id> --body <json|@file>
97
- agenticflow agent reference-impact --agent-id <id>
79
+ af gateway serve --channels paperclip
98
80
  ```
99
81
 
100
- ### workflow
101
-
82
+ **Linear** — engineering project management:
102
83
  ```bash
103
- agenticflow workflow list [--workspace-id <id>] [--project-id <id>] [--search <q>] [--limit <n>]
104
- agenticflow workflow get --workflow-id <id>
105
- agenticflow workflow create --body <json|@file> [--workspace-id <id>]
106
- agenticflow workflow update --workflow-id <id> --body <json|@file> [--workspace-id <id>]
107
- agenticflow workflow delete --workflow-id <id> [--workspace-id <id>]
108
- agenticflow workflow run --workflow-id <id> [--input <json|@file>]
109
- agenticflow workflow run-status --workflow-run-id <id>
110
- agenticflow workflow list-runs --workflow-id <id> [--sort-order asc|desc]
111
- agenticflow workflow run-history --workflow-id <id>
112
- agenticflow workflow validate --body <json|@file> [--local-only]
113
- agenticflow workflow reference-impact --workflow-id <id>
114
- agenticflow workflow like-status --workflow-id <id>
84
+ af gateway serve --channels linear
115
85
  ```
116
86
 
117
- ### connections
118
-
119
- ```bash
120
- agenticflow connections list [--workspace-id <id>] [--project-id <id>]
121
- agenticflow connections create --body <json|@file> [--workspace-id <id>]
122
- agenticflow connections update --connection-id <id> --body <json|@file> [--workspace-id <id>]
123
- agenticflow connections delete --connection-id <id> [--workspace-id <id>]
124
- ```
87
+ ### Paperclip Integration
125
88
 
126
- ### node-types
89
+ Deploy agents to [Paperclip](https://github.com/paperclipai/paperclip) companies:
127
90
 
128
91
  ```bash
129
- agenticflow node-types list
130
- agenticflow node-types get --name <name>
131
- agenticflow node-types search --query <q>
132
- agenticflow node-types dynamic-options --name <name> --field-name <field> [--connection <name>]
92
+ af paperclip company create --name "My Company" --budget 100000
93
+ af paperclip deploy --agent-id <id> --role engineer
94
+ af paperclip goal create --title "Build the product" --level company
95
+ af paperclip issue create --title "Design landing page" --assignee <agent-id>
96
+ af paperclip connect # Wire agents to gateway
97
+ af paperclip agent wakeup --id <id> # Trigger execution
98
+ af paperclip dashboard # Monitor
133
99
  ```
134
100
 
135
- ### uploads
101
+ ### AI-Agent Discovery
136
102
 
137
103
  ```bash
138
- agenticflow uploads create --body <json|@file>
139
- agenticflow uploads status --session-id <id>
104
+ af context --json # Bootstrap guide with invariants and schemas
105
+ af schema agent # Payload schema with examples
106
+ af schema --json # List all resource schemas
107
+ af discover --json # Full capability index
108
+ af playbook quickstart # Step-by-step guide
140
109
  ```
141
110
 
142
- ### Generic API call
143
-
144
- For any endpoint not covered by resource commands:
111
+ ### Node Types & Connections
145
112
 
146
113
  ```bash
147
- # By operation ID
148
- agenticflow call --operation-id get_by_id_v1_agents__agent_id__get -P agent_id=abc123
149
-
150
- # By method + path
151
- agenticflow call --method GET --path /v1/agents/
152
-
153
- # With parameters and body
154
- agenticflow call --operation-id update_v1_agents__agent_id__put \
155
- -P agent_id=abc123 \
156
- --body '{"name": "Updated"}'
157
-
158
- # Query parameters
159
- agenticflow call --method GET --path /v1/agents/ -Q limit=10
160
-
161
- # Dry run (shows request without executing)
162
- agenticflow call --operation-id get_all_v1_agents__get --dry-run
114
+ af node-types search --query "llm" --json
115
+ af node-types get --name <name> --json
116
+ af connections list --limit 200 --json
163
117
  ```
164
118
 
165
- ### Utilities
119
+ ### Playbooks
166
120
 
167
121
  ```bash
168
- # Preflight diagnostics
169
- agenticflow doctor
170
-
171
- # Machine-readable capability discovery
172
- agenticflow discover --json
173
-
174
- # OpenAPI operation discovery
175
- agenticflow ops list [--public-only] [--tag <tag>] [--json]
176
- agenticflow ops show <operation-id>
177
-
178
- # Operation catalog
179
- agenticflow catalog export [--public-only]
180
- agenticflow catalog rank --task "send a message" [--top <n>]
181
-
182
- # Policy guardrails
183
- agenticflow policy show
184
- agenticflow policy init [--spend-ceiling <amount>]
185
-
186
- # Built-in playbooks
187
- agenticflow playbook [topic] [--list]
188
- # First-touch onboarding for cold agents
189
- agenticflow playbook first-touch
190
- agenticflow playbook --list --json
191
-
192
- # Template bootstrap cache for cold agents
193
- agenticflow templates sync [--dir .agenticflow/templates] [--limit 100] [--strict] [--json]
194
- agenticflow templates index [--dir .agenticflow/templates] [--json]
195
-
196
- # Duplicate resources from templates (web-like flow)
197
- agenticflow templates duplicate workflow --template-id <workflow_template_id> --json
198
- agenticflow templates duplicate agent --template-id <agent_template_id> --json
199
- # Build payloads only (no create)
200
- agenticflow templates duplicate workflow --template-id <id> --dry-run --json
201
- # Resolve template IDs from local cache first (cold/sandbox-friendly)
202
- agenticflow templates duplicate workflow --template-id <id> --cache-dir .agenticflow/templates --json
203
- agenticflow templates duplicate agent --template-file .agenticflow/templates/agent/<file>.json --cache-dir .agenticflow/templates --dry-run --json
122
+ af playbook quickstart # Zero to working agent in 5 min
123
+ af playbook gateway-setup # Webhook gateway setup
124
+ af playbook deploy-to-paperclip # Paperclip company setup
125
+ af playbook agent-channels # Connect Linear, webhooks, etc.
126
+ af playbook agent-build # Agent configuration
127
+ af playbook workflow-build # Workflow design
128
+ af playbook template-bootstrap # Start from templates
204
129
  ```
205
130
 
206
131
  ## Global Options
207
132
 
208
- | Flag | Description |
209
- |---|---|
210
- | `--api-key <key>` | API key for authentication |
211
- | `--workspace-id <id>` | Default workspace ID |
212
- | `--project-id <id>` | Default project ID |
213
- | `--spec-file <path>` | Path to OpenAPI spec JSON |
214
- | `--no-color` | Disable ANSI color output |
215
- | `--json` | Force JSON output |
216
- | `--version` | Show version |
217
- | `--help` | Show help |
218
-
219
- ## Output
220
-
221
- Use `--json` for machine-readable output. In JSON mode, errors use a structured envelope and exit non-zero.
222
-
223
- Create/update/run/stream commands perform local payload validation first. This returns `local_schema_validation_failed` immediately for malformed inputs, before any API request is sent.
224
-
225
- `templates duplicate` can resolve workflow templates from a local `templates sync` cache via `--cache-dir` before attempting API fetches. This improves cold-start behavior in restricted environments.
226
-
227
- ```bash
228
- agenticflow agent list | jq '.[] | .name'
229
- ```
133
+ | Flag | Purpose |
134
+ |------|---------|
135
+ | `--json` | Machine-readable JSON output |
136
+ | `--fields <fields>` | Filter output fields (saves context window) |
137
+ | `--dry-run` | Validate without executing |
138
+ | `--api-key <key>` | Override API key |
139
+ | `--workspace-id <id>` | Override workspace |
140
+ | `--project-id <id>` | Override project |
141
+
142
+ ## Links
143
+
144
+ - [AgenticFlow Platform](https://agenticflow.ai)
145
+ - [Documentation](https://docs.agenticflow.ai)
146
+ - [SDK Package](https://www.npmjs.com/package/@pixelml/agenticflow-sdk)
147
+ - [GitHub](https://github.com/PixelML/agenticflow-cli)
230
148
 
231
149
  ## License
232
150
 
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Channel connector interface — inspired by hermes-agent's platform adapters.
3
+ *
4
+ * A "channel" is any external platform that can send tasks to AgenticFlow
5
+ * agents: Paperclip, Linear, GitHub, Slack, webhooks, etc.
6
+ *
7
+ * Each connector normalizes platform-specific events into a standard task
8
+ * and posts results back to the originating channel.
9
+ */
10
+ /** Platform-agnostic task representation (the "MessageEvent" equivalent). */
11
+ export interface NormalizedTask {
12
+ /** Stable UUID for AF thread continuity across messages. */
13
+ threadId: string;
14
+ /** Human-readable identifier, e.g. "PIX-1", "LIN-123". */
15
+ taskIdentifier: string;
16
+ /** The full message to send to the AF agent. */
17
+ message: string;
18
+ /** AF agent ID to invoke. */
19
+ afAgentId: string;
20
+ /** Override AF stream URL. */
21
+ afStreamUrl?: string;
22
+ /** Source channel info (for routing responses back). */
23
+ source: {
24
+ channel: string;
25
+ chatId: string;
26
+ userId?: string;
27
+ userName?: string;
28
+ };
29
+ /** Opaque platform data the connector needs in postResult. */
30
+ platformContext: Record<string, unknown>;
31
+ }
32
+ /** Channel connector for receiving tasks from an external platform. */
33
+ export interface ChannelConnector {
34
+ /** Short slug: paperclip, linear, github, webhook, etc. */
35
+ readonly name: string;
36
+ /** Human-readable display name. */
37
+ readonly displayName: string;
38
+ /**
39
+ * Parse incoming webhook into a NormalizedTask.
40
+ * Return null to skip (irrelevant event type).
41
+ * Throw to reject with 400.
42
+ */
43
+ parseWebhook(headers: Record<string, string | string[] | undefined>, body: string): Promise<NormalizedTask | null>;
44
+ /** Post agent response back to the originating channel. */
45
+ postResult(task: NormalizedTask, resultText: string): Promise<void>;
46
+ /** Optional: check if the channel is reachable. */
47
+ healthCheck?(): Promise<boolean>;
48
+ }
49
+ /** Registry of available channel connectors. */
50
+ export type ConnectorRegistry = Map<string, ChannelConnector>;
51
+ //# sourceMappingURL=connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../src/cli/gateway/connector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,YAAY,CACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAElC,2DAA2D;IAC3D,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,mDAAmD;IACnD,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAClC;AAED,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Channel connector interface — inspired by hermes-agent's platform adapters.
3
+ *
4
+ * A "channel" is any external platform that can send tasks to AgenticFlow
5
+ * agents: Paperclip, Linear, GitHub, Slack, webhooks, etc.
6
+ *
7
+ * Each connector normalizes platform-specific events into a standard task
8
+ * and posts results back to the originating channel.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector.js","sourceRoot":"","sources":["../../../src/cli/gateway/connector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,4 @@
1
+ export { PaperclipConnector, type PaperclipConnectorConfig } from "./paperclip.js";
2
+ export { LinearConnector, type LinearConnectorConfig } from "./linear.js";
3
+ export { WebhookConnector } from "./webhook.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/gateway/connectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { PaperclipConnector } from "./paperclip.js";
2
+ export { LinearConnector } from "./linear.js";
3
+ export { WebhookConnector } from "./webhook.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/gateway/connectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAiC,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,eAAe,EAA8B,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Linear channel connector.
3
+ *
4
+ * Receives Linear webhooks (issue.create, issue.update, comment.create),
5
+ * fetches issue context, and posts results back as comments.
6
+ *
7
+ * Setup: In Linear → Settings → API → Webhooks, add:
8
+ * URL: https://your-gateway/webhook/linear
9
+ * Events: Issues (created, updated), Comments (created)
10
+ */
11
+ import type { ChannelConnector, NormalizedTask } from "../connector.js";
12
+ export interface LinearConnectorConfig {
13
+ linearApiKey: string;
14
+ /** Map of Linear team key → AF agent ID. e.g. { "ENG": "af-agent-uuid" } */
15
+ agentMapping: Record<string, string>;
16
+ /** Optional: AF stream URL override per agent. */
17
+ streamUrlMapping?: Record<string, string>;
18
+ }
19
+ export declare class LinearConnector implements ChannelConnector {
20
+ private config;
21
+ readonly name = "linear";
22
+ readonly displayName = "Linear";
23
+ constructor(config: LinearConnectorConfig);
24
+ parseWebhook(_headers: Record<string, string | string[] | undefined>, body: string): Promise<NormalizedTask | null>;
25
+ postResult(task: NormalizedTask, resultText: string): Promise<void>;
26
+ }
27
+ //# sourceMappingURL=linear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../../src/cli/gateway/connectors/linear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAgDD,qBAAa,eAAgB,YAAW,gBAAgB;IAI1C,OAAO,CAAC,MAAM;IAH1B,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;gBAEZ,MAAM,EAAE,qBAAqB;IAE3C,YAAY,CAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACvD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA4E3B,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAU1E"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Linear channel connector.
3
+ *
4
+ * Receives Linear webhooks (issue.create, issue.update, comment.create),
5
+ * fetches issue context, and posts results back as comments.
6
+ *
7
+ * Setup: In Linear → Settings → API → Webhooks, add:
8
+ * URL: https://your-gateway/webhook/linear
9
+ * Events: Issues (created, updated), Comments (created)
10
+ */
11
+ // Minimal Linear GraphQL client
12
+ async function linearQuery(apiKey, query, variables) {
13
+ const resp = await fetch("https://api.linear.app/graphql", {
14
+ method: "POST",
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ Authorization: apiKey,
18
+ },
19
+ body: JSON.stringify({ query, variables }),
20
+ });
21
+ if (!resp.ok)
22
+ throw new Error(`Linear API failed (${resp.status})`);
23
+ const result = (await resp.json());
24
+ if (result.errors)
25
+ throw new Error(`Linear GraphQL: ${JSON.stringify(result.errors)}`);
26
+ return result.data;
27
+ }
28
+ async function linearGetIssue(apiKey, issueId) {
29
+ const data = (await linearQuery(apiKey, `
30
+ query($id: String!) {
31
+ issue(id: $id) {
32
+ id identifier title description priority priorityLabel
33
+ state { name }
34
+ team { key name }
35
+ assignee { name }
36
+ labels { nodes { name } }
37
+ comments { nodes { body user { name } createdAt } }
38
+ }
39
+ }
40
+ `, { id: issueId }));
41
+ return data.issue;
42
+ }
43
+ async function linearAddComment(apiKey, issueId, body) {
44
+ await linearQuery(apiKey, `
45
+ mutation($issueId: String!, $body: String!) {
46
+ commentCreate(input: { issueId: $issueId, body: $body }) {
47
+ success
48
+ }
49
+ }
50
+ `, { issueId, body });
51
+ }
52
+ export class LinearConnector {
53
+ config;
54
+ name = "linear";
55
+ displayName = "Linear";
56
+ constructor(config) {
57
+ this.config = config;
58
+ }
59
+ async parseWebhook(_headers, body) {
60
+ const payload = JSON.parse(body);
61
+ // Only handle issue creates/updates and comment creates
62
+ const isIssue = payload.type === "Issue" && ["create", "update"].includes(payload.action);
63
+ const isComment = payload.type === "Comment" && payload.action === "create";
64
+ if (!isIssue && !isComment)
65
+ return null;
66
+ const issueId = isComment ? payload.data.issueId : payload.data.id;
67
+ // Fetch full issue details
68
+ const issue = await linearGetIssue(this.config.linearApiKey, issueId);
69
+ const team = issue.team;
70
+ const teamKey = team?.key ?? "";
71
+ // Find AF agent for this team
72
+ const afAgentId = this.config.agentMapping[teamKey];
73
+ if (!afAgentId)
74
+ return null; // No agent mapped for this team — skip
75
+ const state = issue.state;
76
+ const labels = issue.labels;
77
+ const comments = issue.comments;
78
+ // Build message
79
+ const parts = [];
80
+ parts.push("You have received a task from Linear.\n");
81
+ parts.push(`## Task: ${issue.identifier} — ${issue.title}`);
82
+ parts.push(`- **Priority:** ${issue.priorityLabel ?? "medium"}`);
83
+ parts.push(`- **Status:** ${state?.name ?? "unknown"}`);
84
+ if (labels?.nodes?.length) {
85
+ parts.push(`- **Labels:** ${labels.nodes.map((l) => l.name).join(", ")}`);
86
+ }
87
+ if (issue.description) {
88
+ parts.push(`\n### Description\n${issue.description}`);
89
+ }
90
+ if (comments?.nodes?.length) {
91
+ parts.push("\n### Recent Comments");
92
+ for (const c of comments.nodes.slice(-5)) {
93
+ const user = c.user;
94
+ parts.push(`- **${user?.name ?? "Unknown"}:** ${c.body}`);
95
+ }
96
+ }
97
+ if (isComment && payload.data.body) {
98
+ parts.push(`\n### New Comment (trigger)\n${payload.data.body}`);
99
+ }
100
+ parts.push("\n## Instructions\nComplete this task. Provide a clear summary of your work.");
101
+ return {
102
+ threadId: issueId, // reuse Linear issue ID as thread for continuity
103
+ taskIdentifier: issue.identifier ?? issueId,
104
+ message: parts.join("\n"),
105
+ afAgentId,
106
+ afStreamUrl: this.config.streamUrlMapping?.[afAgentId],
107
+ source: {
108
+ channel: "linear",
109
+ chatId: teamKey,
110
+ userName: issue.assignee?.name,
111
+ },
112
+ platformContext: { issueId, teamKey },
113
+ };
114
+ }
115
+ async postResult(task, resultText) {
116
+ const issueId = task.platformContext.issueId;
117
+ if (issueId && resultText) {
118
+ await linearAddComment(this.config.linearApiKey, issueId, `**Agent Response:**\n\n${resultText}`);
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=linear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../../src/cli/gateway/connectors/linear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,gCAAgC;AAChC,KAAK,UAAU,WAAW,CACxB,MAAc,EACd,KAAa,EACb,SAAmC;IAEnC,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,gCAAgC,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,MAAM;SACtB;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAC3C,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA2C,CAAC;IAC7E,IAAI,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvF,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,OAAe;IAC3D,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,MAAM,EAAE;;;;;;;;;;;GAWvC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAuC,CAAC;IAC3D,OAAO,IAAI,CAAC,KAAK,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAc,EAAE,OAAe,EAAE,IAAY;IAC3E,MAAM,WAAW,CAAC,MAAM,EAAE;;;;;;GAMzB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,OAAO,eAAe;IAIN;IAHX,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,QAAQ,CAAC;IAEhC,YAAoB,MAA6B;QAA7B,WAAM,GAAN,MAAM,CAAuB;IAAG,CAAC;IAErD,KAAK,CAAC,YAAY,CAChB,QAAuD,EACvD,IAAY;QAEZ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAc9B,CAAC;QAEF,wDAAwD;QACxD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1F,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC;QAC5E,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAExC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAEpE,2BAA2B;QAC3B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,KAAK,CAAC,IAA2C,CAAC;QAC/D,MAAM,OAAO,GAAI,IAAI,EAAE,GAAc,IAAI,EAAE,CAAC;QAE5C,8BAA8B;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,CAAC,uCAAuC;QAEpE,MAAM,KAAK,GAAG,KAAK,CAAC,KAA4C,CAAC;QACjE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAwD,CAAC;QAC9E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAiE,CAAC;QAEzF,gBAAgB;QAChB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,UAAU,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,mBAAmB,KAAK,CAAC,aAAa,IAAI,QAAQ,EAAE,CAAC,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC,iBAAiB,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;QACxD,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACpC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAA2C,CAAC;gBAC3D,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,IAAI,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,gCAAgC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;QAE3F,OAAO;YACL,QAAQ,EAAE,OAAO,EAAE,iDAAiD;YACpE,cAAc,EAAG,KAAK,CAAC,UAAqB,IAAI,OAAO;YACvD,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YACzB,SAAS;YACT,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,SAAS,CAAC;YACtD,MAAM,EAAE;gBACN,OAAO,EAAE,QAAQ;gBACjB,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAG,KAAK,CAAC,QAAoC,EAAE,IAA0B;aAClF;YACD,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;SACtC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAoB,EAAE,UAAkB;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAiB,CAAC;QACvD,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;YAC1B,MAAM,gBAAgB,CACpB,IAAI,CAAC,MAAM,CAAC,YAAY,EACxB,OAAO,EACP,0BAA0B,UAAU,EAAE,CACvC,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Paperclip channel connector.
3
+ *
4
+ * Receives heartbeat POSTs from Paperclip, fetches issue context,
5
+ * builds agent message, and posts results back as comments.
6
+ */
7
+ import type { ChannelConnector, NormalizedTask } from "../connector.js";
8
+ export interface PaperclipConnectorConfig {
9
+ paperclipUrl: string;
10
+ }
11
+ export declare class PaperclipConnector implements ChannelConnector {
12
+ private config;
13
+ readonly name = "paperclip";
14
+ readonly displayName = "Paperclip";
15
+ private pc;
16
+ constructor(config: PaperclipConnectorConfig);
17
+ healthCheck(): Promise<boolean>;
18
+ parseWebhook(_headers: Record<string, string | string[] | undefined>, body: string): Promise<NormalizedTask | null>;
19
+ postResult(task: NormalizedTask, resultText: string): Promise<void>;
20
+ private buildMessage;
21
+ }
22
+ //# sourceMappingURL=paperclip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paperclip.d.ts","sourceRoot":"","sources":["../../../../src/cli/gateway/connectors/paperclip.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,kBAAmB,YAAW,gBAAgB;IAK7C,OAAO,CAAC,MAAM;IAJ1B,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,eAAe;IACnC,OAAO,CAAC,EAAE,CAAoB;gBAEV,MAAM,EAAE,wBAAwB;IAI9C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,YAAY,CAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACvD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAmD3B,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAS3D,YAAY;CAiD3B"}