@take-out/cli 0.0.93 → 0.0.94

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 (180) hide show
  1. package/README.md +0 -32
  2. package/cli.mjs +2 -2
  3. package/dist/cjs/cli.cjs +33 -11
  4. package/dist/cjs/cli.js +32 -12
  5. package/dist/cjs/cli.js.map +1 -1
  6. package/dist/cjs/commands/run.cjs +6 -5
  7. package/dist/cjs/commands/run.js +6 -5
  8. package/dist/cjs/commands/run.js.map +1 -1
  9. package/dist/cjs/commands/script.cjs +2 -3
  10. package/dist/cjs/commands/script.js +2 -3
  11. package/dist/cjs/commands/script.js.map +1 -1
  12. package/dist/cjs/index.cjs +2 -40
  13. package/dist/cjs/index.js +2 -36
  14. package/dist/cjs/index.js.map +1 -1
  15. package/dist/cjs/utils/env-setup.js.map +1 -1
  16. package/dist/cjs/utils/script-listing.cjs +22 -29
  17. package/dist/cjs/utils/script-listing.js +20 -39
  18. package/dist/cjs/utils/script-listing.js.map +1 -1
  19. package/dist/cjs/utils/script-utils.cjs +46 -47
  20. package/dist/cjs/utils/script-utils.js +41 -46
  21. package/dist/cjs/utils/script-utils.js.map +1 -1
  22. package/dist/esm/cli.js +32 -11
  23. package/dist/esm/cli.js.map +1 -1
  24. package/dist/esm/cli.mjs +32 -10
  25. package/dist/esm/cli.mjs.map +1 -1
  26. package/dist/esm/commands/run.js +6 -5
  27. package/dist/esm/commands/run.js.map +1 -1
  28. package/dist/esm/commands/run.mjs +6 -5
  29. package/dist/esm/commands/run.mjs.map +1 -1
  30. package/dist/esm/commands/script.js +3 -8
  31. package/dist/esm/commands/script.js.map +1 -1
  32. package/dist/esm/commands/script.mjs +4 -4
  33. package/dist/esm/commands/script.mjs.map +1 -1
  34. package/dist/esm/index.js +2 -80
  35. package/dist/esm/index.js.map +1 -1
  36. package/dist/esm/index.mjs +2 -6
  37. package/dist/esm/index.mjs.map +1 -1
  38. package/dist/esm/utils/env-setup.js +2 -4
  39. package/dist/esm/utils/env-setup.js.map +1 -1
  40. package/dist/esm/utils/env-setup.mjs +1 -1
  41. package/dist/esm/utils/env-setup.mjs.map +1 -1
  42. package/dist/esm/utils/script-listing.js +25 -40
  43. package/dist/esm/utils/script-listing.js.map +1 -1
  44. package/dist/esm/utils/script-listing.mjs +24 -30
  45. package/dist/esm/utils/script-listing.mjs.map +1 -1
  46. package/dist/esm/utils/script-utils.js +42 -54
  47. package/dist/esm/utils/script-utils.js.map +1 -1
  48. package/dist/esm/utils/script-utils.mjs +45 -46
  49. package/dist/esm/utils/script-utils.mjs.map +1 -1
  50. package/package.json +6 -5
  51. package/src/cli.ts +42 -14
  52. package/src/commands/run.ts +10 -8
  53. package/src/commands/script.ts +4 -8
  54. package/src/index.ts +1 -63
  55. package/src/utils/env-setup.ts +3 -7
  56. package/src/utils/script-listing.ts +46 -70
  57. package/src/utils/script-utils.ts +51 -105
  58. package/types/cli.d.ts +1 -1
  59. package/types/commands/run.d.ts.map +1 -1
  60. package/types/commands/script.d.ts +1 -1
  61. package/types/commands/script.d.ts.map +1 -1
  62. package/types/index.d.ts +1 -11
  63. package/types/index.d.ts.map +1 -1
  64. package/types/utils/env-setup.d.ts.map +1 -1
  65. package/types/utils/script-listing.d.ts +2 -3
  66. package/types/utils/script-listing.d.ts.map +1 -1
  67. package/types/utils/script-utils.d.ts +3 -5
  68. package/types/utils/script-utils.d.ts.map +1 -1
  69. package/dist/cjs/cli.native.js +0 -72
  70. package/dist/cjs/cli.native.js.map +0 -1
  71. package/dist/cjs/commands/changed.native.js +0 -310
  72. package/dist/cjs/commands/changed.native.js.map +0 -1
  73. package/dist/cjs/commands/docs.native.js +0 -553
  74. package/dist/cjs/commands/docs.native.js.map +0 -1
  75. package/dist/cjs/commands/env-setup.native.js +0 -96
  76. package/dist/cjs/commands/env-setup.native.js.map +0 -1
  77. package/dist/cjs/commands/onboard.native.js +0 -628
  78. package/dist/cjs/commands/onboard.native.js.map +0 -1
  79. package/dist/cjs/commands/run.native.js +0 -169
  80. package/dist/cjs/commands/run.native.js.map +0 -1
  81. package/dist/cjs/commands/script.native.js +0 -491
  82. package/dist/cjs/commands/script.native.js.map +0 -1
  83. package/dist/cjs/commands/sync.native.js +0 -228
  84. package/dist/cjs/commands/sync.native.js.map +0 -1
  85. package/dist/cjs/commands/upgrade.cjs +0 -90
  86. package/dist/cjs/commands/upgrade.js +0 -78
  87. package/dist/cjs/commands/upgrade.js.map +0 -6
  88. package/dist/cjs/commands/upgrade.native.js +0 -95
  89. package/dist/cjs/commands/upgrade.native.js.map +0 -1
  90. package/dist/cjs/constants/ascii.native.js +0 -39
  91. package/dist/cjs/constants/ascii.native.js.map +0 -1
  92. package/dist/cjs/index.native.js +0 -67
  93. package/dist/cjs/index.native.js.map +0 -1
  94. package/dist/cjs/types.native.js +0 -19
  95. package/dist/cjs/types.native.js.map +0 -1
  96. package/dist/cjs/utils/env-categories.native.js +0 -288
  97. package/dist/cjs/utils/env-categories.native.js.map +0 -1
  98. package/dist/cjs/utils/env-setup.native.js +0 -281
  99. package/dist/cjs/utils/env-setup.native.js.map +0 -1
  100. package/dist/cjs/utils/env.native.js +0 -130
  101. package/dist/cjs/utils/env.native.js.map +0 -1
  102. package/dist/cjs/utils/files.native.js +0 -278
  103. package/dist/cjs/utils/files.native.js.map +0 -1
  104. package/dist/cjs/utils/parallel-runner.native.js +0 -144
  105. package/dist/cjs/utils/parallel-runner.native.js.map +0 -1
  106. package/dist/cjs/utils/ports.native.js +0 -123
  107. package/dist/cjs/utils/ports.native.js.map +0 -1
  108. package/dist/cjs/utils/prerequisites.native.js +0 -128
  109. package/dist/cjs/utils/prerequisites.native.js.map +0 -1
  110. package/dist/cjs/utils/prompts.native.js +0 -167
  111. package/dist/cjs/utils/prompts.native.js.map +0 -1
  112. package/dist/cjs/utils/script-listing.native.js +0 -191
  113. package/dist/cjs/utils/script-listing.native.js.map +0 -1
  114. package/dist/cjs/utils/script-utils.native.js +0 -126
  115. package/dist/cjs/utils/script-utils.native.js.map +0 -6
  116. package/dist/cjs/utils/sync.native.js +0 -93
  117. package/dist/cjs/utils/sync.native.js.map +0 -1
  118. package/dist/cjs/utils/welcome.cjs +0 -50
  119. package/dist/cjs/utils/welcome.js +0 -42
  120. package/dist/cjs/utils/welcome.js.map +0 -6
  121. package/dist/cjs/utils/welcome.native.js +0 -47
  122. package/dist/cjs/utils/welcome.native.js.map +0 -6
  123. package/dist/esm/cli.native.js +0 -69
  124. package/dist/esm/cli.native.js.map +0 -1
  125. package/dist/esm/commands/changed.native.js +0 -273
  126. package/dist/esm/commands/changed.native.js.map +0 -1
  127. package/dist/esm/commands/docs.native.js +0 -515
  128. package/dist/esm/commands/docs.native.js.map +0 -1
  129. package/dist/esm/commands/env-setup.native.js +0 -59
  130. package/dist/esm/commands/env-setup.native.js.map +0 -1
  131. package/dist/esm/commands/onboard.native.js +0 -591
  132. package/dist/esm/commands/onboard.native.js.map +0 -1
  133. package/dist/esm/commands/run.native.js +0 -132
  134. package/dist/esm/commands/run.native.js.map +0 -1
  135. package/dist/esm/commands/script.native.js +0 -445
  136. package/dist/esm/commands/script.native.js.map +0 -1
  137. package/dist/esm/commands/sync.native.js +0 -190
  138. package/dist/esm/commands/sync.native.js.map +0 -1
  139. package/dist/esm/commands/upgrade.js +0 -65
  140. package/dist/esm/commands/upgrade.js.map +0 -6
  141. package/dist/esm/commands/upgrade.mjs +0 -67
  142. package/dist/esm/commands/upgrade.mjs.map +0 -1
  143. package/dist/esm/commands/upgrade.native.js +0 -69
  144. package/dist/esm/commands/upgrade.native.js.map +0 -1
  145. package/dist/esm/constants/ascii.native.js +0 -12
  146. package/dist/esm/constants/ascii.native.js.map +0 -1
  147. package/dist/esm/index.native.js +0 -7
  148. package/dist/esm/index.native.js.map +0 -1
  149. package/dist/esm/types.native.js +0 -2
  150. package/dist/esm/types.native.js.map +0 -1
  151. package/dist/esm/utils/env-categories.native.js +0 -246
  152. package/dist/esm/utils/env-categories.native.js.map +0 -1
  153. package/dist/esm/utils/env-setup.native.js +0 -243
  154. package/dist/esm/utils/env-setup.native.js.map +0 -1
  155. package/dist/esm/utils/env.native.js +0 -99
  156. package/dist/esm/utils/env.native.js.map +0 -1
  157. package/dist/esm/utils/files.native.js +0 -247
  158. package/dist/esm/utils/files.native.js.map +0 -1
  159. package/dist/esm/utils/parallel-runner.native.js +0 -118
  160. package/dist/esm/utils/parallel-runner.native.js.map +0 -1
  161. package/dist/esm/utils/ports.native.js +0 -93
  162. package/dist/esm/utils/ports.native.js.map +0 -1
  163. package/dist/esm/utils/prerequisites.native.js +0 -97
  164. package/dist/esm/utils/prerequisites.native.js.map +0 -1
  165. package/dist/esm/utils/prompts.native.js +0 -115
  166. package/dist/esm/utils/prompts.native.js.map +0 -1
  167. package/dist/esm/utils/script-listing.native.js +0 -151
  168. package/dist/esm/utils/script-listing.native.js.map +0 -1
  169. package/dist/esm/utils/script-utils.native.js +0 -112
  170. package/dist/esm/utils/script-utils.native.js.map +0 -6
  171. package/dist/esm/utils/sync.native.js +0 -53
  172. package/dist/esm/utils/sync.native.js.map +0 -1
  173. package/dist/esm/utils/welcome.js +0 -21
  174. package/dist/esm/utils/welcome.js.map +0 -6
  175. package/dist/esm/utils/welcome.mjs +0 -15
  176. package/dist/esm/utils/welcome.mjs.map +0 -1
  177. package/dist/esm/utils/welcome.native.js +0 -18
  178. package/dist/esm/utils/welcome.native.js.map +0 -1
  179. package/types/utils/welcome.d.ts +0 -6
  180. package/types/utils/welcome.d.ts.map +0 -1
package/src/cli.ts CHANGED
@@ -1,10 +1,11 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
 
3
3
  /**
4
4
  * Takeout CLI
5
5
  * Interactive tools for Takeout starter kit setup and management
6
6
  */
7
7
 
8
+ import { spawnSync } from 'node:child_process'
8
9
  import { existsSync, statSync } from 'node:fs'
9
10
  import { join } from 'node:path'
10
11
 
@@ -22,23 +23,27 @@ function isScriptCategory(name: string): boolean {
22
23
  }
23
24
  }
24
25
 
25
- // check if a name is a local script in ./scripts/
26
- function isLocalScript(name: string): boolean {
26
+ // find a local script in ./scripts/, returns path or null
27
+ function findLocalScript(name: string): string | null {
27
28
  const scriptsDir = join(process.cwd(), 'scripts')
28
29
  const normalizedName = name.replace(/:/g, '/')
29
30
 
30
31
  for (const ext of ['.ts', '.js', '']) {
31
32
  const scriptPath = join(scriptsDir, `${normalizedName}${ext}`)
32
33
  if (existsSync(scriptPath)) {
33
- return true
34
+ return scriptPath
34
35
  }
35
36
  }
36
37
 
37
- return false
38
+ return null
38
39
  }
39
40
 
40
- // check if a name could be a built-in script
41
- function isBuiltInScript(name: string): boolean {
41
+ function isLocalScript(name: string): boolean {
42
+ return findLocalScript(name) !== null
43
+ }
44
+
45
+ // find a built-in script in @take-out/scripts, returns path or null
46
+ function findBuiltInScript(name: string): string | null {
42
47
  try {
43
48
  const resolved = import.meta.resolve('@take-out/scripts/package.json')
44
49
  const packageJsonPath = new URL(resolved).pathname
@@ -52,19 +57,22 @@ function isBuiltInScript(name: string): boolean {
52
57
  for (const ext of ['.ts', '.js', '']) {
53
58
  const scriptPath = join(srcPath, `${normalizedName}${ext}`)
54
59
  if (existsSync(scriptPath)) {
55
- return true
60
+ return scriptPath
56
61
  }
57
62
  }
58
63
  } catch {
59
64
  // package not found or error resolving
60
65
  }
61
66
 
62
- return false
67
+ return null
68
+ }
69
+
70
+ function isBuiltInScript(name: string): boolean {
71
+ return findBuiltInScript(name) !== null
63
72
  }
64
73
 
65
- // detect if running as tko (shorthand mode)
66
- const isShorthand =
67
- process.argv[1]?.endsWith('tko') || process.argv[1]?.includes('/.bin/tko')
74
+ // always enable shorthand mode — both tko and takeout resolve to this file
75
+ const isShorthand = true
68
76
 
69
77
  if (isShorthand) {
70
78
  // in shorthand mode, treat first arg as potential script command
@@ -86,21 +94,27 @@ if (isShorthand) {
86
94
  ]
87
95
 
88
96
  if (firstArg && !builtInCommands.includes(firstArg)) {
97
+ // resolve the script name for category/script patterns
98
+ let resolvedScriptName: string | undefined
99
+
89
100
  // check if it's a script category or has a slash (category/script format)
90
101
  // Do a lazy check only on the specific arg, not scanning all directories
91
102
  if (isScriptCategory(firstArg)) {
92
103
  // If there's a second arg, treat it as a script within the category
93
104
  // e.g., "tko aws health" becomes "tko run aws/health"
94
105
  if (secondArg && !secondArg.startsWith('-')) {
106
+ resolvedScriptName = `${firstArg}/${secondArg}`
95
107
  // Replace the two args with the combined path
96
- process.argv.splice(2, 2, `${firstArg}/${secondArg}`)
108
+ process.argv.splice(2, 2, resolvedScriptName)
97
109
  }
98
110
  // inject "run" into args to use the run command directly
99
111
  process.argv.splice(2, 0, 'run')
100
112
  } else if (firstArg?.includes('/')) {
113
+ resolvedScriptName = firstArg
101
114
  // inject "run" into args to use the run command directly
102
115
  process.argv.splice(2, 0, 'run')
103
116
  } else if (isLocalScript(firstArg) || isBuiltInScript(firstArg)) {
117
+ resolvedScriptName = firstArg
104
118
  // check if it's a local or built-in script (like update-deps, clean, etc.)
105
119
  // use "run" to avoid citty parsing issues with hyphens
106
120
  process.argv.splice(2, 0, 'run')
@@ -108,6 +122,20 @@ if (isShorthand) {
108
122
  // assume it's a script command, inject "script" into args
109
123
  process.argv.splice(2, 0, 'script')
110
124
  }
125
+
126
+ // bypass citty for --help on scripts so the script handles it itself
127
+ const hasHelp = process.argv.includes('--help') || process.argv.includes('-h')
128
+ if (resolvedScriptName && hasHelp) {
129
+ const scriptPath = findLocalScript(resolvedScriptName) || findBuiltInScript(resolvedScriptName)
130
+ if (scriptPath) {
131
+ const flagArgs = process.argv.slice(3).filter((a) => a !== resolvedScriptName)
132
+ const result = spawnSync('bun', [scriptPath, ...flagArgs], {
133
+ stdio: 'inherit',
134
+ shell: false,
135
+ })
136
+ process.exit(result.status || 0)
137
+ }
138
+ }
111
139
  }
112
140
  }
113
141
 
@@ -131,7 +159,7 @@ const main = defineCommand({
131
159
  const hasArgs = process.argv.length > 2
132
160
  if (!hasArgs) {
133
161
  const { listAllScripts } = await import('./utils/script-listing')
134
- listAllScripts()
162
+ await listAllScripts()
135
163
  }
136
164
  },
137
165
  })
@@ -59,7 +59,7 @@ export const runCommand = defineCommand({
59
59
  }
60
60
 
61
61
  // Lazy load script functions only when needed
62
- const { discoverScripts, getScriptMetadata } =
62
+ const { discoverScripts, getAllScriptMetadata } =
63
63
  await import('../utils/script-utils')
64
64
  const pc = (await import('picocolors')).default
65
65
 
@@ -67,21 +67,23 @@ export const runCommand = defineCommand({
67
67
  const categoryScripts = discoverScripts(categoryPath)
68
68
 
69
69
  if (categoryScripts.size > 0) {
70
+ const metadata = await getAllScriptMetadata(categoryScripts)
71
+
70
72
  console.info()
71
- console.info(pc.bold(pc.cyan(`📁 ${firstArg} Scripts`)))
73
+ console.info(pc.bold(pc.cyan(`${firstArg} Scripts`)))
72
74
  console.info()
73
75
 
74
- for (const [name, path] of categoryScripts) {
76
+ for (const [name] of categoryScripts) {
75
77
  const shortName = name.replace(`${firstArg}/`, '')
76
- const metadata = getScriptMetadata(path)
78
+ const meta = metadata.get(name)
77
79
  let line = ` ${pc.green(shortName)}`
78
80
 
79
- if (metadata.description) {
80
- line += pc.dim(` - ${metadata.description}`)
81
+ if (meta?.description) {
82
+ line += pc.dim(` - ${meta.description}`)
81
83
  }
82
84
 
83
- if (metadata.args && metadata.args.length > 0) {
84
- line += pc.dim(` [${metadata.args.join(', ')}]`)
85
+ if (meta?.args && meta.args.length > 0) {
86
+ line += pc.dim(` [${meta.args.join(', ')}]`)
85
87
  }
86
88
 
87
89
  console.info(line)
@@ -74,11 +74,7 @@ export function findScript(name: string): string | null {
74
74
  return null
75
75
  }
76
76
 
77
- export {
78
- formatScriptList,
79
- listAllScripts,
80
- listCategoryScripts,
81
- } from '../utils/script-listing'
77
+ export { listAllScripts, listCategoryScripts } from '../utils/script-listing'
82
78
 
83
79
  // run a script
84
80
  async function runScript(scriptPath: string, args: string[]): Promise<void> {
@@ -372,12 +368,12 @@ export const scriptCommand = defineCommand({
372
368
 
373
369
  // if no name provided, list all available scripts
374
370
  if (!scriptName) {
375
- listAllScripts(false) // don't show built-in commands in script listing
371
+ await listAllScripts(false)
376
372
  return
377
373
  }
378
374
 
379
- // check if this is a category listing (e.g., "takeout script ci")
380
- if (listCategoryScripts(scriptName)) {
375
+ // check if this is a category listing
376
+ if (await listCategoryScripts(scriptName)) {
381
377
  return
382
378
  }
383
379
 
package/src/index.ts CHANGED
@@ -1,63 +1 @@
1
- /**
2
- * Takeout CLI - Library exports
3
- *
4
- * Use these utilities programmatically in your own scripts
5
- */
6
-
7
- // Types
8
- export type * from './types'
9
-
10
- // Prerequisites checking
11
- export {
12
- checkAllPrerequisites,
13
- checkBun,
14
- checkDocker,
15
- checkGit,
16
- checkNode,
17
- hasRequiredPrerequisites,
18
- } from './utils/prerequisites'
19
-
20
- // Port management
21
- export {
22
- checkAllPorts,
23
- checkPort,
24
- getConflictingPorts,
25
- hasPortConflicts,
26
- TAKEOUT_PORTS,
27
- } from './utils/ports'
28
-
29
- // Environment file operations
30
- export {
31
- copyEnvFile,
32
- createEnvLocal,
33
- envFileExists,
34
- generateSecret,
35
- readEnvVariable,
36
- updateEnvVariable,
37
- } from './utils/env'
38
-
39
- // File operations
40
- export {
41
- checkOnboarded,
42
- markOnboarded,
43
- updateAppConfig,
44
- updatePackageJson,
45
- } from './utils/files'
46
-
47
- // Prompts (for building custom CLIs)
48
- export {
49
- confirmContinue,
50
- displayOutro,
51
- displayPortConflicts,
52
- displayPrerequisites,
53
- displayWelcome,
54
- promptPassword,
55
- promptSelect,
56
- promptText,
57
- showError,
58
- showInfo,
59
- showSpinner,
60
- showStep,
61
- showSuccess,
62
- showWarning,
63
- } from './utils/prompts'
1
+ export { cmd } from '@take-out/scripts/cmd'
@@ -1,15 +1,11 @@
1
- import { existsSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { writeFileSync } from 'node:fs'
2
2
  import { resolve } from 'node:path'
3
3
 
4
4
  import * as clack from '@clack/prompts'
5
5
  import pc from 'picocolors'
6
6
 
7
- import { updateEnvVariable, readEnvVariable, envFileExists, copyEnvFile } from './env'
8
- import {
9
- envCategories,
10
- getRequiredCategories,
11
- getOptionalCategories,
12
- } from './env-categories'
7
+ import { copyEnvFile, envFileExists, readEnvVariable, updateEnvVariable } from './env'
8
+ import { envCategories } from './env-categories'
13
9
 
14
10
  import type { EnvCategory, EnvVariable } from '../types'
15
11
 
@@ -8,13 +8,17 @@ import { fileURLToPath } from 'node:url'
8
8
 
9
9
  import pc from 'picocolors'
10
10
 
11
- import { discoverScripts, getLocalScriptsDir, getScriptMetadata } from './script-utils'
11
+ import {
12
+ type ScriptMetadata,
13
+ discoverScripts,
14
+ getAllScriptMetadata,
15
+ getLocalScriptsDir,
16
+ } from './script-utils'
12
17
 
13
18
  // find scripts package root using import.meta.resolve
14
19
  function findScriptsPackageRoot(): string | null {
15
20
  try {
16
21
  const resolved = import.meta.resolve('@take-out/scripts/package.json')
17
- // use fileURLToPath for proper cross-platform handling
18
22
  const packageJsonPath = fileURLToPath(new URL(resolved))
19
23
  const packageRoot = join(packageJsonPath, '..')
20
24
  const srcPath = join(packageRoot, 'src')
@@ -22,18 +26,18 @@ function findScriptsPackageRoot(): string | null {
22
26
  if (existsSync(srcPath)) {
23
27
  return srcPath
24
28
  }
25
- } catch (err) {
26
- // scripts package not found, that's ok for hybrid mode
29
+ } catch {
30
+ // scripts package not found
27
31
  }
28
32
 
29
33
  return null
30
34
  }
31
35
 
32
- // format script listing
33
- export function formatScriptList(
36
+ // format script listing with pre-fetched metadata
37
+ function formatScriptList(
34
38
  title: string,
35
39
  scripts: Map<string, string>,
36
- showDescriptions: boolean = false
40
+ metadata: Map<string, ScriptMetadata>
37
41
  ): void {
38
42
  if (scripts.size === 0) return
39
43
 
@@ -41,65 +45,48 @@ export function formatScriptList(
41
45
  console.info(pc.bold(pc.cyan(title)))
42
46
  console.info()
43
47
 
44
- // group by category
45
48
  const categories = new Map<string, Array<[string, string]>>()
46
49
  const rootScripts: Array<[string, string]> = []
47
50
 
48
51
  for (const [name, path] of scripts) {
49
52
  if (name.includes('/')) {
50
- const parts = name.split('/')
51
- if (parts.length > 0 && parts[0]) {
52
- const category = parts[0]
53
- if (!categories.has(category)) {
54
- categories.set(category, [])
55
- }
56
- categories.get(category)!.push([name, path])
53
+ const category = name.split('/')[0]!
54
+ if (!categories.has(category)) {
55
+ categories.set(category, [])
57
56
  }
57
+ categories.get(category)!.push([name, path])
58
58
  } else {
59
59
  rootScripts.push([name, path])
60
60
  }
61
61
  }
62
62
 
63
- // display root scripts
64
- for (const [name, path] of rootScripts) {
63
+ for (const [name] of rootScripts) {
65
64
  let line = ` ${pc.green(name)}`
66
-
67
- if (showDescriptions) {
68
- const metadata = getScriptMetadata(path)
69
- if (metadata.description) {
70
- line += pc.dim(` - ${metadata.description}`)
71
- }
65
+ const meta = metadata.get(name)
66
+ if (meta?.description) {
67
+ line += pc.dim(` - ${meta.description}`)
72
68
  }
73
-
74
69
  console.info(line)
75
70
  }
76
71
 
77
- // display categorized scripts
78
72
  for (const [category, categoryScripts] of categories) {
79
73
  console.info()
80
74
  console.info(` ${pc.yellow(category)}/`)
81
75
 
82
- for (const [name, path] of categoryScripts) {
83
- const shortName = name.startsWith(`${category}/`)
84
- ? name.substring(category.length + 1)
85
- : name
76
+ for (const [name] of categoryScripts) {
77
+ const shortName = name.substring(category.length + 1)
86
78
  let line = ` ${pc.green(shortName)}`
87
-
88
- if (showDescriptions) {
89
- const metadata = getScriptMetadata(path)
90
- if (metadata.description) {
91
- line += pc.dim(` - ${metadata.description}`)
92
- }
79
+ const meta = metadata.get(name)
80
+ if (meta?.description) {
81
+ line += pc.dim(` - ${meta.description}`)
93
82
  }
94
-
95
83
  console.info(line)
96
84
  }
97
85
  }
98
86
  }
99
87
 
100
- // list all available scripts (local and built-in)
101
- export function listAllScripts(includeCommands = true): void {
102
- // show header with description
88
+ // list all available scripts
89
+ export async function listAllScripts(includeCommands = true) {
103
90
  console.info()
104
91
  console.info(pc.bold(pc.cyan('Takeout CLI - Project Scripts & Commands')))
105
92
  console.info()
@@ -107,8 +94,7 @@ export function listAllScripts(includeCommands = true): void {
107
94
  console.info()
108
95
 
109
96
  if (includeCommands) {
110
- // Show built-in CLI commands
111
- console.info(pc.bold(pc.cyan('🛠️ Built-in Commands')))
97
+ console.info(pc.bold(pc.cyan('Built-in Commands')))
112
98
  console.info()
113
99
  console.info(` ${pc.green('onboard')} - Setup wizard for new projects`)
114
100
  console.info(` ${pc.green('docs')} - View documentation`)
@@ -124,70 +110,60 @@ export function listAllScripts(includeCommands = true): void {
124
110
  const builtInDir = findScriptsPackageRoot()
125
111
  const builtInScripts = builtInDir ? discoverScripts(builtInDir) : new Map()
126
112
 
113
+ const allScripts = new Map([...localScripts, ...builtInScripts])
114
+ const metadata = await getAllScriptMetadata(allScripts)
115
+
127
116
  if (localScripts.size > 0) {
128
- formatScriptList('📁 Local Scripts', localScripts, true)
117
+ formatScriptList('Local Scripts', localScripts, metadata)
129
118
  }
130
119
 
131
120
  if (builtInScripts.size > 0) {
132
- formatScriptList('📦 Built-in Scripts', builtInScripts, true)
121
+ formatScriptList('Built-in Scripts', builtInScripts, metadata)
133
122
  }
134
123
 
135
124
  if (localScripts.size === 0 && builtInScripts.size === 0) {
136
125
  console.info()
137
126
  console.info(pc.yellow('No scripts found'))
138
127
  console.info()
139
- console.info(
140
- pc.dim(`Create scripts in ${relative(process.cwd(), getLocalScriptsDir())}/`)
141
- )
128
+ console.info(pc.dim(`Create scripts in ${relative(process.cwd(), getLocalScriptsDir())}/`))
142
129
  console.info(pc.dim(`Or install @take-out/scripts package for built-in scripts`))
143
130
  }
144
131
 
145
132
  console.info()
146
133
  console.info(pc.bold('Usage:'))
147
- console.info(
148
- ` ${pc.cyan('tko <command>')} ${pc.dim('Run a built-in command')}`
149
- )
150
- console.info(
151
- ` ${pc.cyan('tko <script-name>')} ${pc.dim('Execute direct script (e.g., tko onboard)')}`
152
- )
153
- console.info(
154
- ` ${pc.cyan('tko <group-name> <script-name>')} ${pc.dim('Execute nested script (e.g., tko web build)')}`
155
- )
134
+ console.info(` ${pc.cyan('tko <command>')} ${pc.dim('Run a built-in command')}`)
135
+ console.info(` ${pc.cyan('tko <script-name>')} ${pc.dim('Execute direct script')}`)
136
+ console.info(` ${pc.cyan('tko <group> <script>')} ${pc.dim('Execute nested script')}`)
156
137
  console.info(` ${pc.cyan('tko script new <path>')} ${pc.dim('Create a new script')}`)
157
138
  console.info()
158
- console.info(pc.bold('Examples:'))
159
- console.info(` ${pc.cyan('tko web build')} ${pc.dim('Build web platform')}`)
160
- console.info(
161
- ` ${pc.cyan('tko check types')} ${pc.dim('Run TypeScript type checking')}`
162
- )
163
- console.info()
164
139
  }
165
140
 
166
141
  // check if a name is a category and list its scripts
167
- export function listCategoryScripts(categoryName: string): boolean {
142
+ export async function listCategoryScripts(categoryName: string): Promise<boolean> {
168
143
  const localDir = getLocalScriptsDir()
169
144
  const categoryPath = join(localDir, categoryName)
170
145
 
171
146
  if (existsSync(categoryPath) && statSync(categoryPath).isDirectory()) {
172
- // list scripts in this category
173
147
  const categoryScripts = discoverScripts(categoryPath)
174
148
 
175
149
  if (categoryScripts.size > 0) {
150
+ const metadata = await getAllScriptMetadata(categoryScripts)
151
+
176
152
  console.info()
177
- console.info(pc.bold(pc.cyan(`📁 ${categoryName} Scripts`)))
153
+ console.info(pc.bold(pc.cyan(`${categoryName} Scripts`)))
178
154
  console.info()
179
155
 
180
- for (const [name, path] of categoryScripts) {
156
+ for (const [name] of categoryScripts) {
181
157
  const shortName = name.replace(`${categoryName}/`, '')
182
- const metadata = getScriptMetadata(path)
158
+ const meta = metadata.get(name)
183
159
  let line = ` ${pc.green(shortName)}`
184
160
 
185
- if (metadata.description) {
186
- line += pc.dim(` - ${metadata.description}`)
161
+ if (meta?.description) {
162
+ line += pc.dim(` - ${meta.description}`)
187
163
  }
188
164
 
189
- if (metadata.args && metadata.args.length > 0) {
190
- line += pc.dim(` [${metadata.args.join(', ')}]`)
165
+ if (meta?.args && meta.args.length > 0) {
166
+ line += pc.dim(` [${meta.args.join(', ')}]`)
191
167
  }
192
168
 
193
169
  console.info(line)