@keystrokehq/cli 0.0.31 → 0.0.37

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 (148) hide show
  1. package/README.md +25 -4
  2. package/dist/{accept.handler-DNfIXPSP.mjs → accept.handler-DCsud1s5.mjs} +4 -4
  3. package/dist/{admin-CJp8XksD.mjs → admin-BaOtHeZ2.mjs} +10 -10
  4. package/dist/{agent-manifest-De5TCxZq.mjs → agent-manifest-DfWD5tvv.mjs} +17 -27
  5. package/dist/{agents-G37PM35Z.mjs → agents-BVAVfMR_.mjs} +9 -9
  6. package/dist/{api-keys-4igNHJ_W.mjs → api-keys-BhEEsHUh.mjs} +6 -6
  7. package/dist/{api-BK3EhPvs.mjs → api-sWkB_Wta.mjs} +1 -1
  8. package/dist/{auth-CIOmmV4x.mjs → auth-BnsitjzT.mjs} +6 -6
  9. package/dist/{auth.handler-CznN_vfz.mjs → auth.handler-W_xk14TL.mjs} +3 -3
  10. package/dist/authored-workflow-ref-fkHEEVnd.mjs +113 -0
  11. package/dist/{build-agents-DseUtzd4-CSGpNXur.mjs → build-agents-CUzBnlAG-3ePFZiJ6.mjs} +12 -11
  12. package/dist/{build-progress-DLM1Bt4T.mjs → build-progress-CM-b6Bby.mjs} +2 -2
  13. package/dist/{build-tasks-C09SdfjC-BmAVLTtQ.mjs → build-tasks-5eOvI19S-tbN6CRx9.mjs} +4 -4
  14. package/dist/{build-workflows-BZ_m97Pr-BiyptCrn.mjs → build-workflows-C-gQM3l5-_zcBHE3M.mjs} +14 -9
  15. package/dist/{build.handler-zHimoO7c.mjs → build.handler-CpAsAsBc.mjs} +12 -9
  16. package/dist/{clear-cache.handler-BP0K1-uN.mjs → clear-cache.handler-gJpwslkK.mjs} +2 -2
  17. package/dist/{clear.handler-T27GpgSu.mjs → clear.handler-CDyG6-dk.mjs} +1 -1
  18. package/dist/{clear.handler-PsA5QKHx.mjs → clear.handler-_sR33Hp8.mjs} +2 -2
  19. package/dist/{commander-BlrSdFcu.mjs → commander-C6SSTQJ2.mjs} +22 -3
  20. package/dist/{connect-BbLJhlIA.mjs → connect-27EgnljZ.mjs} +3 -3
  21. package/dist/{connect.handler-BthE-7Wg.mjs → connect.handler-COM1LnNg.mjs} +5 -5
  22. package/dist/{context-sgKhRc5v.mjs → context-ebZssGCY.mjs} +4 -4
  23. package/dist/{create.handler-BovbO_g0.mjs → create.handler-CAWJAGzQ.mjs} +3 -3
  24. package/dist/{credential-env-map-CRs0llf0.mjs → credential-env-map-5a41jLwM.mjs} +1 -1
  25. package/dist/{credential-requirements-D0mavK8j-CFMf0Xwu.mjs → credential-requirements-B5Alhu1v-DanlSKnT.mjs} +3 -3
  26. package/dist/{credential-schema-mismatch-ClQgEVtO.mjs → credential-schema-mismatch-c17ktoNU.mjs} +1 -1
  27. package/dist/{credentials-CsncZ52a.mjs → credentials-C0ssbMlp.mjs} +10 -10
  28. package/dist/{credentials-DKrSaaLw.mjs → credentials-DtwLbee6.mjs} +1 -1
  29. package/dist/current-deployment-workflow-C6x65imE.mjs +20 -0
  30. package/dist/current.handler-DP1L_hm3.mjs +19 -0
  31. package/dist/{delete.handler-DkAK396w.mjs → delete.handler-C-5XFkgN.mjs} +2 -2
  32. package/dist/{deploy-DvPfR9fC.mjs → deploy-BcVQJza8.mjs} +2 -2
  33. package/dist/{deploy-progress-BsUH7fGE.mjs → deploy-progress-Bt86Yc1r.mjs} +2 -2
  34. package/dist/{deploy.handler-BW3f2N2G.mjs → deploy.handler-GPS9lxGk.mjs} +16 -16
  35. package/dist/{diff-utils-Bs--xmoV.mjs → diff-utils-YEUYtSRs.mjs} +1 -1
  36. package/dist/{diff.handler-BwhsoAg0.mjs → diff.handler-DkM5dhaN.mjs} +15 -9
  37. package/dist/{dist-Dw7gCE7y.mjs → dist-B5jy238v.mjs} +37 -11
  38. package/dist/{dist-CTEtWDW4.mjs → dist-BmbFJq8U.mjs} +8 -27
  39. package/dist/{env.handler-Dks6ZQh-.mjs → env.handler-V_isbSi2.mjs} +52 -29
  40. package/dist/{error-boundary-0veZ_RDS.mjs → error-boundary-BRxUsPi7.mjs} +3 -3
  41. package/dist/{iam-command-utils-CSZj4XlH.mjs → iam-command-utils-DNDN0wT6.mjs} +3 -13
  42. package/dist/{import-module-y0glInUe-DV_3dsU0.mjs → import-module-y0glInUe-EuAWaw9g.mjs} +506 -128
  43. package/dist/{init-DX08T87c.mjs → init-D1OmmclX.mjs} +8 -3
  44. package/dist/{init.handler-CzlmkNXi.mjs → init.handler-CUbYlUgP.mjs} +57 -14
  45. package/dist/{inspect.handler-v9snxDLi.mjs → inspect.handler-BE6coOuW.mjs} +24 -13
  46. package/dist/{integration-catalog-CiZ62hb_.mjs → integration-catalog-pSmWHFLQ.mjs} +3 -3
  47. package/dist/{integrations-MEExmqcg.mjs → integrations-DZD5t8n2.mjs} +7 -7
  48. package/dist/{invites-BuatfJmN.mjs → invites-BuR1H-tA.mjs} +5 -5
  49. package/dist/{invites.list.handler-CK6mL10z.mjs → invites.list.handler-Dj4a6XOg.mjs} +6 -5
  50. package/dist/{invites.resend.handler-CKZouK1Z.mjs → invites.resend.handler-DEGF4vlB.mjs} +6 -5
  51. package/dist/{invites.revoke.handler-H0VI-3sp.mjs → invites.revoke.handler-Dg4ZvlFS.mjs} +6 -5
  52. package/dist/keystroke.mjs +122 -77
  53. package/dist/{list-enrichment-DP1wEyBZ.mjs → list-enrichment-dqbkXJzy.mjs} +2 -2
  54. package/dist/{list.handler-LxZInip2.mjs → list.handler-2g1CZAvB.mjs} +4 -4
  55. package/dist/{list.handler-BKfGLkFu.mjs → list.handler-7MkJfkak.mjs} +5 -5
  56. package/dist/list.handler-BTYVIn6z.mjs +39 -0
  57. package/dist/{list.handler-BiY5NFWd.mjs → list.handler-Bchcr3-e.mjs} +3 -3
  58. package/dist/list.handler-Choc4SZz.mjs +64 -0
  59. package/dist/{list.handler-Jk_vK66s.mjs → list.handler-D47C1z3m.mjs} +4 -4
  60. package/dist/{list.handler-DVnFrlis.mjs → list.handler-DYE48apa.mjs} +7 -7
  61. package/dist/{list.handler-DIMWZx78.mjs → list.handler-KcCaG3PZ.mjs} +4 -4
  62. package/dist/list2.handler-BIaIyrQf.mjs +99 -0
  63. package/dist/{listen-C_7Rgwkb.mjs → listen-CVY-_F29.mjs} +3 -3
  64. package/dist/{listen.handler-dJgorIzr.mjs → listen.handler-D_nEvXRn.mjs} +4 -4
  65. package/dist/{logs-B9YMhUGt.mjs → logs-CZ2qnsSH.mjs} +3 -3
  66. package/dist/{logs.handler-BfjCsAyq.mjs → logs.handler-BRUzZC9Z.mjs} +26 -29
  67. package/dist/{logs.handler-DGGVPMOX.mjs → logs.handler-Wk6mYyAZ.mjs} +1 -1
  68. package/dist/{members.add.handler-DSRCRxsI.mjs → members.add.handler-BJ0wr6rP.mjs} +6 -5
  69. package/dist/{members.invite.handler-BNpHn1dY.mjs → members.invite.handler-DyveDMuq.mjs} +6 -5
  70. package/dist/{members.list.handler-Bn9LJEPG.mjs → members.list.handler-CyQxH_zS.mjs} +6 -5
  71. package/dist/{members.remove.handler-Dkr2t_tX.mjs → members.remove.handler-Dtv9PooY.mjs} +6 -5
  72. package/dist/{members.update.handler-DBtUYuAY.mjs → members.update.handler-CeK-tCjT.mjs} +6 -5
  73. package/dist/{operations-AWMLs6mE.mjs → operations-CxQlt0S0.mjs} +5 -5
  74. package/dist/{org-DOH7YHk2.mjs → org-B8MPHJJu.mjs} +35 -28
  75. package/dist/org-context-BI9OSpbb.mjs +112 -0
  76. package/dist/org-output-DffU7DKn.mjs +64 -0
  77. package/dist/{orgs.create.handler-BO70zIdp.mjs → orgs.create.handler-BKvSmkU3.mjs} +4 -4
  78. package/dist/{orgs.get.handler-BuGg5bc9.mjs → orgs.get.handler-BA-CexIY.mjs} +4 -4
  79. package/dist/{orgs.list.handler--5HutMkl.mjs → orgs.list.handler-eCEg5kC1.mjs} +4 -4
  80. package/dist/{output-BWcVRt-T.mjs → output-DnIFEmi5.mjs} +1 -1
  81. package/dist/package-manager-BP3-q8hh.mjs +162 -0
  82. package/dist/{paused.handler-DHvxz-cC.mjs → paused.handler-4wKMTKZ-.mjs} +20 -33
  83. package/dist/{projects-C5GZ5Jrf.mjs → projects-Wu_2fB_x.mjs} +11 -9
  84. package/dist/{register.handler-CePNU3sP.mjs → register.handler-BvAkXCwE.mjs} +2 -2
  85. package/dist/{render-credential-Bn15FEUC.mjs → render-credential-D-H1ECDt.mjs} +1 -1
  86. package/dist/{render-operation-Bc7Wu1sP.mjs → render-operation-VdEPhoII.mjs} +2 -2
  87. package/dist/{requirements.handler-B5rqCjMu.mjs → requirements.handler-Bab4kBtw.mjs} +7 -7
  88. package/dist/{resolve-cli-credentials-CAOSVMJP.mjs → resolve-cli-credentials-GVOOedoQ.mjs} +1 -1
  89. package/dist/{resolve-project-E9mrh_el.mjs → resolve-project-DLKlAy0z.mjs} +24 -8
  90. package/dist/{run-polling-DawiBus-.mjs → run-polling-C5fI7xTp.mjs} +97 -14
  91. package/dist/{run.handler-BG7xitEK.mjs → run.handler-BKD5Xu0A.mjs} +42 -30
  92. package/dist/{runs-swYYBT6C.mjs → runs-CT31dczt.mjs} +4 -4
  93. package/dist/{schema-display-FvI8QjOQ.mjs → schema-display-sZ6ConJd.mjs} +33 -26
  94. package/dist/schemas-ClAIoIrX.mjs +281 -0
  95. package/dist/{search-BEfy2fG9.mjs → search-BeQW_pf4.mjs} +3 -3
  96. package/dist/{search.handler-V7ObLGjN.mjs → search.handler-BJ-ZlDL4.mjs} +6 -6
  97. package/dist/{show.handler-C_VDYU91.mjs → show.handler-BrIHUH28.mjs} +4 -4
  98. package/dist/{show.handler-CsidInW8.mjs → show.handler-Cqe_hCqU.mjs} +5 -5
  99. package/dist/{show.handler-Wmv0tkxx.mjs → show.handler-DB8xl5FU.mjs} +6 -6
  100. package/dist/{skill-installer-D6j9IA3Z.mjs → skill-installer-DuMhavmM.mjs} +3 -1
  101. package/dist/{skills-sync.handler-BAATdT6N.mjs → skills-sync.handler-BGs-_YD9.mjs} +13 -7
  102. package/dist/{skills.command-0-E8mcYE.mjs → skills.command-DUWn6FbL.mjs} +5 -5
  103. package/dist/skills.handler-DqLXJepA.mjs +9 -0
  104. package/dist/{spinner-progress-lrKDs4YF.mjs → spinner-progress-BYxlr3lY.mjs} +1 -1
  105. package/dist/status.handler-DAId4bVU.mjs +72 -0
  106. package/dist/{switch.handler-BwYndsP-.mjs → switch.handler-Cd4Yg2n8.mjs} +17 -4
  107. package/dist/{sync-6fZkIUtn.mjs → sync-DgC4lcxh.mjs} +2 -2
  108. package/dist/{sync.handler-Ctr-cN9X.mjs → sync.handler-Cm_WtGmH.mjs} +8 -8
  109. package/dist/{task-BWuIKWh4.mjs → task-DTvLzUkA.mjs} +2 -88
  110. package/dist/{task-target-build-QllcCfoN.mjs → task-target-build-CtvRyVjH.mjs} +5 -5
  111. package/dist/task-target-deploy-runner.mjs +6 -6
  112. package/dist/{test-C8VIZe9V.mjs → test-4V7nh67i.mjs} +5 -5
  113. package/dist/{test.handler-BCW0YBPd.mjs → test.handler-BdCYcwR4.mjs} +2 -2
  114. package/dist/{test.handler-DLaxrJ9V.mjs → test.handler-Bo4YTs2Z.mjs} +19 -16
  115. package/dist/{tool.handler-8qNmgdRe.mjs → tool.handler-CPCrSDq2.mjs} +12 -12
  116. package/dist/{trigger-artifacts-BcRScRSp-BiD2h6do.mjs → trigger-artifacts-BcRScRSp-BRpU-He5.mjs} +2 -2
  117. package/dist/{trigger-manifest-C07EM-b2.mjs → trigger-manifest-BVqjDhxU.mjs} +1 -1
  118. package/dist/{upgrade-DgOcc8IT.mjs → upgrade-2qUOcjxb.mjs} +4 -8
  119. package/dist/upgrade.handler-PqlKSuUE.mjs +99 -0
  120. package/dist/{upload.handler-B7xle1oX.mjs → upload.handler-CS-vLpzC.mjs} +9 -9
  121. package/dist/{users.get.handler-C4t1vXwi.mjs → users.get.handler-CH1c6Lnj.mjs} +4 -4
  122. package/dist/{users.list.handler-Dvl90grq.mjs → users.list.handler-CxbZFgjO.mjs} +4 -4
  123. package/dist/{users.set-role.handler-Djw1_VGf.mjs → users.set-role.handler-CBRE-Ws6.mjs} +4 -4
  124. package/dist/{validate.handler-Drf_lssw.mjs → validate.handler-1d-UmtXB.mjs} +171 -26
  125. package/dist/{workflow-build-Begvjfq8.mjs → workflow-build-Bm8JoVv4.mjs} +234 -32
  126. package/dist/{workflow-build-manifest-1sC52TIG.mjs → workflow-build-manifest-CV6bBmDO.mjs} +1 -1
  127. package/dist/{workflow-bundler-BzHk73PM-muPv1yGG.mjs → workflow-bundler-Bs3zQNQv-Dy7lXxy3.mjs} +15 -4
  128. package/dist/{workflows-DjMlxuBX.mjs → workflows-ny7rOdeH.mjs} +34 -37
  129. package/dist/{writer-byNNUjRm-B-on1n6c.mjs → writer-BLg0RuZa-Y6ExdYH9.mjs} +6 -4
  130. package/package.json +11 -11
  131. package/dist/current-deployment-workflow-B1VQCYC-.mjs +0 -94
  132. package/dist/current.handler-BaGaCLzB.mjs +0 -21
  133. package/dist/list.handler-BEMj3FyH.mjs +0 -76
  134. package/dist/list.handler-Cq_oQY5B.mjs +0 -52
  135. package/dist/list.handler-htR9TeiS.mjs +0 -24
  136. package/dist/package-manager-DT1EhOkS.mjs +0 -61
  137. package/dist/schemas-D2zfmyC-.mjs +0 -671
  138. package/dist/skills.handler-DYIQK0Vu.mjs +0 -9
  139. package/dist/status.handler-Ch_DtyBp.mjs +0 -109
  140. package/dist/upgrade.handler-DSZuw7-9.mjs +0 -80
  141. /package/dist/{build-metadata-BB_L45ZS-DSJL7dTy.mjs → build-metadata-BB_L45ZS-DRQsV6JK.mjs} +0 -0
  142. /package/dist/{deploy-DhCbYFc7.mjs → deploy-BiKBH25R.mjs} +0 -0
  143. /package/dist/{detect-env-access-CwkOYeYM-COq4U-4Y.mjs → detect-env-access-CwkOYeYM-r4aynBU0.mjs} +0 -0
  144. /package/dist/{read-credential-keys-77a91T8M-DGK5XTQp.mjs → read-credential-keys-77a91T8M-I07NYwfH.mjs} +0 -0
  145. /package/dist/{run-polling-fBouPjJ2.mjs → run-polling-1c0ckC1A.mjs} +0 -0
  146. /package/dist/{schemas-4Mq_bxob.mjs → schemas-8nhXlXWh.mjs} +0 -0
  147. /package/dist/{task-target-deploy-B_3HPSo2.mjs → task-target-deploy-m9LfE488.mjs} +0 -0
  148. /package/dist/{types-AlA-ifK9.mjs → types-Cb0eWmUU.mjs} +0 -0
@@ -9,10 +9,10 @@ import * as fsPromises from "node:fs/promises";
9
9
  import * as fs from "node:fs";
10
10
  import { existsSync, writeFileSync } from "node:fs";
11
11
  import { Command, CommanderError, Option } from "commander";
12
+ import { log } from "@clack/prompts";
12
13
  import { fileURLToPath } from "node:url";
13
14
  import { config } from "dotenv";
14
15
  import { z } from "zod";
15
- import { log } from "@clack/prompts";
16
16
  //#region ../../packages/local-memory/dist/logger/index.mjs
17
17
  const LOGS_DIR = "logs";
18
18
  const LOG_FILE = "cli.jsonl";
@@ -521,7 +521,7 @@ const logger = {
521
521
  };
522
522
  //#endregion
523
523
  //#region package.json
524
- var version = "0.0.31";
524
+ var version = "0.0.37";
525
525
  //#endregion
526
526
  //#region src/command-registry.ts
527
527
  const ROOT_OPTIONS_WITH_VALUES$1 = new Set([
@@ -533,92 +533,92 @@ const ROOT_VERSION_FLAGS = new Set(["-V", "--version"]);
533
533
  const lazyCommandDefinitions = [
534
534
  {
535
535
  name: "agents",
536
- loadCommand: async () => (await import("./agents-G37PM35Z.mjs")).createAgentsCommand()
536
+ loadCommand: async () => (await import("./agents-BVAVfMR_.mjs")).createAgentsCommand()
537
537
  },
538
538
  {
539
539
  name: "admin",
540
- loadCommand: async () => (await import("./admin-CJp8XksD.mjs")).createAdminCommand()
540
+ loadCommand: async () => (await import("./admin-BaOtHeZ2.mjs")).createAdminCommand()
541
541
  },
542
542
  {
543
543
  name: "api-keys",
544
- loadCommand: async () => (await import("./api-keys-4igNHJ_W.mjs")).createApiKeysCommand()
544
+ loadCommand: async () => (await import("./api-keys-BhEEsHUh.mjs")).createApiKeysCommand()
545
545
  },
546
546
  {
547
547
  name: "auth",
548
- loadCommand: async () => (await import("./auth-CIOmmV4x.mjs")).createAuthCommand()
548
+ loadCommand: async () => (await import("./auth-BnsitjzT.mjs")).createAuthCommand()
549
549
  },
550
550
  {
551
551
  name: "connect",
552
- loadCommand: async () => (await import("./connect-BbLJhlIA.mjs")).createConnectCommand()
552
+ loadCommand: async () => (await import("./connect-27EgnljZ.mjs")).createConnectCommand()
553
553
  },
554
554
  {
555
555
  name: "credentials",
556
- loadCommand: async () => (await import("./credentials-CsncZ52a.mjs")).createCredentialsCommand(),
556
+ loadCommand: async () => (await import("./credentials-C0ssbMlp.mjs")).createCredentialsCommand(),
557
557
  copyInheritedSettings: true
558
558
  },
559
559
  {
560
560
  name: "org",
561
- loadCommand: async () => (await import("./org-DOH7YHk2.mjs")).createOrgCommand()
561
+ loadCommand: async () => (await import("./org-B8MPHJJu.mjs")).createOrgCommand()
562
562
  },
563
563
  {
564
564
  name: "deploy",
565
- loadCommand: async () => (await import("./deploy-DvPfR9fC.mjs")).createDeployCommand()
565
+ loadCommand: async () => (await import("./deploy-BcVQJza8.mjs")).createDeployCommand()
566
566
  },
567
567
  {
568
568
  name: "init",
569
- loadCommand: async () => (await import("./init-DX08T87c.mjs")).createInitCommand()
569
+ loadCommand: async () => (await import("./init-D1OmmclX.mjs")).createInitCommand()
570
570
  },
571
571
  {
572
572
  name: "integrations",
573
- loadCommand: async () => (await import("./integrations-MEExmqcg.mjs")).createIntegrationsCommand()
573
+ loadCommand: async () => (await import("./integrations-DZD5t8n2.mjs")).createIntegrationsCommand()
574
574
  },
575
575
  {
576
576
  name: "invites",
577
- loadCommand: async () => (await import("./invites-BuatfJmN.mjs")).createInvitesCommand()
577
+ loadCommand: async () => (await import("./invites-BuR1H-tA.mjs")).createInvitesCommand()
578
578
  },
579
579
  {
580
580
  name: "logs",
581
- loadCommand: async () => (await import("./logs-B9YMhUGt.mjs")).createLogsCommand()
581
+ loadCommand: async () => (await import("./logs-CZ2qnsSH.mjs")).createLogsCommand()
582
582
  },
583
583
  {
584
584
  name: "listen",
585
- loadCommand: async () => (await import("./listen-C_7Rgwkb.mjs")).createListenCommand()
585
+ loadCommand: async () => (await import("./listen-CVY-_F29.mjs")).createListenCommand()
586
586
  },
587
587
  {
588
588
  name: "operations",
589
- loadCommand: async () => (await import("./operations-AWMLs6mE.mjs")).createOperationsCommand()
589
+ loadCommand: async () => (await import("./operations-CxQlt0S0.mjs")).createOperationsCommand()
590
590
  },
591
591
  {
592
592
  name: "projects",
593
- loadCommand: async () => (await import("./projects-C5GZ5Jrf.mjs")).createProjectsCommand()
593
+ loadCommand: async () => (await import("./projects-Wu_2fB_x.mjs")).createProjectsCommand()
594
594
  },
595
595
  {
596
596
  name: "runs",
597
- loadCommand: async () => (await import("./runs-swYYBT6C.mjs")).createRunsCommand()
597
+ loadCommand: async () => (await import("./runs-CT31dczt.mjs")).createRunsCommand()
598
598
  },
599
599
  {
600
600
  name: "search",
601
- loadCommand: async () => (await import("./search-BEfy2fG9.mjs")).createSearchCommand()
601
+ loadCommand: async () => (await import("./search-BeQW_pf4.mjs")).createSearchCommand()
602
602
  },
603
603
  {
604
604
  name: "skills",
605
- loadCommand: async () => (await import("./skills.command-0-E8mcYE.mjs")).createSkillsCommand()
605
+ loadCommand: async () => (await import("./skills.command-DUWn6FbL.mjs")).createSkillsCommand()
606
606
  },
607
607
  {
608
608
  name: "sync",
609
- loadCommand: async () => (await import("./sync-6fZkIUtn.mjs")).createSyncCommand()
609
+ loadCommand: async () => (await import("./sync-DgC4lcxh.mjs")).createSyncCommand()
610
610
  },
611
611
  {
612
612
  name: "test",
613
- loadCommand: async () => (await import("./test-C8VIZe9V.mjs")).createTestCommand()
613
+ loadCommand: async () => (await import("./test-4V7nh67i.mjs")).createTestCommand()
614
614
  },
615
615
  {
616
616
  name: "upgrade",
617
- loadCommand: async () => (await import("./upgrade-DgOcc8IT.mjs")).createUpgradeCommand()
617
+ loadCommand: async () => (await import("./upgrade-2qUOcjxb.mjs")).createUpgradeCommand()
618
618
  },
619
619
  {
620
620
  name: "workflows",
621
- loadCommand: async () => (await import("./workflows-DjMlxuBX.mjs")).createWorkflowsCommand()
621
+ loadCommand: async () => (await import("./workflows-ny7rOdeH.mjs")).createWorkflowsCommand()
622
622
  }
623
623
  ];
624
624
  function selectCommandRegistration(argv, commandNames = new Set(lazyCommandDefinitions.map((definition) => definition.name))) {
@@ -927,6 +927,80 @@ async function flushCliTelemetryForExit(exitCode) {
927
927
  });
928
928
  }
929
929
  //#endregion
930
+ //#region src/lib/ui.ts
931
+ const ui = {
932
+ /** Blank line separator */
933
+ br: () => {
934
+ originalConsole.info("");
935
+ logger.info("");
936
+ },
937
+ /** Primary informational text — raw, no prefix (used for tables, structured output) */
938
+ text: (msg) => {
939
+ originalConsole.info(msg);
940
+ logger.info(msg);
941
+ },
942
+ /** Section header */
943
+ header: (msg) => {
944
+ log.info(msg);
945
+ logger.info(msg);
946
+ },
947
+ /** Success message */
948
+ success: (msg) => {
949
+ log.success(msg);
950
+ logger.info(msg);
951
+ },
952
+ /** Warning message */
953
+ warn: (msg) => {
954
+ log.warn(msg);
955
+ logger.warn(msg);
956
+ },
957
+ /** Error message */
958
+ error: (msg) => {
959
+ log.error(msg);
960
+ logger.error(msg);
961
+ },
962
+ /** Secondary/hint text */
963
+ hint: (msg) => {
964
+ log.message(msg);
965
+ logger.info(msg);
966
+ }
967
+ };
968
+ //#endregion
969
+ //#region src/lib/commander-errors.ts
970
+ /** Suppress Commander's default stderr; errors are reported in `main()` instead. */
971
+ const SUPPRESS_COMMANDER_STDERR = { writeErr: () => {} };
972
+ function applyCommanderOutput(command) {
973
+ command.configureOutput(SUPPRESS_COMMANDER_STDERR);
974
+ }
975
+ /**
976
+ * Maps Commander parse failures to Keystroke-styled messages and hints. Callers
977
+ * must only invoke this for real failures (`exitCode !== 0`); informational
978
+ * exits like `--help` / `--version` are handled by the catch block in `main`.
979
+ * Returns true when the error was reported.
980
+ */
981
+ function reportCommanderError(error) {
982
+ if (error.code === "commander.unknownOption") {
983
+ const option = error.message.match(/option '([^']+)'/)?.[1] ?? "flag";
984
+ ui.error(`Unknown option ${option}.`);
985
+ if (option === "--json") ui.hint("This command may not support --json. Run `<command> --help` to see available flags.");
986
+ else ui.hint("Run `keystroke <command> --help` to see available options.");
987
+ return true;
988
+ }
989
+ if (error.code === "commander.excessArguments" || error.code === "commander.unknownCommand") {
990
+ ui.error("Unrecognized command or argument.");
991
+ ui.hint("Run `keystroke <command> --help` to see available subcommands.");
992
+ return true;
993
+ }
994
+ if (error.code === "commander.missingArgument") {
995
+ ui.error(error.message);
996
+ ui.hint("Run `keystroke <command> --help` for usage.");
997
+ return true;
998
+ }
999
+ ui.error(error.message.replace(/^error:\s*/i, ""));
1000
+ ui.hint("Run `keystroke --help` for usage.");
1001
+ return true;
1002
+ }
1003
+ //#endregion
930
1004
  //#region ../../packages/env-utils/dist/index.mjs
931
1005
  const __filename = fileURLToPath(import.meta.url);
932
1006
  const __dirname = path.dirname(__filename);
@@ -1095,44 +1169,8 @@ function createHiddenGlobalOptions() {
1095
1169
  return Object.values(GLOBAL_OPTIONS_CONFIG).map((cfg) => new Option(cfg.flag).hideHelp());
1096
1170
  }
1097
1171
  //#endregion
1098
- //#region src/lib/ui.ts
1099
- const ui = {
1100
- /** Blank line separator */
1101
- br: () => {
1102
- originalConsole.info("");
1103
- logger.info("");
1104
- },
1105
- /** Primary informational text — raw, no prefix (used for tables, structured output) */
1106
- text: (msg) => {
1107
- originalConsole.info(msg);
1108
- logger.info(msg);
1109
- },
1110
- /** Section header */
1111
- header: (msg) => {
1112
- log.info(msg);
1113
- logger.info(msg);
1114
- },
1115
- /** Success message */
1116
- success: (msg) => {
1117
- log.success(msg);
1118
- logger.info(msg);
1119
- },
1120
- /** Warning message */
1121
- warn: (msg) => {
1122
- log.warn(msg);
1123
- logger.warn(msg);
1124
- },
1125
- /** Error message */
1126
- error: (msg) => {
1127
- log.error(msg);
1128
- logger.error(msg);
1129
- },
1130
- /** Secondary/hint text */
1131
- hint: (msg) => {
1132
- log.message(msg);
1133
- logger.info(msg);
1134
- }
1135
- };
1172
+ //#region src/lib/cli-package.ts
1173
+ const CLI_PACKAGE_NAME = "@keystrokehq/cli";
1136
1174
  //#endregion
1137
1175
  //#region src/lib/npm-registry.ts
1138
1176
  const NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org";
@@ -1183,7 +1221,6 @@ function style(text, color) {
1183
1221
  }
1184
1222
  //#endregion
1185
1223
  //#region src/lib/update-notice.ts
1186
- const CLI_PACKAGE_NAME = "@keystrokehq/cli";
1187
1224
  const DEFAULT_TIMEOUT_MS = 750;
1188
1225
  const ROOT_OPTIONS_WITH_VALUES = new Set([
1189
1226
  "--api-key",
@@ -1288,26 +1325,23 @@ async function allowBufferedOutputToFlush() {
1288
1325
  function shouldLogCliStartup(argv) {
1289
1326
  return argv[0] !== "logs";
1290
1327
  }
1291
- function resolveCliExitCode(error) {
1292
- if (error instanceof CommanderError) return error.exitCode;
1293
- if (error instanceof CliExitError) return error.exitCode;
1294
- return 1;
1295
- }
1296
1328
  async function runCli() {
1329
+ const cliArgs = process.argv.slice(2);
1297
1330
  await initLogger();
1298
- if (process.argv.includes("--debug")) setDebug(true);
1299
- if (shouldLogCliStartup(process.argv.slice(2))) logger.info("CLI started", {
1300
- argv: process.argv.slice(2),
1331
+ if (cliArgs.includes("--debug")) setDebug(true);
1332
+ if (shouldLogCliStartup(cliArgs)) logger.info("CLI started", {
1333
+ argv: cliArgs,
1301
1334
  runMode: getRunMode()
1302
1335
  });
1303
1336
  const program = new Command().name("keystroke").description("Keystroke CLI - Headless workflow management").version(version).enablePositionalOptions();
1304
1337
  program.exitOverride();
1338
+ program.configureOutput(SUPPRESS_COMMANDER_STDERR);
1305
1339
  for (const cfg of Object.values(GLOBAL_OPTIONS_CONFIG)) program.option(cfg.flag, cfg.description);
1306
- await registerCommandsForArgv(program, process.argv.slice(2));
1340
+ await registerCommandsForArgv(program, cliArgs);
1307
1341
  registerCliTelemetryHooks(program);
1308
1342
  await maybeShowCliUpdateNotice({
1309
1343
  currentVersion: version,
1310
- argv: process.argv.slice(2),
1344
+ argv: cliArgs,
1311
1345
  env: getProcessEnv()
1312
1346
  });
1313
1347
  await program.parseAsync(process.argv);
@@ -1318,9 +1352,20 @@ async function main() {
1318
1352
  try {
1319
1353
  await runCli();
1320
1354
  } catch (error) {
1321
- exitCode = resolveCliExitCode(error);
1322
- failure = error;
1323
- if (!(error instanceof CliExitError) && !(error instanceof CommanderError)) ui.error(`Error: ${toErrorMessage(error)}`);
1355
+ if (error instanceof CommanderError) {
1356
+ exitCode = error.exitCode;
1357
+ if (error.exitCode !== 0) {
1358
+ failure = error;
1359
+ reportCommanderError(error);
1360
+ }
1361
+ } else if (error instanceof CliExitError) {
1362
+ exitCode = error.exitCode;
1363
+ failure = error;
1364
+ } else {
1365
+ exitCode = 1;
1366
+ failure = error;
1367
+ ui.error(`Error: ${toErrorMessage(error)}`);
1368
+ }
1324
1369
  }
1325
1370
  if (failure) captureCliTelemetryFailure(failure);
1326
1371
  await flushCliTelemetryForExit(exitCode);
@@ -1333,4 +1378,4 @@ async function main() {
1333
1378
  }
1334
1379
  main();
1335
1380
  //#endregion
1336
- export { WorkflowResolutionError as A, CALLBACK_LOOPBACK_ORIGIN as C, CliExitError as D, AuthenticationError as E, originalConsole as F, readLogEntries as I, setDebug as L, clearLog as M, closeLogger as N, InputValidationError as O, logger as P, CALLBACK_LOOPBACK_HOST as S, CLI_AUTH_COMMAND as T, isAuthError as _, ui as a, AUTH_TIMEOUT_SECONDS as b, getProcessEnv as c, resolveCliWebUrl as d, captureCliTelemetryResolvedContext as f, getHttpStatus as g, getApiErrorCode as h, fetchLatestNpmPackageVersion as i, throwReportedCliExit as j, ProjectNotFoundError as k, isLocalMode as l, REAUTH_HINT as m, style as n, createHiddenGlobalOptions as o, AUTH_HINT as p, isTTY as r, getEnv as s, ANSI as t, resolveCliServerUrl as u, isNetworkError as v, CALLBACK_PATH as w, AUTH_URL_PATH as x, toErrorMessage as y };
1381
+ export { InputValidationError as A, AUTH_URL_PATH as C, CLI_AUTH_COMMAND as D, CALLBACK_PATH as E, closeLogger as F, logger as I, originalConsole as L, WorkflowResolutionError as M, throwReportedCliExit as N, AuthenticationError as O, clearLog as P, readLogEntries as R, AUTH_TIMEOUT_SECONDS as S, CALLBACK_LOOPBACK_ORIGIN as T, getApiErrorCode as _, CLI_PACKAGE_NAME as a, isNetworkError as b, getProcessEnv as c, resolveCliWebUrl as d, applyCommanderOutput as f, REAUTH_HINT as g, AUTH_HINT as h, fetchLatestNpmPackageVersion as i, ProjectNotFoundError as j, CliExitError as k, isLocalMode as l, captureCliTelemetryResolvedContext as m, style as n, createHiddenGlobalOptions as o, ui as p, isTTY as r, getEnv as s, ANSI as t, resolveCliServerUrl as u, getHttpStatus as v, CALLBACK_LOOPBACK_HOST as w, toErrorMessage as x, isAuthError as y, setDebug as z };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui, n as style, t as ANSI } from "./keystroke.mjs";
4
- import { n as resolveCredentialValuesFromEnv, t as groupCredentialRequirements } from "./credentials-DKrSaaLw.mjs";
3
+ import { n as style, p as ui, t as ANSI } from "./keystroke.mjs";
4
+ import { n as resolveCredentialValuesFromEnv, t as groupCredentialRequirements } from "./credentials-DtwLbee6.mjs";
5
5
  import path from "node:path";
6
6
  import { readFile } from "node:fs/promises";
7
7
  import { parse } from "dotenv";
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { n as isIamJsonMode, t as handleIamError } from "./iam-command-utils-CSZj4XlH.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
+ import { n as isIamJsonMode, t as handleIamError } from "./iam-command-utils-DNDN0wT6.mjs";
7
7
  import Table from "cli-table3";
8
8
  //#region src/commands/invites/list.handler.ts
9
9
  async function handleInvitesList(_options, ctx) {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { t as detectPackageManager } from "./package-manager-DT1EhOkS.mjs";
7
- import { t as renderOperation } from "./render-operation-Bc7Wu1sP.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
+ import { r as detectPackageManager } from "./package-manager-BP3-q8hh.mjs";
7
+ import { t as renderOperation } from "./render-operation-VdEPhoII.mjs";
8
8
  //#region src/commands/operations/list.handler.ts
9
9
  async function handleOperationsList(options, ctx) {
10
10
  const result = await requireClient(ctx).operations.list({
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
5
+ import { c as resolveEffectiveOrganization, l as resolveListActiveOrganizationId, o as requireEffectiveOrganization, r as buildOrgListRows, u as warnUnknownOrganizationOverride } from "./org-context-BI9OSpbb.mjs";
6
+ import { i as renderOrgListJson, r as renderOrgListHuman } from "./org-output-DffU7DKn.mjs";
7
+ //#region src/commands/org/list.handler.ts
8
+ async function handleOrgList(_options, ctx) {
9
+ const { user } = await requireClient(ctx).users.getMe();
10
+ const memberships = user.organizations ?? [];
11
+ const storedOrgIds = new Set(ctx.storedOrgs.map((org) => org.organizationId));
12
+ if (!ctx.jsonMode && ctx.organizationId && (ctx.orgSource === "flag" || ctx.orgSource === "env")) warnUnknownOrganizationOverride({
13
+ organizationId: ctx.organizationId,
14
+ orgSource: ctx.orgSource,
15
+ memberships
16
+ });
17
+ const effective = await resolveEffectiveOrganization(ctx, memberships);
18
+ if (ctx.jsonMode && effective && !effective.isMembershipKnown) requireEffectiveOrganization(effective, ctx);
19
+ const activeOrganizationId = resolveListActiveOrganizationId(effective);
20
+ const rows = buildOrgListRows({
21
+ memberships,
22
+ activeOrganizationId,
23
+ storedOrgIds
24
+ });
25
+ if (ctx.jsonMode) {
26
+ renderOrgListJson({
27
+ rows,
28
+ activeOrganizationId: activeOrganizationId ?? null
29
+ });
30
+ return;
31
+ }
32
+ if (memberships.length === 0) {
33
+ ui.warn("You do not belong to any organization.");
34
+ return;
35
+ }
36
+ renderOrgListHuman(rows);
37
+ }
38
+ //#endregion
39
+ export { handleOrgList };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui, j as throwReportedCliExit, n as style, t as ANSI, y as toErrorMessage } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
3
+ import { N as throwReportedCliExit, n as style, p as ui, t as ANSI, x as toErrorMessage } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
6
  import Table from "cli-table3";
7
7
  //#region src/commands/api-keys/list.handler.ts
8
8
  async function handleApiKeysList(_options, ctx) {
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { N as throwReportedCliExit, n as style, p as ui, t as ANSI } from "./keystroke.mjs";
4
+ import { i as projects } from "./dist-B5jy238v.mjs";
5
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
6
+ import { t as requireWorkflowsDir } from "./resolve-project-DLKlAy0z.mjs";
7
+ import { t as createSpinnerProgress } from "./spinner-progress-BYxlr3lY.mjs";
8
+ import { a as runWorkflowBuild, n as renderBuildFailure } from "./workflow-build-Bm8JoVv4.mjs";
9
+ import { i as formatWorkflowInputFlag, t as formatExampleInputJson } from "./schema-display-sZ6ConJd.mjs";
10
+ //#region src/commands/workflows/list.handler.ts
11
+ function workflowListJsonEntry(artifact) {
12
+ const authoredWorkflowId = artifact.manifest.id;
13
+ return {
14
+ name: artifact.manifest.name,
15
+ id: authoredWorkflowId ?? null,
16
+ filePath: artifact.workflow.resolvedFilePath,
17
+ description: artifact.manifest.description ?? null,
18
+ exportName: artifact.workflow.exportName,
19
+ exampleInput: authoredWorkflowId ? formatExampleInputJson(artifact.manifest.workflowSchemas?.input) : null
20
+ };
21
+ }
22
+ function formatWorkflow(artifact) {
23
+ const name = style(artifact.manifest.name, `${ANSI.bold}${ANSI.cyan}`);
24
+ const filePath = style(artifact.workflow.resolvedFilePath, ANSI.dim);
25
+ const lines = [` ${name}`, ` ${filePath}`];
26
+ if (artifact.manifest.id) lines.push(` ${style(`id: ${artifact.manifest.id}`, ANSI.dim)}`);
27
+ if (artifact.manifest.description) lines.push(` ${artifact.manifest.description}`);
28
+ if (artifact.manifest.id) {
29
+ const inputFlag = formatWorkflowInputFlag(artifact.manifest.workflowSchemas?.input);
30
+ lines.push(` ${style(`$ keystroke workflows test ${artifact.manifest.id} ${inputFlag}`, ANSI.dim)}`);
31
+ lines.push(` ${style(`$ keystroke workflows run ${artifact.manifest.id} ${inputFlag}`, ANSI.dim)}`);
32
+ }
33
+ return lines.join("\n");
34
+ }
35
+ async function handleWorkflowsList(options, ctx) {
36
+ const workflowsDir = await requireWorkflowsDir(options.path);
37
+ await projects.track(workflowsDir);
38
+ const spinner = !ctx.jsonMode ? createSpinnerProgress("[list]") : void 0;
39
+ spinner?.start("Loading workflows...");
40
+ try {
41
+ const { result } = await runWorkflowBuild({
42
+ workflowsDir,
43
+ verbose: false
44
+ });
45
+ spinner?.stop();
46
+ if (ctx.jsonMode) {
47
+ writeJson(result.artifacts.map(workflowListJsonEntry));
48
+ return;
49
+ }
50
+ if (result.artifacts.length === 0) {
51
+ ui.hint(`No workflows found in ${workflowsDir}`);
52
+ return;
53
+ }
54
+ ui.text(result.artifacts.map(formatWorkflow).join("\n\n"));
55
+ ui.br();
56
+ ui.hint(`${result.artifacts.length} workflow(s) found`);
57
+ } catch (error) {
58
+ spinner?.stop();
59
+ renderBuildFailure(error);
60
+ throwReportedCliExit("Failed to list workflows.", { cause: error });
61
+ }
62
+ }
63
+ //#endregion
64
+ export { handleWorkflowsList };
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui, n as style, t as ANSI, v as isNetworkError, y as toErrorMessage } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { t as getIntegrationCatalog } from "./integration-catalog-CiZ62hb_.mjs";
3
+ import { b as isNetworkError, n as style, p as ui, t as ANSI, x as toErrorMessage } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
+ import { t as getIntegrationCatalog } from "./integration-catalog-pSmWHFLQ.mjs";
7
7
  import Table from "cli-table3";
8
8
  //#region src/commands/integrations/list.handler.ts
9
9
  function summarizeConnections(entry, connections) {
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui, c as getProcessEnv, j as throwReportedCliExit } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { a as readManifestsFromOutDir } from "./dist-CTEtWDW4.mjs";
7
- import { n as resolveWorkflowsDir } from "./resolve-project-E9mrh_el.mjs";
8
- import { t as readCredentialEnvMap } from "./credential-env-map-CRs0llf0.mjs";
9
- import { a as loadProjectDotenvFile, i as enrichServerCredentialRow, l as renderCredentialListBlocks, n as buildSyntheticNotOnServerRows, r as collectMergedManifestGroups, t as buildCredentialWorkflowConsumersByGroup } from "./list-enrichment-DP1wEyBZ.mjs";
3
+ import { N as throwReportedCliExit, c as getProcessEnv, p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
+ import { a as readManifestsFromOutDir } from "./dist-BmbFJq8U.mjs";
7
+ import { n as resolveWorkflowsDir } from "./resolve-project-DLKlAy0z.mjs";
8
+ import { t as readCredentialEnvMap } from "./credential-env-map-5a41jLwM.mjs";
9
+ import { a as loadProjectDotenvFile, i as enrichServerCredentialRow, l as renderCredentialListBlocks, n as buildSyntheticNotOnServerRows, r as collectMergedManifestGroups, t as buildCredentialWorkflowConsumersByGroup } from "./list-enrichment-dqbkXJzy.mjs";
10
10
  import dayjs from "dayjs";
11
11
  //#region src/commands/credentials/list/fetch-all-credential-sets.ts
12
12
  /**
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { a as ui } from "./keystroke.mjs";
4
- import { i as writeJson } from "./output-BWcVRt-T.mjs";
5
- import { i as requireClient } from "./context-sgKhRc5v.mjs";
6
- import { t as renderCredential } from "./render-credential-Bn15FEUC.mjs";
3
+ import { p as ui } from "./keystroke.mjs";
4
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
5
+ import { i as requireClient } from "./context-ebZssGCY.mjs";
6
+ import { t as renderCredential } from "./render-credential-D-H1ECDt.mjs";
7
7
  //#region src/commands/credentials/definitions/list.handler.ts
8
8
  async function handleCredentialDefinitionsList(options, ctx) {
9
9
  const result = await requireClient(ctx).credentials.definitions.list({
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { n as style, p as ui, t as ANSI } from "./keystroke.mjs";
4
+ import { i as projects } from "./dist-B5jy238v.mjs";
5
+ import { i as readProjectConfig } from "./project-config-DudGRFPO.mjs";
6
+ import { i as writeJson } from "./output-DnIFEmi5.mjs";
7
+ import { access } from "node:fs/promises";
8
+ import Table from "cli-table3";
9
+ //#region src/commands/projects/projects-list.ts
10
+ const EMPTY_PROJECTS_HINT = "No tracked projects. Run `keystroke init` to get started.";
11
+ async function pathExists(projectPath) {
12
+ try {
13
+ await access(projectPath);
14
+ return true;
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ async function resolveProjectName(entry, exists) {
20
+ if (entry.name) return entry.name;
21
+ if (!exists) return null;
22
+ return (await readProjectConfig(entry.path))?.name ?? null;
23
+ }
24
+ function relativeTime(isoDate) {
25
+ const diff = Date.now() - new Date(isoDate).getTime();
26
+ const seconds = Math.floor(diff / 1e3);
27
+ if (seconds < 60) return `${seconds}s ago`;
28
+ const minutes = Math.floor(seconds / 60);
29
+ if (minutes < 60) return `${minutes}m ago`;
30
+ const hours = Math.floor(minutes / 60);
31
+ if (hours < 24) return `${hours}h ago`;
32
+ return `${Math.floor(hours / 24)}d ago`;
33
+ }
34
+ function sortByLastAccessed(entries) {
35
+ return [...entries].sort((a, b) => new Date(b.lastAccessed).getTime() - new Date(a.lastAccessed).getTime());
36
+ }
37
+ async function buildResolvedProjectList(entries, lastProject) {
38
+ return Promise.all(sortByLastAccessed(entries).map(async (entry) => {
39
+ const exists = await pathExists(entry.path);
40
+ return {
41
+ name: await resolveProjectName(entry, exists),
42
+ path: entry.path,
43
+ lastAccessed: entry.lastAccessed,
44
+ exists,
45
+ isRecent: lastProject === entry.path
46
+ };
47
+ }));
48
+ }
49
+ function toProjectsListJson(entries) {
50
+ return entries.map(({ name, path, lastAccessed, isRecent }) => ({
51
+ name,
52
+ path,
53
+ lastAccessed,
54
+ isRecent
55
+ }));
56
+ }
57
+ function formatProjectsTable(entries) {
58
+ const table = new Table({
59
+ head: [
60
+ "Name",
61
+ "Path",
62
+ "Last Accessed"
63
+ ],
64
+ style: { head: [] }
65
+ });
66
+ for (const entry of entries) {
67
+ const nameCol = entry.name ?? style("(unnamed)", ANSI.dim);
68
+ const pathCol = entry.exists ? entry.path : `${entry.path} ${style("(missing)", ANSI.yellow)}`;
69
+ const indicator = entry.isRecent ? ` ${style("(recent)", ANSI.cyan)}` : "";
70
+ table.push([
71
+ nameCol,
72
+ `${pathCol}${indicator}`,
73
+ relativeTime(entry.lastAccessed)
74
+ ]);
75
+ }
76
+ return table.toString();
77
+ }
78
+ //#endregion
79
+ //#region src/commands/projects/list.handler.ts
80
+ async function handleProjectsList(_options, ctx) {
81
+ const [tracked, lastProject] = await Promise.all([projects.list(), projects.getLast()]);
82
+ if (tracked.length === 0) {
83
+ if (ctx.jsonMode) {
84
+ writeJson([]);
85
+ return;
86
+ }
87
+ ui.hint(EMPTY_PROJECTS_HINT);
88
+ return;
89
+ }
90
+ const resolved = await buildResolvedProjectList(tracked, lastProject);
91
+ if (ctx.jsonMode) {
92
+ writeJson(toProjectsListJson(resolved));
93
+ return;
94
+ }
95
+ ui.text(formatProjectsTable(resolved));
96
+ ui.hint(`\n${resolved.length} project(s) tracked`);
97
+ }
98
+ //#endregion
99
+ export { handleProjectsList };