@funnelsgrove/cli 0.1.0 → 0.1.2
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 +7 -7
- package/dist/cli.js +37 -37
- package/package.json +2 -2
- package/template_docs/agent.md +3 -3
package/README.md
CHANGED
|
@@ -4,24 +4,24 @@ Install:
|
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install -g @funnelsgrove/cli
|
|
7
|
-
|
|
7
|
+
fgrove login
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
Set the active project and funnel:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
fgrove use --project claimbee --funnel claimbee-ios
|
|
14
|
+
fgrove status
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Common workflow:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
fgrove sync down --dir ./claimbee-ios
|
|
21
21
|
cd ./claimbee-ios
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
fgrove docs
|
|
23
|
+
fgrove sync up --message 'Update funnel copy'
|
|
24
|
+
fgrove publish --env preview
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
The package also keeps the longer `funnelsgrove` command as a compatibility alias.
|
package/dist/cli.js
CHANGED
|
@@ -30,7 +30,7 @@ const getConfigPath = () => {
|
|
|
30
30
|
const readAuthToken = async () => {
|
|
31
31
|
const token = await loadAuthToken(getConfigPath());
|
|
32
32
|
if (!token) {
|
|
33
|
-
throw new Error('Not logged in. Run `
|
|
33
|
+
throw new Error('Not logged in. Run `fgrove login` first.');
|
|
34
34
|
}
|
|
35
35
|
return token;
|
|
36
36
|
};
|
|
@@ -173,7 +173,7 @@ const resolveSyncTarget = async (input) => {
|
|
|
173
173
|
? await resolveFunnelId(input.token, workspaceId, input.funnel)
|
|
174
174
|
: manifest?.funnelId || active?.funnelId;
|
|
175
175
|
if (!funnelId) {
|
|
176
|
-
throw new Error('No active funnel. Run `
|
|
176
|
+
throw new Error('No active funnel. Run `fgrove use --funnel <id-or-slug>` or pass `--funnel`.');
|
|
177
177
|
}
|
|
178
178
|
return {
|
|
179
179
|
workspaceId,
|
|
@@ -203,23 +203,23 @@ const printRows = (rows, columns) => {
|
|
|
203
203
|
const addExamples = (command, examples) => command.addHelpText('after', `\nExamples:\n${examples.map((example) => ` $ ${example}`).join('\n')}`);
|
|
204
204
|
const program = new Command();
|
|
205
205
|
program
|
|
206
|
-
.name('
|
|
206
|
+
.name('fgrove')
|
|
207
207
|
.description('FunnelsGrove CLI for editing, syncing, and publishing funnels')
|
|
208
208
|
.version('0.1.0')
|
|
209
209
|
.option('--api-url <url>', 'FunnelsGrove tRPC API URL', process.env.FUNNELSGROVE_API_URL || DEFAULT_API_URL)
|
|
210
210
|
.option('--config <path>', 'Auth config path', process.env.FUNNELSGROVE_CONFIG || getDefaultAuthConfigPath());
|
|
211
211
|
addExamples(program, [
|
|
212
|
-
'
|
|
213
|
-
'
|
|
214
|
-
'
|
|
215
|
-
'
|
|
212
|
+
'fgrove login',
|
|
213
|
+
'fgrove use --project claimbee --funnel claimbee-ios',
|
|
214
|
+
'fgrove sync down --dir ./claimbee-ios',
|
|
215
|
+
'fgrove publish --env preview',
|
|
216
216
|
]);
|
|
217
217
|
addExamples(program
|
|
218
218
|
.command('login')
|
|
219
219
|
.description('Authorize this CLI with your FunnelsGrove account')
|
|
220
220
|
.option('--code <code>', '8 digit code from the authorization page'), [
|
|
221
|
-
'
|
|
222
|
-
'
|
|
221
|
+
'fgrove login',
|
|
222
|
+
'fgrove login --api-url http://localhost:3001/trpc',
|
|
223
223
|
])
|
|
224
224
|
.action(async (options) => {
|
|
225
225
|
const request = await callApi({
|
|
@@ -244,7 +244,7 @@ addExamples(program
|
|
|
244
244
|
addExamples(program
|
|
245
245
|
.command('whoami')
|
|
246
246
|
.description('Show the current authenticated user'), [
|
|
247
|
-
'
|
|
247
|
+
'fgrove whoami',
|
|
248
248
|
])
|
|
249
249
|
.action(async () => {
|
|
250
250
|
const token = await readAuthToken();
|
|
@@ -258,9 +258,9 @@ addExamples(program
|
|
|
258
258
|
.option('--project <id-or-slug-or-name>', 'Project id, slug, or name')
|
|
259
259
|
.option('--funnel <id-or-slug-or-name>', 'Funnel id, slug, or name')
|
|
260
260
|
.option('--clear', 'Clear the active CLI context'), [
|
|
261
|
-
'
|
|
262
|
-
'
|
|
263
|
-
'
|
|
261
|
+
'fgrove use --project claimbee --funnel claimbee-ios',
|
|
262
|
+
'fgrove use --workspace acme --project claimbee',
|
|
263
|
+
'fgrove use --clear',
|
|
264
264
|
])
|
|
265
265
|
.action(async (options) => {
|
|
266
266
|
if (options.clear) {
|
|
@@ -292,8 +292,8 @@ addExamples(program
|
|
|
292
292
|
.command('status')
|
|
293
293
|
.description('Show the authenticated user and active CLI context')
|
|
294
294
|
.option('--dir <path>', 'Local source directory for reading sync manifest', '.'), [
|
|
295
|
-
'
|
|
296
|
-
'
|
|
295
|
+
'fgrove status',
|
|
296
|
+
'fgrove status --dir ./claimbee-ios',
|
|
297
297
|
])
|
|
298
298
|
.action(async (options) => {
|
|
299
299
|
const token = await readAuthToken();
|
|
@@ -315,15 +315,15 @@ addExamples(program
|
|
|
315
315
|
}
|
|
316
316
|
});
|
|
317
317
|
const projectsCommand = addExamples(program.command('projects').description('Manage projects'), [
|
|
318
|
-
'
|
|
319
|
-
'
|
|
318
|
+
'fgrove projects list',
|
|
319
|
+
'fgrove projects list --workspace acme',
|
|
320
320
|
]);
|
|
321
321
|
addExamples(projectsCommand
|
|
322
322
|
.command('list')
|
|
323
323
|
.description('List projects in the active or provided workspace')
|
|
324
324
|
.option('--workspace <id-or-slug-or-name>', 'Workspace id, slug, or name'), [
|
|
325
|
-
'
|
|
326
|
-
'
|
|
325
|
+
'fgrove projects list',
|
|
326
|
+
'fgrove projects list --workspace acme',
|
|
327
327
|
])
|
|
328
328
|
.action(async (options) => {
|
|
329
329
|
const token = await readAuthToken();
|
|
@@ -332,15 +332,15 @@ addExamples(projectsCommand
|
|
|
332
332
|
printRows(projects, ['id', 'name', 'slug']);
|
|
333
333
|
});
|
|
334
334
|
const funnelsCommand = addExamples(program.command('funnels').description('Manage funnels'), [
|
|
335
|
-
'
|
|
336
|
-
'
|
|
335
|
+
'fgrove funnels list',
|
|
336
|
+
'fgrove funnels clone --funnel claimbee --name claimbee-ios',
|
|
337
337
|
]);
|
|
338
338
|
addExamples(funnelsCommand
|
|
339
339
|
.command('list')
|
|
340
340
|
.description('List funnels in a workspace')
|
|
341
341
|
.option('--workspace <id-or-slug-or-name>', 'Workspace id, slug, or name'), [
|
|
342
|
-
'
|
|
343
|
-
'
|
|
342
|
+
'fgrove funnels list',
|
|
343
|
+
'fgrove funnels list --workspace acme',
|
|
344
344
|
])
|
|
345
345
|
.action(async (options) => {
|
|
346
346
|
const token = await readAuthToken();
|
|
@@ -354,8 +354,8 @@ addExamples(funnelsCommand
|
|
|
354
354
|
.option('--workspace <id-or-slug-or-name>', 'Workspace id, slug, or name')
|
|
355
355
|
.requiredOption('--funnel <id-or-slug>', 'Source funnel id or slug')
|
|
356
356
|
.requiredOption('--name <name>', 'New funnel name'), [
|
|
357
|
-
'
|
|
358
|
-
'
|
|
357
|
+
'fgrove funnels clone --funnel claimbee --name claimbee-ios',
|
|
358
|
+
'fgrove funnels clone --workspace acme --funnel claimbee --name claimbee-ios',
|
|
359
359
|
])
|
|
360
360
|
.action(async (options) => {
|
|
361
361
|
const token = await readAuthToken();
|
|
@@ -374,8 +374,8 @@ addExamples(funnelsCommand
|
|
|
374
374
|
console.log(`${result.funnel.id}\t${result.funnel.name}\t${result.funnel.slug}`);
|
|
375
375
|
});
|
|
376
376
|
const syncCommand = addExamples(program.command('sync').description('Sync funnel source'), [
|
|
377
|
-
'
|
|
378
|
-
'
|
|
377
|
+
'fgrove sync down --dir ./claimbee-ios',
|
|
378
|
+
'fgrove sync up --message "Update copy"',
|
|
379
379
|
]);
|
|
380
380
|
addExamples(syncCommand
|
|
381
381
|
.command('down')
|
|
@@ -383,8 +383,8 @@ addExamples(syncCommand
|
|
|
383
383
|
.option('--workspace <id-or-slug-or-name>', 'Workspace id, slug, or name')
|
|
384
384
|
.option('--funnel <id-or-slug>', 'Funnel id or slug')
|
|
385
385
|
.requiredOption('--dir <path>', 'Local target directory'), [
|
|
386
|
-
'
|
|
387
|
-
'
|
|
386
|
+
'fgrove sync down --dir ./claimbee-ios',
|
|
387
|
+
'fgrove sync down --funnel claimbee-ios --dir ./claimbee-ios',
|
|
388
388
|
])
|
|
389
389
|
.action(async (options) => {
|
|
390
390
|
const token = await readAuthToken();
|
|
@@ -423,8 +423,8 @@ addExamples(syncCommand
|
|
|
423
423
|
.option('--funnel <id-or-slug>', 'Funnel id or slug')
|
|
424
424
|
.option('--dir <path>', 'Local source directory', '.')
|
|
425
425
|
.option('--message <message>', 'Draft version message'), [
|
|
426
|
-
'
|
|
427
|
-
'
|
|
426
|
+
'fgrove sync up --message "Update hero copy"',
|
|
427
|
+
'fgrove sync up --dir ./claimbee-ios --message "Update paywall"',
|
|
428
428
|
])
|
|
429
429
|
.action(async (options) => {
|
|
430
430
|
const token = await readAuthToken();
|
|
@@ -462,8 +462,8 @@ addExamples(program
|
|
|
462
462
|
.option('--env <preview-or-production>', 'Publish environment', 'preview')
|
|
463
463
|
.option('--domain <domain>', 'Production custom domain')
|
|
464
464
|
.option('--message <message>', 'Publish version message'), [
|
|
465
|
-
'
|
|
466
|
-
'
|
|
465
|
+
'fgrove publish --env preview --message "Preview copy updates"',
|
|
466
|
+
'fgrove publish --env production --domain claimbee.example.com --message "Launch"',
|
|
467
467
|
])
|
|
468
468
|
.action(async (options) => {
|
|
469
469
|
const token = await readAuthToken();
|
|
@@ -497,8 +497,8 @@ addExamples(program
|
|
|
497
497
|
.command('docs')
|
|
498
498
|
.description('Install or refresh local funnel editing docs in a funnel directory')
|
|
499
499
|
.option('--dir <path>', 'Local funnel directory', '.'), [
|
|
500
|
-
'
|
|
501
|
-
'
|
|
500
|
+
'fgrove docs',
|
|
501
|
+
'fgrove docs --dir ./claimbee-ios',
|
|
502
502
|
])
|
|
503
503
|
.action(async (options) => {
|
|
504
504
|
const targetDir = path.resolve(process.cwd(), options.dir);
|
|
@@ -511,8 +511,8 @@ addExamples(program
|
|
|
511
511
|
.requiredOption('--from <template>', 'Template slug from rag-catalog')
|
|
512
512
|
.requiredOption('--app <name>', 'Your app name')
|
|
513
513
|
.option('--output <dir>', 'Output directory'), [
|
|
514
|
-
'
|
|
515
|
-
'
|
|
514
|
+
'fgrove create --from headway-funnel --app ClaimBee',
|
|
515
|
+
'fgrove create --from promova --app ClaimBee --output ./claimbee-funnel',
|
|
516
516
|
])
|
|
517
517
|
.action(async (options) => {
|
|
518
518
|
const { from: templateSlug, app: appName, output } = options;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelsgrove/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "FunnelsGrove command-line tools for editing, syncing, and publishing funnels",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"fgrove": "dist/cli.js",
|
|
8
8
|
"funnelsgrove": "dist/cli.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
package/template_docs/agent.md
CHANGED
|
@@ -4,11 +4,11 @@ Use this folder as the local source-of-truth guide when editing a synced Funnels
|
|
|
4
4
|
|
|
5
5
|
## Workflow
|
|
6
6
|
|
|
7
|
-
1. Run `
|
|
7
|
+
1. Run `fgrove status` and confirm the active project and funnel.
|
|
8
8
|
2. Keep edits inside the synced funnel tree.
|
|
9
9
|
3. Run the funnel's local checks before syncing.
|
|
10
|
-
4. Run `
|
|
11
|
-
5. Run `
|
|
10
|
+
4. Run `fgrove sync up --message '<summary>'`.
|
|
11
|
+
5. Run `fgrove publish --env preview --message '<summary>'` and verify the preview.
|
|
12
12
|
6. Publish production only when explicitly requested.
|
|
13
13
|
|
|
14
14
|
## Topics
|