@usefillo/cli 0.19.0 → 0.21.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/dist/index.js
CHANGED
|
@@ -815,6 +815,7 @@ async function provisionWorkspace(flags, usageHint, apiBase = API) {
|
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
817
|
const workspaceName = flagString(flags, "workspace-name") ?? defaultWorkspaceName();
|
|
818
|
+
const promptCopyId = flagString(flags, "pc")?.trim();
|
|
818
819
|
const res = await api(
|
|
819
820
|
"/workspaces/provision",
|
|
820
821
|
{
|
|
@@ -823,7 +824,8 @@ async function provisionWorkspace(flags, usageHint, apiBase = API) {
|
|
|
823
824
|
email: email3,
|
|
824
825
|
source: "cli",
|
|
825
826
|
...name ? { name } : {},
|
|
826
|
-
...workspaceName ? { workspaceName } : {}
|
|
827
|
+
...workspaceName ? { workspaceName } : {},
|
|
828
|
+
...promptCopyId ? { promptCopyId } : {}
|
|
827
829
|
})
|
|
828
830
|
},
|
|
829
831
|
apiBase
|
|
@@ -958,7 +960,7 @@ async function init(flags) {
|
|
|
958
960
|
}
|
|
959
961
|
var initCommand = {
|
|
960
962
|
name: "init",
|
|
961
|
-
flags: ["email", "name", "workspace-name"],
|
|
963
|
+
flags: ["email", "name", "workspace-name", "pc"],
|
|
962
964
|
run: (_args, flags) => init(flags)
|
|
963
965
|
};
|
|
964
966
|
|
|
@@ -1210,7 +1212,7 @@ var skillCommand = {
|
|
|
1210
1212
|
};
|
|
1211
1213
|
|
|
1212
1214
|
// src/commands/agent.ts
|
|
1213
|
-
var BOOTSTRAP_USAGE = 'To set up a workspace I need
|
|
1215
|
+
var BOOTSTRAP_USAGE = 'To set up a workspace I need the human\'s real work email for the recovery link. Ask the human for their work email once \u2014 never invent an address or use a documentation placeholder \u2014 then re-run: npx @usefillo/cli@latest agent bootstrap --email <work-email> [--name "Your Name"]. (Already have an account? `fillo login`.)';
|
|
1214
1216
|
async function bootstrapStandalone(flags, apiBase) {
|
|
1215
1217
|
if (flags.account === true) {
|
|
1216
1218
|
die(
|
|
@@ -1403,9 +1405,10 @@ function agentHelp() {
|
|
|
1403
1405
|
|
|
1404
1406
|
${boldRaw("Commands")}
|
|
1405
1407
|
agent bootstrap Set up a workspace and install the Build with Fillo skill
|
|
1406
|
-
${dimRaw("--email
|
|
1408
|
+
${dimRaw("--email <work-email> provision a fresh workspace (ask the human first; a TTY confirms git identity)")}
|
|
1407
1409
|
${dimRaw('--name "Your Name" optional display name')}
|
|
1408
1410
|
${dimRaw("--workspace-name <name> name the new workspace (default: this repo/directory)")}
|
|
1411
|
+
${dimRaw("--pc <uuid> optional marketing stitch id from /agents?pc=")}
|
|
1409
1412
|
${dimRaw("--api <url> target a different Fillo deployment (default: FILLO_API or https://fillo.so)")}
|
|
1410
1413
|
${dimRaw("--run <id> --token <token> instead: attach to an open browser modal")}
|
|
1411
1414
|
${dimRaw("--account with --run/--token: approve an existing workspace in the browser")}
|
|
@@ -1432,6 +1435,7 @@ var agentCommand = {
|
|
|
1432
1435
|
"email",
|
|
1433
1436
|
"name",
|
|
1434
1437
|
"workspace-name",
|
|
1438
|
+
"pc",
|
|
1435
1439
|
"run",
|
|
1436
1440
|
"token",
|
|
1437
1441
|
"api",
|
|
@@ -2075,10 +2079,30 @@ function printDestination(body) {
|
|
|
2075
2079
|
console.log(
|
|
2076
2080
|
` ${dim("Role grant:")} ${grant ? `${terminalText(grant.roleId)} in ${terminalText(grant.guildId)}${grant.autoJoin ? " (auto-join)" : ""}` : "off"}`
|
|
2077
2081
|
);
|
|
2078
|
-
if (!body.webhookMatches) {
|
|
2082
|
+
if (!body.webhookMatches && body.connectionLabel) {
|
|
2079
2083
|
console.log(
|
|
2080
2084
|
`
|
|
2081
|
-
${
|
|
2085
|
+
${dim(
|
|
2086
|
+
`This form posts to its own channel; the project default is ${terminalText(body.connectionLabel)}. Re-point it with \`fillo discord enable <form> --channel <channelId>\`.`
|
|
2087
|
+
)}`
|
|
2088
|
+
);
|
|
2089
|
+
}
|
|
2090
|
+
const servers = body.servers ?? [];
|
|
2091
|
+
if (servers.length > 0) {
|
|
2092
|
+
console.log("");
|
|
2093
|
+
printTable(
|
|
2094
|
+
["SERVER", "ID"],
|
|
2095
|
+
servers.map((server) => [terminalText(server.name ?? "(name unavailable)"), server.guildId])
|
|
2096
|
+
);
|
|
2097
|
+
console.log(`
|
|
2098
|
+
${dim("Aim a form: fillo discord enable <form> --channel <channelId>")}`);
|
|
2099
|
+
}
|
|
2100
|
+
const channels = body.channels ?? [];
|
|
2101
|
+
if (servers.length === 0 && channels.length > 1) {
|
|
2102
|
+
console.log("");
|
|
2103
|
+
printTable(
|
|
2104
|
+
["CHANNEL", "WEBHOOK ID"],
|
|
2105
|
+
channels.map((channel) => [terminalText(channel.label), channel.webhookId])
|
|
2082
2106
|
);
|
|
2083
2107
|
}
|
|
2084
2108
|
}
|
|
@@ -2105,18 +2129,35 @@ function parseRole(raw) {
|
|
|
2105
2129
|
async function enable(form, flags) {
|
|
2106
2130
|
const json = jsonMode(flags);
|
|
2107
2131
|
if (!form)
|
|
2108
|
-
die(
|
|
2132
|
+
die(
|
|
2133
|
+
"Usage: fillo discord enable <form> [--channel <webhookId>] [--fields a,b,c] [--early-signal 5|10|25|off]"
|
|
2134
|
+
);
|
|
2109
2135
|
const token = requireToken();
|
|
2110
2136
|
const current = await fetchDestination(token, form);
|
|
2111
|
-
|
|
2137
|
+
const channels = current.channels ?? [];
|
|
2138
|
+
if ((!current.connected || !current.connectionWebhookId) && channels.length === 0) {
|
|
2112
2139
|
die(
|
|
2113
2140
|
"Discord isn't connected to this project. Run `fillo discord connect`, or `fillo discord webhook` to paste a channel URL."
|
|
2114
2141
|
);
|
|
2115
2142
|
}
|
|
2143
|
+
const rawChannel = flagString(flags, "channel");
|
|
2144
|
+
if (rawChannel !== void 0 && !SNOWFLAKE.test(rawChannel.trim())) {
|
|
2145
|
+
die("--channel must be a Discord channel id (right-click the channel \u2192 Copy Channel ID).");
|
|
2146
|
+
}
|
|
2147
|
+
const targetChannelId = rawChannel?.trim() ?? null;
|
|
2148
|
+
const fallbackWebhookId = current.connectionWebhookId ?? (channels.length === 1 ? channels[0]?.webhookId ?? null : null);
|
|
2149
|
+
if (!current.enabled && !targetChannelId && !fallbackWebhookId) {
|
|
2150
|
+
die(
|
|
2151
|
+
"Pass --channel <channelId> to pick where this form posts. `fillo discord status <form>` lists the connected servers."
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2116
2154
|
const patch = {};
|
|
2117
|
-
if (
|
|
2155
|
+
if (targetChannelId) {
|
|
2156
|
+
patch.enabled = true;
|
|
2157
|
+
patch.channelId = targetChannelId;
|
|
2158
|
+
} else if (!current.enabled && fallbackWebhookId) {
|
|
2118
2159
|
patch.enabled = true;
|
|
2119
|
-
patch.webhookId =
|
|
2160
|
+
patch.webhookId = fallbackWebhookId;
|
|
2120
2161
|
}
|
|
2121
2162
|
const rawFields = flagString(flags, "fields");
|
|
2122
2163
|
if (rawFields !== void 0) patch.includeFieldIds = parseFields(rawFields);
|
|
@@ -2244,6 +2285,7 @@ function discordHelp() {
|
|
|
2244
2285
|
${dimRaw(`reads the URL from a hidden prompt, or ${WEBHOOK_URL_ENV}`)}
|
|
2245
2286
|
discord status <form> What this form sends, to where, with which extras
|
|
2246
2287
|
discord enable <form> Start sending \u2014 and set any of the options below
|
|
2288
|
+
${dimRaw("--channel <channelId> which channel this form posts to (bot lane)")}
|
|
2247
2289
|
${dimRaw("--fields a,b,c up to three field ids (none = link only)")}
|
|
2248
2290
|
${dimRaw("--early-signal 5|10|25 first N responses arrive in full (off to stop)")}
|
|
2249
2291
|
${dimRaw("--role <guildId>/<roleId> grant that role on an accepted response")}
|
|
@@ -2263,7 +2305,7 @@ function discordHelp() {
|
|
|
2263
2305
|
}
|
|
2264
2306
|
var discordCommand = {
|
|
2265
2307
|
name: "discord",
|
|
2266
|
-
flags: ["label", "fields", "early-signal", "role", "auto-join"],
|
|
2308
|
+
flags: ["label", "channel", "fields", "early-signal", "role", "auto-join"],
|
|
2267
2309
|
run: (args, flags) => discord(args[0], args.slice(1), flags),
|
|
2268
2310
|
help: discordHelp
|
|
2269
2311
|
};
|
|
@@ -3774,7 +3816,7 @@ var schemaShape = object({
|
|
|
3774
3816
|
});
|
|
3775
3817
|
var MAX_SCHEMA_VERSION = 1;
|
|
3776
3818
|
var FILLO_SCHEMA_VERSION = 1;
|
|
3777
|
-
var FILLO_SDK_VERSION = true ? "0.
|
|
3819
|
+
var FILLO_SDK_VERSION = true ? "0.21.0" : "0.0.0-dev";
|
|
3778
3820
|
function str(value, max, fallback = "") {
|
|
3779
3821
|
return typeof value === "string" ? value.trim().slice(0, max) : fallback;
|
|
3780
3822
|
}
|
|
@@ -20,8 +20,12 @@ Never require a provider-specific agent command.
|
|
|
20
20
|
with a three-line plan before running anything, for example: "1) I install
|
|
21
21
|
Fillo's SDK and skill. 2) I build the form inside your app. 3) You get an
|
|
22
22
|
email to claim your workspace, where responses live." Add that a few
|
|
23
|
-
permission prompts may need approving along the way.
|
|
24
|
-
|
|
23
|
+
permission prompts may need approving along the way. Then, if their work
|
|
24
|
+
email is not already in this task, ask them for it once. Do not invent an
|
|
25
|
+
address, infer or scrape it, or use a documentation placeholder as the
|
|
26
|
+
address. Run `npx @usefillo/cli@latest agent bootstrap --email <their email>`
|
|
27
|
+
with the address they give you. Skip the recap and the email ask when Fillo
|
|
28
|
+
is already set up in the repo or a handoff already supplied a workspace.
|
|
25
29
|
2. Inspect the task environment and any host repository. For an embed, identify
|
|
26
30
|
its framework, package manager, target route, existing Fillo packages, theme
|
|
27
31
|
provider/switch, light and dark selectors, CSS `color-scheme`, design tokens,
|
|
@@ -37,12 +37,16 @@
|
|
|
37
37
|
- Older existing-account handoff: run its exact
|
|
38
38
|
`login --api … --run … --token …` command, wait for approval, then run the
|
|
39
39
|
supplied `agent connect --account` command.
|
|
40
|
-
- New workspace outside a browser handoff:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
- New workspace outside a browser handoff: ask the human once for their real
|
|
41
|
+
work email if it is not already in the task. Never invent an address, never
|
|
42
|
+
infer or scrape one, and never use a documentation placeholder as the
|
|
43
|
+
address. Then run
|
|
44
|
+
`npx @usefillo/cli@latest agent bootstrap --email <their email>` to provision
|
|
45
|
+
a capped preview workspace, email its link, store the `pk_` you build
|
|
46
|
+
against, and install the skill. Use
|
|
47
|
+
`npx @usefillo/cli@latest init --email <their email>` only when you need the
|
|
48
|
+
workspace without the skill. `https://fillo.so/start` stays available when
|
|
49
|
+
the user prefers the dashboard.
|
|
46
50
|
|
|
47
51
|
Never inspect `~/.fillo/config.json`, expose the account token, or call
|
|
48
52
|
`provisionWorkspace()` during component render.
|
|
@@ -78,7 +82,7 @@ workspace:
|
|
|
78
82
|
|
|
79
83
|
```bash
|
|
80
84
|
npx @usefillo/cli@latest claim
|
|
81
|
-
# Sent a claim link to
|
|
85
|
+
# Sent a claim link to alex@acme.dev. Approval code: 4KT2-9QF1
|
|
82
86
|
# Open the link in that inbox — it shows this code — and approve this terminal.
|
|
83
87
|
```
|
|
84
88
|
|
|
@@ -180,10 +180,13 @@ downstream writes duplicate-safe.
|
|
|
180
180
|
With a CLI login, connect Discord and manage its per-form settings — plus
|
|
181
181
|
mint a connector token for n8n or Zapier — without a dashboard trip.
|
|
182
182
|
|
|
183
|
-
Connect
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
Connect one of two ways. On a deployment where Fillo's Discord app is
|
|
184
|
+
configured, `discord connect` opens Discord's consent screen: ONE approval
|
|
185
|
+
adds Fillo's bot to the chosen server (Manage Webhooks only — it can't read
|
|
186
|
+
messages) and connects the first channel. After that, channels are picked
|
|
187
|
+
per form with `enable --channel` — no further approvals. Print the URL and
|
|
188
|
+
let the user approve it; do not loop, the same as `storage connect
|
|
189
|
+
drive`/`box`:
|
|
187
190
|
|
|
188
191
|
```bash
|
|
189
192
|
npx @usefillo/cli@latest discord connect
|
|
@@ -209,8 +212,13 @@ standing message (default: link only):
|
|
|
209
212
|
npx @usefillo/cli@latest discord enable customer-intake --fields email,plan
|
|
210
213
|
```
|
|
211
214
|
|
|
212
|
-
`enable` takes
|
|
215
|
+
`enable` takes more flags beyond field selection:
|
|
213
216
|
|
|
217
|
+
- `--channel <channelId>` aims this form at any channel of a connected
|
|
218
|
+
server (right-click the channel in Discord → Copy Channel ID); Fillo
|
|
219
|
+
resolves the channel through its bot and creates or reuses the channel's
|
|
220
|
+
webhook. Each form pins its own channel, so two forms can post to two
|
|
221
|
+
rooms. `discord status <form>` lists the connected servers.
|
|
214
222
|
- `--early-signal 5|10|25` sends every answered field — not only the picked
|
|
215
223
|
three — for that many responses, then reverts to the standing message on
|
|
216
224
|
its own; `--early-signal off` turns it back off early.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usefillo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Create and publish Fillo forms, and install the Fillo Agent Skill.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@types/node": "^22.10.0",
|
|
35
35
|
"tsup": "^8.4.0",
|
|
36
36
|
"typescript": "^5.8.3",
|
|
37
|
-
"@usefillo/core": "0.
|
|
37
|
+
"@usefillo/core": "0.21.0"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsup && node scripts/copy-skill.mjs",
|