@interactive-inc/claude-funnel 0.15.2 → 0.17.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
@@ -87,8 +87,8 @@ Every event the connector sees now arrives in the running agent session, and the
87
87
  Save it as a profile for one-command launches:
88
88
 
89
89
  ```bash
90
- fnl profiles add cto --path=/repo/myapp --sub-agent=cto --channel=ops
91
- fnl claude --profile cto # cd + sub-agent + channel binding in one shot
90
+ fnl profiles add cto --path=/repo/myapp --channel=ops
91
+ fnl claude --profile cto # cd + channel binding in one shot
92
92
  ```
93
93
 
94
94
  Or drop a `funnel.json` in the repo and `fnl claude` (no args) inside the repo will use it:
@@ -96,31 +96,39 @@ Or drop a `funnel.json` in the repo and `fnl claude` (no args) inside the repo w
96
96
  ```json
97
97
  {
98
98
  "$schema": "./node_modules/@interactive-inc/claude-funnel/funnel.schema.json",
99
- "channel": "ops",
100
- "options": ["--brief", "--agent", "cto"],
101
- "env": {
102
- "ANTHROPIC_MODEL": "claude-sonnet-4-6"
103
- },
104
- "connectors": [
99
+ "channels": [
105
100
  {
106
- "type": "slack",
107
- "name": "my-slack",
101
+ "name": "ops",
102
+ "options": ["--brief", "--agent", "pm"],
108
103
  "env": {
109
- "botToken": "SLACK_BOT_TOKEN",
110
- "appToken": "SLACK_APP_TOKEN"
111
- }
104
+ "ANTHROPIC_MODEL": "claude-sonnet-4-6"
105
+ },
106
+ "connectors": [
107
+ {
108
+ "type": "slack",
109
+ "name": "my-slack",
110
+ "env": {
111
+ "botToken": "SLACK_BOT_TOKEN",
112
+ "appToken": "SLACK_APP_TOKEN"
113
+ }
114
+ }
115
+ ]
116
+ },
117
+ {
118
+ "name": "review",
119
+ "options": ["--agent", "reviewer"]
112
120
  }
113
121
  ]
114
122
  }
115
123
  ```
116
124
 
117
- Only `channel` is required.
125
+ `channels[]` is required and the first entry is the default. `fnl claude --channel review` picks one by name; `fnl claude` with no `--channel` uses the first.
118
126
 
119
- The optional `options` array is prepended to the claude argv on every launch, before any args the user types after `fnl claude`. Use it for repo-wide claude flags (e.g. `--brief`, `--agent <name>`, `--model <name>`). User-supplied CLI args appear later in the argv so they still win on collision.
127
+ Each channel has its own `options` (prepended to the claude argv before user-supplied CLI args, which still come last use it for per-channel flags like `--brief`, `--agent <name>`, `--model <name>`) and `env` (layered under the launched claude process — `process.env` from the launching shell wins on collision, so funnel.json sets defaults that the user can still override one-off via the shell).
120
128
 
121
- The optional top-level `env` is a `Record<string, string>` of environment variables to layer under the claude process. `process.env` from the launching shell wins on collision, so funnel.json sets defaults that the user can still override one-off via the shell.
129
+ The optional `connectors` array on a channel is the source of truth for that channel: missing connectors are created, an existing connector matched by token under a different name is renamed in place, and connectors not declared are removed on launch. An absent `connectors` field leaves `~/.funnel` alone.
122
130
 
123
- The optional `connectors` array is treated as the source of truth for the declared channel: missing connectors are created, an existing connector that the spec references by token (not by name) is renamed in place, and connectors not declared in the spec are removed on launch. An absent `connectors` field leaves `~/.funnel` alone.
131
+ On launch, the chosen channel's `options` / `env` / `connectors` are also materialized into the global `~/.funnel/settings.json` Channel entry. Raw launches (`fnl claude --channel <name>` without funnel.json) and profile launches read the same fields from there, so funnel.json and settings.json share one Channel data model.
124
132
 
125
133
  The optional top-level `$schema` points at the JSON Schema so editors can validate and autocomplete the file. The recommended reference for repos with a local install is `./node_modules/@interactive-inc/claude-funnel/funnel.schema.json` — it works without a network round-trip and editors do not need to prompt for trust. The same file is also published at `https://interactive-inc.github.io/open-claude-funnel/funnel.schema.json` (editors usually require explicit trust on first use), and `fnl schema > funnel.schema.json` regenerates a local copy on demand.
126
134
 
@@ -180,17 +188,17 @@ fnl channels <ch> connectors <c> schedules add <id> --cron="<expr>" --prompt="<t
180
188
  fnl channels <ch> connectors <c> schedules remove <id>
181
189
 
182
190
  fnl profiles list (first entry is the default)
183
- fnl profiles add <name> --path=<dir> --sub-agent=<agent> --channel=<channel-name>
191
+ fnl profiles add <name> --path=<dir> --channel=<channel-name>
184
192
  fnl profiles <name> launch (alias for `<name> run`)
185
193
  fnl profiles <name> run launch (sugar for `fnl claude --profile <name>`)
186
- fnl profiles <name> set [--path=...] [--sub-agent=...] [--channel=...]
194
+ fnl profiles <name> set [--path=...] [--channel=...]
187
195
  fnl profiles <name> as-default move to the front of the list
188
196
  fnl profiles rename <old> <new>
189
197
  fnl profiles remove <name>
190
198
 
191
- fnl claude launch using ./funnel.json, or the default profile
192
- fnl claude --profile <name> launch a named profile
193
- fnl claude --channel <name> raw launch (no profile, cwd = current dir)
199
+ fnl claude launch the first channel from ./funnel.json, or the default profile
200
+ fnl claude --channel <name> with funnel.json: pick that channel; without: raw launch
201
+ fnl claude --profile <name> launch a named profile (ignores funnel.json)
194
202
  fnl claude [...] positionals and any flag other than -p / --profile / --channel
195
203
  (e.g. --agent, --resume, -c, --model) pass through to claude
196
204
  fnl mcp run as an MCP server (invoked from .mcp.json)
@@ -237,9 +245,10 @@ To invoke a connector from outside an agent, the same path is reachable as `fnl
237
245
  ## Data model
238
246
 
239
247
  ```
240
- Channel = { id, name, delivery, connectors[] }
241
- subscription box; delivery is `fanout` (every WS client sees every event)
242
- or `exclusive` (round-robin one client per event)
248
+ Channel = { id, name, delivery, options[], env, connectors[] }
249
+ subscription box plus launch settings. delivery is `fanout` (every WS client sees every event)
250
+ or `exclusive` (round-robin one client per event). options[] prepends to the claude argv on
251
+ launch; env layers under the launched process (process.env wins on collision)
243
252
 
244
253
  Connector =
245
254
  | { type: "slack", name, botToken, appToken } Slack Socket Mode
@@ -247,15 +256,17 @@ Connector =
247
256
  | { type: "discord", name, botToken } Discord Gateway
248
257
  | { type: "schedule", name, entries[] } cron-driven; entries = { id, cron, prompt, enabled?, catchupPolicy? }
249
258
 
250
- Profile = { name, path, subAgent, channelId }
251
- named launch preset; the first profile in the list is the default
259
+ Profile = { name, path, channelId }
260
+ named launch preset (just where to launch a channel from); the first profile is the default
261
+
262
+ LocalConfig = { channels: ChannelSpec[] }
263
+ per-repo file (funnel.json). channels[] required; first entry is default, --channel selects.
252
264
 
253
- LocalConfig = { channel, options?, env?, connectors? }
254
- per-repo file (funnel.json) checked by `fnl claude` when no --profile / --channel is given
255
- options[] is prepended to claude argv (user CLI args override); env merges under process.env;
256
- connectors[] declares connectors to materialize on launch (each token field accepts a literal,
257
- an env-var reference at `env.<field>` resolved from process.env and ./.env.local, or omission
258
- for a TTY prompt persisted to ~/.funnel)
265
+ ChannelSpec = { name, options?, env?, connectors? }
266
+ mirrors Channel above (no id, since funnel.json declares by name). options/env/connectors
267
+ materialize into the matching Channel in ~/.funnel/settings.json on launch. Connector token
268
+ fields accept a literal, an env-var reference at `env.<field>` resolved from process.env and
269
+ ./.env.local, or omission for a TTY prompt persisted to ~/.funnel.
259
270
 
260
271
  Settings = { channels[], profiles[] } → ~/.funnel/settings.json
261
272
  ```