brainrot-cli 0.1.0
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 +372 -0
- package/dist/AchievementNotification.d.ts +28 -0
- package/dist/AchievementNotification.d.ts.map +1 -0
- package/dist/AchievementNotification.js +74 -0
- package/dist/AchievementNotification.js.map +1 -0
- package/dist/GameSelector.d.ts +25 -0
- package/dist/GameSelector.d.ts.map +1 -0
- package/dist/GameSelector.js +105 -0
- package/dist/GameSelector.js.map +1 -0
- package/dist/HelpOverlay.d.ts +15 -0
- package/dist/HelpOverlay.d.ts.map +1 -0
- package/dist/HelpOverlay.js +134 -0
- package/dist/HelpOverlay.js.map +1 -0
- package/dist/Layout.d.ts +49 -0
- package/dist/Layout.d.ts.map +1 -0
- package/dist/Layout.js +83 -0
- package/dist/Layout.js.map +1 -0
- package/dist/Leaderboard.d.ts +46 -0
- package/dist/Leaderboard.d.ts.map +1 -0
- package/dist/Leaderboard.js +68 -0
- package/dist/Leaderboard.js.map +1 -0
- package/dist/LogViewer.d.ts +33 -0
- package/dist/LogViewer.d.ts.map +1 -0
- package/dist/LogViewer.js +179 -0
- package/dist/LogViewer.js.map +1 -0
- package/dist/LoopAlertOverlay.d.ts +15 -0
- package/dist/LoopAlertOverlay.d.ts.map +1 -0
- package/dist/LoopAlertOverlay.js +17 -0
- package/dist/LoopAlertOverlay.js.map +1 -0
- package/dist/LoopManagementPanel.d.ts +44 -0
- package/dist/LoopManagementPanel.d.ts.map +1 -0
- package/dist/LoopManagementPanel.js +220 -0
- package/dist/LoopManagementPanel.js.map +1 -0
- package/dist/SettingsMenu.d.ts +22 -0
- package/dist/SettingsMenu.d.ts.map +1 -0
- package/dist/SettingsMenu.js +367 -0
- package/dist/SettingsMenu.js.map +1 -0
- package/dist/SplitPane.d.ts +63 -0
- package/dist/SplitPane.d.ts.map +1 -0
- package/dist/SplitPane.js +104 -0
- package/dist/SplitPane.js.map +1 -0
- package/dist/StatsMenu.d.ts +15 -0
- package/dist/StatsMenu.d.ts.map +1 -0
- package/dist/StatsMenu.js +230 -0
- package/dist/StatsMenu.js.map +1 -0
- package/dist/StatusBar.d.ts +58 -0
- package/dist/StatusBar.d.ts.map +1 -0
- package/dist/StatusBar.js +106 -0
- package/dist/StatusBar.js.map +1 -0
- package/dist/__tests__/ralph-loop-parser.test.d.ts +2 -0
- package/dist/__tests__/ralph-loop-parser.test.d.ts.map +1 -0
- package/dist/__tests__/ralph-loop-parser.test.js +143 -0
- package/dist/__tests__/ralph-loop-parser.test.js.map +1 -0
- package/dist/claude-code-process.d.ts +76 -0
- package/dist/claude-code-process.d.ts.map +1 -0
- package/dist/claude-code-process.js +221 -0
- package/dist/claude-code-process.js.map +1 -0
- package/dist/cli.d.ts +42 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +265 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +206 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +270 -0
- package/dist/config.js.map +1 -0
- package/dist/game-types.d.ts +177 -0
- package/dist/game-types.d.ts.map +1 -0
- package/dist/game-types.js +55 -0
- package/dist/game-types.js.map +1 -0
- package/dist/games/MinesweeperGame.d.ts +15 -0
- package/dist/games/MinesweeperGame.d.ts.map +1 -0
- package/dist/games/MinesweeperGame.js +555 -0
- package/dist/games/MinesweeperGame.js.map +1 -0
- package/dist/games/PongGame.d.ts +15 -0
- package/dist/games/PongGame.d.ts.map +1 -0
- package/dist/games/PongGame.js +379 -0
- package/dist/games/PongGame.js.map +1 -0
- package/dist/games/SnakeGame.d.ts +15 -0
- package/dist/games/SnakeGame.d.ts.map +1 -0
- package/dist/games/SnakeGame.js +333 -0
- package/dist/games/SnakeGame.js.map +1 -0
- package/dist/games/TetrisGame.d.ts +15 -0
- package/dist/games/TetrisGame.d.ts.map +1 -0
- package/dist/games/TetrisGame.js +654 -0
- package/dist/games/TetrisGame.js.map +1 -0
- package/dist/games/index.d.ts +23 -0
- package/dist/games/index.d.ts.map +1 -0
- package/dist/games/index.js +47 -0
- package/dist/games/index.js.map +1 -0
- package/dist/high-scores.d.ts +57 -0
- package/dist/high-scores.d.ts.map +1 -0
- package/dist/high-scores.js +230 -0
- package/dist/high-scores.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +264 -0
- package/dist/index.js.map +1 -0
- package/dist/ralph-loop-parser.d.ts +58 -0
- package/dist/ralph-loop-parser.d.ts.map +1 -0
- package/dist/ralph-loop-parser.js +315 -0
- package/dist/ralph-loop-parser.js.map +1 -0
- package/dist/stats.d.ts +142 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +521 -0
- package/dist/stats.js.map +1 -0
- package/dist/styled-components.d.ts +231 -0
- package/dist/styled-components.d.ts.map +1 -0
- package/dist/styled-components.js +192 -0
- package/dist/styled-components.js.map +1 -0
- package/dist/theme.d.ts +301 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +372 -0
- package/dist/theme.js.map +1 -0
- package/dist/themes.d.ts +117 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +296 -0
- package/dist/themes.js.map +1 -0
- package/dist/ui/index.d.ts +13 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +29 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/use-claude-code.d.ts +30 -0
- package/dist/use-claude-code.d.ts.map +1 -0
- package/dist/use-claude-code.js +84 -0
- package/dist/use-claude-code.js.map +1 -0
- package/dist/use-config.d.ts +58 -0
- package/dist/use-config.d.ts.map +1 -0
- package/dist/use-config.js +113 -0
- package/dist/use-config.js.map +1 -0
- package/dist/use-game-loop.d.ts +47 -0
- package/dist/use-game-loop.d.ts.map +1 -0
- package/dist/use-game-loop.js +136 -0
- package/dist/use-game-loop.js.map +1 -0
- package/dist/use-high-scores.d.ts +41 -0
- package/dist/use-high-scores.d.ts.map +1 -0
- package/dist/use-high-scores.js +94 -0
- package/dist/use-high-scores.js.map +1 -0
- package/dist/use-layout-state.d.ts +77 -0
- package/dist/use-layout-state.d.ts.map +1 -0
- package/dist/use-layout-state.js +160 -0
- package/dist/use-layout-state.js.map +1 -0
- package/dist/use-ralph-loop.d.ts +41 -0
- package/dist/use-ralph-loop.d.ts.map +1 -0
- package/dist/use-ralph-loop.js +106 -0
- package/dist/use-ralph-loop.js.map +1 -0
- package/dist/use-spinner.d.ts +46 -0
- package/dist/use-spinner.d.ts.map +1 -0
- package/dist/use-spinner.js +71 -0
- package/dist/use-spinner.js.map +1 -0
- package/dist/use-stats.d.ts +59 -0
- package/dist/use-stats.d.ts.map +1 -0
- package/dist/use-stats.js +150 -0
- package/dist/use-stats.js.map +1 -0
- package/dist/use-terminal-size.d.ts +29 -0
- package/dist/use-terminal-size.d.ts.map +1 -0
- package/dist/use-terminal-size.js +48 -0
- package/dist/use-terminal-size.js.map +1 -0
- package/dist/useTheme.d.ts +76 -0
- package/dist/useTheme.d.ts.map +1 -0
- package/dist/useTheme.js +136 -0
- package/dist/useTheme.js.map +1 -0
- package/package.json +58 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration File Support
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent configuration storage following XDG Base Directory conventions.
|
|
5
|
+
* Supports JSON format with comprehensive settings for games, layout, theme, and Claude Code.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Game-specific preferences
|
|
9
|
+
*/
|
|
10
|
+
export interface GamePreferences {
|
|
11
|
+
/** Default difficulty for games that support it */
|
|
12
|
+
defaultDifficulty?: "easy" | "medium" | "hard";
|
|
13
|
+
/** Snake game settings */
|
|
14
|
+
snake?: {
|
|
15
|
+
/** Initial speed (1-10, where 10 is fastest) */
|
|
16
|
+
initialSpeed?: number;
|
|
17
|
+
/** Growth per food item */
|
|
18
|
+
growthRate?: number;
|
|
19
|
+
};
|
|
20
|
+
/** Tetris game settings */
|
|
21
|
+
tetris?: {
|
|
22
|
+
/** Starting level (1-10) */
|
|
23
|
+
startingLevel?: number;
|
|
24
|
+
/** Enable ghost piece preview */
|
|
25
|
+
showGhostPiece?: boolean;
|
|
26
|
+
};
|
|
27
|
+
/** Minesweeper game settings */
|
|
28
|
+
minesweeper?: {
|
|
29
|
+
/** Default difficulty */
|
|
30
|
+
defaultDifficulty?: "easy" | "medium" | "hard";
|
|
31
|
+
/** Show timer */
|
|
32
|
+
showTimer?: boolean;
|
|
33
|
+
};
|
|
34
|
+
/** Pong game settings */
|
|
35
|
+
pong?: {
|
|
36
|
+
/** AI difficulty (1-10) */
|
|
37
|
+
aiDifficulty?: number;
|
|
38
|
+
/** Ball speed multiplier (0.5-2.0) */
|
|
39
|
+
ballSpeedMultiplier?: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Layout preferences for the split-pane interface
|
|
44
|
+
*/
|
|
45
|
+
export interface LayoutPreferences {
|
|
46
|
+
/** Initial split direction: horizontal (left/right) or vertical (top/bottom) */
|
|
47
|
+
direction?: "horizontal" | "vertical";
|
|
48
|
+
/** Initial split ratio (0.0 - 1.0), proportion of first pane */
|
|
49
|
+
splitRatio?: number;
|
|
50
|
+
/** Minimum split ratio allowed */
|
|
51
|
+
minRatio?: number;
|
|
52
|
+
/** Maximum split ratio allowed */
|
|
53
|
+
maxRatio?: number;
|
|
54
|
+
/** Step size for keyboard resizing */
|
|
55
|
+
resizeStep?: number;
|
|
56
|
+
/** Whether to show the secondary pane (management panel) by default */
|
|
57
|
+
showSecondary?: boolean;
|
|
58
|
+
/** Which pane is focused by default (0 = game, 1 = management) */
|
|
59
|
+
defaultFocusedPane?: 0 | 1;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Theme settings for visual customization
|
|
63
|
+
*/
|
|
64
|
+
export interface ThemePreferences {
|
|
65
|
+
/** Color scheme - multiple themes available */
|
|
66
|
+
colorScheme?: "default" | "dark" | "light" | "retro";
|
|
67
|
+
/** Border style for panels */
|
|
68
|
+
borderStyle?: "single" | "round" | "double" | "heavy";
|
|
69
|
+
/** Spinner animation style */
|
|
70
|
+
spinnerStyle?: "spinner" | "dots" | "braille";
|
|
71
|
+
/** Enable/disable animations */
|
|
72
|
+
enableAnimations?: boolean;
|
|
73
|
+
/** Custom color overrides */
|
|
74
|
+
colors?: {
|
|
75
|
+
primary?: string;
|
|
76
|
+
secondary?: string;
|
|
77
|
+
accent?: string;
|
|
78
|
+
success?: string;
|
|
79
|
+
warning?: string;
|
|
80
|
+
error?: string;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Claude Code integration settings
|
|
85
|
+
*/
|
|
86
|
+
export interface ClaudeCodeSettings {
|
|
87
|
+
/** Path to Claude Code executable (defaults to 'claude' in PATH) */
|
|
88
|
+
executablePath?: string;
|
|
89
|
+
/** Default working directory for Claude Code sessions */
|
|
90
|
+
workingDirectory?: string;
|
|
91
|
+
/** Default command-line arguments */
|
|
92
|
+
defaultArgs?: string[];
|
|
93
|
+
/** Environment variables to pass to Claude Code */
|
|
94
|
+
environment?: Record<string, string>;
|
|
95
|
+
/** Timeout for graceful shutdown in milliseconds */
|
|
96
|
+
shutdownTimeout?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Application behavior settings
|
|
100
|
+
*/
|
|
101
|
+
export interface AppSettings {
|
|
102
|
+
/** Maximum scores to keep per game leaderboard */
|
|
103
|
+
maxScoresPerGame?: number;
|
|
104
|
+
/** Default game to select on startup (game ID) */
|
|
105
|
+
defaultGame?: string;
|
|
106
|
+
/** Enable debug mode */
|
|
107
|
+
debugMode?: boolean;
|
|
108
|
+
/** Log verbosity level */
|
|
109
|
+
logLevel?: "error" | "warn" | "info" | "debug";
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Complete configuration structure
|
|
113
|
+
*/
|
|
114
|
+
export interface BrainrotConfig {
|
|
115
|
+
/** Config file format version */
|
|
116
|
+
version: number;
|
|
117
|
+
/** Game-specific preferences */
|
|
118
|
+
games?: GamePreferences;
|
|
119
|
+
/** Layout preferences */
|
|
120
|
+
layout?: LayoutPreferences;
|
|
121
|
+
/** Theme settings */
|
|
122
|
+
theme?: ThemePreferences;
|
|
123
|
+
/** Claude Code settings */
|
|
124
|
+
claudeCode?: ClaudeCodeSettings;
|
|
125
|
+
/** Application settings */
|
|
126
|
+
app?: AppSettings;
|
|
127
|
+
}
|
|
128
|
+
/** Config directory following XDG conventions */
|
|
129
|
+
export declare const CONFIG_DIR: string;
|
|
130
|
+
/** Data directory following XDG conventions */
|
|
131
|
+
export declare const DATA_DIR: string;
|
|
132
|
+
/** Config file path */
|
|
133
|
+
export declare const CONFIG_FILE: string;
|
|
134
|
+
/**
|
|
135
|
+
* Default configuration values
|
|
136
|
+
*/
|
|
137
|
+
export declare const DEFAULT_CONFIG: BrainrotConfig;
|
|
138
|
+
/**
|
|
139
|
+
* Ensure data directory exists
|
|
140
|
+
*/
|
|
141
|
+
export declare function ensureDataDir(): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Deep merge two objects, with source taking precedence
|
|
144
|
+
* Exported for use in CLI override merging
|
|
145
|
+
*/
|
|
146
|
+
export declare function deepMerge<T extends object>(target: T, source: Partial<T>): T;
|
|
147
|
+
/**
|
|
148
|
+
* Load configuration from disk
|
|
149
|
+
* Returns merged config with defaults for any missing values
|
|
150
|
+
*/
|
|
151
|
+
export declare function loadConfig(): Promise<BrainrotConfig>;
|
|
152
|
+
/**
|
|
153
|
+
* Save configuration to disk
|
|
154
|
+
*/
|
|
155
|
+
export declare function saveConfig(config: BrainrotConfig): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Update specific configuration sections
|
|
158
|
+
*/
|
|
159
|
+
export declare function updateConfig(updates: Partial<Omit<BrainrotConfig, "version">>): Promise<BrainrotConfig>;
|
|
160
|
+
/**
|
|
161
|
+
* Reset configuration to defaults
|
|
162
|
+
*/
|
|
163
|
+
export declare function resetConfig(): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Check if a config file exists
|
|
166
|
+
*/
|
|
167
|
+
export declare function configExists(): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Get the effective data directory (handles legacy migration)
|
|
170
|
+
* If legacy directory exists and XDG directory doesn't, returns legacy
|
|
171
|
+
* Otherwise returns XDG directory
|
|
172
|
+
*/
|
|
173
|
+
export declare function getDataDir(): string;
|
|
174
|
+
/**
|
|
175
|
+
* Get path for a data file
|
|
176
|
+
*/
|
|
177
|
+
export declare function getDataFilePath(filename: string): string;
|
|
178
|
+
/**
|
|
179
|
+
* Get game preferences with defaults filled in
|
|
180
|
+
*/
|
|
181
|
+
export declare function getGameConfig(config: BrainrotConfig, gameId: string): GamePreferences[keyof GamePreferences] | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Get layout options suitable for useLayoutState hook
|
|
184
|
+
*/
|
|
185
|
+
export declare function getLayoutOptions(config: BrainrotConfig): {
|
|
186
|
+
initialDirection: "horizontal" | "vertical";
|
|
187
|
+
initialSplitRatio: number;
|
|
188
|
+
minRatio: number;
|
|
189
|
+
maxRatio: number;
|
|
190
|
+
resizeStep: number;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Get Claude Code spawn options
|
|
194
|
+
*/
|
|
195
|
+
export declare function getClaudeCodeOptions(config: BrainrotConfig): {
|
|
196
|
+
executablePath: string;
|
|
197
|
+
defaultArgs: string[];
|
|
198
|
+
workingDirectory?: string;
|
|
199
|
+
environment?: Record<string, string>;
|
|
200
|
+
shutdownTimeout: number;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Get app settings
|
|
204
|
+
*/
|
|
205
|
+
export declare function getAppSettings(config: BrainrotConfig): Required<AppSettings>;
|
|
206
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration File Support
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent configuration storage following XDG Base Directory conventions.
|
|
5
|
+
* Supports JSON format with comprehensive settings for games, layout, theme, and Claude Code.
|
|
6
|
+
*/
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// XDG DIRECTORY PATHS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Get XDG config directory
|
|
16
|
+
* Falls back to ~/.config on macOS/Linux if XDG_CONFIG_HOME is not set
|
|
17
|
+
*/
|
|
18
|
+
function getXdgConfigHome() {
|
|
19
|
+
return process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get XDG data directory
|
|
23
|
+
* Falls back to ~/.local/share on macOS/Linux if XDG_DATA_HOME is not set
|
|
24
|
+
*/
|
|
25
|
+
function getXdgDataHome() {
|
|
26
|
+
return process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share");
|
|
27
|
+
}
|
|
28
|
+
/** Application identifier */
|
|
29
|
+
const APP_ID = "brainrot-cli";
|
|
30
|
+
/** Legacy data directory (for migration) */
|
|
31
|
+
const LEGACY_DATA_DIR = join(homedir(), ".brainrot-cli");
|
|
32
|
+
/** Config directory following XDG conventions */
|
|
33
|
+
export const CONFIG_DIR = join(getXdgConfigHome(), APP_ID);
|
|
34
|
+
/** Data directory following XDG conventions */
|
|
35
|
+
export const DATA_DIR = join(getXdgDataHome(), APP_ID);
|
|
36
|
+
/** Config file path */
|
|
37
|
+
export const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
38
|
+
/** Current config format version */
|
|
39
|
+
const CONFIG_VERSION = 1;
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// DEFAULT CONFIGURATION
|
|
42
|
+
// ============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Default configuration values
|
|
45
|
+
*/
|
|
46
|
+
export const DEFAULT_CONFIG = {
|
|
47
|
+
version: CONFIG_VERSION,
|
|
48
|
+
games: {
|
|
49
|
+
defaultDifficulty: "medium",
|
|
50
|
+
snake: {
|
|
51
|
+
initialSpeed: 5,
|
|
52
|
+
growthRate: 1,
|
|
53
|
+
},
|
|
54
|
+
tetris: {
|
|
55
|
+
startingLevel: 1,
|
|
56
|
+
showGhostPiece: true,
|
|
57
|
+
},
|
|
58
|
+
minesweeper: {
|
|
59
|
+
defaultDifficulty: "easy",
|
|
60
|
+
showTimer: true,
|
|
61
|
+
},
|
|
62
|
+
pong: {
|
|
63
|
+
aiDifficulty: 5,
|
|
64
|
+
ballSpeedMultiplier: 1.0,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
layout: {
|
|
68
|
+
direction: "horizontal",
|
|
69
|
+
splitRatio: 0.5,
|
|
70
|
+
minRatio: 0.25,
|
|
71
|
+
maxRatio: 0.75,
|
|
72
|
+
resizeStep: 0.05,
|
|
73
|
+
showSecondary: true,
|
|
74
|
+
defaultFocusedPane: 0,
|
|
75
|
+
},
|
|
76
|
+
theme: {
|
|
77
|
+
colorScheme: "default",
|
|
78
|
+
borderStyle: "round",
|
|
79
|
+
spinnerStyle: "spinner",
|
|
80
|
+
enableAnimations: true,
|
|
81
|
+
},
|
|
82
|
+
claudeCode: {
|
|
83
|
+
executablePath: "claude",
|
|
84
|
+
shutdownTimeout: 5000,
|
|
85
|
+
},
|
|
86
|
+
app: {
|
|
87
|
+
maxScoresPerGame: 10,
|
|
88
|
+
debugMode: false,
|
|
89
|
+
logLevel: "info",
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// CONFIG FILE OPERATIONS
|
|
94
|
+
// ============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* Ensure config directory exists
|
|
97
|
+
*/
|
|
98
|
+
async function ensureConfigDir() {
|
|
99
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
100
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Ensure data directory exists
|
|
105
|
+
*/
|
|
106
|
+
export async function ensureDataDir() {
|
|
107
|
+
if (!existsSync(DATA_DIR)) {
|
|
108
|
+
await mkdir(DATA_DIR, { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Deep merge two objects, with source taking precedence
|
|
113
|
+
* Exported for use in CLI override merging
|
|
114
|
+
*/
|
|
115
|
+
export function deepMerge(target, source) {
|
|
116
|
+
const result = { ...target };
|
|
117
|
+
for (const key of Object.keys(source)) {
|
|
118
|
+
const sourceValue = source[key];
|
|
119
|
+
const targetValue = target[key];
|
|
120
|
+
if (sourceValue !== undefined &&
|
|
121
|
+
sourceValue !== null &&
|
|
122
|
+
typeof sourceValue === "object" &&
|
|
123
|
+
!Array.isArray(sourceValue) &&
|
|
124
|
+
typeof targetValue === "object" &&
|
|
125
|
+
targetValue !== null &&
|
|
126
|
+
!Array.isArray(targetValue)) {
|
|
127
|
+
// Recursively merge objects
|
|
128
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
129
|
+
}
|
|
130
|
+
else if (sourceValue !== undefined) {
|
|
131
|
+
// Use source value directly
|
|
132
|
+
result[key] = sourceValue;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load configuration from disk
|
|
139
|
+
* Returns merged config with defaults for any missing values
|
|
140
|
+
*/
|
|
141
|
+
export async function loadConfig() {
|
|
142
|
+
try {
|
|
143
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
144
|
+
return DEFAULT_CONFIG;
|
|
145
|
+
}
|
|
146
|
+
const content = await readFile(CONFIG_FILE, "utf-8");
|
|
147
|
+
const userConfig = JSON.parse(content);
|
|
148
|
+
// Handle version migration if needed
|
|
149
|
+
if (userConfig.version !== CONFIG_VERSION) {
|
|
150
|
+
// For now, just merge with defaults
|
|
151
|
+
// Future versions can add migration logic here
|
|
152
|
+
}
|
|
153
|
+
// Deep merge with defaults to fill in any missing values
|
|
154
|
+
return deepMerge(DEFAULT_CONFIG, userConfig);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// If file is corrupted or unreadable, return defaults
|
|
158
|
+
return DEFAULT_CONFIG;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Save configuration to disk
|
|
163
|
+
*/
|
|
164
|
+
export async function saveConfig(config) {
|
|
165
|
+
try {
|
|
166
|
+
await ensureConfigDir();
|
|
167
|
+
// Ensure version is set
|
|
168
|
+
const configToSave = {
|
|
169
|
+
...config,
|
|
170
|
+
version: CONFIG_VERSION,
|
|
171
|
+
};
|
|
172
|
+
await writeFile(CONFIG_FILE, JSON.stringify(configToSave, null, 2), "utf-8");
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
// Log error but don't throw - config saving is not critical
|
|
176
|
+
console.error("Failed to save configuration:", error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Update specific configuration sections
|
|
181
|
+
*/
|
|
182
|
+
export async function updateConfig(updates) {
|
|
183
|
+
const current = await loadConfig();
|
|
184
|
+
const updated = deepMerge(current, updates);
|
|
185
|
+
await saveConfig(updated);
|
|
186
|
+
return updated;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Reset configuration to defaults
|
|
190
|
+
*/
|
|
191
|
+
export async function resetConfig() {
|
|
192
|
+
await saveConfig(DEFAULT_CONFIG);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if a config file exists
|
|
196
|
+
*/
|
|
197
|
+
export function configExists() {
|
|
198
|
+
return existsSync(CONFIG_FILE);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get the effective data directory (handles legacy migration)
|
|
202
|
+
* If legacy directory exists and XDG directory doesn't, returns legacy
|
|
203
|
+
* Otherwise returns XDG directory
|
|
204
|
+
*/
|
|
205
|
+
export function getDataDir() {
|
|
206
|
+
// If XDG data dir exists, use it
|
|
207
|
+
if (existsSync(DATA_DIR)) {
|
|
208
|
+
return DATA_DIR;
|
|
209
|
+
}
|
|
210
|
+
// If legacy dir exists and XDG doesn't, use legacy for backwards compatibility
|
|
211
|
+
if (existsSync(LEGACY_DATA_DIR)) {
|
|
212
|
+
return LEGACY_DATA_DIR;
|
|
213
|
+
}
|
|
214
|
+
// Default to XDG
|
|
215
|
+
return DATA_DIR;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get path for a data file
|
|
219
|
+
*/
|
|
220
|
+
export function getDataFilePath(filename) {
|
|
221
|
+
return join(getDataDir(), filename);
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// CONFIGURATION HELPERS
|
|
225
|
+
// ============================================================================
|
|
226
|
+
/**
|
|
227
|
+
* Get game preferences with defaults filled in
|
|
228
|
+
*/
|
|
229
|
+
export function getGameConfig(config, gameId) {
|
|
230
|
+
return config.games?.[gameId];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get layout options suitable for useLayoutState hook
|
|
234
|
+
*/
|
|
235
|
+
export function getLayoutOptions(config) {
|
|
236
|
+
const layout = config.layout ?? DEFAULT_CONFIG.layout;
|
|
237
|
+
return {
|
|
238
|
+
initialDirection: layout.direction ?? "horizontal",
|
|
239
|
+
initialSplitRatio: layout.splitRatio ?? 0.5,
|
|
240
|
+
minRatio: layout.minRatio ?? 0.25,
|
|
241
|
+
maxRatio: layout.maxRatio ?? 0.75,
|
|
242
|
+
resizeStep: layout.resizeStep ?? 0.05,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get Claude Code spawn options
|
|
247
|
+
*/
|
|
248
|
+
export function getClaudeCodeOptions(config) {
|
|
249
|
+
const claudeCode = config.claudeCode ?? DEFAULT_CONFIG.claudeCode;
|
|
250
|
+
return {
|
|
251
|
+
executablePath: claudeCode.executablePath ?? "claude",
|
|
252
|
+
defaultArgs: claudeCode.defaultArgs ?? [],
|
|
253
|
+
workingDirectory: claudeCode.workingDirectory,
|
|
254
|
+
environment: claudeCode.environment,
|
|
255
|
+
shutdownTimeout: claudeCode.shutdownTimeout ?? 5000,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get app settings
|
|
260
|
+
*/
|
|
261
|
+
export function getAppSettings(config) {
|
|
262
|
+
const app = config.app ?? DEFAULT_CONFIG.app;
|
|
263
|
+
return {
|
|
264
|
+
maxScoresPerGame: app.maxScoresPerGame ?? 10,
|
|
265
|
+
defaultGame: app.defaultGame ?? "",
|
|
266
|
+
debugMode: app.debugMode ?? false,
|
|
267
|
+
logLevel: app.logLevel ?? "info",
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Game Framework Types and Interfaces
|
|
3
|
+
*
|
|
4
|
+
* Provides common types for building terminal games that run
|
|
5
|
+
* alongside Claude Code work.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Game state status
|
|
9
|
+
*/
|
|
10
|
+
export type GameStatus = "menu" | "playing" | "paused" | "game_over";
|
|
11
|
+
/**
|
|
12
|
+
* Input key representation for game input handling
|
|
13
|
+
*/
|
|
14
|
+
export interface GameInput {
|
|
15
|
+
key: string;
|
|
16
|
+
ctrl: boolean;
|
|
17
|
+
shift: boolean;
|
|
18
|
+
meta: boolean;
|
|
19
|
+
/** Arrow keys */
|
|
20
|
+
upArrow: boolean;
|
|
21
|
+
downArrow: boolean;
|
|
22
|
+
leftArrow: boolean;
|
|
23
|
+
rightArrow: boolean;
|
|
24
|
+
/** Special keys */
|
|
25
|
+
return: boolean;
|
|
26
|
+
escape: boolean;
|
|
27
|
+
space: boolean;
|
|
28
|
+
tab: boolean;
|
|
29
|
+
backspace: boolean;
|
|
30
|
+
delete: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Game dimensions from the container
|
|
34
|
+
*/
|
|
35
|
+
export interface GameDimensions {
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Base game state interface - games extend this
|
|
41
|
+
*/
|
|
42
|
+
export interface BaseGameState {
|
|
43
|
+
status: GameStatus;
|
|
44
|
+
score: number;
|
|
45
|
+
highScore: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Game metadata for the selector
|
|
49
|
+
*/
|
|
50
|
+
export interface GameInfo {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
controls: string;
|
|
55
|
+
/** Minimum dimensions required to play */
|
|
56
|
+
minWidth?: number;
|
|
57
|
+
minHeight?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Loop attention information passed to games
|
|
61
|
+
*/
|
|
62
|
+
export interface LoopAttention {
|
|
63
|
+
/** Whether the loop needs user attention */
|
|
64
|
+
needsAttention: boolean;
|
|
65
|
+
/** Reason for needing attention */
|
|
66
|
+
reason: string | null;
|
|
67
|
+
/** Type of attention needed */
|
|
68
|
+
type: "question" | "confirmation" | "error" | "permission" | null;
|
|
69
|
+
/** Prompt text if any */
|
|
70
|
+
prompt: string | null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Game state update for status bar
|
|
74
|
+
*/
|
|
75
|
+
export interface GameStateUpdate {
|
|
76
|
+
/** Current score */
|
|
77
|
+
score: number | null;
|
|
78
|
+
/** Game status */
|
|
79
|
+
status: "playing" | "paused" | "game_over" | "menu" | null;
|
|
80
|
+
/** High score for comparison */
|
|
81
|
+
highScore: number | null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Props passed to game components
|
|
85
|
+
*/
|
|
86
|
+
export interface GameComponentProps {
|
|
87
|
+
/** Whether the game pane has focus */
|
|
88
|
+
hasFocus: boolean;
|
|
89
|
+
/** Available dimensions for the game */
|
|
90
|
+
dimensions: GameDimensions;
|
|
91
|
+
/** Callback when game wants to return to menu */
|
|
92
|
+
onExit: () => void;
|
|
93
|
+
/** Loop attention state for auto-pause feature */
|
|
94
|
+
loopAttention?: LoopAttention;
|
|
95
|
+
/** Callback when user acknowledges/dismisses loop alert */
|
|
96
|
+
onLoopAlertDismiss?: () => void;
|
|
97
|
+
/** Callback to report game state changes to status bar */
|
|
98
|
+
onGameStateChange?: (update: GameStateUpdate) => void;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Game registry entry
|
|
102
|
+
*/
|
|
103
|
+
export interface GameRegistryEntry {
|
|
104
|
+
info: GameInfo;
|
|
105
|
+
component: React.ComponentType<GameComponentProps>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Game loop timing info
|
|
109
|
+
*/
|
|
110
|
+
export interface GameLoopInfo {
|
|
111
|
+
/** Frames per second */
|
|
112
|
+
fps: number;
|
|
113
|
+
/** Time since last frame in milliseconds */
|
|
114
|
+
deltaTime: number;
|
|
115
|
+
/** Total elapsed time in milliseconds */
|
|
116
|
+
elapsedTime: number;
|
|
117
|
+
/** Current frame number */
|
|
118
|
+
frameCount: number;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Canvas cell for character-based rendering
|
|
122
|
+
*/
|
|
123
|
+
export interface CanvasCell {
|
|
124
|
+
char: string;
|
|
125
|
+
color?: string;
|
|
126
|
+
backgroundColor?: string;
|
|
127
|
+
bold?: boolean;
|
|
128
|
+
dim?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Simple 2D point
|
|
132
|
+
*/
|
|
133
|
+
export interface Point {
|
|
134
|
+
x: number;
|
|
135
|
+
y: number;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Simple 2D vector
|
|
139
|
+
*/
|
|
140
|
+
export interface Vector2D {
|
|
141
|
+
x: number;
|
|
142
|
+
y: number;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Direction enum for movement
|
|
146
|
+
*/
|
|
147
|
+
export type Direction = "up" | "down" | "left" | "right";
|
|
148
|
+
/**
|
|
149
|
+
* Convert direction to vector
|
|
150
|
+
*/
|
|
151
|
+
export declare function directionToVector(direction: Direction): Vector2D;
|
|
152
|
+
/**
|
|
153
|
+
* Check if two points are equal
|
|
154
|
+
*/
|
|
155
|
+
export declare function pointsEqual(a: Point, b: Point): boolean;
|
|
156
|
+
/**
|
|
157
|
+
* Add two vectors
|
|
158
|
+
*/
|
|
159
|
+
export declare function addVectors(a: Vector2D, b: Vector2D): Vector2D;
|
|
160
|
+
/**
|
|
161
|
+
* Create a game input object from ink's useInput callback params
|
|
162
|
+
*/
|
|
163
|
+
export declare function createGameInput(input: string, key: {
|
|
164
|
+
upArrow: boolean;
|
|
165
|
+
downArrow: boolean;
|
|
166
|
+
leftArrow: boolean;
|
|
167
|
+
rightArrow: boolean;
|
|
168
|
+
return: boolean;
|
|
169
|
+
escape: boolean;
|
|
170
|
+
ctrl: boolean;
|
|
171
|
+
shift: boolean;
|
|
172
|
+
meta: boolean;
|
|
173
|
+
tab: boolean;
|
|
174
|
+
backspace: boolean;
|
|
175
|
+
delete: boolean;
|
|
176
|
+
}): GameInput;
|
|
177
|
+
//# sourceMappingURL=game-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-types.d.ts","sourceRoot":"","sources":["../src/game-types.ts"],"names":[],"mappings":"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"}
|