@usehyper/cli 0.1.0

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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/package.json +40 -0
  4. package/registry-sources/agent-rules/README.md +12 -0
  5. package/registry-sources/agent-rules/files/.cursor/rules/hyper.md +178 -0
  6. package/registry-sources/agent-rules/files/AGENTS.md +64 -0
  7. package/registry-sources/agent-rules/manifest.json +15 -0
  8. package/src/__tests__/add.test.ts +125 -0
  9. package/src/__tests__/cli.test.ts +50 -0
  10. package/src/__tests__/security.test.ts +101 -0
  11. package/src/args.ts +38 -0
  12. package/src/bin.ts +77 -0
  13. package/src/commands/add.ts +232 -0
  14. package/src/commands/bench.ts +185 -0
  15. package/src/commands/build.ts +146 -0
  16. package/src/commands/client.ts +78 -0
  17. package/src/commands/dev.ts +53 -0
  18. package/src/commands/diff.ts +80 -0
  19. package/src/commands/env.ts +92 -0
  20. package/src/commands/help.ts +42 -0
  21. package/src/commands/init.ts +119 -0
  22. package/src/commands/list.ts +46 -0
  23. package/src/commands/mcp.ts +51 -0
  24. package/src/commands/openapi.ts +50 -0
  25. package/src/commands/routes.ts +45 -0
  26. package/src/commands/security.ts +233 -0
  27. package/src/commands/test.ts +191 -0
  28. package/src/commands/typecheck.ts +19 -0
  29. package/src/commands/update.ts +91 -0
  30. package/src/commands/version.ts +16 -0
  31. package/src/config/index.ts +30 -0
  32. package/src/config/io.ts +112 -0
  33. package/src/config/tsconfig.ts +138 -0
  34. package/src/config/types.ts +63 -0
  35. package/src/entry.ts +42 -0
  36. package/src/index.ts +57 -0
  37. package/src/load-app.ts +89 -0
  38. package/src/registry/__tests__/env-writer.test.ts +83 -0
  39. package/src/registry/apply.ts +268 -0
  40. package/src/registry/client.ts +127 -0
  41. package/src/registry/env-writer.ts +135 -0
  42. package/src/registry/index.ts +18 -0
  43. package/src/registry/rewrite.ts +177 -0
  44. package/src/registry/snapshot.ts +1018 -0
  45. package/src/registry/types.ts +62 -0
  46. package/src/templates.ts +141 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Wire-format types for the Hyper registry. Mirrors `tools/registry-types.ts`
3
+ * one-to-one — kept here so the CLI has zero workspace deps on `tools/`.
4
+ *
5
+ * Anyone can host their own registry by serving JSON in this shape at:
6
+ * GET <registryUrl>/r/index.json
7
+ * GET <registryUrl>/r/<name>.json
8
+ * GET <registryUrl>/r/<name>@<version>.json
9
+ */
10
+
11
+ export interface RegistryFile {
12
+ readonly path: string
13
+ readonly contents: string
14
+ readonly sha256: string
15
+ /**
16
+ * Optional override for where this file lands in the user's project.
17
+ * Placeholders: `@base/...`, `@root/...`, `@cursor/...`, `~/...`.
18
+ * See `tools/registry-types.ts` for full semantics.
19
+ */
20
+ readonly target?: string
21
+ }
22
+
23
+ export interface RegistryComponent {
24
+ /** JSON Schema URL emitted by the registry — present in HTTP responses. */
25
+ readonly $schema?: string
26
+ readonly name: string
27
+ readonly version: string
28
+ readonly title?: string
29
+ readonly description: string
30
+ readonly readme: string
31
+ readonly registryDeps: readonly string[]
32
+ readonly peerDeps: Readonly<Record<string, string>>
33
+ readonly optionalPeerDeps: Readonly<Record<string, string>>
34
+ readonly files: readonly RegistryFile[]
35
+ readonly subpaths: Readonly<Record<string, string>>
36
+ /**
37
+ * Env vars the component needs at runtime. The CLI appends them to
38
+ * `.env.local` (existing keys preserved). `${random:hex:N}` and
39
+ * `${random:base64:N}` are resolved locally with `crypto.randomBytes`.
40
+ */
41
+ readonly envVars?: Readonly<Record<string, string>>
42
+ /** Markdown blurb printed after `hyper add`. */
43
+ readonly docs?: string
44
+ }
45
+
46
+ export interface RegistryIndexEntry {
47
+ readonly name: string
48
+ readonly version: string
49
+ readonly title?: string
50
+ readonly description: string
51
+ readonly registryDeps: readonly string[]
52
+ readonly fileCount: number
53
+ }
54
+
55
+ export interface RegistryIndex {
56
+ /** JSON Schema URL emitted by the registry — present in HTTP responses. */
57
+ readonly $schema?: string
58
+ readonly schema: 1
59
+ readonly generatedAt: string
60
+ readonly source: string
61
+ readonly components: readonly RegistryIndexEntry[]
62
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Built-in scaffolding templates.
3
+ *
4
+ * After `hyper init`, the CLI runs `hyper add core` to copy the framework
5
+ * source into `<baseDir>/core/`. Templates therefore have NO `@usehyper/*`
6
+ * runtime deps — imports use `@hyper/core` and resolve via tsconfig paths.
7
+ */
8
+
9
+ export interface Template {
10
+ readonly name: string
11
+ /** Files emitted by `hyper init`. Paths are relative to the project root. */
12
+ readonly files: Readonly<Record<string, string>>
13
+ /** Components installed via `hyper add` after the files are written. */
14
+ readonly components: readonly string[]
15
+ /**
16
+ * Peer deps that should land in `package.json` immediately. The CLI prints
17
+ * a one-liner suggesting `bun add` for these.
18
+ */
19
+ readonly extraPeerDeps?: Readonly<Record<string, string>>
20
+ }
21
+
22
+ const MINIMAL_APP = `import { Hyper, ok } from "@hyper/core"
23
+
24
+ export default new Hyper()
25
+ .get("/health", () => ok({ ok: true }))
26
+ .get("/hello/:name", ({ params }) => ok({ hello: params.name }))
27
+ .listen(Number(process.env.PORT ?? 3000))
28
+ `
29
+
30
+ const MINIMAL_TSCONFIG = `{
31
+ "compilerOptions": {
32
+ "target": "ES2024",
33
+ "lib": ["ES2024"],
34
+ "module": "preserve",
35
+ "moduleResolution": "bundler",
36
+ "strict": true,
37
+ "noUncheckedIndexedAccess": true,
38
+ "exactOptionalPropertyTypes": true,
39
+ "verbatimModuleSyntax": true,
40
+ "allowImportingTsExtensions": true,
41
+ "noEmit": true,
42
+ "skipLibCheck": true,
43
+ "types": ["@types/bun"],
44
+ "paths": {
45
+ "@hyper/*": ["./src/hyper/*", "./src/hyper/*/index.ts"]
46
+ }
47
+ },
48
+ "include": ["src/**/*.ts", "test/**/*.ts"]
49
+ }
50
+ `
51
+
52
+ const MINIMAL_PKG = `{
53
+ "name": "my-hyper-app",
54
+ "type": "module",
55
+ "private": true,
56
+ "scripts": {
57
+ "dev": "bun --hot src/app.ts",
58
+ "start": "bun src/app.ts",
59
+ "test": "bun test",
60
+ "typecheck": "tsc --noEmit"
61
+ },
62
+ "devDependencies": {
63
+ "@types/bun": "latest",
64
+ "typescript": "^5.6.0"
65
+ }
66
+ }
67
+ `
68
+
69
+ const API_APP = `import { Hyper, ok, route } from "@hyper/core"
70
+ import { hyperLog } from "@hyper/log"
71
+
72
+ const health = route.get("/health").handle(() => ok({ ok: true }))
73
+ const listUsers = route.get("/users").handle(() => ok([{ id: "u1", name: "Ada" }]))
74
+ const getUser = route
75
+ .get("/users/:id")
76
+ .handle(({ params }) => ok({ id: params.id, name: "Ada" }))
77
+
78
+ export default new Hyper()
79
+ .use(hyperLog({ service: "my-hyper-app" }))
80
+ .use([health, listUsers, getUser])
81
+ .listen(Number(process.env.PORT ?? 3000))
82
+ `
83
+
84
+ const HEALTH_TEST = `import { describe, expect, test } from "bun:test"
85
+ import app from "../src/app.ts"
86
+
87
+ describe("app", () => {
88
+ test("GET /health returns ok", async () => {
89
+ const res = await app.fetch(new Request("http://localhost/health"))
90
+ expect(res.status).toBe(200)
91
+ expect(await res.json()).toEqual({ ok: true })
92
+ })
93
+ })
94
+ `
95
+
96
+ const README = `# my-hyper-app
97
+
98
+ A Hyper app. The framework source lives under \`src/hyper/<component>/\` —
99
+ managed by the \`hyper\` CLI.
100
+
101
+ ## Develop
102
+
103
+ \`\`\`bash
104
+ bun install
105
+ bun run dev
106
+ \`\`\`
107
+
108
+ ## Manage components
109
+
110
+ \`\`\`bash
111
+ hyper list # browse the registry
112
+ hyper add cors # add a component
113
+ hyper diff log # inspect drift on an installed component
114
+ hyper update # pull the latest registry versions
115
+ \`\`\`
116
+ `
117
+
118
+ export const TEMPLATES: Record<string, Template> = {
119
+ minimal: {
120
+ name: "minimal",
121
+ files: {
122
+ "src/app.ts": MINIMAL_APP,
123
+ "tsconfig.json": MINIMAL_TSCONFIG,
124
+ "package.json": MINIMAL_PKG,
125
+ "test/app.test.ts": HEALTH_TEST,
126
+ "README.md": README,
127
+ },
128
+ components: ["core"],
129
+ },
130
+ api: {
131
+ name: "api",
132
+ files: {
133
+ "src/app.ts": API_APP,
134
+ "tsconfig.json": MINIMAL_TSCONFIG,
135
+ "package.json": MINIMAL_PKG,
136
+ "test/app.test.ts": HEALTH_TEST,
137
+ "README.md": README,
138
+ },
139
+ components: ["core", "log"],
140
+ },
141
+ }