@feralfile/cli 1.5.0 → 2.0.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 +6 -11
- package/config.json.example +0 -65
- package/dist/index.js +1 -3
- package/dist/package.json +3 -4
- package/dist/src/commands/config.js +15 -13
- package/dist/src/commands/find.js +55 -4
- package/dist/src/commands/play.js +55 -0
- package/dist/src/commands/setup.js +1 -73
- package/dist/src/commands/status.js +0 -13
- package/dist/src/config.js +3 -126
- package/dist/src/main.js +2 -361
- package/dist/src/utilities/ff1-device.js +55 -0
- package/dist/src/utilities/marketplace-url.js +25 -0
- package/dist/src/utilities/playlist-builder.js +63 -16
- package/dist/src/utilities/raster-client.js +30 -1
- package/docs/CONFIGURATION.md +0 -34
- package/docs/EXAMPLES.md +206 -215
- package/docs/PROJECT_SPEC.md +20 -18
- package/docs/README.md +51 -104
- package/package.json +3 -4
- package/dist/src/ai-orchestrator/index.js +0 -1040
- package/dist/src/ai-orchestrator/registry.js +0 -96
- package/dist/src/commands/chat.js +0 -189
- package/dist/src/intent-parser/index.js +0 -1393
- package/dist/src/intent-parser/utils.js +0 -116
- package/docs/FUNCTION_CALLING.md +0 -100
package/docs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ff-cli Documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ff-cli is a set of deterministic commands for building DP-1 (Display Protocol 1) playlists and playing them on an Art Computer. There's no built-in chat — natural language belongs in your coding agent (Claude Code, Codex), which drives ff-cli through the `ff-control` skill. No LLM API key required. This doc covers install, config, and day‑to‑day usage.
|
|
4
4
|
|
|
5
5
|
For project-level planning and future agentic work, see `./PROJECT_SPEC.md`.
|
|
6
6
|
|
|
@@ -42,33 +42,6 @@ ff-cli config validate
|
|
|
42
42
|
|
|
43
43
|
```json
|
|
44
44
|
{
|
|
45
|
-
"defaultModel": "claude",
|
|
46
|
-
"models": {
|
|
47
|
-
"claude": {
|
|
48
|
-
"apiKey": "sk-ant-your-api-key-here",
|
|
49
|
-
"baseURL": "https://api.anthropic.com/v1/",
|
|
50
|
-
"model": "claude-sonnet-4-6",
|
|
51
|
-
"supportsFunctionCalling": true
|
|
52
|
-
},
|
|
53
|
-
"grok": {
|
|
54
|
-
"apiKey": "xai-your-api-key-here",
|
|
55
|
-
"baseURL": "https://api.x.ai/v1",
|
|
56
|
-
"model": "grok-beta",
|
|
57
|
-
"supportsFunctionCalling": true
|
|
58
|
-
},
|
|
59
|
-
"gpt": {
|
|
60
|
-
"apiKey": "sk-your-openai-key-here",
|
|
61
|
-
"baseURL": "https://api.openai.com/v1",
|
|
62
|
-
"model": "gpt-4o",
|
|
63
|
-
"supportsFunctionCalling": true
|
|
64
|
-
},
|
|
65
|
-
"gemini": {
|
|
66
|
-
"apiKey": "your-gemini-key-here",
|
|
67
|
-
"baseURL": "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
68
|
-
"model": "gemini-2.5-flash",
|
|
69
|
-
"supportsFunctionCalling": true
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
45
|
"defaultDuration": 10,
|
|
73
46
|
"playlist": {
|
|
74
47
|
"privateKey": "your_ed25519_private_key_hex_or_base64_here"
|
|
@@ -92,13 +65,13 @@ See `./CONFIGURATION.md` for environment variable mappings.
|
|
|
92
65
|
## Quick Start
|
|
93
66
|
|
|
94
67
|
```bash
|
|
95
|
-
#
|
|
96
|
-
ff-cli
|
|
68
|
+
# Resolve a URL, on-chain coords, or wallet and build a playlist
|
|
69
|
+
ff-cli find https://www.artblocks.io/collection/ringers-by-dmitri-cherniak -o playlist.json
|
|
97
70
|
|
|
98
|
-
#
|
|
99
|
-
ff-cli
|
|
71
|
+
# Build and play it on your FF1 in one step
|
|
72
|
+
ff-cli find https://objkt.com/tokens/hicetnunc/111068 --play
|
|
100
73
|
|
|
101
|
-
#
|
|
74
|
+
# Build from pre-structured params (JSON file or stdin)
|
|
102
75
|
ff-cli build examples/params-example.json -o playlist.json
|
|
103
76
|
```
|
|
104
77
|
|
|
@@ -106,38 +79,26 @@ For development in this repo:
|
|
|
106
79
|
|
|
107
80
|
```bash
|
|
108
81
|
npm run build
|
|
109
|
-
node dist/index.js
|
|
82
|
+
node dist/index.js find https://objkt.com/tokens/hicetnunc/111068 --play
|
|
110
83
|
```
|
|
111
84
|
|
|
112
85
|
If you're running from source without a build, use:
|
|
113
86
|
|
|
114
87
|
```bash
|
|
115
|
-
npm run dev --
|
|
88
|
+
npm run dev -- find https://objkt.com/tokens/hicetnunc/111068 --play
|
|
116
89
|
```
|
|
117
90
|
|
|
118
|
-
##
|
|
119
|
-
|
|
120
|
-
The model orchestrates; deterministic tools keep us honest and DP1‑conformant.
|
|
91
|
+
## Two ways to build a playlist
|
|
121
92
|
|
|
122
|
-
|
|
123
|
-
2. Orchestration: The LLM parses your prompt and calls tools that:
|
|
124
|
-
- Fetch NFT metadata via OSS libs (`viem` for Ethereum, `@taquito/taquito` for Tezos)
|
|
125
|
-
- Validate DP1 schema with `dp1-js`
|
|
126
|
-
- Build a DP1 playlist envelope deterministically
|
|
127
|
-
- Optionally sign with Ed25519 (canonical JSON via `dp1-js`)
|
|
128
|
-
3. Preview/send: Send to an FF1 on your LAN over HTTP (recommended). Point `ff1Devices.devices[].host` at a local relay if needed.
|
|
129
|
-
4. Publish: Optional feed/registry publishing via the `publish` command.
|
|
93
|
+
ff-cli is deterministic: no chat, no model orchestration. There are two entry points for assembling a playlist.
|
|
130
94
|
|
|
131
|
-
|
|
95
|
+
1. **`ff-cli find "<input>"`** — resolve a marketplace URL, raw `chain:contract:tokenId`, or wallet address into a playable DP-1 playlist. Add `--play` to build and play in one step. This is the fastest path for a single artwork, a collection/series, or a wallet.
|
|
96
|
+
2. **`ff-cli build <params.json>`** — build from pre-structured `requirements` and `playlistSettings` (JSON file or stdin). Use this when you already have the contract, token IDs, feed names, or artwork ids and want explicit control over ordering, durations, and title.
|
|
132
97
|
|
|
133
|
-
-
|
|
134
|
-
- **OSS‑first**: `viem` and `@taquito/taquito`, with room for local caching.
|
|
135
|
-
- **Relay**: Swap the example host for a local Node/Hono relay; avoid vendor lock‑in.
|
|
98
|
+
Both paths run the same deterministic pipeline: fetch metadata, assemble a DP-1 envelope, and validate it. Validation rejects malformed data rather than passing it through. Natural language lives in your coding agent (Claude Code, Codex) via the `ff-control` skill, which translates a request into one of these two commands.
|
|
136
99
|
|
|
137
100
|
## Commands (cheat sheet)
|
|
138
101
|
|
|
139
|
-
- `chat [content]` – AI-driven natural language playlists
|
|
140
|
-
- Options: `-o, --output <file>`, `-m, --model <name>`, `-d, --device <name>`, `-v, --verbose`
|
|
141
102
|
- `build [params.json]` – Deterministic build from JSON or stdin
|
|
142
103
|
- Options: `-o, --output <file>`, `-v, --verbose`
|
|
143
104
|
- `validate <file-or-url>` – Validate playlist structure only
|
|
@@ -164,76 +125,63 @@ Notes:
|
|
|
164
125
|
|
|
165
126
|
## Usage Highlights
|
|
166
127
|
|
|
167
|
-
###
|
|
128
|
+
### Find an artwork
|
|
168
129
|
|
|
169
|
-
|
|
170
|
-
npm run dev -- chat "Get 3 works from reas.eth"
|
|
171
|
-
npm run dev -- chat "Get 3 works from einstein-rosen.tez"
|
|
172
|
-
npm run dev -- chat "Get tokens 52932,52457 from Ethereum contract 0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0" -o playlist.json
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Feed playlists (for example `Unsupervised`, `Social Codes`) depend on your configured feed servers and network reachability.
|
|
176
|
-
Use exact or near-exact playlist titles for best results.
|
|
177
|
-
|
|
178
|
-
If you prompt with a bare EVM address (for example `from 0x...`), the CLI now tries owner-address lookup first, then automatically falls back to contract lookup when no owned tokens are found.
|
|
179
|
-
|
|
180
|
-
### One-shot complex prompt
|
|
181
|
-
|
|
182
|
-
The model reads your request via the intent parser and turns it into structured `requirements` and `playlistSettings` (including shuffle, durations, and device). You can do everything in one line:
|
|
130
|
+
`ff-cli find` resolves a URL, raw `chain:contract:tokenId`, or wallet address into a playable DP-1 playlist.
|
|
183
131
|
|
|
184
132
|
```bash
|
|
185
|
-
#
|
|
186
|
-
|
|
187
|
-
```
|
|
133
|
+
# Paste a URL and play it on your FF1
|
|
134
|
+
ff-cli find https://www.artblocks.io/collection/ringers-by-dmitri-cherniak --play
|
|
188
135
|
|
|
189
|
-
|
|
136
|
+
# Tezos / hic et nunc via Objkt (the alias resolves to a KT1 contract)
|
|
137
|
+
ff-cli find https://objkt.com/tokens/hicetnunc/111068 --play
|
|
190
138
|
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
- If `deviceName` is present, the CLI will send the verified playlist to that FF1 device.
|
|
194
|
-
- If `feedServer` is present (via "publish to my feed"), the CLI will publish the playlist to the selected feed server.
|
|
139
|
+
# Save without playing
|
|
140
|
+
ff-cli find ethereum:0xababababab20053426ad1c782de9ea8444358070:5001410 -o send-receive.json
|
|
195
141
|
|
|
196
|
-
|
|
142
|
+
# Wallet address (owner lookup); cap the number of tokens with --limit
|
|
143
|
+
ff-cli find 0xaeE022552B539dB18297D7481b6D547C622488B3 -l 10 -o wallet.json
|
|
197
144
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
The intent parser recognizes publishing keywords and can both display and publish in one command:
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
# Build and publish
|
|
204
|
-
npm run dev -- chat "Build playlist from Ethereum contract 0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0 with tokens 52932 and 52457; publish to my feed" -o playlist.json -v
|
|
205
|
-
|
|
206
|
-
# Display on Art Computer AND publish to feed
|
|
207
|
-
npm run dev -- chat "Get 3 from Unsupervised; shuffle; send to my Art Computer and publish to feed" -o playlist.json -v
|
|
145
|
+
# Build and publish to a configured feed server
|
|
146
|
+
ff-cli find https://objkt.com/tokens/hicetnunc/111068 --publish
|
|
208
147
|
```
|
|
209
148
|
|
|
210
|
-
|
|
211
|
-
`https://github.com/feral-file/dp1-feed/tree/main/playlists`
|
|
149
|
+
Sources: Art Blocks, Objkt, fxhash, OpenSea, SuperRare, Feral File, Neort, Verse, raw on-chain coordinates, and wallet addresses. Run `ff-cli find --help` for the full input list.
|
|
212
150
|
|
|
213
|
-
|
|
151
|
+
### Build from structured params
|
|
214
152
|
|
|
215
153
|
```bash
|
|
216
|
-
|
|
154
|
+
ff-cli build params.json -o playlist.json
|
|
155
|
+
cat params.json | ff-cli build -o playlist.json
|
|
217
156
|
```
|
|
218
157
|
|
|
219
|
-
|
|
158
|
+
`params.json` should include `requirements` and optional `playlistSettings`. See `examples/params-example.json`. Each requirement has a `type`:
|
|
220
159
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
160
|
+
- `build_playlist` — `blockchain`, `contractAddress`, `tokenIds`, optional `quantity`
|
|
161
|
+
- `feral_file_artwork` — `artworkId` (a Feral File public artwork id or `/exhibitions/artwork/{id}` URL)
|
|
162
|
+
- `query_address` — `ownerAddress`, optional `quantity` (random selection)
|
|
163
|
+
- `fetch_feed` — `playlistName`, `quantity`
|
|
225
164
|
|
|
226
|
-
|
|
165
|
+
`playlistSettings` may set `title`, `durationPerItem`, `preserveOrder` (set `false` to shuffle), and `deviceName`. Feed playlists (for example `Unsupervised`, `Social Codes`) depend on your configured feed servers and network reachability; use exact or near-exact playlist titles for best results.
|
|
227
166
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"requirements": [
|
|
170
|
+
{
|
|
171
|
+
"type": "build_playlist",
|
|
172
|
+
"blockchain": "ethereum",
|
|
173
|
+
"contractAddress": "0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0",
|
|
174
|
+
"tokenIds": ["52932", "52457"]
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"playlistSettings": {
|
|
178
|
+
"title": "My Mix",
|
|
179
|
+
"preserveOrder": false,
|
|
180
|
+
"durationPerItem": 7
|
|
181
|
+
}
|
|
182
|
+
}
|
|
233
183
|
```
|
|
234
184
|
|
|
235
|
-
`params.json` should include `requirements` and optional `playlistSettings`. See `examples/params-example.json`.
|
|
236
|
-
|
|
237
185
|
### Validate, sign, and play
|
|
238
186
|
|
|
239
187
|
```bash
|
|
@@ -348,7 +296,6 @@ Setup preserves existing devices when adding new ones. See selection rules and e
|
|
|
348
296
|
|
|
349
297
|
## Links
|
|
350
298
|
|
|
351
|
-
- Function calling details: `./FUNCTION_CALLING.md`
|
|
352
299
|
- Examples: `./EXAMPLES.md`
|
|
353
300
|
- Release assets: `./RELEASING.md`
|
|
354
301
|
- DP1 spec: `https://github.com/display-protocol/dp1`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feralfile/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI for building DP-1 playlists of digital art
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "CLI for building, signing, and playing DP-1 playlists of digital art on Feral File devices",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/feral-file/ff-cli.git"
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"nft",
|
|
52
52
|
"playlist",
|
|
53
53
|
"dp1",
|
|
54
|
-
"
|
|
54
|
+
"feralfile",
|
|
55
55
|
"cli"
|
|
56
56
|
],
|
|
57
57
|
"author": "",
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"dp1-js": "2.0.0",
|
|
66
66
|
"ff1": "^1.0.0",
|
|
67
67
|
"fuzzysort": "^3.1.0",
|
|
68
|
-
"openai": "^4.58.1",
|
|
69
68
|
"viem": "^2.38.2"
|
|
70
69
|
},
|
|
71
70
|
"devDependencies": {
|