@interactive-inc/claude-funnel 0.16.1 → 0.18.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,14 +96,13 @@ 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
- "options": ["--brief"],
100
- "env": {
101
- "ANTHROPIC_MODEL": "claude-sonnet-4-6"
102
- },
103
99
  "channels": [
104
100
  {
105
101
  "name": "ops",
106
- "options": ["--agent", "pm"],
102
+ "options": ["--brief", "--agent", "pm"],
103
+ "env": {
104
+ "ANTHROPIC_MODEL": "claude-sonnet-4-6"
105
+ },
107
106
  "connectors": [
108
107
  {
109
108
  "type": "slack",
@@ -125,11 +124,11 @@ Or drop a `funnel.json` in the repo and `fnl claude` (no args) inside the repo w
125
124
 
126
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.
127
126
 
128
- The optional top-level `options` array is shared by every channel and prepended to each channel's own `options` (and both appear before user-supplied CLI args, which still come last). Use it for flags that should apply repo-wide (e.g. `--brief`). Per-channel `options` add channel-specific flags (e.g. a different `--agent`).
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).
129
128
 
130
- The optional top-level `env` is a `Record<string, string>` of environment variables shared by every channel; each channel's own `env` shallow-merges on top. `process.env` from the launching shell wins overall, 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.
131
130
 
132
- 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.
133
132
 
134
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.
135
134
 
@@ -189,10 +188,10 @@ fnl channels <ch> connectors <c> schedules add <id> --cron="<expr>" --prompt="<t
189
188
  fnl channels <ch> connectors <c> schedules remove <id>
190
189
 
191
190
  fnl profiles list (first entry is the default)
192
- fnl profiles add <name> --path=<dir> --sub-agent=<agent> --channel=<channel-name>
191
+ fnl profiles add <name> --path=<dir> --channel=<channel-name>
193
192
  fnl profiles <name> launch (alias for `<name> run`)
194
193
  fnl profiles <name> run launch (sugar for `fnl claude --profile <name>`)
195
- fnl profiles <name> set [--path=...] [--sub-agent=...] [--channel=...]
194
+ fnl profiles <name> set [--path=...] [--channel=...]
196
195
  fnl profiles <name> as-default move to the front of the list
197
196
  fnl profiles rename <old> <new>
198
197
  fnl profiles remove <name>
@@ -246,9 +245,10 @@ To invoke a connector from outside an agent, the same path is reachable as `fnl
246
245
  ## Data model
247
246
 
248
247
  ```
249
- Channel = { id, name, delivery, connectors[] }
250
- subscription box; delivery is `fanout` (every WS client sees every event)
251
- 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)
252
252
 
253
253
  Connector =
254
254
  | { type: "slack", name, botToken, appToken } Slack Socket Mode
@@ -256,19 +256,17 @@ Connector =
256
256
  | { type: "discord", name, botToken } Discord Gateway
257
257
  | { type: "schedule", name, entries[] } cron-driven; entries = { id, cron, prompt, enabled?, catchupPolicy? }
258
258
 
259
- Profile = { name, path, subAgent, channelId }
260
- 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
261
 
262
- LocalConfig = { options?, env?, channels: ChannelSpec[] }
262
+ LocalConfig = { channels: ChannelSpec[] }
263
263
  per-repo file (funnel.json). channels[] required; first entry is default, --channel selects.
264
- Top-level options/env are shared defaults merged into each channel.
265
264
 
266
265
  ChannelSpec = { name, options?, env?, connectors? }
267
- options[] is appended to the shared options (user CLI args still come last); env shallow-merges
268
- on top of the shared env (process.env wins overall); connectors[] declares connectors to
269
- materialize on launch (each token field accepts a literal, an env-var reference at
270
- `env.<field>` resolved from process.env and ./.env.local, or omission for a TTY prompt
271
- persisted to ~/.funnel)
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.
272
270
 
273
271
  Settings = { channels[], profiles[] } → ~/.funnel/settings.json
274
272
  ```