@nearform/fling 0.8.0 → 0.10.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 +134 -25
- package/dist/cli.js +2204 -388
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,13 +38,64 @@ This does everything a new machine needs:
|
|
|
38
38
|
sign-in providers, its login page, to choose one) and an API key is
|
|
39
39
|
stored in `~/.fling/config.json` (mode 0600). This is skipped if you're already signed in.
|
|
40
40
|
The server becomes your current one; logins to other Flings are kept.
|
|
41
|
+
When you are already signed in, it reads the server's `/.well-known/fling` again, so the CLI
|
|
42
|
+
knows the release it runs now.
|
|
41
43
|
2. **Adds Fling to Claude Code.** If `claude` is on your PATH, setup installs the Fling plugin
|
|
42
|
-
(skill + MCP server) from the `nearform/fling` marketplace
|
|
43
|
-
|
|
44
|
+
(skill + MCP server) from the `nearform/fling` marketplace. `--scope project|local` installs it
|
|
45
|
+
for this project only (default `user`). When the plugin is already installed, setup refreshes
|
|
46
|
+
it instead (`claude plugin marketplace update fling`, then `claude plugin update fling@fling`)
|
|
47
|
+
and says which version it went from and to; restart Claude Code (or run `/reload-plugins`)
|
|
48
|
+
after an update. A refresh that fails is reported and leaves the installed plugin as it was;
|
|
49
|
+
it doesn't fail setup.
|
|
44
50
|
3. **Adds Fling to Claude Desktop.** If Claude Desktop is installed (macOS, Windows), setup
|
|
45
|
-
downloads `fling.mcpb` and opens it, and Claude Desktop asks you
|
|
51
|
+
downloads the `fling.mcpb` of the CLI's own version and opens it, and Claude Desktop asks you
|
|
52
|
+
to confirm. That is the server's copy when the server runs the same release, otherwise the one
|
|
53
|
+
attached to the CLI's GitHub Release (the server's copy if that download fails). Running setup
|
|
54
|
+
again updates an older extension in place.
|
|
46
55
|
|
|
47
|
-
On a terminal it asks before
|
|
56
|
+
On a terminal it asks before installing the plugin and before step 3. With `--yes` it does them
|
|
57
|
+
without asking. Refreshing an installed plugin needs no question.
|
|
58
|
+
|
|
59
|
+
### Staying up to date
|
|
60
|
+
|
|
61
|
+
Every Fling publishes the release it runs (`release` in `/.well-known/fling`). After a command, when
|
|
62
|
+
the server it used runs a newer release than the CLI, the CLI prints one line on stderr:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
▲ Fling 0.9.0 is out (this CLI is 0.8.0). Update: npm i -g @nearform/fling@latest && fling setup
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It compares with the metadata the CLI already holds, so it never makes a request of its own. The
|
|
69
|
+
stored release stays current because every server response says which release the server runs (the
|
|
70
|
+
`Fling-Release` header): when it differs from the stored one, the CLI stores the new release. That
|
|
71
|
+
needs both the server and the CLI on a release after 0.8.0; with an older server, the stored release
|
|
72
|
+
changes only at sign-in, when `fling setup` reads the metadata again, and when a command needs a
|
|
73
|
+
feature the stored copy lacks. It says it at most once a day per server, remembering when in
|
|
74
|
+
`update-check.json` in the config directory. It says nothing under `--json`, when stderr isn't a
|
|
75
|
+
terminal, when `CI` is set, or when `FLING_NO_UPDATE_CHECK` is set (to anything). A server older
|
|
76
|
+
than the CLI says nothing either. The MCP server tells Claude instead (see [Claude Code plugin and
|
|
77
|
+
MCP](#claude-code-plugin-and-mcp)).
|
|
78
|
+
|
|
79
|
+
### When something doesn't work
|
|
80
|
+
|
|
81
|
+
`fling doctor` checks the setup and prints one line per check, `✔` ok, `▲` warning or `✖` problem,
|
|
82
|
+
each warning and problem with its fix:
|
|
83
|
+
|
|
84
|
+
- **CLI:** its version, Node.js against the versions it supports, the latest version on npm
|
|
85
|
+
(skipped when npm can't be reached), and whether `fling` on your PATH is this CLI.
|
|
86
|
+
- **Config:** where it lives (`FLING_CONFIG_DIR`), whether the config file is private (mode 0600:
|
|
87
|
+
it holds your API keys), and whether `FLING_URL` or `FLING_API_KEY` is in effect (named, never
|
|
88
|
+
shown).
|
|
89
|
+
- **Each Fling** you signed in to, the current one marked: whether its `/.well-known/fling`
|
|
90
|
+
answers, the release it runs against the CLI's, whether your API key is still accepted, and the
|
|
91
|
+
features it reports.
|
|
92
|
+
- **Claude Code:** `claude` on your PATH, the Fling plugin (installed, enabled, its version against
|
|
93
|
+
the CLI's) and the `fling` marketplace.
|
|
94
|
+
- **Claude Desktop:** whether the extension is installed, enabled, and its version.
|
|
95
|
+
|
|
96
|
+
It only reads: it changes nothing, and each request has a short timeout. `--json` prints
|
|
97
|
+
`{ ok, checks: [{ area, id, status, message, fix?, server? }] }`. The exit code is 1 when any check
|
|
98
|
+
is a problem.
|
|
48
99
|
|
|
49
100
|
To sign in only, use `fling login <url>` (the URL is remembered: later `fling login` needs none).
|
|
50
101
|
There is no default server: until you log in, commands say to run `fling login <url>`.
|
|
@@ -94,7 +145,9 @@ What you can fling:
|
|
|
94
145
|
- **A single `.html`/`.htm` file**, served as the site's `index.html`.
|
|
95
146
|
- **A `.zip`**: extracted (paths that would escape the folder are refused), `__MACOSX/` and dotfiles
|
|
96
147
|
skipped (dotfiles such as `.env` are listed), and a single top-level folder unwrapped.
|
|
97
|
-
- **
|
|
148
|
+
- **A single Markdown file** (`.md`, `.markdown`), on a Fling that renders Markdown (the
|
|
149
|
+
`markdown` capability): its rendered page is the site's home page.
|
|
150
|
+
- **Any other file** (`.pdf`, `.svg`, `.png`…), served next to a small generated `index.html`
|
|
98
151
|
that shows it (images, PDF, video, audio) or links to it.
|
|
99
152
|
|
|
100
153
|
A file's default site name comes from its name, without the extension or a browser's ` (1)`
|
|
@@ -105,21 +158,23 @@ does; see below).
|
|
|
105
158
|
|
|
106
159
|
- Re-fling to update. Identical content is a no-op, and content you deployed before is restored
|
|
107
160
|
instantly without uploading.
|
|
108
|
-
- **Publish one folder of a site** with `--path` (and `--name`): `fling deploy ./
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
161
|
+
- **Publish one folder of a site as its Path** with `--path` (and `--name`): `fling deploy ./plan
|
|
162
|
+
--name payments-plans --path PAY-412` serves the plan at `https://payments-plans.<sites
|
|
163
|
+
domain>/PAY-412/`. A Path is one top-level folder with its own versions, rollback, owners and
|
|
164
|
+
publishers; publishing it never touches the rest of the site or its other Paths, so teammates
|
|
165
|
+
publishing different Paths never collide. The first publish makes the Path, with you as its
|
|
166
|
+
owner. `--path` takes one folder: nested folders (`reports/2026`) are refused, so publish them as
|
|
167
|
+
part of their top-level folder. A folder pulled with `fling pull --path` deploys back to its
|
|
168
|
+
Path. On a Fling without path publishing (`pathPublish`) the CLI refuses rather than replace the
|
|
169
|
+
whole site. See [Paths](#paths).
|
|
115
170
|
- **Change a site you can open** with `fling pull <name> [dir]`: it downloads the current version
|
|
116
171
|
into `dir` (default `./<name>`) with a site link, `.fling-site.json`, naming the server, the site
|
|
117
172
|
and the version pulled. `fling deploy <dir>` then publishes to that site on that version and
|
|
118
173
|
uploads only what changed (`3 changed, 1 removed`). If someone published the site since you
|
|
119
174
|
pulled, it stops (`base_changed`) rather than overwrite their work: pull again into another
|
|
120
175
|
folder and redo your change, or `fling deploy <dir> --force` to replace what they published.
|
|
121
|
-
`--path <folder>` pulls one
|
|
122
|
-
publishers). Anyone signed in who can open the site may pull it; only its owners and publishers
|
|
176
|
+
`--path <folder>` pulls one of the site's Paths, its files at the top of `dir`; `--version-id
|
|
177
|
+
<id>` another version (owners and publishers). Anyone signed in who can open the site may pull it; only its owners and publishers
|
|
123
178
|
may deploy. A folder that isn't empty needs `--force`. On a Fling without the `pull` capability
|
|
124
179
|
the CLI says so.
|
|
125
180
|
- **Fling never publishes dotfiles, gitignored files, secret files (keys, certs, credentials) or
|
|
@@ -201,15 +256,15 @@ and a taken name fails (exit 1) with suggestions rather than picking another nam
|
|
|
201
256
|
|---|---|
|
|
202
257
|
| `fling ls [--archived] [--sort updated\|created\|name]` | your sites, last updated first (`created`: newest first; `name`: A–Z) |
|
|
203
258
|
| `fling ls --shared [--sort …]` | the restricted sites others have shared with you: owner, and how (your address or a group) |
|
|
204
|
-
| `fling info <name>` / `fling versions <name
|
|
259
|
+
| `fling info <name>` / `fling versions <name> [--path <folder>]` | details and version history, with who published each version; `--path`: a Path's own versions |
|
|
205
260
|
| `fling pull <name> [dir] [--path <folder>] [--version-id <id>] [--force]` | download a site's files to change them; `fling deploy <dir>` publishes on the version pulled |
|
|
206
|
-
| `fling files <name> [versionId]` | the files in the live version (or an earlier one) |
|
|
207
|
-
| `fling rollback <name> <versionId
|
|
261
|
+
| `fling files <name> [versionId] [--path <folder>]` | the files in the live version (or an earlier one), or a Path's |
|
|
262
|
+
| `fling rollback <name> <versionId> [--path <folder>]` | serve an earlier version (of the site, or of one Path) |
|
|
208
263
|
| `fling share <name> [--refresh] [--revoke]` | public share link: print or create it, rotate it, or remove it |
|
|
209
264
|
| `fling visibility <name> private\|public` | require sign-in, or not (private again: the access it had) |
|
|
210
265
|
| `fling access <name> [--only-me \| --members \| --public] [--add <emails>] [--remove <emails>] [--group <slugs>] [--remove-group <slugs>] [--clear]` | who can open a site: only you, listed people and groups, everyone signed in, or anyone |
|
|
211
|
-
| `fling owners <name> [--add <emails>] [--remove <emails>] [--set <emails>] [--group <slugs>] [--remove-group <slugs>]` | who owns a site, or change it |
|
|
212
|
-
| `fling publishers <name> [--add …] [--remove …] [--set …] [--group …] [--remove-group …]` | who publishes a site without owning it, or change it |
|
|
266
|
+
| `fling owners <name> [--add <emails>] [--remove <emails>] [--set <emails>] [--group <slugs>] [--remove-group <slugs>] [--path <folder>]` | who owns a site (or a Path), or change it |
|
|
267
|
+
| `fling publishers <name> [--add …] [--remove …] [--set …] [--group …] [--remove-group …] [--path <folder>]` | who publishes a site (or a Path) without owning it, or change it |
|
|
213
268
|
| `fling archive <name>` / `fling unarchive <name>` | take offline and keep the files, or bring back |
|
|
214
269
|
| `fling rm <name> [--yes]` | delete permanently |
|
|
215
270
|
|
|
@@ -287,6 +342,46 @@ admin for an admin's view), and `fling info` its Owners, Publishers and You. As
|
|
|
287
342
|
commands print `{ name, role, owners, publishers }`, each list `{ emails: [{ email, known, guest?
|
|
288
343
|
}], groups: [{ slug, name, size }] }`.
|
|
289
344
|
|
|
345
|
+
### Paths
|
|
346
|
+
|
|
347
|
+
A **Path** is a top-level folder of a site published on its own, such as one plan per ticket on a
|
|
348
|
+
team's site: `fling deploy ./plan --name payments-plans --path PAY-412`. Each Path has its own
|
|
349
|
+
versions, rollback, owners and publishers, and is served at `<site>/<folder>/`. Who can open it is
|
|
350
|
+
the site's. Its owners and publishers, and the site's owners, can publish it, roll it back and
|
|
351
|
+
change it; the site's publishers can make new Paths. On a Fling with Paths (the `paths`
|
|
352
|
+
capability):
|
|
353
|
+
|
|
354
|
+
```sh
|
|
355
|
+
fling paths payments-plans # its Paths: folder, title, version, state, can you publish, updated
|
|
356
|
+
fling versions payments-plans --path PAY-412 # the Path's own versions (* = live)
|
|
357
|
+
fling files payments-plans --path PAY-412 # the files of its live version (or give a version id)
|
|
358
|
+
fling rollback payments-plans <versionId> --path PAY-412 # roll back only the Path
|
|
359
|
+
fling owners payments-plans --path PAY-412 --add cat@example.com
|
|
360
|
+
fling publishers payments-plans --path PAY-412 --add bob@example.com
|
|
361
|
+
fling paths archive payments-plans PAY-412 # take it off the site (404), keep its versions; `paths unarchive` brings it back
|
|
362
|
+
fling paths delete payments-plans PAY-412 # delete it and its versions (asks first unless --yes)
|
|
363
|
+
fling pull payments-plans --path PAY-412 # its files, to change and deploy back to the Path
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**The home page.** A site's home page (its root `index.html`) can list its Paths, three ways:
|
|
367
|
+
|
|
368
|
+
- **Default**: with no `index.html` of its own, the site's home page is a listing of its live
|
|
369
|
+
Paths. A site whose first publish is a Path gets one. Nothing to do.
|
|
370
|
+
- **Custom**: your own `index.html` with a Paths block, which Fling fills with the live Paths
|
|
371
|
+
whenever one changes (and serves as JSON at `/_fling-paths.json`). `fling paths init [dir]
|
|
372
|
+
--template plans|docs|reports|minimal [--title T]` writes a starter (it never replaces an
|
|
373
|
+
`index.html` without `--force`); adapt it, keeping the block, check it with `fling paths check
|
|
374
|
+
[dir|file]` (errors exit 1, warnings are printed), then deploy the folder as the site root,
|
|
375
|
+
without `--path`. The block is the bare marker `<!-- fling:paths -->` (Fling's default list,
|
|
376
|
+
styled by your page) or a template, `<!-- fling:paths sort=updated --> <a href="{{href}}">{{title}}</a>
|
|
377
|
+
<!-- fling:empty --> None yet. <!-- /fling:paths -->`, whose item repeats per Path with
|
|
378
|
+
`{{href}} {{folder}} {{title}} {{updated}} {{date}} {{version}}`. Options: `sort=updated|oldest|folder|folder-desc`,
|
|
379
|
+
`nocontrols`, `nostyle`; `<!-- fling:paths-controls -->` places the search and sort controls.
|
|
380
|
+
- **None**: an `index.html` without a Paths block lists no Paths, and a deploy says so.
|
|
381
|
+
|
|
382
|
+
With `--json`, `fling paths` prints `{ name, paths: [{ folder, title, url, currentVersionId,
|
|
383
|
+
archived, owners?, publishers?, canPublish, createdAt, updatedAt }] }`.
|
|
384
|
+
|
|
290
385
|
### Groups
|
|
291
386
|
|
|
292
387
|
A group is a named list of people, such as a team, that anyone signed in can use in a site's
|
|
@@ -346,8 +441,10 @@ fling responses my-app --format csv -o labels.csv # the export: json, j
|
|
|
346
441
|
- `fling deploy` checks the file against the folder's pages and stops on errors. After the deploy
|
|
347
442
|
it lists each form and the pages it applies to (`forms` in `--json`). Without the file, it ends
|
|
348
443
|
with one line on adding a form (`formsHint` in `--json`; `--quiet` leaves it out).
|
|
349
|
-
- Without the file, deploying a whole site removes its forms. A
|
|
350
|
-
|
|
444
|
+
- Without the file, deploying a whole site removes its forms. A pulled folder keeps them, unless it
|
|
445
|
+
was pulled with a `fling.forms.json` you have since deleted. Forms are the site's: a `--path`
|
|
446
|
+
deploy leaves them as they are and refuses a folder with `fling.forms.json`. Deploy the forms with
|
|
447
|
+
the site's root, with `paths` patterns that reach the Path's pages (`PAY-412/**`).
|
|
351
448
|
- `fling pull` writes the site's `fling.forms.json` back into the folder.
|
|
352
449
|
- On a form with `"visibility": "own"`, reviewers see only their own answers; the site's owners see
|
|
353
450
|
everyone's.
|
|
@@ -382,7 +479,8 @@ another server (a remembered one brings its key; see [Several Flings](#several-f
|
|
|
382
479
|
Environment: `FLING_API_KEY`, `FLING_URL`, `FLING_CONFIG_DIR`, `FLING_DEBUG`, `FLING_DOWNLOADS_DIR`
|
|
383
480
|
(where the MCP server looks for files given by name first), `FLING_ADD_SERVER` (a Fling the MCP
|
|
384
481
|
server adds to the remembered ones when it starts), `FLING_NO_WAIT=1` (after a deploy or a new share
|
|
385
|
-
link, don't wait the few seconds it takes to reach every edge)
|
|
482
|
+
link, don't wait the few seconds it takes to reach every edge), `FLING_NO_UPDATE_CHECK` (never say
|
|
483
|
+
that a newer Fling release is out; see [Staying up to date](#staying-up-to-date)).
|
|
386
484
|
|
|
387
485
|
## Claude Code plugin and MCP
|
|
388
486
|
|
|
@@ -422,14 +520,14 @@ accepts).
|
|
|
422
520
|
The MCP tools:
|
|
423
521
|
|
|
424
522
|
- `fling_deploy`: a folder, `.html`, `.zip` or other file on this computer, by path or just its
|
|
425
|
-
name (looked up like the CLI does). `sitePath` (with `name`) publishes it
|
|
426
|
-
site
|
|
523
|
+
name (looked up like the CLI does). `sitePath` (with `name`) publishes it as that Path of the
|
|
524
|
+
site, the rest untouched, like `--path`. A folder pulled with `fling pull` or `fling_pull` deploys
|
|
427
525
|
on the version pulled, like the CLI; `force: true` publishes over whatever is live.
|
|
428
526
|
- `fling_pull`: downloads a site into a folder on this computer (default
|
|
429
527
|
`~/Documents/Claude/fling/<name>`) to change it and deploy it again with `fling_deploy`.
|
|
430
528
|
- `fling_read_files`: a site's files inline, a page at a time, for reading without a download.
|
|
431
529
|
- `fling_publish`: files passed inline, for content Claude wrote in the conversation. It has the same
|
|
432
|
-
definition as the remote connector's tool; `path` publishes them
|
|
530
|
+
definition as the remote connector's tool; `path` publishes them as that Path of the site;
|
|
433
531
|
`base` (a version from `fling_read_files`) sends only the files that changed, and `remove` names
|
|
434
532
|
files to delete.
|
|
435
533
|
- `fling_find_files`: recent `.html`/`.zip` files and folders with an `index.html` in those folders,
|
|
@@ -439,6 +537,12 @@ The MCP tools:
|
|
|
439
537
|
Fling, including a new one, which becomes current only if none is.
|
|
440
538
|
- `fling_servers`: lists the Flings on this computer (address, name, who is signed in, which is
|
|
441
539
|
current), read when called. `{use: <server>}` makes one current, the same as `fling use`.
|
|
540
|
+
- `fling_doctor`: the checks of `fling doctor`, read-only, as lines and data. Claude calls it when
|
|
541
|
+
something about Fling doesn't work (sign-in, tools missing, versions) and tells you the fixes.
|
|
542
|
+
- `fling_paths` (a site's Paths, and what its home page does with them) where a Fling has Paths,
|
|
543
|
+
and `fling_paths_template` and `fling_paths_check` (a starter home page with a Paths block, and
|
|
544
|
+
its check), which need no Fling. `fling_info`, `fling_files` and `fling_rollback` take `path` to
|
|
545
|
+
act on one Path.
|
|
442
546
|
- `fling_check_name`, `fling_list`, `fling_info`, `fling_files`, `fling_share`,
|
|
443
547
|
`fling_set_visibility`, `fling_archive`, `fling_rollback`, `fling_delete` (needs
|
|
444
548
|
`confirm: true`), `fling_whoami`, the comment tools when a Fling has comments, the forms tools when it has forms
|
|
@@ -454,6 +558,11 @@ The MCP tools:
|
|
|
454
558
|
|
|
455
559
|
Results that give URLs (deploys, publishes, comments) end with the Fling they went to.
|
|
456
560
|
|
|
561
|
+
**Updates.** When a Fling the MCP server knows runs a newer release than it, its instructions say
|
|
562
|
+
so, and so does the first `fling_publish` or `fling_deploy` result of the session on that Fling.
|
|
563
|
+
Claude then suggests the update command (`npm i -g @nearform/fling@latest && fling setup`, then
|
|
564
|
+
restart Claude): inside Claude you never see the CLI's own update line.
|
|
565
|
+
|
|
457
566
|
The MCP server never prompts:
|
|
458
567
|
|
|
459
568
|
- **Names.** Without a `name`, `fling_deploy` uses the generated name and fails with suggestions if
|