flingit 0.0.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 (161) hide show
  1. package/README.md +84 -0
  2. package/dist/cli/commands/db.d.ts +9 -0
  3. package/dist/cli/commands/db.d.ts.map +1 -0
  4. package/dist/cli/commands/db.js +215 -0
  5. package/dist/cli/commands/db.js.map +1 -0
  6. package/dist/cli/commands/dev.d.ts +6 -0
  7. package/dist/cli/commands/dev.d.ts.map +1 -0
  8. package/dist/cli/commands/dev.js +145 -0
  9. package/dist/cli/commands/dev.js.map +1 -0
  10. package/dist/cli/commands/feedback.d.ts +6 -0
  11. package/dist/cli/commands/feedback.d.ts.map +1 -0
  12. package/dist/cli/commands/feedback.js +116 -0
  13. package/dist/cli/commands/feedback.js.map +1 -0
  14. package/dist/cli/commands/init.d.ts +6 -0
  15. package/dist/cli/commands/init.d.ts.map +1 -0
  16. package/dist/cli/commands/init.js +161 -0
  17. package/dist/cli/commands/init.js.map +1 -0
  18. package/dist/cli/commands/launch.d.ts +12 -0
  19. package/dist/cli/commands/launch.d.ts.map +1 -0
  20. package/dist/cli/commands/launch.js +176 -0
  21. package/dist/cli/commands/launch.js.map +1 -0
  22. package/dist/cli/commands/login.d.ts +6 -0
  23. package/dist/cli/commands/login.d.ts.map +1 -0
  24. package/dist/cli/commands/login.js +90 -0
  25. package/dist/cli/commands/login.js.map +1 -0
  26. package/dist/cli/commands/logout.d.ts +6 -0
  27. package/dist/cli/commands/logout.d.ts.map +1 -0
  28. package/dist/cli/commands/logout.js +32 -0
  29. package/dist/cli/commands/logout.js.map +1 -0
  30. package/dist/cli/commands/logs.d.ts +12 -0
  31. package/dist/cli/commands/logs.d.ts.map +1 -0
  32. package/dist/cli/commands/logs.js +261 -0
  33. package/dist/cli/commands/logs.js.map +1 -0
  34. package/dist/cli/commands/onboard.d.ts +22 -0
  35. package/dist/cli/commands/onboard.d.ts.map +1 -0
  36. package/dist/cli/commands/onboard.js +244 -0
  37. package/dist/cli/commands/onboard.js.map +1 -0
  38. package/dist/cli/commands/project.d.ts +6 -0
  39. package/dist/cli/commands/project.d.ts.map +1 -0
  40. package/dist/cli/commands/project.js +142 -0
  41. package/dist/cli/commands/project.js.map +1 -0
  42. package/dist/cli/commands/push.d.ts +6 -0
  43. package/dist/cli/commands/push.d.ts.map +1 -0
  44. package/dist/cli/commands/push.js +351 -0
  45. package/dist/cli/commands/push.js.map +1 -0
  46. package/dist/cli/commands/register.d.ts +6 -0
  47. package/dist/cli/commands/register.d.ts.map +1 -0
  48. package/dist/cli/commands/register.js +115 -0
  49. package/dist/cli/commands/register.js.map +1 -0
  50. package/dist/cli/commands/secret.d.ts +11 -0
  51. package/dist/cli/commands/secret.d.ts.map +1 -0
  52. package/dist/cli/commands/secret.js +124 -0
  53. package/dist/cli/commands/secret.js.map +1 -0
  54. package/dist/cli/commands/whoami.d.ts +6 -0
  55. package/dist/cli/commands/whoami.d.ts.map +1 -0
  56. package/dist/cli/commands/whoami.js +54 -0
  57. package/dist/cli/commands/whoami.js.map +1 -0
  58. package/dist/cli/deploy/assets.d.ts +73 -0
  59. package/dist/cli/deploy/assets.d.ts.map +1 -0
  60. package/dist/cli/deploy/assets.js +167 -0
  61. package/dist/cli/deploy/assets.js.map +1 -0
  62. package/dist/cli/deploy/base64-stream.d.ts +16 -0
  63. package/dist/cli/deploy/base64-stream.d.ts.map +1 -0
  64. package/dist/cli/deploy/base64-stream.js +44 -0
  65. package/dist/cli/deploy/base64-stream.js.map +1 -0
  66. package/dist/cli/deploy/bucket-stream.d.ts +18 -0
  67. package/dist/cli/deploy/bucket-stream.d.ts.map +1 -0
  68. package/dist/cli/deploy/bucket-stream.js +63 -0
  69. package/dist/cli/deploy/bucket-stream.js.map +1 -0
  70. package/dist/cli/deploy/bundler.d.ts +22 -0
  71. package/dist/cli/deploy/bundler.d.ts.map +1 -0
  72. package/dist/cli/deploy/bundler.js +131 -0
  73. package/dist/cli/deploy/bundler.js.map +1 -0
  74. package/dist/cli/deploy/worker-entry.d.ts +14 -0
  75. package/dist/cli/deploy/worker-entry.d.ts.map +1 -0
  76. package/dist/cli/deploy/worker-entry.js +60 -0
  77. package/dist/cli/deploy/worker-entry.js.map +1 -0
  78. package/dist/cli/deploy/wrangler-config.d.ts +20 -0
  79. package/dist/cli/deploy/wrangler-config.d.ts.map +1 -0
  80. package/dist/cli/deploy/wrangler-config.js +54 -0
  81. package/dist/cli/deploy/wrangler-config.js.map +1 -0
  82. package/dist/cli/index.d.ts +10 -0
  83. package/dist/cli/index.d.ts.map +1 -0
  84. package/dist/cli/index.js +72 -0
  85. package/dist/cli/index.js.map +1 -0
  86. package/dist/cli/utils/config.d.ts +39 -0
  87. package/dist/cli/utils/config.d.ts.map +1 -0
  88. package/dist/cli/utils/config.js +105 -0
  89. package/dist/cli/utils/config.js.map +1 -0
  90. package/dist/cli/utils/duration.d.ts +21 -0
  91. package/dist/cli/utils/duration.d.ts.map +1 -0
  92. package/dist/cli/utils/duration.js +44 -0
  93. package/dist/cli/utils/duration.js.map +1 -0
  94. package/dist/cli/utils/environment.d.ts +17 -0
  95. package/dist/cli/utils/environment.d.ts.map +1 -0
  96. package/dist/cli/utils/environment.js +27 -0
  97. package/dist/cli/utils/environment.js.map +1 -0
  98. package/dist/cli/utils/project.d.ts +24 -0
  99. package/dist/cli/utils/project.d.ts.map +1 -0
  100. package/dist/cli/utils/project.js +47 -0
  101. package/dist/cli/utils/project.js.map +1 -0
  102. package/dist/cli/utils/registry.d.ts +34 -0
  103. package/dist/cli/utils/registry.d.ts.map +1 -0
  104. package/dist/cli/utils/registry.js +94 -0
  105. package/dist/cli/utils/registry.js.map +1 -0
  106. package/dist/cli/utils/token.d.ts +12 -0
  107. package/dist/cli/utils/token.d.ts.map +1 -0
  108. package/dist/cli/utils/token.js +27 -0
  109. package/dist/cli/utils/token.js.map +1 -0
  110. package/dist/index.d.ts +12 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +12 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/runtime/cron.d.ts +50 -0
  115. package/dist/runtime/cron.d.ts.map +1 -0
  116. package/dist/runtime/cron.js +80 -0
  117. package/dist/runtime/cron.js.map +1 -0
  118. package/dist/runtime/db.d.ts +93 -0
  119. package/dist/runtime/db.d.ts.map +1 -0
  120. package/dist/runtime/db.js +137 -0
  121. package/dist/runtime/db.js.map +1 -0
  122. package/dist/runtime/http.d.ts +33 -0
  123. package/dist/runtime/http.d.ts.map +1 -0
  124. package/dist/runtime/http.js +36 -0
  125. package/dist/runtime/http.js.map +1 -0
  126. package/dist/runtime/log.d.ts +90 -0
  127. package/dist/runtime/log.d.ts.map +1 -0
  128. package/dist/runtime/log.js +211 -0
  129. package/dist/runtime/log.js.map +1 -0
  130. package/dist/runtime/migrate.d.ts +54 -0
  131. package/dist/runtime/migrate.d.ts.map +1 -0
  132. package/dist/runtime/migrate.js +130 -0
  133. package/dist/runtime/migrate.js.map +1 -0
  134. package/dist/runtime/secrets.d.ts +36 -0
  135. package/dist/runtime/secrets.d.ts.map +1 -0
  136. package/dist/runtime/secrets.js +75 -0
  137. package/dist/runtime/secrets.js.map +1 -0
  138. package/dist/worker-runtime/index.d.ts +79 -0
  139. package/dist/worker-runtime/index.d.ts.map +1 -0
  140. package/dist/worker-runtime/index.js +203 -0
  141. package/dist/worker-runtime/index.js.map +1 -0
  142. package/package.json +81 -0
  143. package/templates/default/.nvmrc +1 -0
  144. package/templates/default/CLAUDE.md +197 -0
  145. package/templates/default/index.html +13 -0
  146. package/templates/default/package.json +25 -0
  147. package/templates/default/public/vite.svg +1 -0
  148. package/templates/default/skills/fling/API.md +335 -0
  149. package/templates/default/skills/fling/EXAMPLES.md +204 -0
  150. package/templates/default/skills/fling/FEEDBACK.md +73 -0
  151. package/templates/default/skills/fling/SKILL.md +159 -0
  152. package/templates/default/src/react-app/App.css +34 -0
  153. package/templates/default/src/react-app/App.tsx +27 -0
  154. package/templates/default/src/react-app/index.css +15 -0
  155. package/templates/default/src/react-app/main.tsx +10 -0
  156. package/templates/default/src/react-app/vite-env.d.ts +1 -0
  157. package/templates/default/src/worker/index.ts +27 -0
  158. package/templates/default/tsconfig.app.json +22 -0
  159. package/templates/default/tsconfig.json +7 -0
  160. package/templates/default/tsconfig.worker.json +11 -0
  161. package/templates/default/vite.config.ts +21 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * fling init - Scaffold a new project in the current directory
3
+ */
4
+ import { Command } from "commander";
5
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, cpSync, } from "node:fs";
6
+ import { join, dirname } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { registerProject } from "../utils/registry.js";
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ // Get Fling root directory (where package.json lives)
11
+ function getFlingRoot() {
12
+ // From src/cli/commands/ or dist/cli/commands/
13
+ return join(__dirname, "..", "..", "..");
14
+ }
15
+ // Check if running from a development checkout
16
+ function isDevelopmentMode() {
17
+ const flingRoot = getFlingRoot();
18
+ // Development checkout has src/ directory and tsconfig.json
19
+ return (existsSync(join(flingRoot, "src")) &&
20
+ existsSync(join(flingRoot, "tsconfig.json")));
21
+ }
22
+ export const initCommand = new Command("init")
23
+ .description("Create a new Fling project in the current directory")
24
+ .option("--local", "Use local Fling package via file: reference (for development)")
25
+ .addHelpText("after", `
26
+ Prerequisites:
27
+ - Node.js 24 or later
28
+ - Empty or new directory (run mkdir my-project && cd my-project first)
29
+
30
+ Creates:
31
+ index.html Vite entry HTML
32
+ vite.config.ts Vite configuration
33
+ tsconfig.json TypeScript root config
34
+ tsconfig.app.json React TypeScript config
35
+ tsconfig.worker.json Worker TypeScript config
36
+ src/worker/index.ts Backend API code
37
+ src/react-app/ React frontend code
38
+ public/ Static assets
39
+ package.json Project configuration with React, Vite deps
40
+ .nvmrc Node.js version (24)
41
+ CLAUDE.md Instructions for Claude Code
42
+ .claude/skills/ Claude skill files for Fling commands
43
+ .fling/ Local data directory (gitignored)
44
+ .fling/secrets Local secrets file (gitignored)
45
+ .fling/data/ SQLite database location (gitignored)
46
+
47
+ Next steps after init:
48
+ npm install Install dependencies
49
+ fling dev Start local development server
50
+
51
+ Example:
52
+ mkdir my-project && cd my-project
53
+ fling init
54
+ npm install
55
+ fling dev
56
+ `)
57
+ .action(async (options) => {
58
+ const cwd = process.cwd();
59
+ // Check if already initialized
60
+ if (existsSync(join(cwd, ".fling"))) {
61
+ console.log("Fling project already initialized in this directory.");
62
+ return;
63
+ }
64
+ console.log("Initializing Fling project...\n");
65
+ // Templates are located relative to this file:
66
+ // In dev: src/cli/commands/init.ts -> ../../../templates/default
67
+ // In dist: dist/cli/commands/init.js -> ../../../templates/default
68
+ const templateDir = join(__dirname, "..", "..", "..", "templates", "default");
69
+ if (!existsSync(templateDir)) {
70
+ console.error("Error: Could not find template directory at", templateDir);
71
+ process.exit(1);
72
+ }
73
+ // Copy template files to project root
74
+ // We copy specific files to handle .gitignore specially
75
+ const filesToCopy = [
76
+ { src: "package.json", dest: "package.json" },
77
+ { src: "tsconfig.json", dest: "tsconfig.json" },
78
+ { src: "tsconfig.app.json", dest: "tsconfig.app.json" },
79
+ { src: "tsconfig.worker.json", dest: "tsconfig.worker.json" },
80
+ { src: "vite.config.ts", dest: "vite.config.ts" },
81
+ { src: "index.html", dest: "index.html" },
82
+ { src: ".nvmrc", dest: ".nvmrc" },
83
+ { src: "CLAUDE.md", dest: "CLAUDE.md" },
84
+ ];
85
+ for (const { src, dest } of filesToCopy) {
86
+ const srcPath = join(templateDir, src);
87
+ if (existsSync(srcPath)) {
88
+ cpSync(srcPath, join(cwd, dest));
89
+ }
90
+ }
91
+ // Copy src directory
92
+ const srcTemplateDir = join(templateDir, "src");
93
+ if (existsSync(srcTemplateDir)) {
94
+ cpSync(srcTemplateDir, join(cwd, "src"), { recursive: true });
95
+ }
96
+ // Copy public directory (static assets for Vite)
97
+ const publicTemplateDir = join(templateDir, "public");
98
+ if (existsSync(publicTemplateDir)) {
99
+ cpSync(publicTemplateDir, join(cwd, "public"), { recursive: true });
100
+ }
101
+ // Copy skills to .claude/skills/
102
+ const skillsTemplateDir = join(templateDir, "skills");
103
+ const skillsDestDir = join(cwd, ".claude", "skills");
104
+ if (existsSync(skillsTemplateDir)) {
105
+ mkdirSync(skillsDestDir, { recursive: true });
106
+ cpSync(skillsTemplateDir, skillsDestDir, { recursive: true });
107
+ }
108
+ // Modify package.json with project name and fling dependency
109
+ const projectName = cwd.split("/").pop() ?? "fling-project";
110
+ const useLocal = options.local ?? isDevelopmentMode();
111
+ const flingRoot = getFlingRoot();
112
+ const flingDependency = useLocal ? `file:${flingRoot}` : "^0.1.0";
113
+ if (useLocal) {
114
+ console.log(`Using local Fling: ${flingRoot}\n`);
115
+ }
116
+ const packageJsonPath = join(cwd, "package.json");
117
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
118
+ packageJson.name = projectName;
119
+ packageJson.dependencies.fling = flingDependency;
120
+ writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
121
+ // Create .fling directory
122
+ mkdirSync(join(cwd, ".fling", "data"), { recursive: true });
123
+ // Register project in the global registry
124
+ registerProject(cwd);
125
+ // Create empty secrets file with restricted permissions (owner read/write only)
126
+ writeFileSync(join(cwd, ".fling", "secrets"), "# Fling secrets\n# Format: KEY=value\n", { mode: 0o600 });
127
+ // Handle .gitignore - copy template or append to existing
128
+ const gitignorePath = join(cwd, ".gitignore");
129
+ const gitignoreTemplate = join(templateDir, ".gitignore");
130
+ if (existsSync(gitignorePath)) {
131
+ // Append Fling entries if not already present
132
+ const existing = readFileSync(gitignorePath, "utf-8");
133
+ if (!existing.includes(".fling/secrets")) {
134
+ writeFileSync(gitignorePath, existing + "\n# Fling\n.fling/secrets\n.fling/data/\n");
135
+ }
136
+ }
137
+ else if (existsSync(gitignoreTemplate)) {
138
+ cpSync(gitignoreTemplate, gitignorePath);
139
+ }
140
+ console.log("Created:");
141
+ console.log(" index.html - Vite entry HTML");
142
+ console.log(" vite.config.ts - Vite configuration");
143
+ console.log(" tsconfig.json - TypeScript root config");
144
+ console.log(" tsconfig.app.json - React TypeScript config");
145
+ console.log(" tsconfig.worker.json - Worker TypeScript config");
146
+ console.log(" src/worker/index.ts - Backend API code");
147
+ console.log(" src/react-app/ - React frontend code");
148
+ console.log(" public/ - Static assets");
149
+ console.log(" .claude/skills/fling/ - Claude skill files");
150
+ console.log(" CLAUDE.md - Claude Code instructions");
151
+ console.log(" .nvmrc - Node.js version (24)");
152
+ console.log(" package.json - Project configuration");
153
+ console.log(" .fling/ - Fling data directory");
154
+ console.log(" .fling/secrets - Local secrets file (gitignored)");
155
+ console.log(" .fling/data/ - SQLite database location (gitignored)");
156
+ console.log("");
157
+ console.log("Next steps:");
158
+ console.log(" 1. Run: npm install");
159
+ console.log(" 2. Run: fling dev");
160
+ });
161
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Default action when running `fling` with no arguments
3
+ *
4
+ * - Inside a Fling project: auto-register and show Commander help
5
+ * - Otherwise: show project selector or create-new flow
6
+ */
7
+ import type { Command } from "commander";
8
+ /**
9
+ * Launch Fling - the default action when running `fling` with no args.
10
+ */
11
+ export declare function launch(program: Command): Promise<void>;
12
+ //# sourceMappingURL=launch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/launch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6IzC;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD5D"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Default action when running `fling` with no arguments
3
+ *
4
+ * - Inside a Fling project: auto-register and show Commander help
5
+ * - Otherwise: show project selector or create-new flow
6
+ */
7
+ import { existsSync, mkdirSync, readdirSync } from "node:fs";
8
+ import { join, resolve } from "node:path";
9
+ import { homedir } from "node:os";
10
+ import { spawn } from "node:child_process";
11
+ import * as p from "@clack/prompts";
12
+ import { initCommand } from "./init.js";
13
+ import { findEnclosingProject, isProjectRoot } from "../utils/project.js";
14
+ import { registerProject, getValidProjects } from "../utils/registry.js";
15
+ const FLING_HOME = join(homedir(), "fling");
16
+ /**
17
+ * Create a new Fling project in the given directory.
18
+ * Runs init, then npm install.
19
+ */
20
+ async function createProject(dir) {
21
+ console.log(`Creating your Fling project at ${dir}...\n`);
22
+ mkdirSync(dir, { recursive: true });
23
+ const originalCwd = process.cwd();
24
+ process.chdir(dir);
25
+ try {
26
+ await initCommand.parseAsync([], { from: "user" });
27
+ }
28
+ finally {
29
+ process.chdir(originalCwd);
30
+ }
31
+ console.log("");
32
+ console.log("Installing dependencies...\n");
33
+ await new Promise((resolve, reject) => {
34
+ const npm = spawn("npm", ["install"], {
35
+ cwd: dir,
36
+ stdio: "inherit",
37
+ });
38
+ npm.on("error", reject);
39
+ npm.on("close", (code) => {
40
+ if (code === 0) {
41
+ resolve();
42
+ }
43
+ else {
44
+ reject(new Error(`npm install failed with code ${code}`));
45
+ }
46
+ });
47
+ });
48
+ console.log("");
49
+ }
50
+ /**
51
+ * Launch Claude Code in the given project directory.
52
+ */
53
+ function launchClaudeCode(projectDir) {
54
+ console.log(`Opening Claude Code in ${projectDir}...\n`);
55
+ const claude = spawn("claude", [], {
56
+ cwd: projectDir,
57
+ stdio: "inherit",
58
+ env: { ...process.env, PWD: projectDir },
59
+ });
60
+ claude.on("error", (error) => {
61
+ if (error.code === "ENOENT") {
62
+ console.error("Error: 'claude' command not found.");
63
+ console.error("Please install Claude Code: https://claude.ai/code");
64
+ process.exit(1);
65
+ }
66
+ else {
67
+ console.error("Error launching Claude Code:", error);
68
+ process.exit(1);
69
+ }
70
+ });
71
+ claude.on("close", (code) => {
72
+ process.exit(code ?? 0);
73
+ });
74
+ }
75
+ /**
76
+ * Check if a directory is empty (has no entries).
77
+ */
78
+ function isDirEmpty(dir) {
79
+ try {
80
+ return readdirSync(dir).length === 0;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Prompt the user to create a new project.
88
+ * Returns the chosen directory path, or null if cancelled.
89
+ */
90
+ async function promptNewProject() {
91
+ const cwd = process.cwd();
92
+ const options = [];
93
+ // Suggest ~/fling only if it doesn't already exist
94
+ if (!existsSync(FLING_HOME)) {
95
+ options.push({ value: FLING_HOME, label: "Start in ~/fling" });
96
+ }
97
+ // Suggest current directory only if it's empty (and not ~/fling)
98
+ if (cwd !== FLING_HOME && isDirEmpty(cwd)) {
99
+ options.push({
100
+ value: cwd,
101
+ label: `Start in current directory (${cwd})`,
102
+ });
103
+ }
104
+ options.push({ value: "enter-path", label: "Enter a path" });
105
+ options.push({ value: "cancel", label: "Cancel" });
106
+ const choice = await p.select({
107
+ message: "Where would you like to create a new Fling project?",
108
+ options,
109
+ });
110
+ if (p.isCancel(choice) || choice === "cancel") {
111
+ return null;
112
+ }
113
+ if (choice === "enter-path") {
114
+ const entered = await p.text({
115
+ message: "Enter the path for your new project:",
116
+ placeholder: "~/my-project",
117
+ });
118
+ if (p.isCancel(entered) || !entered) {
119
+ return null;
120
+ }
121
+ // Expand ~ to home directory
122
+ const expanded = entered.startsWith("~/")
123
+ ? join(homedir(), entered.slice(2))
124
+ : entered;
125
+ return resolve(expanded);
126
+ }
127
+ return choice;
128
+ }
129
+ /**
130
+ * Launch Fling - the default action when running `fling` with no args.
131
+ */
132
+ export async function launch(program) {
133
+ const cwd = process.cwd();
134
+ // Step 1: Are we inside a Fling project?
135
+ const enclosingProject = findEnclosingProject(cwd);
136
+ if (enclosingProject) {
137
+ registerProject(enclosingProject);
138
+ program.outputHelp();
139
+ return;
140
+ }
141
+ // Step 2: Do we have registered projects?
142
+ const projects = getValidProjects();
143
+ if (projects.length > 0) {
144
+ // Show project selector
145
+ const options = projects.map((p) => ({
146
+ value: p,
147
+ label: p,
148
+ }));
149
+ options.push({ value: "new", label: "Create new project" });
150
+ options.push({ value: "cancel", label: "Cancel" });
151
+ const choice = await p.select({
152
+ message: "Select a Fling project to open:",
153
+ options,
154
+ });
155
+ if (p.isCancel(choice) || choice === "cancel") {
156
+ return;
157
+ }
158
+ if (choice === "new") {
159
+ // Fall through to create-new flow
160
+ }
161
+ else {
162
+ launchClaudeCode(choice);
163
+ return;
164
+ }
165
+ }
166
+ // Step 3: Create a new project
167
+ const dir = await promptNewProject();
168
+ if (!dir) {
169
+ return;
170
+ }
171
+ if (!isProjectRoot(dir)) {
172
+ await createProject(dir);
173
+ }
174
+ launchClaudeCode(dir);
175
+ }
176
+ //# sourceMappingURL=launch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../src/cli/commands/launch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * fling login - Store API token for the Fling platform
3
+ */
4
+ import { Command } from "commander";
5
+ export declare const loginCommand: Command;
6
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,YAAY,SAkFrB,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * fling login - Store API token for the Fling platform
3
+ */
4
+ import { Command } from "commander";
5
+ import { createInterface } from "node:readline";
6
+ import { setToken, isLoggedIn, clearToken, setApiUrl, platformFetch } from "../utils/config.js";
7
+ /**
8
+ * Prompt for input.
9
+ */
10
+ async function prompt(question) {
11
+ const rl = createInterface({
12
+ input: process.stdin,
13
+ output: process.stdout,
14
+ });
15
+ return new Promise((resolve) => {
16
+ rl.question(question, (answer) => {
17
+ rl.close();
18
+ resolve(answer);
19
+ });
20
+ });
21
+ }
22
+ export const loginCommand = new Command("login")
23
+ .description("Log in to the Fling platform with your API token")
24
+ .argument("[token]", "API token starting with 'usr_' (will prompt if not provided)")
25
+ .option("--api-url <url>", "Override API endpoint (internal/testing use only)")
26
+ .addHelpText("after", `
27
+ Getting your token:
28
+ Your API token is available in your Fling dashboard after registration.
29
+ Tokens start with 'usr_' (e.g., usr_abc123...).
30
+
31
+ What it does:
32
+ - Validates the token with the Fling platform
33
+ - Stores the token in ~/.fling/token for future commands
34
+
35
+ If you don't have an account yet:
36
+ fling register <invite-token>
37
+
38
+ Examples:
39
+ fling login Prompt for token interactively
40
+ fling login usr_abc123... Log in with token directly
41
+ `)
42
+ .action(async (tokenArg, options) => {
43
+ // Check if already logged in
44
+ if (isLoggedIn()) {
45
+ const answer = await prompt("Already logged in. Replace existing token? (y/N) ");
46
+ if (answer.toLowerCase() !== "y") {
47
+ console.log("Cancelled.");
48
+ return;
49
+ }
50
+ clearToken();
51
+ }
52
+ // Get token
53
+ const token = tokenArg ?? (await prompt("API token: "));
54
+ if (!token) {
55
+ console.error("Token is required.");
56
+ process.exit(1);
57
+ }
58
+ // Validate token format
59
+ if (!token.startsWith("usr_")) {
60
+ console.error("Invalid token format. Token must start with 'usr_'.");
61
+ process.exit(1);
62
+ }
63
+ // Set API URL if provided
64
+ if (options.apiUrl) {
65
+ setApiUrl(options.apiUrl);
66
+ }
67
+ // Store token
68
+ setToken(token);
69
+ // Verify token by calling /me
70
+ console.log("Verifying token...");
71
+ try {
72
+ const response = await platformFetch("/me");
73
+ const data = (await response.json());
74
+ if (!response.ok) {
75
+ clearToken();
76
+ console.error(`Login failed: ${data.error ?? "Invalid token"}`);
77
+ process.exit(1);
78
+ }
79
+ const project = data.projects?.[0];
80
+ console.log(`\nLogged in as ${data.user?.name} (${data.user?.email})`);
81
+ console.log(`Project: ${project?.slug}`);
82
+ console.log(`URL: ${project?.url}`);
83
+ }
84
+ catch (error) {
85
+ clearToken();
86
+ console.error(`Login failed: ${error instanceof Error ? error.message : "Network error"}`);
87
+ process.exit(1);
88
+ }
89
+ });
90
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * fling logout - Log out from the Fling platform
3
+ */
4
+ import { Command } from "commander";
5
+ export declare const logoutCommand: Command;
6
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,SA0BtB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * fling logout - Log out from the Fling platform
3
+ */
4
+ import { Command } from "commander";
5
+ import { clearToken, isLoggedIn, platformFetch } from "../utils/config.js";
6
+ export const logoutCommand = new Command("logout")
7
+ .description("Log out from the Fling platform and clear stored token")
8
+ .addHelpText("after", `
9
+ What it does:
10
+ - Invalidates the token on the server
11
+ - Removes the token from ~/.fling/token
12
+
13
+ After logout, you'll need to run 'fling login' to use
14
+ commands that require authentication (push, whoami, etc.).
15
+ `)
16
+ .action(async () => {
17
+ if (!isLoggedIn()) {
18
+ console.log("Not logged in.");
19
+ return;
20
+ }
21
+ // Invalidate token on server (optional, ignore errors)
22
+ try {
23
+ await platformFetch("/auth/logout", { method: "POST" });
24
+ }
25
+ catch {
26
+ // Ignore - token might already be invalid
27
+ }
28
+ // Clear local token
29
+ clearToken();
30
+ console.log("Logged out.");
31
+ });
32
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/cli/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,wDAAwD,CAAC;KACrE,WAAW,CAAC,OAAO,EAAE;;;;;;;CAOvB,CAAC;KACC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IAED,oBAAoB;IACpB,UAAU,EAAE,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * fling logs - View application logs
3
+ *
4
+ * Query stored logs with filters for level, time range, and cron job.
5
+ * Supports both local SQLite logs and deployed worker logs.
6
+ *
7
+ * Default: local logs
8
+ * With --prod: deployed worker logs (requires login)
9
+ */
10
+ import { Command } from "commander";
11
+ export declare const logsCommand: Command;
12
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,eAAO,MAAM,WAAW,SAgKpB,CAAC"}