@lark-sh/cli 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +213 -106
  2. package/package.json +8 -2
package/dist/index.js CHANGED
@@ -265,9 +265,12 @@ ${authUrl}
265
265
 
266
266
  // src/commands/auth.ts
267
267
  function registerAuthCommands(program2) {
268
- program2.command("login").description(
269
- "Log in to Lark via your browser.\n\nOpens the Lark dashboard where you authorize the CLI.\nYour session is saved to ~/.lark/config.json.\n\nExample:\n $ lark login"
270
- ).action(async () => {
268
+ program2.command("login").description("Log in to Lark via your browser").addHelpText("after", `
269
+ Opens the Lark dashboard where you authorize the CLI.
270
+ Your session is saved to ~/.lark/config.json.
271
+
272
+ Example:
273
+ $ lark login`).action(async () => {
271
274
  try {
272
275
  const { name, email } = await login();
273
276
  console.log(`Logged in as ${name} (${email})`);
@@ -275,9 +278,9 @@ function registerAuthCommands(program2) {
275
278
  handleError(err, false);
276
279
  }
277
280
  });
278
- program2.command("logout").description(
279
- "Log out and clear the stored session.\n\nExample:\n $ lark logout"
280
- ).action(async () => {
281
+ program2.command("logout").description("Log out and clear the stored session").addHelpText("after", `
282
+ Example:
283
+ $ lark logout`).action(async () => {
281
284
  const json = program2.opts().json;
282
285
  try {
283
286
  const session = getSession();
@@ -297,9 +300,10 @@ function registerAuthCommands(program2) {
297
300
  handleError(err, json);
298
301
  }
299
302
  });
300
- program2.command("whoami").description(
301
- "Show the currently logged-in user.\n\nExamples:\n $ lark whoami\n $ lark whoami --json"
302
- ).action(async () => {
303
+ program2.command("whoami").description("Show the currently logged-in user").addHelpText("after", `
304
+ Examples:
305
+ $ lark whoami
306
+ $ lark whoami --json`).action(async () => {
303
307
  const json = program2.opts().json;
304
308
  try {
305
309
  const user = await admin.getMe();
@@ -316,12 +320,14 @@ function registerAuthCommands(program2) {
316
320
 
317
321
  // src/commands/config.ts
318
322
  function registerConfigCommands(program2) {
319
- const config = program2.command("config").description(
320
- "Manage CLI configuration.\n\nSettings are stored in ~/.lark/config.json."
321
- );
322
- config.command("set-project <id>").description(
323
- "Set the default project for all commands.\n\nOnce set, you can omit --project from other commands.\nThe project ID is verified before saving.\n\nExamples:\n $ lark config set-project my-app\n $ lark config set-project cli-test"
324
- ).action(async (id) => {
323
+ const config = program2.command("config").description("Manage CLI configuration");
324
+ config.command("set-project <id>").description("Set the default project for all commands").addHelpText("after", `
325
+ Once set, you can omit --project from other commands.
326
+ The project ID is verified before saving.
327
+
328
+ Examples:
329
+ $ lark config set-project my-app
330
+ $ lark config set-project cli-test`).action(async (id) => {
325
331
  const json = program2.opts().json;
326
332
  try {
327
333
  const project = await admin.getProject(id);
@@ -335,9 +341,9 @@ function registerConfigCommands(program2) {
335
341
  handleError(err, json);
336
342
  }
337
343
  });
338
- config.command("show").description(
339
- "Show current CLI configuration.\n\nExample:\n $ lark config show"
340
- ).action(() => {
344
+ config.command("show").description("Show current configuration").addHelpText("after", `
345
+ Example:
346
+ $ lark config show`).action(() => {
341
347
  const json = program2.opts().json;
342
348
  const defaultProject = getDefaultProject();
343
349
  if (json) {
@@ -400,12 +406,18 @@ function formatTime(ts) {
400
406
 
401
407
  // src/commands/projects.ts
402
408
  function registerProjectCommands(program2) {
403
- const projects = program2.command("projects").description(
404
- 'Manage Lark projects.\n\nA project is the top-level container for databases, rules, and settings.\nEach project gets a unique ID (DNS-compatible slug) and a secret key.\n\nExamples:\n $ lark projects list\n $ lark projects create "My App"\n $ lark projects show my-app'
405
- );
406
- projects.command("list").description(
407
- "List all your projects.\n\nExamples:\n $ lark projects list\n $ lark projects list --json"
408
- ).action(async () => {
409
+ const projects = program2.command("projects").description("Manage Lark projects").addHelpText("after", `
410
+ A project is the top-level container for databases, rules, and settings.
411
+ Each project gets a unique ID (DNS-compatible slug) and a secret key.
412
+
413
+ Examples:
414
+ $ lark projects list
415
+ $ lark projects create "My App"
416
+ $ lark projects show my-app`);
417
+ projects.command("list").description("List all your projects").addHelpText("after", `
418
+ Examples:
419
+ $ lark projects list
420
+ $ lark projects list --json`).action(async () => {
409
421
  const json = program2.opts().json;
410
422
  try {
411
423
  const { projects: list } = await admin.getProjects();
@@ -425,9 +437,13 @@ function registerProjectCommands(program2) {
425
437
  handleError(err, json);
426
438
  }
427
439
  });
428
- projects.command("create <name>").description(
429
- 'Create a new project.\n\nThe name is used to generate a DNS-compatible project ID.\nFor example, "My App" becomes "my-app".\n\nExamples:\n $ lark projects create "My App"\n $ lark projects create "Game Server" --json'
430
- ).action(async (name) => {
440
+ projects.command("create <name>").description("Create a new project").addHelpText("after", `
441
+ The name is used to generate a DNS-compatible project ID.
442
+ For example, "My App" becomes "my-app".
443
+
444
+ Examples:
445
+ $ lark projects create "My App"
446
+ $ lark projects create "Game Server" --json`).action(async (name) => {
431
447
  const json = program2.opts().json;
432
448
  try {
433
449
  const project = await admin.createProject(name);
@@ -440,9 +456,14 @@ function registerProjectCommands(program2) {
440
456
  handleError(err, json);
441
457
  }
442
458
  });
443
- projects.command("show [id]").description(
444
- "Show project details including secret key and settings.\n\nUses the default project if no ID is given.\n\nExamples:\n $ lark projects show\n $ lark projects show my-app\n $ lark projects show --json"
445
- ).action(async (id) => {
459
+ projects.command("show [id]").description("Show project details").addHelpText("after", `
460
+ Shows the project's settings, secret key, and database counts.
461
+ Uses the default project if no ID is given.
462
+
463
+ Examples:
464
+ $ lark projects show
465
+ $ lark projects show my-app
466
+ $ lark projects show --json`).action(async (id) => {
446
467
  const json = program2.opts().json;
447
468
  try {
448
469
  const projectId = resolveProject(id || program2.opts().project);
@@ -466,9 +487,14 @@ function registerProjectCommands(program2) {
466
487
  handleError(err, json);
467
488
  }
468
489
  });
469
- projects.command("update [id]").description(
470
- 'Update project settings.\n\nPass one or more flags to change settings.\nUses the default project if no ID is given.\n\nExamples:\n $ lark projects update --name "New Name"\n $ lark projects update my-app --ephemeral false\n $ lark projects update --auto-create true --ephemeral true'
471
- ).option("--name <name>", "Project name").option("--ephemeral <bool>", "Enable/disable ephemeral mode (true/false)").option("--auto-create <bool>", "Enable/disable auto-create databases (true/false)").option("--firebase-compat <bool>", "Enable/disable Firebase compatibility (true/false)").option("--firebase-project-id <id>", "Firebase project ID").action(async (id, opts) => {
490
+ projects.command("update [id]").description("Update project settings").option("--name <name>", "Project name").option("--ephemeral <bool>", "Enable/disable ephemeral mode (true/false)").option("--auto-create <bool>", "Enable/disable auto-create databases (true/false)").option("--firebase-compat <bool>", "Enable/disable Firebase compatibility (true/false)").option("--firebase-project-id <id>", "Firebase project ID").addHelpText("after", `
491
+ Pass one or more flags to change settings.
492
+ Uses the default project if no ID is given.
493
+
494
+ Examples:
495
+ $ lark projects update --name "New Name"
496
+ $ lark projects update my-app --ephemeral false
497
+ $ lark projects update --auto-create true --ephemeral true`).action(async (id, opts) => {
472
498
  const json = program2.opts().json;
473
499
  try {
474
500
  const projectId = resolveProject(id || program2.opts().project);
@@ -496,9 +522,12 @@ function registerProjectCommands(program2) {
496
522
  handleError(err, json);
497
523
  }
498
524
  });
499
- projects.command("delete [id]").description(
500
- "Delete a project and all its databases.\n\nThis is irreversible. You must pass --confirm with the project ID.\n\nExamples:\n $ lark projects delete my-app --confirm my-app\n $ lark projects delete --confirm cli-test"
501
- ).option("--confirm <id>", "Confirm deletion by passing the project ID").action(async (id, opts) => {
525
+ projects.command("delete [id]").description("Delete a project and all its databases").option("--confirm <id>", "Confirm deletion by passing the project ID").addHelpText("after", `
526
+ This is irreversible. You must pass --confirm with the project ID.
527
+
528
+ Examples:
529
+ $ lark projects delete my-app --confirm my-app
530
+ $ lark projects delete --confirm cli-test`).action(async (id, opts) => {
502
531
  const json = program2.opts().json;
503
532
  try {
504
533
  const projectId = resolveProject(id || program2.opts().project);
@@ -520,9 +549,13 @@ function registerProjectCommands(program2) {
520
549
  handleError(err, json);
521
550
  }
522
551
  });
523
- projects.command("regenerate-secret [id]").description(
524
- "Regenerate the project secret key.\n\nThe old key is immediately invalidated. Any clients using it\nwill need to be updated.\n\nExamples:\n $ lark projects regenerate-secret\n $ lark projects regenerate-secret my-app"
525
- ).action(async (id) => {
552
+ projects.command("regenerate-secret [id]").description("Regenerate the project secret key").addHelpText("after", `
553
+ The old key is immediately invalidated. Any clients using it
554
+ will need to be updated.
555
+
556
+ Examples:
557
+ $ lark projects regenerate-secret
558
+ $ lark projects regenerate-secret my-app`).action(async (id) => {
526
559
  const json = program2.opts().json;
527
560
  try {
528
561
  const projectId = resolveProject(id || program2.opts().project);
@@ -540,12 +573,22 @@ function registerProjectCommands(program2) {
540
573
 
541
574
  // src/commands/databases.ts
542
575
  function registerDatabaseCommands(program2) {
543
- const databases = program2.command("databases").alias("db").description(
544
- 'Manage databases within a project.\n\nDatabases hold your real-time data. Use "lark data" commands\nto read and write data within a database.\n\nShorthand: "lark db" works the same as "lark databases".\n\nExamples:\n $ lark databases list\n $ lark db create my-database\n $ lark db list --search "user"'
545
- );
546
- databases.command("list").description(
547
- 'List databases in the current project.\n\nExamples:\n $ lark databases list\n $ lark databases list --search "chat"\n $ lark databases list --limit 10 --offset 20\n $ lark --project my-app databases list'
548
- ).option("--search <query>", "Filter databases by ID").option("--limit <n>", "Max results to return", "50").option("--offset <n>", "Number of results to skip", "0").action(async (opts) => {
576
+ const databases = program2.command("databases").alias("db").description("Manage databases within a project").addHelpText("after", `
577
+ Databases hold your real-time data. Use "lark data" commands
578
+ to read and write data within a database.
579
+
580
+ Shorthand: "lark db" works the same as "lark databases".
581
+
582
+ Examples:
583
+ $ lark databases list
584
+ $ lark db create my-database
585
+ $ lark db list --search "user"`);
586
+ databases.command("list").description("List databases in the current project").option("--search <query>", "Filter databases by ID").option("--limit <n>", "Max results to return", "50").option("--offset <n>", "Number of results to skip", "0").addHelpText("after", `
587
+ Examples:
588
+ $ lark databases list
589
+ $ lark databases list --search "chat"
590
+ $ lark databases list --limit 10 --offset 20
591
+ $ lark --project my-app databases list`).action(async (opts) => {
549
592
  const json = program2.opts().json;
550
593
  try {
551
594
  const projectId = resolveProject(program2.opts().project);
@@ -575,9 +618,13 @@ function registerDatabaseCommands(program2) {
575
618
  handleError(err, json);
576
619
  }
577
620
  });
578
- databases.command("create <id>").description(
579
- "Create a new database.\n\nThe ID must be a valid identifier (lowercase, hyphens allowed).\n\nExamples:\n $ lark databases create users\n $ lark databases create game-state\n $ lark db create chat-rooms --json"
580
- ).action(async (id) => {
621
+ databases.command("create <id>").description("Create a new database").addHelpText("after", `
622
+ The ID must be a valid identifier (lowercase, hyphens allowed).
623
+
624
+ Examples:
625
+ $ lark databases create users
626
+ $ lark databases create game-state
627
+ $ lark db create chat-rooms --json`).action(async (id) => {
581
628
  const json = program2.opts().json;
582
629
  try {
583
630
  const projectId = resolveProject(program2.opts().project);
@@ -591,9 +638,12 @@ function registerDatabaseCommands(program2) {
591
638
  handleError(err, json);
592
639
  }
593
640
  });
594
- databases.command("delete <id>").description(
595
- "Delete a database and all its data.\n\nThis is irreversible.\n\nExamples:\n $ lark databases delete old-data\n $ lark db delete test-db"
596
- ).action(async (id) => {
641
+ databases.command("delete <id>").description("Delete a database and all its data").addHelpText("after", `
642
+ This is irreversible.
643
+
644
+ Examples:
645
+ $ lark databases delete old-data
646
+ $ lark db delete test-db`).action(async (id) => {
597
647
  const json = program2.opts().json;
598
648
  try {
599
649
  const projectId = resolveProject(program2.opts().project);
@@ -651,20 +701,26 @@ async function dataRequest(projectId, method, database, path2, body) {
651
701
 
652
702
  // src/commands/data.ts
653
703
  function registerDataCommands(program2) {
654
- const data = program2.command("data").description(
655
- `Read and write data in your databases.
656
-
704
+ const data = program2.command("data").description("Read and write data in your databases").addHelpText("after", `
657
705
  Data is organized as a JSON tree. Use paths like "/" for the
658
706
  root, "/users/alice" for nested data, etc.
659
707
 
660
708
  Examples:
661
709
  $ lark data get mydb /
662
710
  $ lark data set mydb /users/alice '{"name": "Alice"}'
663
- $ lark data watch mydb /messages`
664
- );
665
- data.command("get <database> <path>").description(
666
- 'Get data at a path.\n\nReturns the JSON value at the given path. Use "/" to get\nthe entire database.\n\nArguments:\n database Database ID (e.g. "users")\n path Path in the database (e.g. "/", "/users/alice")\n\nExamples:\n $ lark data get mydb /\n $ lark data get mydb /users/alice\n $ lark data get mydb /settings/theme --json'
667
- ).action(async (database, path2) => {
711
+ $ lark data watch mydb /messages`);
712
+ data.command("get <database> <path>").description("Get data at a path").addHelpText("after", `
713
+ Returns the JSON value at the given path. Use "/" to get
714
+ the entire database.
715
+
716
+ Arguments:
717
+ database Database ID (e.g. "users")
718
+ path Path in the database (e.g. "/", "/users/alice")
719
+
720
+ Examples:
721
+ $ lark data get mydb /
722
+ $ lark data get mydb /users/alice
723
+ $ lark data get mydb /settings/theme --json`).action(async (database, path2) => {
668
724
  const json = program2.opts().json;
669
725
  try {
670
726
  const projectId = resolveProject(program2.opts().project);
@@ -674,9 +730,7 @@ Examples:
674
730
  handleError(err, json);
675
731
  }
676
732
  });
677
- data.command("set <database> <path> <value>").description(
678
- `Set (overwrite) data at a path.
679
-
733
+ data.command("set <database> <path> <value>").description("Set (overwrite) data at a path").addHelpText("after", `
680
734
  Replaces whatever exists at the path with the given JSON value.
681
735
  Use "-" as the value to read JSON from stdin.
682
736
 
@@ -688,8 +742,7 @@ Arguments:
688
742
  Examples:
689
743
  $ lark data set mydb / '{"key": "value"}'
690
744
  $ lark data set mydb /users/alice '{"name": "Alice", "score": 100}'
691
- $ cat data.json | lark data set mydb /path -`
692
- ).action(async (database, path2, value) => {
745
+ $ cat data.json | lark data set mydb /path -`).action(async (database, path2, value) => {
693
746
  const json = program2.opts().json;
694
747
  try {
695
748
  const projectId = resolveProject(program2.opts().project);
@@ -705,9 +758,7 @@ Examples:
705
758
  handleError(err, json);
706
759
  }
707
760
  });
708
- data.command("update <database> <path> <value>").description(
709
- `Update (merge) data at a path.
710
-
761
+ data.command("update <database> <path> <value>").description("Update (merge) data at a path").addHelpText("after", `
711
762
  Merges the given JSON into the existing data. Only the specified
712
763
  keys are changed; other keys are preserved. Use "-" to read
713
764
  from stdin.
@@ -720,8 +771,7 @@ Arguments:
720
771
  Examples:
721
772
  $ lark data update mydb /users/alice '{"score": 150}'
722
773
  $ lark data update mydb /config '{"theme": "dark"}'
723
- $ echo '{"online": true}' | lark data update mydb /users/alice -`
724
- ).action(async (database, path2, value) => {
774
+ $ echo '{"online": true}' | lark data update mydb /users/alice -`).action(async (database, path2, value) => {
725
775
  const json = program2.opts().json;
726
776
  try {
727
777
  const projectId = resolveProject(program2.opts().project);
@@ -737,9 +787,7 @@ Examples:
737
787
  handleError(err, json);
738
788
  }
739
789
  });
740
- data.command("push <database> <path> <value>").description(
741
- `Push data to a list, generating a unique key.
742
-
790
+ data.command("push <database> <path> <value>").description("Push data to a list with an auto-generated key").addHelpText("after", `
743
791
  Appends the value under an auto-generated key (like a list push).
744
792
  Returns the generated key name. Use "-" to read from stdin.
745
793
 
@@ -750,8 +798,7 @@ Arguments:
750
798
 
751
799
  Examples:
752
800
  $ lark data push chat /messages '{"from": "Alice", "text": "Hello"}'
753
- $ echo '{"event": "login"}' | lark data push mydb /logs -`
754
- ).action(async (database, path2, value) => {
801
+ $ echo '{"event": "login"}' | lark data push mydb /logs -`).action(async (database, path2, value) => {
755
802
  const json = program2.opts().json;
756
803
  try {
757
804
  const projectId = resolveProject(program2.opts().project);
@@ -767,9 +814,16 @@ Examples:
767
814
  handleError(err, json);
768
815
  }
769
816
  });
770
- data.command("delete <database> <path>").description(
771
- 'Delete data at a path.\n\nRemoves the value at the path. Parent nodes that become empty\nmay also be removed.\n\nArguments:\n database Database ID (e.g. "users")\n path Path to delete (e.g. "/users/alice")\n\nExamples:\n $ lark data delete mydb /users/alice\n $ lark data delete mydb /temp'
772
- ).action(async (database, path2) => {
817
+ data.command("delete <database> <path>").description("Delete data at a path").addHelpText("after", `
818
+ Removes the value at the given path.
819
+
820
+ Arguments:
821
+ database Database ID (e.g. "users")
822
+ path Path to delete (e.g. "/users/alice")
823
+
824
+ Examples:
825
+ $ lark data delete mydb /users/alice
826
+ $ lark data delete mydb /temp`).action(async (database, path2) => {
773
827
  const json = program2.opts().json;
774
828
  try {
775
829
  const projectId = resolveProject(program2.opts().project);
@@ -783,9 +837,18 @@ Examples:
783
837
  handleError(err, json);
784
838
  }
785
839
  });
786
- data.command("export <database> [path]").description(
787
- 'Export database data as JSON.\n\nPrints the data as formatted JSON. Use -o to write to a file\ninstead of stdout. Path defaults to "/" (entire database).\n\nArguments:\n database Database ID (e.g. "users")\n path Path to export (default: "/")\n\nExamples:\n $ lark data export mydb\n $ lark data export mydb /users -o users.json\n $ lark data export mydb / -o backup.json'
788
- ).option("-o, --output <file>", "Write to file instead of stdout").action(async (database, path2, opts) => {
840
+ data.command("export <database> [path]").description("Export database data as JSON").option("-o, --output <file>", "Write to file instead of stdout").addHelpText("after", `
841
+ Prints the data as formatted JSON. Use -o to write to a file
842
+ instead of stdout. Path defaults to "/" (entire database).
843
+
844
+ Arguments:
845
+ database Database ID (e.g. "users")
846
+ path Path to export (default: "/")
847
+
848
+ Examples:
849
+ $ lark data export mydb
850
+ $ lark data export mydb /users -o users.json
851
+ $ lark data export mydb / -o backup.json`).action(async (database, path2, opts) => {
789
852
  const json = program2.opts().json;
790
853
  try {
791
854
  const projectId = resolveProject(program2.opts().project);
@@ -803,9 +866,17 @@ Examples:
803
866
  handleError(err, json);
804
867
  }
805
868
  });
806
- data.command("import <database> [path]").description(
807
- 'Import data from a JSON file.\n\nOverwrites data at the given path with the contents of the file.\nPath defaults to "/" (entire database).\n\nArguments:\n database Database ID (e.g. "users")\n path Path to import into (default: "/")\n\nExamples:\n $ lark data import mydb -f backup.json\n $ lark data import mydb /users -f users.json'
808
- ).requiredOption("-f, --file <file>", "JSON file to import").action(async (database, path2, opts) => {
869
+ data.command("import <database> [path]").description("Import data from a JSON file").requiredOption("-f, --file <file>", "JSON file to import").addHelpText("after", `
870
+ Overwrites data at the given path with the contents of the file.
871
+ Path defaults to "/" (entire database).
872
+
873
+ Arguments:
874
+ database Database ID (e.g. "users")
875
+ path Path to import into (default: "/")
876
+
877
+ Examples:
878
+ $ lark data import mydb -f backup.json
879
+ $ lark data import mydb /users -f users.json`).action(async (database, path2, opts) => {
809
880
  const json = program2.opts().json;
810
881
  try {
811
882
  const projectId = resolveProject(program2.opts().project);
@@ -821,9 +892,20 @@ Examples:
821
892
  handleError(err, json);
822
893
  }
823
894
  });
824
- data.command("watch <database> <path>").description(
825
- 'Watch for real-time changes via SSE streaming.\n\nStreams live updates as they happen. Each change is printed\nas a line with the event type and data. Press Ctrl+C to stop.\n\nWith --json, outputs one JSON object per line (NDJSON).\n\nArguments:\n database Database ID (e.g. "chat")\n path Path to watch (e.g. "/messages")\n\nExamples:\n $ lark data watch mydb /\n $ lark data watch chat /messages\n $ lark data watch mydb /users --json'
826
- ).action(async (database, path2) => {
895
+ data.command("watch <database> <path>").description("Watch for real-time changes (SSE stream)").addHelpText("after", `
896
+ Streams live updates as they happen. Each change is printed
897
+ as a line with the event type and data. Press Ctrl+C to stop.
898
+
899
+ With --json, outputs one JSON object per line (NDJSON).
900
+
901
+ Arguments:
902
+ database Database ID (e.g. "chat")
903
+ path Path to watch (e.g. "/messages")
904
+
905
+ Examples:
906
+ $ lark data watch mydb /
907
+ $ lark data watch chat /messages
908
+ $ lark data watch mydb /users --json`).action(async (database, path2) => {
827
909
  const jsonMode = program2.opts().json;
828
910
  try {
829
911
  const projectId = resolveProject(program2.opts().project);
@@ -882,9 +964,17 @@ Examples:
882
964
 
883
965
  // src/commands/dashboard.ts
884
966
  function registerDashboardCommands(program2) {
885
- program2.command("dashboard [id]").description(
886
- "Show project dashboard with metrics and recent events.\n\nDisplays CCU, bandwidth, operations, and latency for the\ngiven time range (defaults to last 24 hours).\n\nUses the default project if no ID is given.\n\nExamples:\n $ lark dashboard\n $ lark dashboard my-app\n $ lark dashboard --start 2026-02-01 --end 2026-02-15\n $ lark dashboard --json"
887
- ).option("--start <date>", 'Start date (ISO format, e.g. "2026-02-01")').option("--end <date>", 'End date (ISO format, e.g. "2026-02-15")').action(async (id, opts) => {
967
+ program2.command("dashboard [id]").description("Show project dashboard with metrics").option("--start <date>", 'Start date (ISO format, e.g. "2026-02-01")').option("--end <date>", 'End date (ISO format, e.g. "2026-02-15")').addHelpText("after", `
968
+ Displays CCU, bandwidth, operations, and latency for the
969
+ given time range (defaults to last 24 hours).
970
+
971
+ Uses the default project if no ID is given.
972
+
973
+ Examples:
974
+ $ lark dashboard
975
+ $ lark dashboard my-app
976
+ $ lark dashboard --start 2026-02-01 --end 2026-02-15
977
+ $ lark dashboard --json`).action(async (id, opts) => {
888
978
  const json = program2.opts().json;
889
979
  try {
890
980
  const projectId = resolveProject(id || program2.opts().project);
@@ -937,9 +1027,14 @@ function registerDashboardCommands(program2) {
937
1027
  handleError(err, json);
938
1028
  }
939
1029
  });
940
- program2.command("events [id]").description(
941
- "Show project events (database connections, errors, etc.).\n\nUses the default project if no ID is given.\n\nExamples:\n $ lark events\n $ lark events my-app --limit 50\n $ lark events --json"
942
- ).option("--limit <n>", "Max results to return", "25").option("--offset <n>", "Number of results to skip", "0").action(async (id, opts) => {
1030
+ program2.command("events [id]").description("Show project events").option("--limit <n>", "Max results to return", "25").option("--offset <n>", "Number of results to skip", "0").addHelpText("after", `
1031
+ Shows database events like connections, errors, etc.
1032
+ Uses the default project if no ID is given.
1033
+
1034
+ Examples:
1035
+ $ lark events
1036
+ $ lark events my-app --limit 50
1037
+ $ lark events --json`).action(async (id, opts) => {
943
1038
  const json = program2.opts().json;
944
1039
  try {
945
1040
  const projectId = resolveProject(id || program2.opts().project);
@@ -968,9 +1063,14 @@ function registerDashboardCommands(program2) {
968
1063
  handleError(err, json);
969
1064
  }
970
1065
  });
971
- program2.command("billing [id]").description(
972
- "Show project billing info for a given month.\n\nDefaults to the current billing period.\n\nExamples:\n $ lark billing\n $ lark billing my-app\n $ lark billing --period 2026-01\n $ lark billing --json"
973
- ).option("--period <month>", 'Billing period in YYYY-MM format (e.g. "2026-01")').action(async (id, opts) => {
1066
+ program2.command("billing [id]").description("Show project billing info").option("--period <month>", 'Billing period in YYYY-MM format (e.g. "2026-01")').addHelpText("after", `
1067
+ Defaults to the current billing period.
1068
+
1069
+ Examples:
1070
+ $ lark billing
1071
+ $ lark billing my-app
1072
+ $ lark billing --period 2026-01
1073
+ $ lark billing --json`).action(async (id, opts) => {
974
1074
  const json = program2.opts().json;
975
1075
  try {
976
1076
  const projectId = resolveProject(id || program2.opts().project);
@@ -994,12 +1094,22 @@ function registerDashboardCommands(program2) {
994
1094
  // src/commands/rules.ts
995
1095
  import fs3 from "fs";
996
1096
  function registerRulesCommands(program2) {
997
- const rules = program2.command("rules").description(
998
- "Manage project security rules.\n\nRules control read/write access to your database paths.\nThey use JSON5 format and follow Firebase-style syntax.\n\nExamples:\n $ lark rules get\n $ lark rules set -f rules.json"
999
- );
1000
- rules.command("get [id]").description(
1001
- "Get the current security rules.\n\nPrints the raw rules JSON. Use --json to get a structured\nresponse with both the raw string and parsed object.\n\nExamples:\n $ lark rules get\n $ lark rules get my-app\n $ lark rules get --json\n $ lark rules get > rules-backup.json"
1002
- ).action(async (id) => {
1097
+ const rules = program2.command("rules").description("Manage project security rules").addHelpText("after", `
1098
+ Rules control read/write access to your database paths.
1099
+ They use JSON5 format and follow Firebase-style syntax.
1100
+
1101
+ Examples:
1102
+ $ lark rules get
1103
+ $ lark rules set -f rules.json`);
1104
+ rules.command("get [id]").description("Get the current security rules").addHelpText("after", `
1105
+ Prints the raw rules JSON. Use --json to get a structured
1106
+ response with both the raw string and parsed object.
1107
+
1108
+ Examples:
1109
+ $ lark rules get
1110
+ $ lark rules get my-app
1111
+ $ lark rules get --json
1112
+ $ lark rules get > rules-backup.json`).action(async (id) => {
1003
1113
  const json = program2.opts().json;
1004
1114
  try {
1005
1115
  const projectId = resolveProject(id || program2.opts().project);
@@ -1017,9 +1127,7 @@ function registerRulesCommands(program2) {
1017
1127
  handleError(err, json);
1018
1128
  }
1019
1129
  });
1020
- rules.command("set [id]").description(
1021
- `Set security rules from a file or stdin.
1022
-
1130
+ rules.command("set [id]").description("Set security rules from a file or stdin").option("-f, --file <file>", "Rules file (JSON5 format)").addHelpText("after", `
1023
1131
  Accepts JSON5 format. Use -f to read from a file,
1024
1132
  or pipe rules via stdin.
1025
1133
 
@@ -1027,8 +1135,7 @@ Examples:
1027
1135
  $ lark rules set -f rules.json
1028
1136
  $ lark rules set my-app -f rules.json5
1029
1137
  $ cat rules.json | lark rules set
1030
- $ echo '{"rules": {".read": true}}' | lark rules set`
1031
- ).option("-f, --file <file>", "Rules file (JSON5 format)").action(async (id, opts) => {
1138
+ $ echo '{"rules": {".read": true}}' | lark rules set`).action(async (id, opts) => {
1032
1139
  const json = program2.opts().json;
1033
1140
  try {
1034
1141
  const projectId = resolveProject(id || program2.opts().project);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-sh/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI tool for Lark.sh — manage projects, databases, and data from the terminal",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,13 @@
10
10
  "directory": "cli"
11
11
  },
12
12
  "homepage": "https://lark.sh",
13
- "keywords": ["lark", "larksh", "realtime", "database", "cli"],
13
+ "keywords": [
14
+ "lark",
15
+ "larksh",
16
+ "realtime",
17
+ "database",
18
+ "cli"
19
+ ],
14
20
  "bin": {
15
21
  "lark": "./dist/index.js"
16
22
  },