@getjack/jack 0.1.2 → 0.1.4

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 (91) hide show
  1. package/README.md +77 -29
  2. package/package.json +54 -47
  3. package/src/commands/agents.ts +145 -10
  4. package/src/commands/down.ts +110 -102
  5. package/src/commands/feedback.ts +189 -0
  6. package/src/commands/init.ts +8 -12
  7. package/src/commands/login.ts +88 -0
  8. package/src/commands/logout.ts +14 -0
  9. package/src/commands/logs.ts +21 -0
  10. package/src/commands/mcp.ts +134 -7
  11. package/src/commands/new.ts +43 -17
  12. package/src/commands/open.ts +13 -6
  13. package/src/commands/projects.ts +269 -143
  14. package/src/commands/secrets.ts +413 -0
  15. package/src/commands/services.ts +96 -123
  16. package/src/commands/ship.ts +5 -1
  17. package/src/commands/whoami.ts +31 -0
  18. package/src/index.ts +218 -144
  19. package/src/lib/agent-files.ts +34 -0
  20. package/src/lib/agents.ts +390 -22
  21. package/src/lib/asset-hash.ts +50 -0
  22. package/src/lib/auth/client.ts +115 -0
  23. package/src/lib/auth/constants.ts +5 -0
  24. package/src/lib/auth/guard.ts +57 -0
  25. package/src/lib/auth/index.ts +18 -0
  26. package/src/lib/auth/store.ts +54 -0
  27. package/src/lib/binding-validator.ts +136 -0
  28. package/src/lib/build-helper.ts +211 -0
  29. package/src/lib/cloudflare-api.ts +24 -0
  30. package/src/lib/config.ts +5 -6
  31. package/src/lib/control-plane.ts +295 -0
  32. package/src/lib/debug.ts +3 -1
  33. package/src/lib/deploy-mode.ts +93 -0
  34. package/src/lib/deploy-upload.ts +92 -0
  35. package/src/lib/errors.ts +2 -0
  36. package/src/lib/github.ts +31 -1
  37. package/src/lib/hooks.ts +4 -12
  38. package/src/lib/intent.ts +88 -0
  39. package/src/lib/jsonc.ts +125 -0
  40. package/src/lib/local-paths.test.ts +902 -0
  41. package/src/lib/local-paths.ts +258 -0
  42. package/src/lib/managed-deploy.ts +175 -0
  43. package/src/lib/managed-down.ts +159 -0
  44. package/src/lib/mcp-config.ts +55 -34
  45. package/src/lib/names.ts +9 -29
  46. package/src/lib/project-operations.ts +676 -249
  47. package/src/lib/project-resolver.ts +476 -0
  48. package/src/lib/registry.ts +76 -37
  49. package/src/lib/resources.ts +196 -0
  50. package/src/lib/schema.ts +30 -1
  51. package/src/lib/storage/file-filter.ts +1 -0
  52. package/src/lib/storage/index.ts +5 -1
  53. package/src/lib/telemetry.ts +14 -0
  54. package/src/lib/tty.ts +15 -0
  55. package/src/lib/zip-packager.ts +255 -0
  56. package/src/mcp/resources/index.ts +8 -2
  57. package/src/mcp/server.ts +32 -4
  58. package/src/mcp/tools/index.ts +35 -13
  59. package/src/mcp/types.ts +6 -0
  60. package/src/mcp/utils.ts +1 -1
  61. package/src/templates/index.ts +42 -4
  62. package/src/templates/types.ts +13 -0
  63. package/templates/CLAUDE.md +166 -0
  64. package/templates/api/.jack.json +4 -0
  65. package/templates/api/bun.lock +1 -0
  66. package/templates/api/wrangler.jsonc +5 -0
  67. package/templates/hello/.jack.json +28 -0
  68. package/templates/hello/package.json +10 -0
  69. package/templates/hello/src/index.ts +11 -0
  70. package/templates/hello/tsconfig.json +11 -0
  71. package/templates/hello/wrangler.jsonc +5 -0
  72. package/templates/miniapp/.jack.json +15 -4
  73. package/templates/miniapp/bun.lock +135 -40
  74. package/templates/miniapp/index.html +1 -0
  75. package/templates/miniapp/package.json +3 -1
  76. package/templates/miniapp/public/.well-known/farcaster.json +7 -5
  77. package/templates/miniapp/public/icon.png +0 -0
  78. package/templates/miniapp/public/og.png +0 -0
  79. package/templates/miniapp/schema.sql +8 -0
  80. package/templates/miniapp/src/App.tsx +254 -3
  81. package/templates/miniapp/src/components/ShareSheet.tsx +147 -0
  82. package/templates/miniapp/src/hooks/useAI.ts +35 -0
  83. package/templates/miniapp/src/hooks/useGuestbook.ts +11 -1
  84. package/templates/miniapp/src/hooks/useShare.ts +76 -0
  85. package/templates/miniapp/src/index.css +15 -0
  86. package/templates/miniapp/src/lib/api.ts +2 -1
  87. package/templates/miniapp/src/worker.ts +515 -1
  88. package/templates/miniapp/wrangler.jsonc +15 -3
  89. package/LICENSE +0 -190
  90. package/src/commands/cloud.ts +0 -230
  91. package/templates/api/wrangler.toml +0 -3
package/README.md CHANGED
@@ -1,14 +1,57 @@
1
- # jack
1
+ <p align="center">
2
+ <h1 align="center">jack</h1>
3
+ <p align="center"><strong>Ship before you forget why you started.</strong></p>
4
+ </p>
2
5
 
3
- CLI for vibecoders to rapidly deploy to Cloudflare Workers.
6
+ <p align="center">
7
+ <a href="https://www.npmjs.com/package/@getjack/jack"><img src="https://img.shields.io/npm/v/@getjack/jack" alt="npm"></a>
8
+ <a href="https://github.com/getjack-org/jack/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="license"></a>
9
+ <a href="https://docs.getjack.org"><img src="https://img.shields.io/badge/docs-getjack.org-green" alt="docs"></a>
10
+ <a href="https://discord.gg/fb64krv48R"><img src="https://img.shields.io/badge/discord-community-5865F2" alt="discord"></a>
11
+ </p>
4
12
 
5
- ## Install
13
+ ---
14
+
15
+ <p align="center">
16
+ <img src="https://docs.getjack.org/jack-demo.gif" alt="jack demo" width="600">
17
+ </p>
18
+
19
+ ---
20
+
21
+ You're vibecoding. Ideas are flowing. You want to ship.
22
+
23
+ But first: config files, deployment setup, secret management, debugging infrastructure errors...
24
+
25
+ **30 minutes later, the spark is gone.**
26
+
27
+ jack removes the friction between your idea and a live URL.
6
28
 
7
29
  ```bash
8
- # Install Bun (if needed)
9
- curl -fsSL https://bun.sh/install | bash
30
+ bunx @getjack/jack new my-app # deployed. live. done.
31
+ ```
32
+
33
+ That's it. Write code. Ship again with `jack ship`. Stay in flow.
34
+
35
+ ---
36
+
37
+ ## Why jack
38
+
39
+ **Instant deployment** — `jack new` creates AND deploys. You have a live URL before your first commit.
40
+
41
+ **Works with your agent** — Claude Code, Cursor, Codex, whatever. Every project includes AI context files so your agent understands the stack from prompt one.
42
+
43
+ **Roaming secrets** — Configure once, use across all projects. No more per-project secret ceremony.
44
+
45
+ **Project tracking** — 100 experiments scattered everywhere? `jack ls` finds them all.
10
46
 
11
- # Run directly
47
+ **No lock-in** — Standard config files, standard TypeScript. Your projects work without jack installed.
48
+
49
+ ---
50
+
51
+ ## Quick Start
52
+
53
+ ```bash
54
+ # One command to create and deploy
12
55
  bunx @getjack/jack new my-app
13
56
 
14
57
  # Or install globally
@@ -16,40 +59,45 @@ bun add -g @getjack/jack
16
59
  jack new my-app
17
60
  ```
18
61
 
19
- ## Usage
62
+ You'll need [Bun](https://bun.sh) and a Cloudflare account (free tier works).
20
63
 
21
- ```bash
22
- # Create a new project
23
- jack new my-app
64
+ ---
24
65
 
25
- # Deploy to Cloudflare Workers
26
- jack ship
66
+ ## Commands
27
67
 
28
- # List your projects
29
- jack list
30
- ```
68
+ | Command | What it does |
69
+ |---------|--------------|
70
+ | `jack new <name>` | Create and deploy a new project |
71
+ | `jack ship` | Deploy current project |
72
+ | `jack ls` | Show all your projects |
73
+ | `jack open` | Open project in browser |
74
+ | `jack secrets` | Manage project secrets |
75
+ | `jack feedback` | Share feedback or report issues |
31
76
 
32
- ## Requirements
77
+ Full documentation at **[docs.getjack.org](https://docs.getjack.org)**
33
78
 
34
- - [Bun](https://bun.sh) >= 1.0.0
35
- - Cloudflare account (for deployments)
79
+ ---
36
80
 
37
- ## Releasing
81
+ ## Who This Is For
38
82
 
39
- This project uses [Semantic Versioning](https://semver.org/).
83
+ Builders who ship constantly. You spin up new projects all the time, and suddenly you have dozens scattered across your machine—each with its own env vars, secrets, and deploy setup you've already forgotten.
40
84
 
41
- ```bash
42
- # Bump version, commit, and tag
43
- npm version patch # 0.1.1 → 0.1.2 (bug fixes)
44
- npm version minor # 0.1.1 → 0.2.0 (new features)
45
- npm version major # 0.1.1 → 1.0.0 (breaking changes)
85
+ jack keeps you organized. One command to ship, one place to find everything, zero setup overhead. Stay creative, skip the ceremony.
46
86
 
47
- # Push to trigger publish
48
- git push && git push --tags
49
- ```
87
+ ---
88
+
89
+ ## Philosophy
50
90
 
51
- GitHub Actions automatically publishes to npm when a version tag is pushed.
91
+ In Gibson's *Neuromancer*, "jacking in" means plugging directly into cyberspace. The body becomes irrelevant—you're pure thought in the matrix.
92
+
93
+ jack handles the infrastructure so you stay in creative flow. The boring parts disappear. You just build.
94
+
95
+ ---
52
96
 
53
97
  ## License
54
98
 
55
99
  Apache-2.0
100
+
101
+ <p align="center">
102
+ <i>Every deployment friction point is a creative thought lost.</i>
103
+ </p>
package/package.json CHANGED
@@ -1,49 +1,56 @@
1
1
  {
2
- "name": "@getjack/jack",
3
- "version": "0.1.2",
4
- "description": "CLI for vibecoders to rapidly deploy to Cloudflare Workers",
5
- "license": "Apache-2.0",
6
- "type": "module",
7
- "bin": {
8
- "jack": "./src/index.ts"
9
- },
10
- "files": [
11
- "src",
12
- "templates"
13
- ],
14
- "engines": {
15
- "bun": ">=1.0.0"
16
- },
17
- "repository": {
18
- "type": "git",
19
- "url": "https://github.com/getjack-org/jack"
20
- },
21
- "publishConfig": {
22
- "access": "public"
23
- },
24
- "keywords": [
25
- "cli",
26
- "cloudflare",
27
- "workers",
28
- "deploy",
29
- "vibecode"
30
- ],
31
- "scripts": {
32
- "dev": "bun run src/index.ts",
33
- "build": "bun build --compile src/index.ts --outfile dist/jack",
34
- "lint": "biome check .",
35
- "format": "biome format --write ."
36
- },
37
- "devDependencies": {
38
- "@biomejs/biome": "^1.9.0",
39
- "bun-types": "latest"
40
- },
41
- "dependencies": {
42
- "@inquirer/prompts": "^7.0.0",
43
- "@modelcontextprotocol/sdk": "^1.25.1",
44
- "meow": "^14.0.0",
45
- "posthog-node": "^5.17.4",
46
- "yocto-spinner": "^1.0.0",
47
- "zod": "^4.2.1"
48
- }
2
+ "name": "@getjack/jack",
3
+ "version": "0.1.4",
4
+ "description": "Ship before you forget why you started. The vibecoder's deployment CLI.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "bin": {
8
+ "jack": "./src/index.ts"
9
+ },
10
+ "files": [
11
+ "src",
12
+ "templates"
13
+ ],
14
+ "engines": {
15
+ "bun": ">=1.0.0"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/getjack-org/jack"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "keywords": [
25
+ "cli",
26
+ "deploy",
27
+ "vibecoding",
28
+ "vibecode",
29
+ "shipping",
30
+ "edge",
31
+ "serverless",
32
+ "ai-agent",
33
+ "claude",
34
+ "cursor"
35
+ ],
36
+ "scripts": {
37
+ "dev": "bun run src/index.ts",
38
+ "build": "bun build --compile src/index.ts --outfile dist/jack",
39
+ "lint": "biome check .",
40
+ "format": "biome format --write ."
41
+ },
42
+ "devDependencies": {
43
+ "@types/archiver": "^7.0.0",
44
+ "bun-types": "latest"
45
+ },
46
+ "dependencies": {
47
+ "@inquirer/prompts": "^7.0.0",
48
+ "@modelcontextprotocol/sdk": "^1.25.1",
49
+ "archiver": "^7.0.1",
50
+ "human-id": "^4.1.3",
51
+ "meow": "^14.0.0",
52
+ "posthog-node": "^5.17.4",
53
+ "yocto-spinner": "^1.0.0",
54
+ "zod": "^4.2.1"
55
+ }
49
56
  }
@@ -1,8 +1,12 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { regenerateAgentFiles } from "../lib/agent-files.ts";
1
4
  import {
2
5
  AGENT_REGISTRY,
3
6
  addAgent,
4
7
  disableAgent,
5
8
  enableAgent,
9
+ getActiveAgents,
6
10
  getAgentDefinition,
7
11
  getPreferredAgent,
8
12
  pathExists,
@@ -12,12 +16,24 @@ import {
12
16
  updateAgent,
13
17
  } from "../lib/agents.ts";
14
18
  import { readConfig } from "../lib/config.ts";
15
- import { error, info, item, output as outputSpinner, success } from "../lib/output.ts";
19
+ import { error, info, item, output as outputSpinner, success, warn } from "../lib/output.ts";
20
+ import { getProject } from "../lib/registry.ts";
21
+ import { getProjectNameFromDir } from "../lib/storage/index.ts";
22
+ import { resolveTemplate } from "../templates/index.ts";
23
+ import type { Template } from "../templates/types.ts";
16
24
 
17
25
  /**
18
26
  * Main agents command - handles all agent management
19
27
  */
20
- export default async function agents(subcommand?: string, args: string[] = []): Promise<void> {
28
+ interface AgentsOptions {
29
+ project?: string;
30
+ }
31
+
32
+ export default async function agents(
33
+ subcommand?: string,
34
+ args: string[] = [],
35
+ options: AgentsOptions = {},
36
+ ): Promise<void> {
21
37
  if (!subcommand) {
22
38
  return await listAgents();
23
39
  }
@@ -35,9 +51,11 @@ export default async function agents(subcommand?: string, args: string[] = []):
35
51
  return await disableAgentCommand(args);
36
52
  case "prefer":
37
53
  return await preferAgentCommand(args);
54
+ case "refresh":
55
+ return await refreshAgentFilesCommand(options);
38
56
  default:
39
57
  error(`Unknown subcommand: ${subcommand}`);
40
- info("Available: scan, add, remove, enable, disable, prefer");
58
+ info("Available: scan, add, remove, enable, disable, prefer, refresh");
41
59
  process.exit(1);
42
60
  }
43
61
  }
@@ -76,7 +94,7 @@ async function listAgents(): Promise<void> {
76
94
  console.error("");
77
95
  }
78
96
 
79
- info("Commands: jack agents scan | add | remove | enable | disable | prefer");
97
+ info("Commands: jack agents scan | add | remove | enable | disable | prefer | refresh");
80
98
  }
81
99
 
82
100
  /**
@@ -89,6 +107,7 @@ async function scanAndPrompt(): Promise<void> {
89
107
 
90
108
  if (detectionResult.detected.length === 0) {
91
109
  info("No agents detected");
110
+ await listAgents();
92
111
  return;
93
112
  }
94
113
 
@@ -98,6 +117,7 @@ async function scanAndPrompt(): Promise<void> {
98
117
 
99
118
  if (newAgents.length === 0) {
100
119
  success("No new agents found");
120
+ await listAgents();
101
121
  return;
102
122
  }
103
123
 
@@ -119,13 +139,16 @@ async function scanAndPrompt(): Promise<void> {
119
139
  console.error("");
120
140
  success("New agents enabled");
121
141
  info("Future projects will include context files for these agents");
142
+ await listAgents();
122
143
  }
123
144
 
124
145
  function getFlagValues(args: string[], flag: string): string[] {
125
146
  const values: string[] = [];
126
147
  for (let i = 0; i < args.length; i++) {
127
- if (args[i] === flag && args[i + 1]) {
128
- values.push(args[i + 1]);
148
+ const current = args[i];
149
+ const next = args[i + 1];
150
+ if (current === flag && next) {
151
+ values.push(next);
129
152
  i++;
130
153
  }
131
154
  }
@@ -174,7 +197,7 @@ async function addAgentCommand(args: string[]): Promise<void> {
174
197
  type: "cli" as const,
175
198
  command: customCommand,
176
199
  args: customArgs.length ? customArgs : undefined,
177
- }
200
+ }
178
201
  : undefined;
179
202
 
180
203
  await addAgent(agentId, { launch: launchOverride });
@@ -190,9 +213,7 @@ async function addAgentCommand(args: string[]): Promise<void> {
190
213
  if (err instanceof Error) {
191
214
  error(err.message);
192
215
  if (err.message.includes("Could not detect")) {
193
- info(
194
- `Specify launch manually: jack agents add ${agentId} --command /path/to/command`,
195
- );
216
+ info(`Specify launch manually: jack agents add ${agentId} --command /path/to/command`);
196
217
  }
197
218
  }
198
219
  process.exit(1);
@@ -303,3 +324,117 @@ async function preferAgentCommand(args: string[]): Promise<void> {
303
324
  process.exit(1);
304
325
  }
305
326
  }
327
+
328
+ /**
329
+ * Refresh agent context files from template
330
+ */
331
+ async function refreshAgentFilesCommand(options: AgentsOptions = {}): Promise<void> {
332
+ const projectDir = process.cwd();
333
+ let projectName: string;
334
+ let project = null;
335
+
336
+ if (options.project) {
337
+ // When --project is specified, we still need to run from that project's directory
338
+ // since localPath is no longer stored in the registry
339
+ projectName = options.project;
340
+ project = await getProject(projectName);
341
+
342
+ if (!project) {
343
+ error(`Project "${projectName}" not found in registry`);
344
+ info("List projects with: jack projects list");
345
+ process.exit(1);
346
+ }
347
+
348
+ // Verify the current directory matches the project
349
+ try {
350
+ const cwdProjectName = await getProjectNameFromDir(projectDir);
351
+ if (cwdProjectName !== projectName) {
352
+ error(`Current directory is not the project "${projectName}"`);
353
+ info(`Run this command from the ${projectName} project directory`);
354
+ process.exit(1);
355
+ }
356
+ } catch {
357
+ error(`Current directory is not a valid project`);
358
+ info(`Run this command from the ${projectName} project directory`);
359
+ process.exit(1);
360
+ }
361
+ } else {
362
+ // 1. Detect project name from wrangler config
363
+ outputSpinner.start("Detecting project...");
364
+ try {
365
+ projectName = await getProjectNameFromDir(projectDir);
366
+ } catch {
367
+ outputSpinner.stop();
368
+ error("Could not determine project");
369
+ info("Run this command from a project directory, or use --project <name>");
370
+ process.exit(1);
371
+ }
372
+ outputSpinner.stop();
373
+
374
+ // 2. Get project from registry to find template origin
375
+ project = await getProject(projectName);
376
+ if (!project) {
377
+ error(`Project "${projectName}" not found in registry`);
378
+ info("List projects with: jack projects list");
379
+ process.exit(1);
380
+ }
381
+ }
382
+
383
+ if (!project?.template) {
384
+ error("No template lineage found for this project");
385
+ info("This project was created before lineage tracking was added.");
386
+ info("Re-create the project with `jack new` to enable refresh.");
387
+ process.exit(1);
388
+ }
389
+
390
+ // 3. Resolve template (fetch if GitHub, load if builtin)
391
+ outputSpinner.start("Loading template...");
392
+ let template: Template;
393
+ try {
394
+ template = await resolveTemplate(project.template.name);
395
+ } catch (err) {
396
+ outputSpinner.stop();
397
+ error(`Failed to load template: ${project.template.name}`);
398
+ if (err instanceof Error) {
399
+ info(err.message);
400
+ }
401
+ process.exit(1);
402
+ }
403
+ outputSpinner.stop();
404
+
405
+ // 4. Backup existing files
406
+ const agentsMdPath = join(projectDir, "AGENTS.md");
407
+ if (existsSync(agentsMdPath)) {
408
+ const backupPath = `${agentsMdPath}.backup`;
409
+ const content = await Bun.file(agentsMdPath).text();
410
+ await Bun.write(backupPath, content);
411
+ success("Backed up AGENTS.md → AGENTS.md.backup");
412
+ }
413
+
414
+ const claudeMdPath = join(projectDir, "CLAUDE.md");
415
+ if (existsSync(claudeMdPath)) {
416
+ const backupPath = `${claudeMdPath}.backup`;
417
+ const content = await Bun.file(claudeMdPath).text();
418
+ await Bun.write(backupPath, content);
419
+ success("Backed up CLAUDE.md → CLAUDE.md.backup");
420
+ }
421
+
422
+ // 5. Get active agents
423
+ const activeAgents = await getActiveAgents();
424
+ if (activeAgents.length === 0) {
425
+ warn("No active agents configured");
426
+ info("Run: jack agents scan");
427
+ process.exit(1);
428
+ }
429
+
430
+ // 6. Regenerate agent files
431
+ const updatedFiles = await regenerateAgentFiles(projectDir, projectName, template, activeAgents);
432
+
433
+ console.error("");
434
+ success("Refreshed agent context files:");
435
+ for (const file of updatedFiles) {
436
+ item(file);
437
+ }
438
+ console.error("");
439
+ info("Review changes: git diff AGENTS.md");
440
+ }