flingit 0.0.11 → 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 +7 -3
- package/dist/cli/utils/prompt-new-project.d.ts.map +1 -1
- package/dist/cli/utils/prompt-new-project.js +12 -17
- package/dist/cli/utils/prompt-new-project.js.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
package/dist/cli/utils/config.js
CHANGED
|
@@ -1,56 +1,185 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Platform configuration utilities.
|
|
3
|
-
* Stores token and API URL in ~/.fling/ (
|
|
3
|
+
* Stores token and API URL in ~/.config/fling/ (XDG Base Directory spec).
|
|
4
|
+
*
|
|
5
|
+
* Priority for config directory:
|
|
6
|
+
* 1. FLING_CONFIG_DIR environment variable (explicit override)
|
|
7
|
+
* 2. XDG_CONFIG_HOME/fling (if XDG_CONFIG_HOME is set)
|
|
8
|
+
* 3. ~/.config/fling (XDG default)
|
|
9
|
+
*
|
|
10
|
+
* Automatic migration: If ~/.fling exists but the new location doesn't,
|
|
11
|
+
* config is automatically migrated with a one-time notice.
|
|
4
12
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
13
|
+
import { join, dirname } from "node:path";
|
|
14
|
+
import { configIO as defaultConfigIO } from "./cli-io-impl.js";
|
|
15
|
+
const DEFAULT_API_URL = "https://api.justdeployit.dev";
|
|
16
|
+
// ═══════════════════════════════════════════════════════
|
|
17
|
+
// PURE FUNCTIONS (dependency-injected, testable)
|
|
18
|
+
// ═══════════════════════════════════════════════════════
|
|
19
|
+
/**
|
|
20
|
+
* Get the legacy config directory path (~/.fling).
|
|
21
|
+
*/
|
|
22
|
+
export function getLegacyConfigDir(io) {
|
|
23
|
+
return join(io.env.homedir(), ".fling");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the XDG-compliant config directory path.
|
|
27
|
+
* Respects XDG_CONFIG_HOME if set, otherwise defaults to ~/.config/fling.
|
|
28
|
+
*/
|
|
29
|
+
export function getXdgConfigDir(io) {
|
|
30
|
+
const xdgConfig = io.env.get("XDG_CONFIG_HOME");
|
|
31
|
+
if (xdgConfig) {
|
|
32
|
+
return join(xdgConfig, "fling");
|
|
33
|
+
}
|
|
34
|
+
return join(io.env.homedir(), ".config", "fling");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Migrate config from legacy ~/.fling to XDG location if needed.
|
|
38
|
+
* Returns true if migration was performed, false otherwise.
|
|
39
|
+
*/
|
|
40
|
+
export function migrateConfig(io) {
|
|
41
|
+
// Skip if user has explicit override
|
|
42
|
+
if (io.env.get("FLING_CONFIG_DIR")) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const legacyDir = getLegacyConfigDir(io);
|
|
46
|
+
const newDir = getXdgConfigDir(io);
|
|
47
|
+
// Skip if legacy doesn't exist or new already exists
|
|
48
|
+
if (!io.file.exists(legacyDir) || io.file.exists(newDir)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// Migrate: move ~/.fling to ~/.config/fling
|
|
52
|
+
try {
|
|
53
|
+
// Ensure parent directory exists (e.g., ~/.config or custom XDG_CONFIG_HOME)
|
|
54
|
+
const configBase = dirname(newDir);
|
|
55
|
+
io.file.mkdir(configBase, { recursive: true });
|
|
56
|
+
io.file.rename(legacyDir, newDir);
|
|
57
|
+
io.console.error("Note: Fling config migrated from ~/.fling to ~/.config/fling");
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Migration failed - log warning but continue with new location
|
|
62
|
+
// User may need to manually move files if permissions are an issue
|
|
63
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
64
|
+
io.console.error(`Warning: Failed to migrate config from ~/.fling to ~/.config/fling: ${message}`);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
8
68
|
/**
|
|
9
69
|
* Get the configuration directory.
|
|
10
|
-
*
|
|
70
|
+
* Priority: FLING_CONFIG_DIR > XDG_CONFIG_HOME/fling > ~/.config/fling
|
|
11
71
|
*/
|
|
12
|
-
function
|
|
13
|
-
const envDir =
|
|
72
|
+
export function getConfigDirWithIO(io, attemptMigration = true) {
|
|
73
|
+
const envDir = io.env.get("FLING_CONFIG_DIR");
|
|
14
74
|
if (envDir) {
|
|
15
75
|
return envDir;
|
|
16
76
|
}
|
|
17
|
-
|
|
77
|
+
// Attempt migration from legacy location
|
|
78
|
+
if (attemptMigration) {
|
|
79
|
+
migrateConfig(io);
|
|
80
|
+
}
|
|
81
|
+
return getXdgConfigDir(io);
|
|
18
82
|
}
|
|
19
|
-
const CONFIG_DIR = getConfigDir();
|
|
20
|
-
const TOKEN_FILE = join(CONFIG_DIR, "token");
|
|
21
|
-
const API_URL_FILE = join(CONFIG_DIR, "api-url");
|
|
22
|
-
const DEFAULT_API_URL = "https://api.justdeployit.dev";
|
|
23
83
|
/**
|
|
24
|
-
*
|
|
84
|
+
* Get the stored API token, or null if not logged in.
|
|
85
|
+
* Empty or whitespace-only tokens are treated as null.
|
|
86
|
+
*/
|
|
87
|
+
export function getTokenWithIO(io, configDir) {
|
|
88
|
+
const tokenFile = join(configDir, "token");
|
|
89
|
+
const token = io.file.readFileString(tokenFile);
|
|
90
|
+
// Treat empty/whitespace-only tokens as not logged in
|
|
91
|
+
return token && token.length > 0 ? token : null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Store the API token.
|
|
95
|
+
*/
|
|
96
|
+
export function setTokenWithIO(io, configDir, token) {
|
|
97
|
+
io.file.mkdir(configDir, { recursive: true });
|
|
98
|
+
const tokenFile = join(configDir, "token");
|
|
99
|
+
io.file.writeFileString(tokenFile, token, { mode: 0o600 });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Remove the stored token.
|
|
103
|
+
*/
|
|
104
|
+
export function clearTokenWithIO(io, configDir) {
|
|
105
|
+
const tokenFile = join(configDir, "token");
|
|
106
|
+
io.file.delete(tokenFile);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the API URL.
|
|
110
|
+
* Priority: FLING_API_URL env var > config file > default
|
|
111
|
+
*/
|
|
112
|
+
export function getApiUrlWithIO(io, configDir) {
|
|
113
|
+
const envUrl = io.env.get("FLING_API_URL");
|
|
114
|
+
if (envUrl) {
|
|
115
|
+
return envUrl;
|
|
116
|
+
}
|
|
117
|
+
const apiUrlFile = join(configDir, "api-url");
|
|
118
|
+
const fileUrl = io.file.readFileString(apiUrlFile);
|
|
119
|
+
if (fileUrl) {
|
|
120
|
+
return fileUrl;
|
|
121
|
+
}
|
|
122
|
+
return DEFAULT_API_URL;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Set the API URL (for development/testing).
|
|
126
|
+
*/
|
|
127
|
+
export function setApiUrlWithIO(io, configDir, url) {
|
|
128
|
+
io.file.mkdir(configDir, { recursive: true });
|
|
129
|
+
const apiUrlFile = join(configDir, "api-url");
|
|
130
|
+
io.file.writeFileString(apiUrlFile, url);
|
|
131
|
+
}
|
|
132
|
+
// ═══════════════════════════════════════════════════════
|
|
133
|
+
// MODULE-LEVEL STATE (for backward compatibility)
|
|
134
|
+
// ═══════════════════════════════════════════════════════
|
|
135
|
+
// Track whether migration has been attempted this session
|
|
136
|
+
let migrationAttempted = false;
|
|
137
|
+
/**
|
|
138
|
+
* Reset the migration flag. Used for testing.
|
|
25
139
|
*/
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
140
|
+
export function resetMigrationFlag() {
|
|
141
|
+
migrationAttempted = false;
|
|
142
|
+
}
|
|
143
|
+
// ═══════════════════════════════════════════════════════
|
|
144
|
+
// CONVENIENCE EXPORTS (use default IO, for production)
|
|
145
|
+
// ═══════════════════════════════════════════════════════
|
|
146
|
+
function getConfigDir() {
|
|
147
|
+
if (!migrationAttempted) {
|
|
148
|
+
migrationAttempted = true;
|
|
149
|
+
migrateConfig(defaultConfigIO);
|
|
29
150
|
}
|
|
151
|
+
return getConfigDirWithIO(defaultConfigIO, false);
|
|
152
|
+
}
|
|
153
|
+
// Cache config dir to avoid repeated computation
|
|
154
|
+
let _configDir = null;
|
|
155
|
+
function getCachedConfigDir() {
|
|
156
|
+
_configDir ??= getConfigDir();
|
|
157
|
+
return _configDir;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Reset the cached config dir. Used for testing.
|
|
161
|
+
*/
|
|
162
|
+
export function resetConfigDirCache() {
|
|
163
|
+
_configDir = null;
|
|
164
|
+
migrationAttempted = false;
|
|
30
165
|
}
|
|
31
166
|
/**
|
|
32
167
|
* Get the stored API token, or null if not logged in.
|
|
33
168
|
*/
|
|
34
169
|
export function getToken() {
|
|
35
|
-
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
return readFileSync(TOKEN_FILE, "utf-8").trim();
|
|
170
|
+
return getTokenWithIO(defaultConfigIO, getCachedConfigDir());
|
|
39
171
|
}
|
|
40
172
|
/**
|
|
41
173
|
* Store the API token.
|
|
42
174
|
*/
|
|
43
175
|
export function setToken(token) {
|
|
44
|
-
|
|
45
|
-
writeFileSync(TOKEN_FILE, token, { mode: 0o600 });
|
|
176
|
+
setTokenWithIO(defaultConfigIO, getCachedConfigDir(), token);
|
|
46
177
|
}
|
|
47
178
|
/**
|
|
48
179
|
* Remove the stored token.
|
|
49
180
|
*/
|
|
50
181
|
export function clearToken() {
|
|
51
|
-
|
|
52
|
-
unlinkSync(TOKEN_FILE);
|
|
53
|
-
}
|
|
182
|
+
clearTokenWithIO(defaultConfigIO, getCachedConfigDir());
|
|
54
183
|
}
|
|
55
184
|
/**
|
|
56
185
|
* Check if logged in to the platform.
|
|
@@ -62,28 +191,20 @@ export function isLoggedIn() {
|
|
|
62
191
|
* Check if the config directory exists (indicates previous setup).
|
|
63
192
|
*/
|
|
64
193
|
export function configDirExists() {
|
|
65
|
-
return
|
|
194
|
+
return defaultConfigIO.file.exists(getCachedConfigDir());
|
|
66
195
|
}
|
|
67
196
|
/**
|
|
68
197
|
* Get the API URL.
|
|
69
|
-
* Priority: FLING_API_URL env var > ~/.fling/api-url file > default
|
|
198
|
+
* Priority: FLING_API_URL env var > ~/.config/fling/api-url file > default
|
|
70
199
|
*/
|
|
71
200
|
export function getApiUrl() {
|
|
72
|
-
|
|
73
|
-
if (envUrl) {
|
|
74
|
-
return envUrl;
|
|
75
|
-
}
|
|
76
|
-
if (existsSync(API_URL_FILE)) {
|
|
77
|
-
return readFileSync(API_URL_FILE, "utf-8").trim();
|
|
78
|
-
}
|
|
79
|
-
return DEFAULT_API_URL;
|
|
201
|
+
return getApiUrlWithIO(defaultConfigIO, getCachedConfigDir());
|
|
80
202
|
}
|
|
81
203
|
/**
|
|
82
204
|
* Set the API URL (for development/testing).
|
|
83
205
|
*/
|
|
84
206
|
export function setApiUrl(url) {
|
|
85
|
-
|
|
86
|
-
writeFileSync(API_URL_FILE, url);
|
|
207
|
+
setApiUrlWithIO(defaultConfigIO, getCachedConfigDir(), url);
|
|
87
208
|
}
|
|
88
209
|
/**
|
|
89
210
|
* The actual implementation of platformFetch.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/utils/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,60 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides helpers for locating project files and validating project structure.
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get Fling root directory by walking up from this file to find package.json.
|
|
8
|
+
* Verifies the package name is "flingit" to ensure we found the right one.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getFlingRoot(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Result of checking skills update status.
|
|
13
|
+
*/
|
|
14
|
+
export type SkillsStatus = {
|
|
15
|
+
status: "not-in-project";
|
|
16
|
+
} | {
|
|
17
|
+
status: "symlink-detected";
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
} | {
|
|
20
|
+
status: "template-missing";
|
|
21
|
+
projectRoot: string;
|
|
22
|
+
} | {
|
|
23
|
+
status: "up-to-date";
|
|
24
|
+
projectRoot: string;
|
|
25
|
+
} | {
|
|
26
|
+
status: "update-available";
|
|
27
|
+
projectRoot: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* File operations needed for checking skills status.
|
|
31
|
+
* Allows dependency injection for testing.
|
|
32
|
+
*/
|
|
33
|
+
export interface SkillsStatusIO {
|
|
34
|
+
findEnclosingProject(startDir: string): string | null;
|
|
35
|
+
hasSymlinkInPath(targetPath: string, basePath: string): boolean;
|
|
36
|
+
readFileString(path: string): string | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check whether skills need updating.
|
|
40
|
+
* Returns a discriminated union with the status and relevant paths.
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkSkillsStatus(cwd: string, templateDir: string, io: SkillsStatusIO): SkillsStatus;
|
|
43
|
+
/**
|
|
44
|
+
* Path components for the Fling skills directory within a project.
|
|
45
|
+
* Used to identify Fling projects and locate skill files.
|
|
46
|
+
*/
|
|
47
|
+
export declare const FLING_SKILLS_PATH: readonly [".claude", "skills", "fling"];
|
|
48
|
+
/**
|
|
49
|
+
* Path components for the Fling skills directory within templates.
|
|
50
|
+
*/
|
|
51
|
+
export declare const TEMPLATE_SKILLS_PATH: readonly ["skills", "fling"];
|
|
52
|
+
/**
|
|
53
|
+
* Get the full path to the Fling skills directory in a project.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getProjectSkillsDir(projectRoot: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Get the full path to the Fling skills directory in templates.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getTemplateSkillsDir(templateDir: string): string;
|
|
6
60
|
/**
|
|
7
61
|
* Get the worker entry point path.
|
|
8
62
|
* Always expects src/worker/index.ts.
|
|
@@ -21,4 +75,10 @@ export declare function isProjectRoot(dir: string): boolean;
|
|
|
21
75
|
* Returns the project root path, or null if none found.
|
|
22
76
|
*/
|
|
23
77
|
export declare function findEnclosingProject(startDir: string): string | null;
|
|
78
|
+
/**
|
|
79
|
+
* Check if any component of a path is a symlink.
|
|
80
|
+
* Walks from the target path up to (but not including) the base path.
|
|
81
|
+
* This only checks symlinks within the project, not above it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function hasSymlinkInPath(targetPath: string, basePath: string): boolean;
|
|
24
84
|
//# sourceMappingURL=project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CA4BrC;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC5B;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtD,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAChE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,cAAc,GACjB,YAAY,CAgCd;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yCAA0C,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,oBAAoB,8BAA+B,CAAC;AAEjE;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAepE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoB9E"}
|
|
@@ -3,8 +3,93 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides helpers for locating project files and validating project structure.
|
|
5
5
|
*/
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
6
|
+
import { existsSync, lstatSync, readFileSync } from "node:fs";
|
|
7
7
|
import { join, dirname, resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
// Cache the result since it won't change during execution
|
|
10
|
+
let cachedFlingRoot = null;
|
|
11
|
+
/**
|
|
12
|
+
* Get Fling root directory by walking up from this file to find package.json.
|
|
13
|
+
* Verifies the package name is "flingit" to ensure we found the right one.
|
|
14
|
+
*/
|
|
15
|
+
export function getFlingRoot() {
|
|
16
|
+
if (cachedFlingRoot !== null) {
|
|
17
|
+
return cachedFlingRoot;
|
|
18
|
+
}
|
|
19
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
20
|
+
let current = dirname(thisFile);
|
|
21
|
+
let parent = dirname(current);
|
|
22
|
+
while (current !== parent) {
|
|
23
|
+
const packageJsonPath = join(current, "package.json");
|
|
24
|
+
if (existsSync(packageJsonPath)) {
|
|
25
|
+
try {
|
|
26
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
27
|
+
const pkg = JSON.parse(content);
|
|
28
|
+
if (pkg.name === "flingit") {
|
|
29
|
+
cachedFlingRoot = current;
|
|
30
|
+
return current;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Invalid JSON, keep looking
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
current = parent;
|
|
38
|
+
parent = dirname(current);
|
|
39
|
+
}
|
|
40
|
+
throw new Error("Could not find Fling root directory (no package.json with name 'flingit' found)");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check whether skills need updating.
|
|
44
|
+
* Returns a discriminated union with the status and relevant paths.
|
|
45
|
+
*/
|
|
46
|
+
export function checkSkillsStatus(cwd, templateDir, io) {
|
|
47
|
+
const projectRoot = io.findEnclosingProject(cwd);
|
|
48
|
+
if (projectRoot === null) {
|
|
49
|
+
return { status: "not-in-project" };
|
|
50
|
+
}
|
|
51
|
+
const projectSkillsDir = getProjectSkillsDir(projectRoot);
|
|
52
|
+
if (io.hasSymlinkInPath(projectSkillsDir, projectRoot)) {
|
|
53
|
+
return { status: "symlink-detected", projectRoot };
|
|
54
|
+
}
|
|
55
|
+
const templateSkillsDir = getTemplateSkillsDir(templateDir);
|
|
56
|
+
const templateHashFile = join(templateSkillsDir, ".hash");
|
|
57
|
+
const templateHash = io.readFileString(templateHashFile);
|
|
58
|
+
if (templateHash === null) {
|
|
59
|
+
return { status: "template-missing", projectRoot };
|
|
60
|
+
}
|
|
61
|
+
const projectHashFile = join(projectSkillsDir, ".hash");
|
|
62
|
+
const projectHash = io.readFileString(projectHashFile);
|
|
63
|
+
// Old project without hash file - needs upgrade
|
|
64
|
+
if (projectHash === null) {
|
|
65
|
+
return { status: "update-available", projectRoot };
|
|
66
|
+
}
|
|
67
|
+
if (templateHash.trim() === projectHash.trim()) {
|
|
68
|
+
return { status: "up-to-date", projectRoot };
|
|
69
|
+
}
|
|
70
|
+
return { status: "update-available", projectRoot };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Path components for the Fling skills directory within a project.
|
|
74
|
+
* Used to identify Fling projects and locate skill files.
|
|
75
|
+
*/
|
|
76
|
+
export const FLING_SKILLS_PATH = [".claude", "skills", "fling"];
|
|
77
|
+
/**
|
|
78
|
+
* Path components for the Fling skills directory within templates.
|
|
79
|
+
*/
|
|
80
|
+
export const TEMPLATE_SKILLS_PATH = ["skills", "fling"];
|
|
81
|
+
/**
|
|
82
|
+
* Get the full path to the Fling skills directory in a project.
|
|
83
|
+
*/
|
|
84
|
+
export function getProjectSkillsDir(projectRoot) {
|
|
85
|
+
return join(projectRoot, ...FLING_SKILLS_PATH);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the full path to the Fling skills directory in templates.
|
|
89
|
+
*/
|
|
90
|
+
export function getTemplateSkillsDir(templateDir) {
|
|
91
|
+
return join(templateDir, ...TEMPLATE_SKILLS_PATH);
|
|
92
|
+
}
|
|
8
93
|
/**
|
|
9
94
|
* Get the worker entry point path.
|
|
10
95
|
* Always expects src/worker/index.ts.
|
|
@@ -22,7 +107,7 @@ export function hasWorkerEntry(projectDir) {
|
|
|
22
107
|
* Check if a directory is a Fling project root (has a fling Claude skill).
|
|
23
108
|
*/
|
|
24
109
|
export function isProjectRoot(dir) {
|
|
25
|
-
return existsSync(
|
|
110
|
+
return existsSync(getProjectSkillsDir(dir));
|
|
26
111
|
}
|
|
27
112
|
/**
|
|
28
113
|
* Walk up from startDir looking for an enclosing Fling project.
|
|
@@ -44,4 +129,29 @@ export function findEnclosingProject(startDir) {
|
|
|
44
129
|
}
|
|
45
130
|
return null;
|
|
46
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if any component of a path is a symlink.
|
|
134
|
+
* Walks from the target path up to (but not including) the base path.
|
|
135
|
+
* This only checks symlinks within the project, not above it.
|
|
136
|
+
*/
|
|
137
|
+
export function hasSymlinkInPath(targetPath, basePath) {
|
|
138
|
+
let current = targetPath;
|
|
139
|
+
let parent = dirname(current);
|
|
140
|
+
// Stop when we reach the base path (don't check it or above)
|
|
141
|
+
while (current !== parent && current !== basePath) {
|
|
142
|
+
try {
|
|
143
|
+
const stats = lstatSync(current);
|
|
144
|
+
if (stats.isSymbolicLink()) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Path doesn't exist, stop checking
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
current = parent;
|
|
153
|
+
parent = dirname(current);
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
47
157
|
//# sourceMappingURL=project.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/utils/project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/utils/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prompt the user to select where to create
|
|
2
|
+
* Prompt the user to select where to create a new Fling project.
|
|
3
3
|
*/
|
|
4
|
-
import type { LaunchIO, PromptNewProjectResult } from "./
|
|
4
|
+
import type { LaunchIO, PromptNewProjectResult } from "./cli-io.js";
|
|
5
5
|
/**
|
|
6
|
-
* Prompt the user to
|
|
6
|
+
* Prompt the user to select a location for creating a new project.
|
|
7
|
+
*
|
|
8
|
+
* Note: This function is called AFTER the user has already chosen
|
|
9
|
+
* "Create new project" in the project selector. It should only offer
|
|
10
|
+
* creation options, not options to open existing projects.
|
|
7
11
|
*
|
|
8
12
|
* @param io - The launch I/O context
|
|
9
13
|
* @returns The chosen directory path, or null if cancelled
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-new-project.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/prompt-new-project.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"prompt-new-project.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/prompt-new-project.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,QAAQ,GACX,OAAO,CAAC,sBAAsB,CAAC,CAwDjC"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prompt the user to select where to create
|
|
2
|
+
* Prompt the user to select where to create a new Fling project.
|
|
3
3
|
*/
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
/**
|
|
6
|
-
* Prompt the user to
|
|
6
|
+
* Prompt the user to select a location for creating a new project.
|
|
7
|
+
*
|
|
8
|
+
* Note: This function is called AFTER the user has already chosen
|
|
9
|
+
* "Create new project" in the project selector. It should only offer
|
|
10
|
+
* creation options, not options to open existing projects.
|
|
7
11
|
*
|
|
8
12
|
* @param io - The launch I/O context
|
|
9
13
|
* @returns The chosen directory path, or null if cancelled
|
|
@@ -14,19 +18,14 @@ export async function promptNewProject(io) {
|
|
|
14
18
|
const options = [];
|
|
15
19
|
// Check ~/fling status
|
|
16
20
|
const flingHomeExists = file.exists(flingHome);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
else if (!flingHomeExists) {
|
|
26
|
-
// ~/fling doesn't exist - offer to create it there
|
|
21
|
+
// Only offer ~/fling as a creation option if it doesn't exist.
|
|
22
|
+
// If ~/fling exists (whether as a project or not), don't offer it.
|
|
23
|
+
// Note: If user wanted to open an existing project, they should have
|
|
24
|
+
// selected it in the project selector - this function is only called
|
|
25
|
+
// AFTER user chose "Create new project".
|
|
26
|
+
if (!flingHomeExists) {
|
|
27
27
|
options.push({ value: flingHome, label: "Start in ~/fling" });
|
|
28
28
|
}
|
|
29
|
-
// If ~/fling exists but is NOT a project, don't show either option
|
|
30
29
|
// Suggest current directory only if it's empty (and not ~/fling)
|
|
31
30
|
if (cwd !== flingHome && file.isDirEmpty(cwd)) {
|
|
32
31
|
options.push({
|
|
@@ -43,10 +42,6 @@ export async function promptNewProject(io) {
|
|
|
43
42
|
if (user.isCancel(choice) || choice === "cancel") {
|
|
44
43
|
return null;
|
|
45
44
|
}
|
|
46
|
-
if (choice === "open-existing") {
|
|
47
|
-
// User wants to open the existing project at ~/fling
|
|
48
|
-
return flingHome;
|
|
49
|
-
}
|
|
50
45
|
if (choice === "enter-path") {
|
|
51
46
|
const entered = await user.text({
|
|
52
47
|
message: "Enter the path for your new project:",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-new-project.js","sourceRoot":"","sources":["../../../src/cli/utils/prompt-new-project.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C
|
|
1
|
+
{"version":3,"file":"prompt-new-project.js","sourceRoot":"","sources":["../../../src/cli/utils/prompt-new-project.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAY;IAEZ,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACjC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAE1C,MAAM,OAAO,GAAuC,EAAE,CAAC;IAEvD,uBAAuB;IACvB,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE/C,+DAA+D;IAC/D,mEAAmE;IACnE,qEAAqE;IACrE,qEAAqE;IACrE,yCAAyC;IACzC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,iEAAiE;IACjE,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,GAAG;YACV,KAAK,EAAE,+BAA+B,GAAG,GAAG;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;QAC/B,OAAO,EAAE,qDAAqD;QAC9D,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC;YAC9B,OAAO,EAAE,sCAAsC;YAC/C,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6BAA6B;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACvC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,OAAO,CAAC;QACZ,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project registry utilities.
|
|
3
|
-
* Manages a list of known Fling project paths in ~/.fling/projects.json
|
|
4
|
-
* (or FLING_CONFIG_DIR if set).
|
|
3
|
+
* Manages a list of known Fling project paths in ~/.config/fling/projects.json
|
|
4
|
+
* (XDG Base Directory spec, or FLING_CONFIG_DIR if set).
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
7
|
* Read the project registry. Returns an empty array if the file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkCH;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAcvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAOtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAO3D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAS3C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAGzD"}
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project registry utilities.
|
|
3
|
-
* Manages a list of known Fling project paths in ~/.fling/projects.json
|
|
4
|
-
* (or FLING_CONFIG_DIR if set).
|
|
3
|
+
* Manages a list of known Fling project paths in ~/.config/fling/projects.json
|
|
4
|
+
* (XDG Base Directory spec, or FLING_CONFIG_DIR if set).
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { join, resolve } from "node:path";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { isProjectRoot } from "./project.js";
|
|
10
|
+
/**
|
|
11
|
+
* Get the configuration directory.
|
|
12
|
+
* Priority: FLING_CONFIG_DIR > XDG_CONFIG_HOME/fling > ~/.config/fling
|
|
13
|
+
* Note: Migration is handled by config.ts; registry just reads the same location.
|
|
14
|
+
*/
|
|
10
15
|
function getConfigDir() {
|
|
11
16
|
const envDir = process.env["FLING_CONFIG_DIR"];
|
|
12
17
|
if (envDir) {
|
|
13
18
|
return envDir;
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
// Respect XDG_CONFIG_HOME if set, otherwise default to ~/.config/fling
|
|
21
|
+
const xdgConfig = process.env["XDG_CONFIG_HOME"];
|
|
22
|
+
if (xdgConfig) {
|
|
23
|
+
return join(xdgConfig, "fling");
|
|
24
|
+
}
|
|
25
|
+
return join(homedir(), ".config", "fling");
|
|
16
26
|
}
|
|
17
27
|
function getRegistryPath() {
|
|
18
28
|
return join(getConfigDir(), "projects.json");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/cli/utils/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAM7C,SAAS,YAAY;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/cli/utils/registry.ts"],"names":[],"mappings":"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"}
|