flingit 0.0.12 → 0.0.13
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 +8 -1
- package/dist/cli/commands/db.d.ts +11 -0
- package/dist/cli/commands/db.d.ts.map +1 -1
- package/dist/cli/commands/db.js +60 -48
- package/dist/cli/commands/db.js.map +1 -1
- package/dist/cli/commands/dev.d.ts +9 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +96 -100
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/feedback.d.ts +23 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -1
- package/dist/cli/commands/feedback.js +60 -73
- package/dist/cli/commands/feedback.js.map +1 -1
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +96 -107
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launch.d.ts +11 -1
- package/dist/cli/commands/launch.d.ts.map +1 -1
- package/dist/cli/commands/launch.js +32 -36
- package/dist/cli/commands/launch.js.map +1 -1
- package/dist/cli/commands/login.d.ts +30 -0
- package/dist/cli/commands/login.d.ts.map +1 -1
- package/dist/cli/commands/login.js +71 -58
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/logs.d.ts +39 -0
- package/dist/cli/commands/logs.d.ts.map +1 -1
- package/dist/cli/commands/logs.js +121 -90
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/onboard.d.ts +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/onboard.js +94 -41
- package/dist/cli/commands/onboard.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts +43 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -1
- package/dist/cli/commands/plugin.js +229 -211
- package/dist/cli/commands/plugin.js.map +1 -1
- package/dist/cli/commands/project.d.ts +27 -0
- package/dist/cli/commands/project.d.ts.map +1 -1
- package/dist/cli/commands/project.js +101 -85
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/push.d.ts +39 -0
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +152 -118
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/storage.d.ts +32 -0
- package/dist/cli/commands/storage.d.ts.map +1 -1
- package/dist/cli/commands/storage.js +180 -140
- package/dist/cli/commands/storage.js.map +1 -1
- package/dist/cli/commands/tunnel.d.ts +41 -0
- package/dist/cli/commands/tunnel.d.ts.map +1 -0
- package/dist/cli/commands/tunnel.js +210 -0
- package/dist/cli/commands/tunnel.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +15 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +82 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/index.js +35 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/cli-io-impl.d.ts +64 -0
- package/dist/cli/utils/cli-io-impl.d.ts.map +1 -0
- package/dist/cli/utils/cli-io-impl.js +521 -0
- package/dist/cli/utils/cli-io-impl.js.map +1 -0
- package/dist/cli/utils/cli-io.d.ts +350 -0
- package/dist/cli/utils/cli-io.d.ts.map +1 -0
- package/dist/cli/utils/cli-io.js +13 -0
- package/dist/cli/utils/cli-io.js.map +1 -0
- package/dist/cli/utils/config.d.ts +60 -2
- package/dist/cli/utils/config.d.ts.map +1 -1
- package/dist/cli/utils/config.js +158 -37
- package/dist/cli/utils/config.js.map +1 -1
- package/dist/cli/utils/project.d.ts +60 -0
- package/dist/cli/utils/project.d.ts.map +1 -1
- package/dist/cli/utils/project.js +112 -2
- package/dist/cli/utils/project.js.map +1 -1
- package/dist/cli/utils/prompt-new-project.d.ts +1 -1
- package/dist/cli/utils/prompt-new-project.d.ts.map +1 -1
- package/dist/cli/utils/registry.d.ts +2 -2
- package/dist/cli/utils/registry.d.ts.map +1 -1
- package/dist/cli/utils/registry.js +13 -3
- package/dist/cli/utils/registry.js.map +1 -1
- package/dist/runtime/log.d.ts.map +1 -1
- package/dist/runtime/log.js +8 -4
- package/dist/runtime/log.js.map +1 -1
- package/dist/runtime/storage.js +1 -1
- package/dist/runtime/storage.js.map +1 -1
- package/package.json +3 -2
- package/templates/default/CLAUDE.md +1 -0
- package/templates/default/skills/fling/.hash +1 -0
- package/templates/default/skills/fling/SKILL.md +12 -4
- /package/templates/default/skills/{discord/SKILL.md → fling/DISCORD.md} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling tunnel - Expose local development server via Cloudflare Tunnel
|
|
3
|
+
*
|
|
4
|
+
* Uses cloudflared (Cloudflare's tunnel daemon) for high-performance,
|
|
5
|
+
* concurrent request handling. The platform provisions tunnel credentials
|
|
6
|
+
* and DNS records; the CLI runs cloudflared with the provided token.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* fling tunnel 3000 # Tunnel localhost:3000
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import { type PlatformFetchFn } from "../utils/config.js";
|
|
13
|
+
import { type ConsoleIO, type ProcessIOWithSignals, type FileIO, type SpawnFn } from "../utils/cli-io.js";
|
|
14
|
+
/**
|
|
15
|
+
* Cloudflared module interface.
|
|
16
|
+
*/
|
|
17
|
+
export interface CloudflaredModule {
|
|
18
|
+
bin: string;
|
|
19
|
+
install(binPath: string): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Combined dependencies for tunnel command.
|
|
23
|
+
*/
|
|
24
|
+
export interface TunnelDeps {
|
|
25
|
+
console: ConsoleIO;
|
|
26
|
+
process: ProcessIOWithSignals;
|
|
27
|
+
file: FileIO;
|
|
28
|
+
spawn: SpawnFn;
|
|
29
|
+
getToken: () => string | null;
|
|
30
|
+
getProjectName: (cwd?: string) => string;
|
|
31
|
+
platformFetch: PlatformFetchFn;
|
|
32
|
+
importCloudflared: () => Promise<CloudflaredModule>;
|
|
33
|
+
}
|
|
34
|
+
export declare const defaultTunnelDeps: TunnelDeps;
|
|
35
|
+
/**
|
|
36
|
+
* Run the tunnel command.
|
|
37
|
+
* Exported for testing with injected dependencies.
|
|
38
|
+
*/
|
|
39
|
+
export declare function runTunnel(port: number, deps?: TunnelDeps): Promise<void>;
|
|
40
|
+
export declare const tunnelCommand: Command;
|
|
41
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAoB,MAAM,oBAAoB,CAAC;AAO5H;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,aAAa,EAAE,eAAe,CAAC;IAC/B,iBAAiB,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACrD;AAMD,eAAO,MAAM,iBAAiB,EAAE,UAS/B,CAAC;AAqJF;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,UAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAwDf;AAED,eAAO,MAAM,aAAa,SAoCtB,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling tunnel - Expose local development server via Cloudflare Tunnel
|
|
3
|
+
*
|
|
4
|
+
* Uses cloudflared (Cloudflare's tunnel daemon) for high-performance,
|
|
5
|
+
* concurrent request handling. The platform provisions tunnel credentials
|
|
6
|
+
* and DNS records; the CLI runs cloudflared with the provided token.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* fling tunnel 3000 # Tunnel localhost:3000
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from "commander";
|
|
12
|
+
import { platformFetch, getToken } from "../utils/config.js";
|
|
13
|
+
import { getProjectName } from "../utils/project-name.js";
|
|
14
|
+
import { consoleIO, processIO, fileIO, spawnFn } from "../utils/cli-io-impl.js";
|
|
15
|
+
// ═══════════════════════════════════════════════════════
|
|
16
|
+
// DEFAULT IMPLEMENTATIONS
|
|
17
|
+
// ═══════════════════════════════════════════════════════
|
|
18
|
+
export const defaultTunnelDeps = {
|
|
19
|
+
console: consoleIO,
|
|
20
|
+
process: processIO,
|
|
21
|
+
file: fileIO,
|
|
22
|
+
spawn: spawnFn,
|
|
23
|
+
getToken,
|
|
24
|
+
getProjectName,
|
|
25
|
+
platformFetch,
|
|
26
|
+
importCloudflared: async () => import("cloudflared"),
|
|
27
|
+
};
|
|
28
|
+
// ═══════════════════════════════════════════════════════
|
|
29
|
+
// CORE FUNCTIONS (with DI)
|
|
30
|
+
// ═══════════════════════════════════════════════════════
|
|
31
|
+
/**
|
|
32
|
+
* Ensure cloudflared binary is installed.
|
|
33
|
+
* Uses the 'cloudflared' npm package which handles platform-specific downloads.
|
|
34
|
+
*/
|
|
35
|
+
async function ensureCloudflared(deps) {
|
|
36
|
+
try {
|
|
37
|
+
const cloudflared = await deps.importCloudflared();
|
|
38
|
+
if (!deps.file.exists(cloudflared.bin)) {
|
|
39
|
+
deps.console.log("Installing cloudflared...");
|
|
40
|
+
await cloudflared.install(cloudflared.bin);
|
|
41
|
+
deps.console.log("cloudflared installed successfully");
|
|
42
|
+
}
|
|
43
|
+
return cloudflared.bin;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
deps.console.error(`Failed to install cloudflared: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Request tunnel credentials from the platform.
|
|
52
|
+
*/
|
|
53
|
+
async function startTunnel(projectName, localPort, deps) {
|
|
54
|
+
try {
|
|
55
|
+
const response = await deps.platformFetch(`/project/${encodeURIComponent(projectName)}/tun/start`, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
|
+
body: JSON.stringify({ localPort }),
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const error = await response.json().catch(() => ({}));
|
|
62
|
+
deps.console.error(`Error: Failed to start tunnel: ${error.error ?? response.statusText}`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return (await response.json());
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
deps.console.error(`Error: Failed to connect to platform: ${error instanceof Error ? error.message : String(error)}`);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Notify platform that tunnel is stopping.
|
|
74
|
+
*/
|
|
75
|
+
async function stopTunnel(projectName, deps) {
|
|
76
|
+
try {
|
|
77
|
+
await deps.platformFetch(`/project/${encodeURIComponent(projectName)}/tun/stop`, { method: "DELETE" });
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Ignore errors on cleanup
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Run cloudflared with the provided token.
|
|
85
|
+
*/
|
|
86
|
+
function runCloudflared(bin, tunnelToken, localPort, deps) {
|
|
87
|
+
const args = [
|
|
88
|
+
"tunnel",
|
|
89
|
+
"--no-autoupdate",
|
|
90
|
+
"run",
|
|
91
|
+
"--token",
|
|
92
|
+
tunnelToken,
|
|
93
|
+
"--url",
|
|
94
|
+
`http://localhost:${localPort}`,
|
|
95
|
+
];
|
|
96
|
+
const child = deps.spawn(bin, args, {
|
|
97
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
98
|
+
});
|
|
99
|
+
// Forward cloudflared output (stdout and stderr are piped, so they're non-null)
|
|
100
|
+
child.stdout?.on("data", (data) => {
|
|
101
|
+
const lines = data.toString().split("\n").filter(Boolean);
|
|
102
|
+
for (const line of lines) {
|
|
103
|
+
// Filter out noisy logs, show important ones
|
|
104
|
+
if (line.includes("error") ||
|
|
105
|
+
line.includes("failed") ||
|
|
106
|
+
line.includes("connected") ||
|
|
107
|
+
line.includes("Registered")) {
|
|
108
|
+
deps.console.log(`[cloudflared] ${line}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
child.stderr?.on("data", (data) => {
|
|
113
|
+
const lines = data.toString().split("\n").filter(Boolean);
|
|
114
|
+
for (const line of lines) {
|
|
115
|
+
// cloudflared logs to stderr by default
|
|
116
|
+
if (line.includes("ERR") ||
|
|
117
|
+
line.includes("error") ||
|
|
118
|
+
line.includes("failed")) {
|
|
119
|
+
deps.console.error(`[cloudflared] ${line}`);
|
|
120
|
+
}
|
|
121
|
+
else if (line.includes("INF") &&
|
|
122
|
+
(line.includes("connect") ||
|
|
123
|
+
line.includes("Registered") ||
|
|
124
|
+
line.includes("serving"))) {
|
|
125
|
+
deps.console.log(`[cloudflared] ${line}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return child;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Run the tunnel command.
|
|
133
|
+
* Exported for testing with injected dependencies.
|
|
134
|
+
*/
|
|
135
|
+
export async function runTunnel(port, deps = defaultTunnelDeps) {
|
|
136
|
+
const token = deps.getToken();
|
|
137
|
+
if (!token) {
|
|
138
|
+
deps.console.error("Error: Not logged in. Run 'fling login' first.");
|
|
139
|
+
deps.process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
// Get project name from package.json (defaults to "default" for backwards compatibility)
|
|
142
|
+
const projectName = deps.getProjectName();
|
|
143
|
+
deps.console.log(`Starting tunnel to localhost:${port}...`);
|
|
144
|
+
// Ensure cloudflared is installed
|
|
145
|
+
const cloudflaredBin = await ensureCloudflared(deps);
|
|
146
|
+
if (!cloudflaredBin) {
|
|
147
|
+
deps.process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
// Request tunnel credentials from platform
|
|
150
|
+
const tunResponse = await startTunnel(projectName, port, deps);
|
|
151
|
+
if (!tunResponse) {
|
|
152
|
+
deps.process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
deps.console.log(`\nTunnel URL: ${tunResponse.tunnelUrl}`);
|
|
155
|
+
deps.console.log(`Forwarding to: http://localhost:${port}`);
|
|
156
|
+
deps.console.log("\nPress Ctrl+C to disconnect\n");
|
|
157
|
+
// Run cloudflared with the token
|
|
158
|
+
const cloudflaredProcess = runCloudflared(cloudflaredBin, tunResponse.token, port, deps);
|
|
159
|
+
// Handle graceful shutdown
|
|
160
|
+
const cleanup = async () => {
|
|
161
|
+
deps.console.log("\nDisconnecting tunnel...");
|
|
162
|
+
cloudflaredProcess.kill("SIGTERM");
|
|
163
|
+
// Stop tunnel on platform
|
|
164
|
+
await stopTunnel(projectName, deps);
|
|
165
|
+
deps.process.exit(0);
|
|
166
|
+
};
|
|
167
|
+
deps.process.on("SIGINT", () => void cleanup());
|
|
168
|
+
deps.process.on("SIGTERM", () => void cleanup());
|
|
169
|
+
// Wait for cloudflared to exit
|
|
170
|
+
cloudflaredProcess.on("exit", (code) => {
|
|
171
|
+
if (code !== 0 && code !== null) {
|
|
172
|
+
deps.console.error(`cloudflared exited with code ${code}`);
|
|
173
|
+
}
|
|
174
|
+
deps.process.exit(code ?? 0);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
export const tunnelCommand = new Command("tunnel")
|
|
178
|
+
.description("Expose local server via Cloudflare Tunnel")
|
|
179
|
+
.argument("<port>", "Local port to tunnel")
|
|
180
|
+
.addHelpText("after", `
|
|
181
|
+
What it does:
|
|
182
|
+
Creates a Cloudflare Tunnel from the internet to your local development server.
|
|
183
|
+
External requests to the tunnel URL are forwarded to localhost:<port>.
|
|
184
|
+
|
|
185
|
+
This uses cloudflared (Cloudflare's tunnel daemon) which provides:
|
|
186
|
+
- Full concurrent request handling (no serialization)
|
|
187
|
+
- Native Cloudflare edge integration
|
|
188
|
+
- Automatic TLS termination
|
|
189
|
+
|
|
190
|
+
Examples:
|
|
191
|
+
fling tunnel 3000 Tunnel localhost:3000
|
|
192
|
+
|
|
193
|
+
The tunnel URL will be displayed when connected. Keep the command running
|
|
194
|
+
to maintain the tunnel. Press Ctrl+C to disconnect.
|
|
195
|
+
|
|
196
|
+
Prerequisites:
|
|
197
|
+
- Must be logged in (fling login)
|
|
198
|
+
- Local server must be running on the specified port
|
|
199
|
+
|
|
200
|
+
Note: cloudflared will be automatically downloaded on first use.
|
|
201
|
+
`)
|
|
202
|
+
.action(async (portArg) => {
|
|
203
|
+
const port = parseInt(portArg, 10);
|
|
204
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
205
|
+
console.error("Error: Port must be a number between 1 and 65535");
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
await runTunnel(port);
|
|
209
|
+
});
|
|
210
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../../src/cli/commands/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAwB,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA4BhF,0DAA0D;AAC1D,0BAA0B;AAC1B,0DAA0D;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC3C,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,QAAQ;IACR,cAAc;IACd,aAAa;IACb,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC;CACrD,CAAC;AASF,0DAA0D;AAC1D,2BAA2B;AAC3B,0DAA0D;AAE1D;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,IAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEnD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YAC9C,MAAM,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,WAAW,CAAC,GAAG,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/G,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,WAAW,CACxB,WAAmB,EACnB,SAAiB,EACjB,IAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CACvC,YAAY,kBAAkB,CAAC,WAAW,CAAC,YAAY,EACvD;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;SACpC,CACF,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,kCAAmC,KAA4B,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC/F,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAqB,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yCAAyC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,UAAU,CACvB,WAAmB,EACnB,IAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,CACtB,YAAY,kBAAkB,CAAC,WAAW,CAAC,WAAW,EACtD,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,GAAW,EACX,WAAmB,EACnB,SAAiB,EACjB,IAAgB;IAEhB,MAAM,IAAI,GAAG;QACX,QAAQ;QACR,iBAAiB;QACjB,KAAK;QACL,SAAS;QACT,WAAW;QACX,OAAO;QACP,oBAAoB,SAAS,EAAE;KAChC,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IAEH,gFAAgF;IAChF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,6CAA6C;YAC7C,IACE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACtB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC1B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC3B,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,wCAAwC;YACxC,IACE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACpB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACtB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACvB,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;YAC9C,CAAC;iBAAM,IACL,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACpB,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;oBACvB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;oBAC3B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAC3B,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,OAAmB,iBAAiB;IAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,yFAAyF;IACzF,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IAE1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,KAAK,CAAC,CAAC;IAE5D,kCAAkC;IAClC,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,2CAA2C;IAC3C,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAEnD,iCAAiC;IACjC,MAAM,kBAAkB,GAAG,cAAc,CACvC,cAAc,EACd,WAAW,CAAC,KAAK,EACjB,IAAI,EACJ,IAAI,CACL,CAAC;IAEF,2BAA2B;IAC3B,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAC9C,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnC,0BAA0B;QAC1B,MAAM,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAEjD,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACrC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,2CAA2C,CAAC;KACxD,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;KAC1C,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;CAqBH,CACE;KACA,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,EAAE;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling upgrade - Update skills in existing projects to latest version
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import type { UpgradeIO } from "../utils/cli-io.js";
|
|
6
|
+
export interface UpgradeOptions {
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Run the upgrade command logic.
|
|
11
|
+
* Extracted for testability via dependency injection.
|
|
12
|
+
*/
|
|
13
|
+
export declare function runUpgrade(options: UpgradeOptions, io: UpgradeIO): Promise<void>;
|
|
14
|
+
export declare const upgradeCommand: Command;
|
|
15
|
+
//# sourceMappingURL=upgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/upgrade.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIpD,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DtF;AAED,eAAO,MAAM,cAAc,SAqBvB,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling upgrade - Update skills in existing projects to latest version
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { createDefaultUpgradeIO } from "../utils/cli-io-impl.js";
|
|
6
|
+
import { getProjectSkillsDir, getTemplateSkillsDir, checkSkillsStatus } from "../utils/project.js";
|
|
7
|
+
/**
|
|
8
|
+
* Run the upgrade command logic.
|
|
9
|
+
* Extracted for testability via dependency injection.
|
|
10
|
+
*/
|
|
11
|
+
export async function runUpgrade(options, io) {
|
|
12
|
+
const result = checkSkillsStatus(io.process.cwd(), io.paths.templateDir, {
|
|
13
|
+
findEnclosingProject: (dir) => io.project.findEnclosingProject(dir),
|
|
14
|
+
hasSymlinkInPath: (target, base) => io.project.hasSymlinkInPath(target, base),
|
|
15
|
+
readFileString: (path) => io.file.readFileString(path),
|
|
16
|
+
});
|
|
17
|
+
switch (result.status) {
|
|
18
|
+
case "not-in-project":
|
|
19
|
+
io.console.error("Error: Not inside a Fling project (no .claude/skills/fling/ directory found)");
|
|
20
|
+
io.console.error("\nRun `fling init` to create a new project.");
|
|
21
|
+
io.process.exit(1);
|
|
22
|
+
break; // unreachable but satisfies TypeScript
|
|
23
|
+
case "symlink-detected":
|
|
24
|
+
io.console.error("Error: Skills directory path contains a symlink.");
|
|
25
|
+
io.console.error("For security reasons, upgrade cannot proceed.");
|
|
26
|
+
io.console.error("\nRemove the symlink and run `fling upgrade` again.");
|
|
27
|
+
io.process.exit(1);
|
|
28
|
+
break;
|
|
29
|
+
case "template-missing":
|
|
30
|
+
io.console.error("Error: Template hash file not found.");
|
|
31
|
+
io.console.error("This may indicate an issue with your Fling installation.");
|
|
32
|
+
io.process.exit(1);
|
|
33
|
+
break;
|
|
34
|
+
case "up-to-date":
|
|
35
|
+
io.console.log("Skills are up to date.");
|
|
36
|
+
return;
|
|
37
|
+
case "update-available":
|
|
38
|
+
io.console.log("Skill update available.");
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
const projectRoot = result.projectRoot;
|
|
42
|
+
const projectSkillsDir = getProjectSkillsDir(projectRoot);
|
|
43
|
+
const templateSkillsDir = getTemplateSkillsDir(io.paths.templateDir);
|
|
44
|
+
if (options.dryRun) {
|
|
45
|
+
io.console.log("\nDry run - no changes made.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// Copy all skill files from template
|
|
49
|
+
try {
|
|
50
|
+
io.file.copy(templateSkillsDir, projectSkillsDir, { recursive: true });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
+
io.console.error(`Error: Failed to copy skill files: ${message}`);
|
|
55
|
+
io.console.error("\nPossible causes:");
|
|
56
|
+
io.console.error(" - Permission denied (check file permissions)");
|
|
57
|
+
io.console.error(" - Disk full");
|
|
58
|
+
io.console.error(" - Template files missing (reinstall Fling)");
|
|
59
|
+
io.process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
io.console.log("Skills updated successfully.");
|
|
62
|
+
}
|
|
63
|
+
export const upgradeCommand = new Command("upgrade")
|
|
64
|
+
.description("Update skills to the latest version")
|
|
65
|
+
.option("--dry-run", "Preview what would change without making changes")
|
|
66
|
+
.addHelpText("after", `
|
|
67
|
+
Description:
|
|
68
|
+
Updates the Claude skill files in .claude/skills/fling/ to the latest
|
|
69
|
+
version included with your Fling installation.
|
|
70
|
+
|
|
71
|
+
Skills are used by Claude Code to understand how to interact with Fling
|
|
72
|
+
projects. Keeping them up to date ensures Claude has the best instructions
|
|
73
|
+
for working with your project.
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
fling upgrade Update skills to latest version
|
|
77
|
+
fling upgrade --dry-run Preview update without making changes
|
|
78
|
+
`)
|
|
79
|
+
.action(async (options) => {
|
|
80
|
+
await runUpgrade(options, createDefaultUpgradeIO());
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=upgrade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../../src/cli/commands/upgrade.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -26,6 +26,7 @@ Then try again.`);
|
|
|
26
26
|
* - Inside a Fling project: shows Commander help
|
|
27
27
|
* - Otherwise: shows project selector or create-new flow
|
|
28
28
|
*/
|
|
29
|
+
import { join } from "node:path";
|
|
29
30
|
import { Command } from "commander";
|
|
30
31
|
import { initCommand } from "./commands/init.js";
|
|
31
32
|
import { devCommand } from "./commands/dev.js";
|
|
@@ -40,12 +41,33 @@ import { registerCommand } from "./commands/register.js";
|
|
|
40
41
|
import { onboardCommand } from "./commands/onboard.js";
|
|
41
42
|
import { feedbackCommand } from "./commands/feedback.js";
|
|
42
43
|
import { projectCommand } from "./commands/project.js";
|
|
43
|
-
import { adminCommand } from "./commands/admin.js";
|
|
44
44
|
import { cronCommand } from "./commands/cron.js";
|
|
45
|
-
import {
|
|
45
|
+
import { tunnelCommand } from "./commands/tunnel.js";
|
|
46
46
|
import { storageCommand } from "./commands/storage.js";
|
|
47
47
|
import { pluginCommand } from "./commands/plugin.js";
|
|
48
|
+
import { upgradeCommand } from "./commands/upgrade.js";
|
|
48
49
|
import { launch } from "./commands/launch.js";
|
|
50
|
+
import { checkSkillsStatus, findEnclosingProject, hasSymlinkInPath, getFlingRoot } from "./utils/project.js";
|
|
51
|
+
import { readFileSync } from "node:fs";
|
|
52
|
+
/**
|
|
53
|
+
* Check if skills need an update.
|
|
54
|
+
*/
|
|
55
|
+
function checkSkillsNeedUpdate() {
|
|
56
|
+
const templateDir = join(getFlingRoot(), "templates", "default");
|
|
57
|
+
const result = checkSkillsStatus(process.cwd(), templateDir, {
|
|
58
|
+
findEnclosingProject,
|
|
59
|
+
hasSymlinkInPath,
|
|
60
|
+
readFileString(path) {
|
|
61
|
+
try {
|
|
62
|
+
return readFileSync(path, "utf-8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return result.status === "update-available";
|
|
70
|
+
}
|
|
49
71
|
const program = new Command();
|
|
50
72
|
program
|
|
51
73
|
.name("fling")
|
|
@@ -84,10 +106,19 @@ program.addCommand(whoamiCommand);
|
|
|
84
106
|
program.addCommand(feedbackCommand);
|
|
85
107
|
program.addCommand(projectCommand);
|
|
86
108
|
program.addCommand(cronCommand);
|
|
87
|
-
program.addCommand(
|
|
109
|
+
program.addCommand(tunnelCommand);
|
|
88
110
|
program.addCommand(storageCommand);
|
|
89
111
|
program.addCommand(pluginCommand);
|
|
90
|
-
program.addCommand(
|
|
112
|
+
program.addCommand(upgradeCommand);
|
|
113
|
+
// Check for skill updates on every command (except upgrade itself)
|
|
114
|
+
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
115
|
+
const commandName = actionCommand.name();
|
|
116
|
+
if (commandName === "upgrade")
|
|
117
|
+
return;
|
|
118
|
+
if (checkSkillsNeedUpdate()) {
|
|
119
|
+
console.log("Skill update available. Run `fling upgrade` to update.\n");
|
|
120
|
+
}
|
|
121
|
+
});
|
|
91
122
|
// If no command specified, run the default launch action
|
|
92
123
|
if (process.argv.length === 2) {
|
|
93
124
|
launch(program).catch((error) => {
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,oFAAoF;AACpF,4FAA4F;AAC5F,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;AACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;AAEhF,IAAI,YAAY,GAAG,gBAAgB,EAAE,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,iCAAiC,gBAAgB;;0BAEvC,cAAc;;;;;;gBAMxB,gBAAgB;YACpB,gBAAgB;;gBAEZ,CAAC,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production implementations of consolidated CLI I/O interfaces.
|
|
3
|
+
*
|
|
4
|
+
* These wrap the real dependencies (fs, process, @clack/prompts, etc.)
|
|
5
|
+
* used in production. Tests can substitute fake implementations.
|
|
6
|
+
*/
|
|
7
|
+
import type { ConsoleIO, ConsoleIOWithProgress, ProcessIOFull, ProcessIOWithStdio, FileIO, FileIOWithRead, DbFileIO, StorageFileIO, LaunchFileIO, OnboardingFileIO, InitFileIO, DevFileIO, UserIO, NetworkIO, BrowserIO, TimingIO, SpawnFn, ClaudeCodeIO, DatabaseIO, DbIO, StorageIO, LaunchIO, OnboardingIO, InitIO, DevIO, SimplePromptIO, SimpleConfirmIO, SimplePromptIOWithMultiline, ConfigFileIO, ConfigIO } from "./cli-io.js";
|
|
8
|
+
export declare const consoleIO: ConsoleIO;
|
|
9
|
+
export declare const consoleIOWithProgress: ConsoleIOWithProgress;
|
|
10
|
+
export declare const processIO: ProcessIOFull;
|
|
11
|
+
export declare const networkIO: NetworkIO;
|
|
12
|
+
export declare const timingIO: TimingIO;
|
|
13
|
+
export declare const spawnFn: SpawnFn;
|
|
14
|
+
/**
|
|
15
|
+
* Create browser opener for the current platform.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createBrowserIO(platform: NodeJS.Platform, spawn: SpawnFn): BrowserIO;
|
|
18
|
+
export declare const browserIO: BrowserIO;
|
|
19
|
+
/**
|
|
20
|
+
* Create simple readline-based prompt IO.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSimplePromptIO(proc: ProcessIOWithStdio): SimplePromptIO;
|
|
23
|
+
/**
|
|
24
|
+
* Create simple readline-based confirm IO.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSimpleConfirmIO(proc: ProcessIOWithStdio): SimpleConfirmIO;
|
|
27
|
+
/**
|
|
28
|
+
* Create simple prompt IO with multiline support (for feedback command).
|
|
29
|
+
*/
|
|
30
|
+
export declare function createSimplePromptIOWithMultiline(cons: ConsoleIO, proc: ProcessIOWithStdio): SimplePromptIOWithMultiline;
|
|
31
|
+
export declare const databaseIO: DatabaseIO;
|
|
32
|
+
export declare const claudeCodeIO: ClaudeCodeIO;
|
|
33
|
+
export declare const fileIO: FileIO;
|
|
34
|
+
export declare const fileIOWithRead: FileIOWithRead;
|
|
35
|
+
export declare const dbFileIO: DbFileIO;
|
|
36
|
+
export declare const storageFileIO: StorageFileIO;
|
|
37
|
+
export declare const launchFileIO: LaunchFileIO;
|
|
38
|
+
export declare const onboardingFileIO: OnboardingFileIO;
|
|
39
|
+
export declare const initFileIO: InitFileIO;
|
|
40
|
+
export declare const configFileIO: ConfigFileIO;
|
|
41
|
+
export declare const configIO: ConfigIO;
|
|
42
|
+
export declare const userIO: UserIO;
|
|
43
|
+
export declare const defaultDbIO: DbIO;
|
|
44
|
+
export declare const defaultStorageIO: StorageIO;
|
|
45
|
+
/**
|
|
46
|
+
* Create the default LaunchIO implementation using real dependencies.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createDefaultLaunchIO(): LaunchIO;
|
|
49
|
+
export declare const defaultOnboardingIO: OnboardingIO;
|
|
50
|
+
/**
|
|
51
|
+
* Create the default InitIO implementation using real dependencies.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createDefaultInitIO(): InitIO;
|
|
54
|
+
export declare const devFileIO: DevFileIO;
|
|
55
|
+
/**
|
|
56
|
+
* Create the default DevIO implementation using real dependencies.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createDefaultDevIO(): DevIO;
|
|
59
|
+
import type { UpgradeIO } from "./cli-io.js";
|
|
60
|
+
/**
|
|
61
|
+
* Create the default UpgradeIO implementation using real dependencies.
|
|
62
|
+
*/
|
|
63
|
+
export declare function createDefaultUpgradeIO(): UpgradeIO;
|
|
64
|
+
//# sourceMappingURL=cli-io-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-io-impl.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/cli-io-impl.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,MAAM,EACN,cAAc,EACd,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,MAAM,EAEN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,OAAO,EAGP,YAAY,EACZ,UAAU,EAKV,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,KAAK,EACL,cAAc,EACd,eAAe,EACf,2BAA2B,EAC3B,YAAY,EACZ,QAAQ,EACT,MAAM,aAAa,CAAC;AAsBrB,eAAO,MAAM,SAAS,EAAE,SAUvB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,qBAKnC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,aAcvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAEvB,CAAC;AAMF,eAAO,MAAM,QAAQ,EAAE,QAEtB,CAAC;AAMF,eAAO,MAAM,OAAO,EAAE,OAMrB,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAoBpF;AAED,eAAO,MAAM,SAAS,EAAE,SAAsD,CAAC;AAM/E;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAgB7E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAgB/E;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,kBAAkB,GACvB,2BAA2B,CAsB7B;AAMD,eAAO,MAAM,UAAU,EAAE,UAExB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,YAG1B,CAAC;AAMF,eAAO,MAAM,MAAM,EAAE,MAEpB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,QAQtB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,aAa3B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAa1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,gBAa9B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAgBxB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAgB1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,QAWtB,CAAC;AAMF,eAAO,MAAM,MAAM,EAAE,MAqDpB,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,IAKzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,SAU9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,QAAQ,CAwBhD;AAED,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAC;AA0CF;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA0B5C;AAOD,eAAO,MAAM,SAAS,EAAE,SAQvB,CAAC;AASF;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,CAiC1C;AAMD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,SAAS,CAqBlD"}
|