@littlepartytime/dev-kit 1.0.0 → 1.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.
Files changed (46) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +4 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/dev.d.ts +6 -0
  5. package/dist/commands/dev.d.ts.map +1 -0
  6. package/dist/commands/dev.js +59 -0
  7. package/dist/commands/dev.js.map +1 -0
  8. package/dist/server/engine-loader.d.ts +11 -0
  9. package/dist/server/engine-loader.d.ts.map +1 -0
  10. package/dist/server/engine-loader.js +45 -0
  11. package/dist/server/engine-loader.js.map +1 -0
  12. package/dist/server/game-room.d.ts +25 -0
  13. package/dist/server/game-room.d.ts.map +1 -0
  14. package/dist/server/game-room.js +78 -0
  15. package/dist/server/game-room.js.map +1 -0
  16. package/dist/server/socket-server.d.ts +16 -0
  17. package/dist/server/socket-server.d.ts.map +1 -0
  18. package/dist/server/socket-server.js +167 -0
  19. package/dist/server/socket-server.js.map +1 -0
  20. package/dist/webapp/App.d.ts +3 -0
  21. package/dist/webapp/App.d.ts.map +1 -0
  22. package/dist/webapp/App.js +70 -0
  23. package/dist/webapp/App.js.map +1 -0
  24. package/dist/webapp/App.tsx +40 -0
  25. package/dist/webapp/index.html +16 -0
  26. package/dist/webapp/main.d.ts +2 -0
  27. package/dist/webapp/main.d.ts.map +1 -0
  28. package/dist/webapp/main.js +12 -0
  29. package/dist/webapp/main.js.map +1 -0
  30. package/dist/webapp/main.tsx +9 -0
  31. package/dist/webapp/pages/Debug.d.ts +3 -0
  32. package/dist/webapp/pages/Debug.d.ts.map +1 -0
  33. package/dist/webapp/pages/Debug.js +69 -0
  34. package/dist/webapp/pages/Debug.js.map +1 -0
  35. package/dist/webapp/pages/Debug.tsx +40 -0
  36. package/dist/webapp/pages/Play.d.ts +3 -0
  37. package/dist/webapp/pages/Play.d.ts.map +1 -0
  38. package/dist/webapp/pages/Play.js +129 -0
  39. package/dist/webapp/pages/Play.js.map +1 -0
  40. package/dist/webapp/pages/Play.tsx +137 -0
  41. package/dist/webapp/pages/Preview.d.ts +3 -0
  42. package/dist/webapp/pages/Preview.d.ts.map +1 -0
  43. package/dist/webapp/pages/Preview.js +118 -0
  44. package/dist/webapp/pages/Preview.js.map +1 -0
  45. package/dist/webapp/pages/Preview.tsx +112 -0
  46. package/package.json +13 -3
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,QAAA,MAAM,OAAO,QAAkB,CAAC;AAEhC,iBAAe,IAAI,kBAmBlB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,QAAA,MAAM,OAAO,QAAkB,CAAC;AAEhC,iBAAe,IAAI,kBAoBlB"}
package/dist/cli.js CHANGED
@@ -42,15 +42,16 @@ async function main() {
42
42
  break;
43
43
  }
44
44
  case 'dev': {
45
- console.log('lpt-dev-kit dev server is not yet implemented (Phase 2)');
46
- process.exit(1);
45
+ const { devCommand } = await Promise.resolve().then(() => __importStar(require('./commands/dev')));
46
+ await devCommand(process.cwd());
47
+ break;
47
48
  }
48
49
  default:
49
50
  console.log('Usage: lpt-dev-kit <command>');
50
51
  console.log('');
51
52
  console.log('Commands:');
53
+ console.log(' dev Start development server');
52
54
  console.log(' pack Build and package game as .zip');
53
- console.log(' dev Start development server (coming soon)');
54
55
  process.exit(command ? 1 : 0);
55
56
  }
56
57
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,WAAW,EAAE,GAAG,wDAAa,iBAAiB,GAAC,CAAC;YACxD,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACjC,MAAM;QACR,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD;YACE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,WAAW,EAAE,GAAG,wDAAa,iBAAiB,GAAC,CAAC;YACxD,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACjC,MAAM;QACR,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,EAAE,UAAU,EAAE,GAAG,wDAAa,gBAAgB,GAAC,CAAC;YACtD,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAChC,MAAM;QACR,CAAC;QACD;YACE,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface DevOptions {
2
+ port?: number;
3
+ socketPort?: number;
4
+ }
5
+ export declare function devCommand(projectDir: string, options?: DevOptions): Promise<void>;
6
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD5F"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.devCommand = devCommand;
7
+ // packages/dev-kit/src/commands/dev.ts
8
+ const path_1 = __importDefault(require("path"));
9
+ const vite_1 = require("vite");
10
+ const socket_server_1 = require("../server/socket-server");
11
+ const chokidar_1 = __importDefault(require("chokidar"));
12
+ async function devCommand(projectDir, options = {}) {
13
+ const port = options.port || 4000;
14
+ const socketPort = options.socketPort || 4001;
15
+ console.log('');
16
+ console.log(' Little Party Time Dev Kit');
17
+ console.log(' =========================');
18
+ console.log('');
19
+ // Start Socket.IO server
20
+ const { reloadEngine } = (0, socket_server_1.createSocketServer)({
21
+ port: socketPort,
22
+ projectDir,
23
+ });
24
+ // Watch for engine changes
25
+ const enginePath = path_1.default.join(projectDir, 'dist', 'engine.cjs');
26
+ const watcher = chokidar_1.default.watch(enginePath, { ignoreInitial: true });
27
+ watcher.on('change', () => {
28
+ console.log('[Dev] Engine changed, reloading...');
29
+ reloadEngine();
30
+ });
31
+ // Start Vite dev server
32
+ const webappDir = path_1.default.join(__dirname, '..', 'webapp');
33
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
34
+ const react = require('@vitejs/plugin-react').default;
35
+ const vite = await (0, vite_1.createServer)({
36
+ root: webappDir,
37
+ plugins: [react()],
38
+ server: {
39
+ port,
40
+ fs: {
41
+ allow: [webappDir, projectDir],
42
+ },
43
+ },
44
+ resolve: {
45
+ alias: {
46
+ '/src': path_1.default.join(projectDir, 'src'),
47
+ },
48
+ },
49
+ });
50
+ await vite.listen();
51
+ console.log(` Preview: http://localhost:${port}/preview`);
52
+ console.log(` Multiplayer: http://localhost:${port}/play`);
53
+ console.log(` Debug Panel: http://localhost:${port}/debug`);
54
+ console.log(` Socket.IO: ws://localhost:${socketPort}`);
55
+ console.log('');
56
+ console.log(' Press Ctrl+C to stop');
57
+ console.log('');
58
+ }
59
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":";;;;;AAWA,gCAsDC;AAjED,uCAAuC;AACvC,gDAAwB;AACxB,+BAAmD;AACnD,2DAA6D;AAC7D,wDAAgC;AAOzB,KAAK,UAAU,UAAU,CAAC,UAAkB,EAAE,UAAsB,EAAE;IAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;IAE9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,yBAAyB;IACzB,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,kCAAkB,EAAC;QAC1C,IAAI,EAAE,UAAU;QAChB,UAAU;KACX,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,kBAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAEvD,8DAA8D;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC;IAEtD,MAAM,IAAI,GAAkB,MAAM,IAAA,mBAAY,EAAC;QAC7C,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,EAAE;YACN,IAAI;YACJ,EAAE,EAAE;gBACF,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;aAC/B;SACF;QACD,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,MAAM,EAAE,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;aACrC;SACF;KACF,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IAEpB,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,UAAU,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,OAAO,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,QAAQ,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface GameEngine {
2
+ init(players: any[], options?: Record<string, unknown>): any;
3
+ handleAction(state: any, playerId: string, action: any): any;
4
+ isGameOver(state: any): boolean;
5
+ getResult(state: any): any;
6
+ getPlayerView(state: any, playerId: string): any;
7
+ }
8
+ export declare function loadEngine(projectDir: string): GameEngine;
9
+ export declare function getEngine(): GameEngine | null;
10
+ export declare function clearEngineCache(): void;
11
+ //# sourceMappingURL=engine-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-loader.d.ts","sourceRoot":"","sources":["../../src/server/engine-loader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC;IAC7D,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAC7D,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC;IAChC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CAAC;IAC3B,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC;CAClD;AAKD,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAyBzD;AAED,wBAAgB,SAAS,IAAI,UAAU,GAAG,IAAI,CAE7C;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadEngine = loadEngine;
7
+ exports.getEngine = getEngine;
8
+ exports.clearEngineCache = clearEngineCache;
9
+ // packages/dev-kit/src/server/engine-loader.ts
10
+ const path_1 = __importDefault(require("path"));
11
+ const fs_1 = __importDefault(require("fs"));
12
+ let cachedEngine = null;
13
+ let cachedEnginePath = null;
14
+ function loadEngine(projectDir) {
15
+ const enginePath = path_1.default.join(projectDir, 'dist', 'engine.cjs');
16
+ if (!fs_1.default.existsSync(enginePath)) {
17
+ throw new Error(`Engine not found at ${enginePath}. Run 'npm run build' first.`);
18
+ }
19
+ // Clear require cache for hot reload
20
+ if (cachedEnginePath && require.cache[require.resolve(cachedEnginePath)]) {
21
+ delete require.cache[require.resolve(cachedEnginePath)];
22
+ }
23
+ const module = require(enginePath);
24
+ cachedEngine = module.engine || module.default?.engine || module;
25
+ cachedEnginePath = enginePath;
26
+ // Validate engine has required methods
27
+ const required = ['init', 'handleAction', 'isGameOver', 'getResult', 'getPlayerView'];
28
+ for (const method of required) {
29
+ if (typeof cachedEngine[method] !== 'function') {
30
+ throw new Error(`Engine missing required method: ${method}`);
31
+ }
32
+ }
33
+ return cachedEngine;
34
+ }
35
+ function getEngine() {
36
+ return cachedEngine;
37
+ }
38
+ function clearEngineCache() {
39
+ if (cachedEnginePath && require.cache[require.resolve(cachedEnginePath)]) {
40
+ delete require.cache[require.resolve(cachedEnginePath)];
41
+ }
42
+ cachedEngine = null;
43
+ cachedEnginePath = null;
44
+ }
45
+ //# sourceMappingURL=engine-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-loader.js","sourceRoot":"","sources":["../../src/server/engine-loader.ts"],"names":[],"mappings":";;;;;AAeA,gCAyBC;AAED,8BAEC;AAED,4CAMC;AApDD,+CAA+C;AAC/C,gDAAwB;AACxB,4CAAoB;AAUpB,IAAI,YAAY,GAAsB,IAAI,CAAC;AAC3C,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAE3C,SAAgB,UAAU,CAAC,UAAkB;IAC3C,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAE/D,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,uBAAuB,UAAU,8BAA8B,CAAC,CAAC;IACnF,CAAC;IAED,qCAAqC;IACrC,IAAI,gBAAgB,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,YAAY,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC;IACjE,gBAAgB,GAAG,UAAU,CAAC;IAE9B,uCAAuC;IACvC,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IACtF,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,OAAQ,YAAoB,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,YAA0B,CAAC;AACpC,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAgB,gBAAgB;IAC9B,IAAI,gBAAgB,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,YAAY,GAAG,IAAI,CAAC;IACpB,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { GameEngine } from './engine-loader';
2
+ export interface Player {
3
+ id: string;
4
+ nickname: string;
5
+ avatarUrl: string | null;
6
+ isHost: boolean;
7
+ socketId: string;
8
+ ready: boolean;
9
+ }
10
+ export interface GameRoom {
11
+ players: Player[];
12
+ state: any | null;
13
+ phase: 'lobby' | 'ready' | 'playing' | 'ended';
14
+ gameId: string;
15
+ }
16
+ export declare function createRoom(gameId: string): GameRoom;
17
+ export declare function addPlayer(room: GameRoom, socketId: string, nickname: string): Player;
18
+ export declare function removePlayer(room: GameRoom, socketId: string): Player | null;
19
+ export declare function getPlayerBySocketId(room: GameRoom, socketId: string): Player | undefined;
20
+ export declare function setPlayerReady(room: GameRoom, socketId: string, ready: boolean): void;
21
+ export declare function allPlayersReady(room: GameRoom): boolean;
22
+ export declare function startGame(room: GameRoom, engine: GameEngine): void;
23
+ export declare function handleAction(room: GameRoom, engine: GameEngine, playerId: string, action: any): void;
24
+ export declare function resetRoom(room: GameRoom): void;
25
+ //# sourceMappingURL=game-room.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-room.d.ts","sourceRoot":"","sources":["../../src/server/game-room.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAOnD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYpF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY5E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExF;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGrF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEvD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAUlE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAQpG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAI9C"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRoom = createRoom;
4
+ exports.addPlayer = addPlayer;
5
+ exports.removePlayer = removePlayer;
6
+ exports.getPlayerBySocketId = getPlayerBySocketId;
7
+ exports.setPlayerReady = setPlayerReady;
8
+ exports.allPlayersReady = allPlayersReady;
9
+ exports.startGame = startGame;
10
+ exports.handleAction = handleAction;
11
+ exports.resetRoom = resetRoom;
12
+ function createRoom(gameId) {
13
+ return {
14
+ players: [],
15
+ state: null,
16
+ phase: 'lobby',
17
+ gameId,
18
+ };
19
+ }
20
+ function addPlayer(room, socketId, nickname) {
21
+ const isHost = room.players.length === 0;
22
+ const player = {
23
+ id: `player-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
24
+ nickname,
25
+ avatarUrl: null,
26
+ isHost,
27
+ socketId,
28
+ ready: false,
29
+ };
30
+ room.players.push(player);
31
+ return player;
32
+ }
33
+ function removePlayer(room, socketId) {
34
+ const index = room.players.findIndex(p => p.socketId === socketId);
35
+ if (index === -1)
36
+ return null;
37
+ const [removed] = room.players.splice(index, 1);
38
+ // Promote new host if needed
39
+ if (removed.isHost && room.players.length > 0) {
40
+ room.players[0].isHost = true;
41
+ }
42
+ return removed;
43
+ }
44
+ function getPlayerBySocketId(room, socketId) {
45
+ return room.players.find(p => p.socketId === socketId);
46
+ }
47
+ function setPlayerReady(room, socketId, ready) {
48
+ const player = getPlayerBySocketId(room, socketId);
49
+ if (player)
50
+ player.ready = ready;
51
+ }
52
+ function allPlayersReady(room) {
53
+ return room.players.length >= 2 && room.players.every(p => p.ready);
54
+ }
55
+ function startGame(room, engine) {
56
+ const players = room.players.map(p => ({
57
+ id: p.id,
58
+ nickname: p.nickname,
59
+ avatarUrl: p.avatarUrl,
60
+ isHost: p.isHost,
61
+ }));
62
+ room.state = engine.init(players);
63
+ room.phase = 'playing';
64
+ }
65
+ function handleAction(room, engine, playerId, action) {
66
+ if (room.phase !== 'playing' || !room.state)
67
+ return;
68
+ room.state = engine.handleAction(room.state, playerId, action);
69
+ if (engine.isGameOver(room.state)) {
70
+ room.phase = 'ended';
71
+ }
72
+ }
73
+ function resetRoom(room) {
74
+ room.state = null;
75
+ room.phase = 'lobby';
76
+ room.players.forEach(p => p.ready = false);
77
+ }
78
+ //# sourceMappingURL=game-room.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game-room.js","sourceRoot":"","sources":["../../src/server/game-room.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Server } from 'socket.io';
2
+ import http from 'http';
3
+ import * as GameRoom from './game-room';
4
+ export interface SocketServerOptions {
5
+ port: number;
6
+ projectDir: string;
7
+ onStateChange?: (room: GameRoom.GameRoom) => void;
8
+ onLog?: (message: string) => void;
9
+ }
10
+ export declare function createSocketServer(options: SocketServerOptions): {
11
+ server: http.Server;
12
+ io: Server;
13
+ getRoom: () => GameRoom.GameRoom;
14
+ reloadEngine: () => void;
15
+ };
16
+ //# sourceMappingURL=socket-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket-server.d.ts","sourceRoot":"","sources":["../../src/server/socket-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,KAAK,QAAQ,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC;IAClD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG;IAChE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,QAAQ,CAAC,QAAQ,CAAC;IACjC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,CAyIA"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createSocketServer = createSocketServer;
40
+ // packages/dev-kit/src/server/socket-server.ts
41
+ const socket_io_1 = require("socket.io");
42
+ const http_1 = __importDefault(require("http"));
43
+ const engine_loader_1 = require("./engine-loader");
44
+ const GameRoom = __importStar(require("./game-room"));
45
+ function createSocketServer(options) {
46
+ const { port, projectDir, onStateChange, onLog } = options;
47
+ const log = (msg) => {
48
+ onLog?.(msg);
49
+ console.log(`[Socket] ${msg}`);
50
+ };
51
+ // Load engine
52
+ let engine = (0, engine_loader_1.loadEngine)(projectDir);
53
+ log(`Engine loaded from ${projectDir}`);
54
+ // Create room
55
+ const room = GameRoom.createRoom('dev-game');
56
+ const server = http_1.default.createServer();
57
+ const io = new socket_io_1.Server(server, {
58
+ cors: { origin: '*' },
59
+ });
60
+ io.on('connection', (socket) => {
61
+ const nickname = socket.handshake.query.nickname || `Player ${room.players.length + 1}`;
62
+ const player = GameRoom.addPlayer(room, socket.id, nickname);
63
+ log(`${player.nickname} joined (${player.id})`);
64
+ // Notify all
65
+ io.emit('room:update', {
66
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
67
+ phase: room.phase,
68
+ });
69
+ onStateChange?.(room);
70
+ // Ready toggle
71
+ socket.on('player:ready', (ready) => {
72
+ GameRoom.setPlayerReady(room, socket.id, ready);
73
+ io.emit('room:update', {
74
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
75
+ phase: room.phase,
76
+ });
77
+ onStateChange?.(room);
78
+ log(`${player.nickname} is ${ready ? 'ready' : 'not ready'}`);
79
+ });
80
+ // Start game (host only)
81
+ socket.on('game:start', () => {
82
+ if (!player.isHost)
83
+ return;
84
+ if (!GameRoom.allPlayersReady(room))
85
+ return;
86
+ GameRoom.startGame(room, engine);
87
+ log(`Game started!`);
88
+ // Send initial state to each player
89
+ room.players.forEach(p => {
90
+ const playerSocket = io.sockets.sockets.get(p.socketId);
91
+ if (playerSocket) {
92
+ const view = engine.getPlayerView(room.state, p.id);
93
+ playerSocket.emit('game:state', view);
94
+ }
95
+ });
96
+ io.emit('room:update', {
97
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
98
+ phase: room.phase,
99
+ });
100
+ onStateChange?.(room);
101
+ });
102
+ // Game action
103
+ socket.on('game:action', (action) => {
104
+ if (room.phase !== 'playing')
105
+ return;
106
+ log(`${player.nickname} action: ${JSON.stringify(action)}`);
107
+ GameRoom.handleAction(room, engine, player.id, action);
108
+ // Broadcast updated state
109
+ room.players.forEach(p => {
110
+ const playerSocket = io.sockets.sockets.get(p.socketId);
111
+ if (playerSocket) {
112
+ const view = engine.getPlayerView(room.state, p.id);
113
+ playerSocket.emit('game:state', view);
114
+ }
115
+ });
116
+ // Check game over (use type assertion since handleAction may have changed phase)
117
+ if (room.phase === 'ended') {
118
+ const result = engine.getResult(room.state);
119
+ io.emit('game:result', result);
120
+ log(`Game ended! Result: ${JSON.stringify(result)}`);
121
+ }
122
+ io.emit('room:update', {
123
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
124
+ phase: room.phase,
125
+ });
126
+ onStateChange?.(room);
127
+ });
128
+ // Play again
129
+ socket.on('game:playAgain', () => {
130
+ if (!player.isHost)
131
+ return;
132
+ GameRoom.resetRoom(room);
133
+ io.emit('room:update', {
134
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
135
+ phase: room.phase,
136
+ });
137
+ onStateChange?.(room);
138
+ log(`Room reset by host`);
139
+ });
140
+ // Disconnect
141
+ socket.on('disconnect', () => {
142
+ const removed = GameRoom.removePlayer(room, socket.id);
143
+ if (removed) {
144
+ log(`${removed.nickname} left`);
145
+ io.emit('room:update', {
146
+ players: room.players.map(p => ({ id: p.id, nickname: p.nickname, isHost: p.isHost, ready: p.ready })),
147
+ phase: room.phase,
148
+ });
149
+ onStateChange?.(room);
150
+ }
151
+ });
152
+ });
153
+ server.listen(port, () => {
154
+ log(`Socket.IO server listening on port ${port}`);
155
+ });
156
+ return {
157
+ server,
158
+ io,
159
+ getRoom: () => room,
160
+ reloadEngine: () => {
161
+ (0, engine_loader_1.clearEngineCache)();
162
+ engine = (0, engine_loader_1.loadEngine)(projectDir);
163
+ log(`Engine reloaded`);
164
+ },
165
+ };
166
+ }
167
+ //# sourceMappingURL=socket-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket-server.js","sourceRoot":"","sources":["../../src/server/socket-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export default function App(): React.JSX.Element;
3
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/webapp/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAOxC,MAAM,CAAC,OAAO,UAAU,GAAG,sBAgC1B"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = App;
40
+ const react_1 = __importStar(require("react"));
41
+ const Preview_1 = __importDefault(require("./pages/Preview"));
42
+ const Play_1 = __importDefault(require("./pages/Play"));
43
+ const Debug_1 = __importDefault(require("./pages/Debug"));
44
+ function App() {
45
+ const [page, setPage] = (0, react_1.useState)(() => {
46
+ const path = window.location.pathname;
47
+ if (path.includes('play'))
48
+ return 'play';
49
+ if (path.includes('debug'))
50
+ return 'debug';
51
+ return 'preview';
52
+ });
53
+ return (<div className="min-h-screen flex flex-col">
54
+ {/* Nav */}
55
+ <nav className="bg-zinc-900 border-b border-zinc-800 px-4 py-2 flex gap-4">
56
+ <span className="text-amber-500 font-bold mr-4">LPT Dev Kit</span>
57
+ {['preview', 'play', 'debug'].map((p) => (<button key={p} onClick={() => { setPage(p); history.pushState(null, '', `/${p}`); }} className={`px-3 py-1 rounded ${page === p ? 'bg-amber-600 text-white' : 'text-zinc-400 hover:text-white'}`}>
58
+ {p.charAt(0).toUpperCase() + p.slice(1)}
59
+ </button>))}
60
+ </nav>
61
+
62
+ {/* Content */}
63
+ <main className="flex-1 p-4">
64
+ {page === 'preview' && <Preview_1.default />}
65
+ {page === 'play' && <Play_1.default />}
66
+ {page === 'debug' && <Debug_1.default />}
67
+ </main>
68
+ </div>);
69
+ }
70
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/webapp/App.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,sBAgCC;AAvCD,+CAAwC;AACxC,8DAAsC;AACtC,wDAAgC;AAChC,0DAAkC;AAIlC,SAAwB,GAAG;IACzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAA,gBAAQ,EAAO,GAAG,EAAE;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CACzC;MAAA,CAAC,SAAS,CACV;MAAA,CAAC,GAAG,CAAC,SAAS,CAAC,2DAA2D,CACxE;QAAA,CAAC,IAAI,CAAC,SAAS,CAAC,+BAA+B,CAAC,WAAW,EAAE,IAAI,CACjE;QAAA,CAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACnD,CAAC,MAAM,CACL,GAAG,CAAC,CAAC,CAAC,CAAC,CACP,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CACrE,SAAS,CAAC,CAAC,qBAAqB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,gCAAgC,EAAE,CAAC,CAE5G;YAAA,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CACzC;UAAA,EAAE,MAAM,CAAC,CACV,CAAC,CACJ;MAAA,EAAE,GAAG,CAEL;;MAAA,CAAC,aAAa,CACd;MAAA,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAC1B;QAAA,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,iBAAO,CAAC,AAAD,EAAG,CAClC;QAAA,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,cAAI,CAAC,AAAD,EAAG,CAC5B;QAAA,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,eAAK,CAAC,AAAD,EAAG,CAChC;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ import React, { useState } from 'react';
2
+ import Preview from './pages/Preview';
3
+ import Play from './pages/Play';
4
+ import Debug from './pages/Debug';
5
+
6
+ type Page = 'preview' | 'play' | 'debug';
7
+
8
+ export default function App() {
9
+ const [page, setPage] = useState<Page>(() => {
10
+ const path = window.location.pathname;
11
+ if (path.includes('play')) return 'play';
12
+ if (path.includes('debug')) return 'debug';
13
+ return 'preview';
14
+ });
15
+
16
+ return (
17
+ <div className="min-h-screen flex flex-col">
18
+ {/* Nav */}
19
+ <nav className="bg-zinc-900 border-b border-zinc-800 px-4 py-2 flex gap-4">
20
+ <span className="text-amber-500 font-bold mr-4">LPT Dev Kit</span>
21
+ {(['preview', 'play', 'debug'] as Page[]).map((p) => (
22
+ <button
23
+ key={p}
24
+ onClick={() => { setPage(p); history.pushState(null, '', `/${p}`); }}
25
+ className={`px-3 py-1 rounded ${page === p ? 'bg-amber-600 text-white' : 'text-zinc-400 hover:text-white'}`}
26
+ >
27
+ {p.charAt(0).toUpperCase() + p.slice(1)}
28
+ </button>
29
+ ))}
30
+ </nav>
31
+
32
+ {/* Content */}
33
+ <main className="flex-1 p-4">
34
+ {page === 'preview' && <Preview />}
35
+ {page === 'play' && <Play />}
36
+ {page === 'debug' && <Debug />}
37
+ </main>
38
+ </div>
39
+ );
40
+ }
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>LPT Dev Kit</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ body { background: #0a0a0a; color: #e5e5e5; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script type="module" src="/main.tsx"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.d.ts.map