@hypercli/kit 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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -0
  3. package/dist/base-command.d.ts +58 -0
  4. package/dist/base-command.d.ts.map +1 -0
  5. package/dist/base-command.js +131 -0
  6. package/dist/base-command.js.map +1 -0
  7. package/dist/commands/cookbook/info.d.ts +24 -0
  8. package/dist/commands/cookbook/info.d.ts.map +1 -0
  9. package/dist/commands/cookbook/info.js +142 -0
  10. package/dist/commands/cookbook/info.js.map +1 -0
  11. package/dist/commands/cookbook/list.d.ts +18 -0
  12. package/dist/commands/cookbook/list.d.ts.map +1 -0
  13. package/dist/commands/cookbook/list.js +81 -0
  14. package/dist/commands/cookbook/list.js.map +1 -0
  15. package/dist/commands/kit/info.d.ts +23 -0
  16. package/dist/commands/kit/info.d.ts.map +1 -0
  17. package/dist/commands/kit/info.js +136 -0
  18. package/dist/commands/kit/info.js.map +1 -0
  19. package/dist/commands/kit/install.d.ts +49 -0
  20. package/dist/commands/kit/install.d.ts.map +1 -0
  21. package/dist/commands/kit/install.js +352 -0
  22. package/dist/commands/kit/install.js.map +1 -0
  23. package/dist/commands/kit/list.d.ts +15 -0
  24. package/dist/commands/kit/list.d.ts.map +1 -0
  25. package/dist/commands/kit/list.js +93 -0
  26. package/dist/commands/kit/list.js.map +1 -0
  27. package/dist/commands/kit/uninstall.d.ts +19 -0
  28. package/dist/commands/kit/uninstall.d.ts.map +1 -0
  29. package/dist/commands/kit/uninstall.js +79 -0
  30. package/dist/commands/kit/uninstall.js.map +1 -0
  31. package/dist/commands/kit/update.d.ts +21 -0
  32. package/dist/commands/kit/update.d.ts.map +1 -0
  33. package/dist/commands/kit/update.js +197 -0
  34. package/dist/commands/kit/update.js.map +1 -0
  35. package/dist/commands/recipe/info.d.ts +24 -0
  36. package/dist/commands/recipe/info.d.ts.map +1 -0
  37. package/dist/commands/recipe/info.js +149 -0
  38. package/dist/commands/recipe/info.js.map +1 -0
  39. package/dist/commands/recipe/list.d.ts +18 -0
  40. package/dist/commands/recipe/list.d.ts.map +1 -0
  41. package/dist/commands/recipe/list.js +104 -0
  42. package/dist/commands/recipe/list.js.map +1 -0
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +7 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/flags.d.ts +14 -0
  48. package/dist/lib/flags.d.ts.map +1 -0
  49. package/dist/lib/flags.js +30 -0
  50. package/dist/lib/flags.js.map +1 -0
  51. package/dist/manifest.d.ts +105 -0
  52. package/dist/manifest.d.ts.map +1 -0
  53. package/dist/manifest.js +115 -0
  54. package/dist/manifest.js.map +1 -0
  55. package/dist/source-resolver.d.ts +62 -0
  56. package/dist/source-resolver.d.ts.map +1 -0
  57. package/dist/source-resolver.js +187 -0
  58. package/dist/source-resolver.js.map +1 -0
  59. package/dist/utils/find-project-root.d.ts +32 -0
  60. package/dist/utils/find-project-root.d.ts.map +1 -0
  61. package/dist/utils/find-project-root.js +135 -0
  62. package/dist/utils/find-project-root.js.map +1 -0
  63. package/help/kit/info.md +41 -0
  64. package/help/kit/install.md +52 -0
  65. package/help/kit/list.md +25 -0
  66. package/help/kit/uninstall.md +38 -0
  67. package/help/kit/update.md +35 -0
  68. package/help/kit.md +36 -0
  69. package/oclif.manifest.json +587 -0
  70. package/package.json +92 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Kit Source Resolution
3
+ *
4
+ * Resolves kit sources from various formats (npm, GitHub, local paths, etc.)
5
+ * into a standardized format that package managers can understand.
6
+ */
7
+ /**
8
+ * Resolve a kit source string into a typed, normalized format.
9
+ *
10
+ * Resolution order:
11
+ * 1. Explicit prefixes (file:, github:, jsr:, npm:, git+, etc.)
12
+ * 2. JSR-specific patterns (@jsr/)
13
+ * 3. Git URLs (by protocol or .git extension)
14
+ * 4. HTTP(S) URLs
15
+ * 5. Windows paths (drive letters, UNC paths, backslashes)
16
+ * 6. Unix paths (/, ./, ../, ~/)
17
+ * 7. GitHub/GitLab/Bitbucket shorthand (user/repo)
18
+ * 8. NPM packages (default)
19
+ *
20
+ * @param input - The kit source string from user input
21
+ * @returns Resolved kit source with type and normalized source
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * resolveKitSource('@kit/nextjs')
26
+ * // → { type: 'npm', source: '@kit/nextjs', registry: 'npm' }
27
+ *
28
+ * resolveKitSource('svallory/hypergen-kit-nextjs')
29
+ * // → { type: 'github', source: 'github:svallory/hypergen-kit-nextjs' }
30
+ *
31
+ * resolveKitSource('./my-local-kit')
32
+ * // → { type: 'local', source: './my-local-kit' }
33
+ *
34
+ * resolveKitSource('C:\\Projects\\my-kit')
35
+ * // → { type: 'local', source: 'C:\\Projects\\my-kit' }
36
+ * ```
37
+ */
38
+ export function resolveKitSource(input) {
39
+ const trimmed = input.trim();
40
+ // 1. Explicit prefix (highest priority)
41
+ if (trimmed.startsWith("file:")) {
42
+ return { type: "local", source: trimmed, original: input };
43
+ }
44
+ if (trimmed.startsWith("github:")) {
45
+ return { type: "github", source: trimmed, original: input };
46
+ }
47
+ if (trimmed.startsWith("gitlab:")) {
48
+ return { type: "gitlab", source: trimmed, original: input };
49
+ }
50
+ if (trimmed.startsWith("bitbucket:")) {
51
+ return { type: "bitbucket", source: trimmed, original: input };
52
+ }
53
+ if (trimmed.startsWith("git+")) {
54
+ return { type: "git", source: trimmed, original: input };
55
+ }
56
+ if (trimmed.startsWith("jsr:")) {
57
+ return { type: "jsr", source: trimmed, original: input, registry: "jsr" };
58
+ }
59
+ if (trimmed.startsWith("npm:")) {
60
+ return {
61
+ type: "npm",
62
+ source: trimmed.slice(4),
63
+ original: input,
64
+ registry: "npm",
65
+ };
66
+ }
67
+ // 2. JSR-specific patterns
68
+ if (trimmed.startsWith("@jsr/")) {
69
+ return { type: "jsr", source: trimmed, original: input, registry: "jsr" };
70
+ }
71
+ // 3. Git URLs (by protocol or .git extension)
72
+ if (trimmed.startsWith("git://") || trimmed.startsWith("ssh://git@")) {
73
+ return { type: "git", source: trimmed, original: input };
74
+ }
75
+ // 4. HTTP(S) URLs
76
+ if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
77
+ // Check if it's a .git URL
78
+ if (trimmed.endsWith(".git")) {
79
+ return { type: "git", source: trimmed, original: input };
80
+ }
81
+ // Otherwise treat as tarball URL
82
+ return { type: "url", source: trimmed, original: input };
83
+ }
84
+ // 5. Windows paths (must check before Unix paths to avoid C: being treated as package)
85
+ // Windows drive letter: C:\ or C:/
86
+ if (/^[a-zA-Z]:[/\\]/.test(trimmed)) {
87
+ return { type: "local", source: trimmed, original: input };
88
+ }
89
+ // Windows UNC path: \\server\share
90
+ if (trimmed.startsWith("\\\\")) {
91
+ return { type: "local", source: trimmed, original: input };
92
+ }
93
+ // Windows relative paths: .\ or ..\
94
+ if (trimmed.startsWith(".\\") || trimmed.startsWith("..\\")) {
95
+ return { type: "local", source: trimmed, original: input };
96
+ }
97
+ // 6. Unix paths
98
+ if (trimmed.startsWith("/") || // Absolute
99
+ trimmed.startsWith("./") || // Relative
100
+ trimmed.startsWith("../") || // Parent
101
+ trimmed.startsWith("~/")) {
102
+ // Home
103
+ return { type: "local", source: trimmed, original: input };
104
+ }
105
+ // 7. GitHub/GitLab/Bitbucket shorthand: user/repo
106
+ // Must not start with @ (that's npm scoped packages)
107
+ // Must have exactly one / (to avoid paths like ./foo/bar)
108
+ const shorthandPattern = /^([a-zA-Z0-9][-a-zA-Z0-9_.]*)\/([a-zA-Z0-9][-a-zA-Z0-9_.]*)(@|#)?/;
109
+ if (!trimmed.startsWith("@") && shorthandPattern.test(trimmed)) {
110
+ // Default to GitHub for shorthand
111
+ return { type: "github", source: `github:${trimmed}`, original: input };
112
+ }
113
+ // 8. Default to npm package
114
+ return { type: "npm", source: trimmed, original: input, registry: "npm" };
115
+ }
116
+ /**
117
+ * Build package manager install command for a resolved kit source.
118
+ *
119
+ * @param resolved - The resolved kit source
120
+ * @param pm - Package manager to use
121
+ * @param flags - Installation flags (dev, global)
122
+ * @returns Command string to execute
123
+ */
124
+ export function buildInstallCommand(resolved, pm, flags) {
125
+ // Special handling for JSR packages
126
+ if (resolved.type === "jsr") {
127
+ if (pm === "bun") {
128
+ // Bun supports JSR natively
129
+ return buildStandardCommand(pm, resolved.source, flags);
130
+ }
131
+ // For npm/pnpm/yarn, use npx jsr add
132
+ const jsrPackage = resolved.source.replace("jsr:", "").replace("@jsr/", "@");
133
+ return `npx jsr add ${jsrPackage}`;
134
+ }
135
+ // All other types work with standard package manager commands
136
+ return buildStandardCommand(pm, resolved.source, flags);
137
+ }
138
+ /**
139
+ * Build standard package manager command
140
+ */
141
+ function buildStandardCommand(pm, source, flags) {
142
+ const escapedSource = shellEscape(source);
143
+ if (pm === "bun") {
144
+ return flags.global
145
+ ? `bun add -g ${escapedSource}`
146
+ : flags.dev
147
+ ? `bun add -d ${escapedSource}`
148
+ : `bun add ${escapedSource}`;
149
+ }
150
+ if (pm === "pnpm") {
151
+ return flags.global
152
+ ? `pnpm add -g ${escapedSource}`
153
+ : flags.dev
154
+ ? `pnpm add -D ${escapedSource}`
155
+ : `pnpm add ${escapedSource}`;
156
+ }
157
+ if (pm === "yarn") {
158
+ return flags.global
159
+ ? `yarn global add ${escapedSource}`
160
+ : flags.dev
161
+ ? `yarn add -D ${escapedSource}`
162
+ : `yarn add ${escapedSource}`;
163
+ }
164
+ // npm
165
+ return flags.global
166
+ ? `npm install -g ${escapedSource}`
167
+ : flags.dev
168
+ ? `npm install -D ${escapedSource}`
169
+ : `npm install ${escapedSource}`;
170
+ }
171
+ /**
172
+ * Shell-escape a kit source string to prevent command injection.
173
+ *
174
+ * @param source - The kit source string
175
+ * @returns Shell-escaped string safe for command execution
176
+ * @throws Error if source contains dangerous shell metacharacters
177
+ */
178
+ function shellEscape(source) {
179
+ // Reject obvious shell injection characters
180
+ const dangerousChars = /[;&|`$(){}!><\n\r]/;
181
+ if (dangerousChars.test(source)) {
182
+ throw new Error(`Invalid kit specifier: "${source}"\nKit sources must not contain shell metacharacters.`);
183
+ }
184
+ // Wrap in single quotes for shell safety, escaping internal single quotes
185
+ return `'${source.replace(/'/g, "'\\''")}'`;
186
+ }
187
+ //# sourceMappingURL=source-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-resolver.js","sourceRoot":"","sources":["../src/source-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Find the project root directory by looking for package.json
3
+ * with monorepo detection support
4
+ */
5
+ export interface ProjectRootInfo {
6
+ /** The project root directory */
7
+ root: string;
8
+ /** Whether this is a monorepo workspace */
9
+ isMonorepo: boolean;
10
+ /** If in a monorepo, the workspace root (otherwise same as root) */
11
+ workspaceRoot: string;
12
+ /** The package.json that was found */
13
+ packageJsonPath: string;
14
+ }
15
+ /**
16
+ * Find the project root, with monorepo detection
17
+ *
18
+ * This function:
19
+ * 1. Finds the nearest package.json from startDir
20
+ * 2. If it's a workspace package, walks up to find the monorepo root
21
+ * 3. Returns both the immediate project root and workspace root (if in monorepo)
22
+ *
23
+ * @param startDir - Directory to start searching from (defaults to process.cwd())
24
+ * @returns Project root information
25
+ */
26
+ export declare function findProjectRoot(startDir?: string): ProjectRootInfo;
27
+ /**
28
+ * Get the directory where .hyper/kits should be located
29
+ * Always uses the workspace root if in a monorepo
30
+ */
31
+ export declare function getKitsDirectory(startDir?: string): string;
32
+ //# sourceMappingURL=find-project-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-project-root.d.ts","sourceRoot":"","sources":["../../src/utils/find-project-root.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,eAAe;IAC/B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,UAAU,EAAE,OAAO,CAAC;IACpB,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAC;CACxB;AA0ED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,eAAe,CAwDjF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAGzE"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Find the project root directory by looking for package.json
3
+ * with monorepo detection support
4
+ */
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { dirname, join } from "node:path";
7
+ import createDebug from "debug";
8
+ const debug = createDebug("hypergen:utils:project-root");
9
+ /**
10
+ * Find the nearest package.json walking up from startDir
11
+ */
12
+ function findNearestPackageJson(startDir) {
13
+ let dir = startDir;
14
+ while (dir !== "/" && dir !== ".") {
15
+ const packageJsonPath = join(dir, "package.json");
16
+ if (existsSync(packageJsonPath)) {
17
+ return packageJsonPath;
18
+ }
19
+ const parent = join(dir, "..");
20
+ if (parent === dir)
21
+ break;
22
+ dir = parent;
23
+ }
24
+ return null;
25
+ }
26
+ /**
27
+ * Check if a package.json indicates a monorepo root
28
+ */
29
+ function isMonorepoRoot(packageJsonPath) {
30
+ try {
31
+ const content = readFileSync(packageJsonPath, "utf-8");
32
+ const packageJson = JSON.parse(content);
33
+ // Check for common monorepo indicators
34
+ return !!((packageJson.workspaces || // npm/yarn/pnpm workspaces
35
+ packageJson.bolt?.workspaces || // bolt
36
+ existsSync(join(dirname(packageJsonPath), "pnpm-workspace.yaml")) || // pnpm
37
+ existsSync(join(dirname(packageJsonPath), "lerna.json"))) // lerna
38
+ );
39
+ }
40
+ catch (error) {
41
+ debug("Error reading package.json: %s", error);
42
+ return false;
43
+ }
44
+ }
45
+ /**
46
+ * Check if we're inside a monorepo workspace package
47
+ */
48
+ function isWorkspacePackage(packageJsonPath) {
49
+ try {
50
+ const content = readFileSync(packageJsonPath, "utf-8");
51
+ JSON.parse(content); // Validate JSON format
52
+ // Workspace packages typically don't have a "private: true" at root
53
+ // but we need to check if there's a parent with workspaces
54
+ const dir = dirname(packageJsonPath);
55
+ const parentPackageJson = findNearestPackageJson(join(dir, ".."));
56
+ if (parentPackageJson && isMonorepoRoot(parentPackageJson)) {
57
+ debug("Found workspace package at %s with monorepo root at %s", packageJsonPath, parentPackageJson);
58
+ return true;
59
+ }
60
+ return false;
61
+ }
62
+ catch (error) {
63
+ debug("Error checking if workspace package: %s", error);
64
+ return false;
65
+ }
66
+ }
67
+ /**
68
+ * Find the project root, with monorepo detection
69
+ *
70
+ * This function:
71
+ * 1. Finds the nearest package.json from startDir
72
+ * 2. If it's a workspace package, walks up to find the monorepo root
73
+ * 3. Returns both the immediate project root and workspace root (if in monorepo)
74
+ *
75
+ * @param startDir - Directory to start searching from (defaults to process.cwd())
76
+ * @returns Project root information
77
+ */
78
+ export function findProjectRoot(startDir = process.cwd()) {
79
+ debug("Finding project root from: %s", startDir);
80
+ // Find nearest package.json
81
+ const nearestPackageJson = findNearestPackageJson(startDir);
82
+ if (!nearestPackageJson) {
83
+ debug("No package.json found, using startDir as root");
84
+ return {
85
+ root: startDir,
86
+ isMonorepo: false,
87
+ workspaceRoot: startDir,
88
+ packageJsonPath: startDir,
89
+ };
90
+ }
91
+ const immediateRoot = dirname(nearestPackageJson);
92
+ debug("Found package.json at: %s", nearestPackageJson);
93
+ // Check if this is a monorepo root
94
+ if (isMonorepoRoot(nearestPackageJson)) {
95
+ debug("This is a monorepo root");
96
+ return {
97
+ root: immediateRoot,
98
+ isMonorepo: true,
99
+ workspaceRoot: immediateRoot,
100
+ packageJsonPath: nearestPackageJson,
101
+ };
102
+ }
103
+ // Check if we're in a workspace package
104
+ if (isWorkspacePackage(nearestPackageJson)) {
105
+ // Walk up to find the monorepo root
106
+ const workspaceRootPackageJson = findNearestPackageJson(join(immediateRoot, ".."));
107
+ if (workspaceRootPackageJson) {
108
+ const workspaceRoot = dirname(workspaceRootPackageJson);
109
+ debug("Found monorepo workspace root at: %s", workspaceRoot);
110
+ return {
111
+ root: immediateRoot,
112
+ isMonorepo: true,
113
+ workspaceRoot,
114
+ packageJsonPath: nearestPackageJson,
115
+ };
116
+ }
117
+ }
118
+ // Not a monorepo or couldn't find workspace root
119
+ debug("Not in a monorepo");
120
+ return {
121
+ root: immediateRoot,
122
+ isMonorepo: false,
123
+ workspaceRoot: immediateRoot,
124
+ packageJsonPath: nearestPackageJson,
125
+ };
126
+ }
127
+ /**
128
+ * Get the directory where .hyper/kits should be located
129
+ * Always uses the workspace root if in a monorepo
130
+ */
131
+ export function getKitsDirectory(startDir = process.cwd()) {
132
+ const projectInfo = findProjectRoot(startDir);
133
+ return join(projectInfo.workspaceRoot, ".hyper", "kits");
134
+ }
135
+ //# sourceMappingURL=find-project-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-project-root.js","sourceRoot":"","sources":["../../src/utils/find-project-root.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ # hyper kit info
2
+
3
+ Show detailed information about an installed kit, including its cookbooks, recipes, and optionally its variables and source provenance.
4
+
5
+ ## Usage
6
+
7
+ `hyper kit info <kit> [flags]`
8
+
9
+ ## Arguments
10
+
11
+ | Argument | Description |
12
+ |----------|-------------|
13
+ | `kit` | Name of the installed kit |
14
+
15
+ ## Flags
16
+
17
+ | Flag | Description |
18
+ |------|-------------|
19
+ | `--variables` | Show variable details defined by the kit |
20
+ | `--source` | Show provenance info (path, URL, commit, branch, tag) |
21
+ | `--recipes` | Expand recipes with descriptions |
22
+ | `--steps` | Show step list with tool types (recipe info only) |
23
+ | `--json` | Output as JSON |
24
+ | `--cwd <dir>` | Working directory |
25
+ | `-d, --debug` | Enable debug output |
26
+
27
+ ## Examples
28
+
29
+ ```sh
30
+ # Show kit overview with cookbooks and recipes
31
+ hyper kit info starlight
32
+
33
+ # Include variable definitions
34
+ hyper kit info starlight --variables
35
+
36
+ # Include source and install metadata
37
+ hyper kit info starlight --source
38
+
39
+ # Output as JSON
40
+ hyper kit info starlight --json
41
+ ```
@@ -0,0 +1,52 @@
1
+ # hyper kit install
2
+
3
+ Install a kit from npm, JSR, GitHub, or local path.
4
+
5
+ ## Usage
6
+
7
+ `hyper kit install <kit> [flags]`
8
+
9
+ ## Arguments
10
+
11
+ | Argument | Description |
12
+ |----------|-------------|
13
+ | `kit` | Kit to install — accepts an npm package name, JSR package, GitHub shorthand (`user/repo`), full Git URL, or local path |
14
+
15
+ ## Flags
16
+
17
+ | Flag | Description |
18
+ |------|-------------|
19
+ | `--dev` | Install as a dev dependency (npm/JSR only) |
20
+ | `-n, --name <name>` | Name to use for the kit directory (default: auto-detected from source) |
21
+ | `-f, --force` | Replace an existing kit even if already installed |
22
+ | `--cwd <dir>` | Working directory |
23
+ | `-d, --debug` | Enable debug output |
24
+
25
+ ## Examples
26
+
27
+ ```sh
28
+ # Install from npm
29
+ hyper kit install @kit/nextjs
30
+
31
+ # Install from GitHub shorthand
32
+ hyper kit install svallory/hypergen-kit-nextjs
33
+
34
+ # Install from JSR
35
+ hyper kit install jsr:@std/path
36
+
37
+ # Install from a local directory
38
+ hyper kit install ./local-kit
39
+
40
+ # Install from a full Git URL
41
+ hyper kit install https://github.com/user/repo.git
42
+
43
+ # Install with a custom name
44
+ hyper kit install svallory/hypergen-kit-nextjs --name nextjs
45
+
46
+ # Force reinstall (change source or refresh)
47
+ hyper kit install ./local-kit --force
48
+ ```
49
+
50
+ ## Notes
51
+
52
+ npm and JSR kits are installed into `node_modules` via your project's package manager. GitHub, Git URL, and local path kits are copied to `.hyper/kits/<name>/` and tracked in the kit manifest.
@@ -0,0 +1,25 @@
1
+ # hyper kit list
2
+
3
+ List all kits installed in the current project, including their cookbooks and available recipes.
4
+
5
+ ## Usage
6
+
7
+ `hyper kit list [flags]`
8
+
9
+ ## Flags
10
+
11
+ | Flag | Description |
12
+ |------|-------------|
13
+ | `--json` | Output as JSON |
14
+ | `--cwd <dir>` | Working directory |
15
+ | `-d, --debug` | Enable debug output |
16
+
17
+ ## Examples
18
+
19
+ ```sh
20
+ # List installed kits with cookbooks and recipes
21
+ hyper kit list
22
+
23
+ # Output as JSON for scripting
24
+ hyper kit list --json
25
+ ```
@@ -0,0 +1,38 @@
1
+ # hyper kit uninstall
2
+
3
+ Remove an installed kit from your project. Also available as `hyper kit remove`.
4
+
5
+ ## Usage
6
+
7
+ `hyper kit uninstall <kit> [flags]`
8
+
9
+ ## Arguments
10
+
11
+ | Argument | Description |
12
+ |----------|-------------|
13
+ | `kit` | Name of the kit to uninstall |
14
+
15
+ ## Flags
16
+
17
+ | Flag | Description |
18
+ |------|-------------|
19
+ | `-f, --force` | Skip the confirmation prompt |
20
+ | `--cwd <dir>` | Working directory |
21
+ | `-d, --debug` | Enable debug output |
22
+
23
+ ## Examples
24
+
25
+ ```sh
26
+ # Remove a kit (prompts for confirmation)
27
+ hyper kit uninstall starlight
28
+
29
+ # Remove without confirmation
30
+ hyper kit uninstall starlight --force
31
+
32
+ # Alias
33
+ hyper kit remove starlight
34
+ ```
35
+
36
+ ## Notes
37
+
38
+ For npm/JSR kits, the package is removed via your project's package manager. For GitHub, Git URL, and local path kits, the directory under `.hyper/kits/` is deleted and the kit is removed from the manifest.
@@ -0,0 +1,35 @@
1
+ # hyper kit update
2
+
3
+ Update installed kits by re-fetching from their original source. Either update a single kit by name or all kits at once with `--all`.
4
+
5
+ ## Usage
6
+
7
+ `hyper kit update [kit] [flags]`
8
+
9
+ ## Arguments
10
+
11
+ | Argument | Description |
12
+ |----------|-------------|
13
+ | `kit` | Name of the kit to update (omit when using `--all`) |
14
+
15
+ ## Flags
16
+
17
+ | Flag | Description |
18
+ |------|-------------|
19
+ | `--all` | Update all installed kits |
20
+ | `--cwd <dir>` | Working directory |
21
+ | `-d, --debug` | Enable debug output |
22
+
23
+ ## Examples
24
+
25
+ ```sh
26
+ # Update a single kit
27
+ hyper kit update nextjs
28
+
29
+ # Update all installed kits
30
+ hyper kit update --all
31
+ ```
32
+
33
+ ## Notes
34
+
35
+ npm and JSR kits are updated through your package manager — this command will print the appropriate command to run (e.g. `bun update <package>`). For GitHub, Git URL, and local path kits, the existing `.hyper/kits/<name>/` directory is replaced by re-fetching from the recorded source.
package/help/kit.md ADDED
@@ -0,0 +1,36 @@
1
+ # hyper kit
2
+
3
+ Manage the kits installed in your project. Kits are generator packages that provide recipes and cookbooks for code generation.
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `hyper kit install <source>` | Install a kit from npm, JSR, GitHub, or local path |
10
+ | `hyper kit list` | List all installed kits |
11
+ | `hyper kit info <kit>` | Show detailed information about a kit |
12
+ | `hyper kit uninstall <kit>` | Remove an installed kit |
13
+ | `hyper kit update [kit]` | Update installed kits from their original source |
14
+
15
+ ## Examples
16
+
17
+ ```sh
18
+ # Install a kit from GitHub
19
+ hyper kit install svallory/hypergen-kit-nextjs
20
+
21
+ # List all installed kits
22
+ hyper kit list
23
+
24
+ # Show details for a specific kit
25
+ hyper kit info nextjs
26
+
27
+ # Update all kits at once
28
+ hyper kit update --all
29
+
30
+ # Remove a kit
31
+ hyper kit uninstall nextjs
32
+ ```
33
+
34
+ ## How kits are stored
35
+
36
+ Kits installed from GitHub, Git URLs, or local paths are stored in `.hyper/kits/` inside your project. Kits installed from npm or JSR are installed as regular node_modules using your project's package manager.