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.
- package/README.md +84 -0
- package/dist/cli/commands/db.d.ts +9 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +215 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +6 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +145 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/feedback.d.ts +6 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +116 -0
- package/dist/cli/commands/feedback.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +161 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/launch.d.ts +12 -0
- package/dist/cli/commands/launch.d.ts.map +1 -0
- package/dist/cli/commands/launch.js +176 -0
- package/dist/cli/commands/launch.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +90 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +6 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +32 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +12 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +261 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +22 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +244 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +142 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/push.d.ts +6 -0
- package/dist/cli/commands/push.d.ts.map +1 -0
- package/dist/cli/commands/push.js +351 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/register.d.ts +6 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +115 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +11 -0
- package/dist/cli/commands/secret.d.ts.map +1 -0
- package/dist/cli/commands/secret.js +124 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +6 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +54 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/deploy/assets.d.ts +73 -0
- package/dist/cli/deploy/assets.d.ts.map +1 -0
- package/dist/cli/deploy/assets.js +167 -0
- package/dist/cli/deploy/assets.js.map +1 -0
- package/dist/cli/deploy/base64-stream.d.ts +16 -0
- package/dist/cli/deploy/base64-stream.d.ts.map +1 -0
- package/dist/cli/deploy/base64-stream.js +44 -0
- package/dist/cli/deploy/base64-stream.js.map +1 -0
- package/dist/cli/deploy/bucket-stream.d.ts +18 -0
- package/dist/cli/deploy/bucket-stream.d.ts.map +1 -0
- package/dist/cli/deploy/bucket-stream.js +63 -0
- package/dist/cli/deploy/bucket-stream.js.map +1 -0
- package/dist/cli/deploy/bundler.d.ts +22 -0
- package/dist/cli/deploy/bundler.d.ts.map +1 -0
- package/dist/cli/deploy/bundler.js +131 -0
- package/dist/cli/deploy/bundler.js.map +1 -0
- package/dist/cli/deploy/worker-entry.d.ts +14 -0
- package/dist/cli/deploy/worker-entry.d.ts.map +1 -0
- package/dist/cli/deploy/worker-entry.js +60 -0
- package/dist/cli/deploy/worker-entry.js.map +1 -0
- package/dist/cli/deploy/wrangler-config.d.ts +20 -0
- package/dist/cli/deploy/wrangler-config.d.ts.map +1 -0
- package/dist/cli/deploy/wrangler-config.js +54 -0
- package/dist/cli/deploy/wrangler-config.js.map +1 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +72 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +39 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +105 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/duration.d.ts +21 -0
- package/dist/cli/utils/duration.d.ts.map +1 -0
- package/dist/cli/utils/duration.js +44 -0
- package/dist/cli/utils/duration.js.map +1 -0
- package/dist/cli/utils/environment.d.ts +17 -0
- package/dist/cli/utils/environment.d.ts.map +1 -0
- package/dist/cli/utils/environment.js +27 -0
- package/dist/cli/utils/environment.js.map +1 -0
- package/dist/cli/utils/project.d.ts +24 -0
- package/dist/cli/utils/project.d.ts.map +1 -0
- package/dist/cli/utils/project.js +47 -0
- package/dist/cli/utils/project.js.map +1 -0
- package/dist/cli/utils/registry.d.ts +34 -0
- package/dist/cli/utils/registry.d.ts.map +1 -0
- package/dist/cli/utils/registry.js +94 -0
- package/dist/cli/utils/registry.js.map +1 -0
- package/dist/cli/utils/token.d.ts +12 -0
- package/dist/cli/utils/token.d.ts.map +1 -0
- package/dist/cli/utils/token.js +27 -0
- package/dist/cli/utils/token.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/cron.d.ts +50 -0
- package/dist/runtime/cron.d.ts.map +1 -0
- package/dist/runtime/cron.js +80 -0
- package/dist/runtime/cron.js.map +1 -0
- package/dist/runtime/db.d.ts +93 -0
- package/dist/runtime/db.d.ts.map +1 -0
- package/dist/runtime/db.js +137 -0
- package/dist/runtime/db.js.map +1 -0
- package/dist/runtime/http.d.ts +33 -0
- package/dist/runtime/http.d.ts.map +1 -0
- package/dist/runtime/http.js +36 -0
- package/dist/runtime/http.js.map +1 -0
- package/dist/runtime/log.d.ts +90 -0
- package/dist/runtime/log.d.ts.map +1 -0
- package/dist/runtime/log.js +211 -0
- package/dist/runtime/log.js.map +1 -0
- package/dist/runtime/migrate.d.ts +54 -0
- package/dist/runtime/migrate.d.ts.map +1 -0
- package/dist/runtime/migrate.js +130 -0
- package/dist/runtime/migrate.js.map +1 -0
- package/dist/runtime/secrets.d.ts +36 -0
- package/dist/runtime/secrets.d.ts.map +1 -0
- package/dist/runtime/secrets.js +75 -0
- package/dist/runtime/secrets.js.map +1 -0
- package/dist/worker-runtime/index.d.ts +79 -0
- package/dist/worker-runtime/index.d.ts.map +1 -0
- package/dist/worker-runtime/index.js +203 -0
- package/dist/worker-runtime/index.js.map +1 -0
- package/package.json +81 -0
- package/templates/default/.nvmrc +1 -0
- package/templates/default/CLAUDE.md +197 -0
- package/templates/default/index.html +13 -0
- package/templates/default/package.json +25 -0
- package/templates/default/public/vite.svg +1 -0
- package/templates/default/skills/fling/API.md +335 -0
- package/templates/default/skills/fling/EXAMPLES.md +204 -0
- package/templates/default/skills/fling/FEEDBACK.md +73 -0
- package/templates/default/skills/fling/SKILL.md +159 -0
- package/templates/default/src/react-app/App.css +34 -0
- package/templates/default/src/react-app/App.tsx +27 -0
- package/templates/default/src/react-app/index.css +15 -0
- package/templates/default/src/react-app/main.tsx +10 -0
- package/templates/default/src/react-app/vite-env.d.ts +1 -0
- package/templates/default/src/worker/index.ts +27 -0
- package/templates/default/tsconfig.app.json +22 -0
- package/templates/default/tsconfig.json +7 -0
- package/templates/default/tsconfig.worker.json +11 -0
- 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 @@
|
|
|
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 @@
|
|
|
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"}
|