@hapico/cli 0.0.26 → 0.0.28

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/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import { isEqual, find, map } from "lodash";
3
+ import { isEqual, find, map, debounce } from "lodash";
4
4
  import { program } from "commander";
5
5
  import axios from "axios";
6
6
  import * as fs from "fs";
@@ -16,6 +16,7 @@ import { exec } from "child_process";
16
16
  import { promisify } from "util";
17
17
  import chalk from "chalk";
18
18
  import pako from "pako";
19
+ import { vibe } from "./tools/vibe";
19
20
 
20
21
  // Promisify exec for async usage
21
22
  const execPromise = promisify(exec);
@@ -117,11 +118,6 @@ interface RoomStateData {
117
118
  [key: string]: any;
118
119
  }
119
120
 
120
- interface WebSocketMessage {
121
- type: string;
122
- state?: RoomStateData;
123
- }
124
-
125
121
  export const tryJSONParse = (str: string): any => {
126
122
  try {
127
123
  return JSON.parse(str);
@@ -232,8 +228,18 @@ class FileManager {
232
228
  }
233
229
 
234
230
  private writeFile(file: FileContent): void {
231
+ if (!file.path || file.path.trim() === "") return;
235
232
  try {
236
233
  const fullPath = path.join(this.basePath, file.path);
234
+
235
+ if (fs.existsSync(fullPath)) {
236
+ try {
237
+ if (fs.statSync(fullPath).isDirectory()) return;
238
+ } catch (e) {
239
+ // ignore
240
+ }
241
+ }
242
+
237
243
  const dir = path.dirname(fullPath);
238
244
  fs.mkdirSync(dir, { recursive: true });
239
245
 
@@ -244,7 +250,8 @@ class FileManager {
244
250
  encoding: "utf8",
245
251
  });
246
252
  hasChanged = existingContent !== file.content;
247
- } catch (readError) {
253
+ } catch (readError: any) {
254
+ if (readError.code === "EISDIR") return;
248
255
  console.warn(
249
256
  chalk.yellow(
250
257
  `Warning: Could not read existing file ${fullPath}, treating as changed:`
@@ -258,7 +265,8 @@ class FileManager {
258
265
  if (hasChanged) {
259
266
  fs.writeFileSync(fullPath, file.content, { encoding: "utf8" });
260
267
  }
261
- } catch (error) {
268
+ } catch (error: any) {
269
+ if (error.code === "EISDIR") return;
262
270
  console.error(chalk.red(`Error processing file ${file.path}:`), error);
263
271
  throw error;
264
272
  }
@@ -475,7 +483,7 @@ class RoomState {
475
483
  }
476
484
  }
477
485
 
478
- program.version("0.0.26").description("Hapico CLI for project management");
486
+ program.version("0.0.28").description("Hapico CLI for project management");
479
487
 
480
488
  program
481
489
  .command("clone <id>")
@@ -614,6 +622,14 @@ program
614
622
  }
615
623
  });
616
624
 
625
+ program
626
+ .command("vibe")
627
+ .description("Refactor code using AI")
628
+ .action(async () => {
629
+ const targetPath = process.cwd();
630
+ await vibe(targetPath);
631
+ });
632
+
617
633
  program
618
634
  .command("dev")
619
635
  .description("Start the project in development mode")
@@ -729,6 +745,11 @@ program
729
745
 
730
746
  room.updateState("view", filteredFiles);
731
747
 
748
+ // Debounce the state update to avoid overwhelming the server while typing/saving
749
+ const debouncedUpdate = debounce((updatedFiles: FileContent[]) => {
750
+ room.updateState("view", updatedFiles);
751
+ }, 200);
752
+
732
753
  fileManager.setOnFileChange((filePath, content) => {
733
754
  const es5 = compileES5(content, filePath) ?? "";
734
755
  console.log(
@@ -741,7 +762,7 @@ program
741
762
  return file;
742
763
  });
743
764
  room.files = updatedFiles;
744
- room.updateState("view", updatedFiles);
765
+ debouncedUpdate(updatedFiles);
745
766
  });
746
767
 
747
768
  // Fetch project info
@@ -775,8 +796,7 @@ program
775
796
  const zversion = options.zversion;
776
797
 
777
798
  if (projectType === "expo_app" || projectType === "emg_edu_lesson") {
778
- const BASE_EXPO_LINK = `exp://u.expo.dev/e362c6df-abe8-4503-8723-1362f015d167/group/3ac94fc0-92b1-445e-8d88-9b2f6a4b869a`;
779
- //exp://u.expo.dev/e362c6df-abe8-4503-8723-1362f015d167/group/8cd11ab9-b6db-4924-9f7a-5e449f027bba?sessionKey=eyJpZCI6IjU1NF8xIiwidmlld0lkIjo1NTR9&mode=development
799
+ const BASE_EXPO_LINK = `exp://u.expo.dev/e362c6df-abe8-4503-8723-1362f015d167/group/e5d6b96e-3c78-485a-a170-1d8aa8b2c47e`;
780
800
  const link = `${BASE_EXPO_LINK}?sessionKey=${projectId}&mode=development`;
781
801
  QRCode.generate(link, { small: true }, (qrcode) => {
782
802
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hapico/cli",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "A simple CLI tool for project management",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -23,6 +23,7 @@
23
23
  "@babel/standalone": "^7.28.2",
24
24
  "axios": "^1.11.0",
25
25
  "commander": "^14.0.0",
26
+ "express": "^5.2.1",
26
27
  "inquirer": "^12.9.6",
27
28
  "lodash": "^4.17.21",
28
29
  "open": "^10.2.0",
@@ -37,6 +38,7 @@
37
38
  "devDependencies": {
38
39
  "@types/babel__standalone": "^7.1.9",
39
40
  "@types/commander": "^2.12.5",
41
+ "@types/express": "^5.0.6",
40
42
  "@types/lodash": "^4.17.20",
41
43
  "@types/node": "^24.1.0",
42
44
  "@types/pako": "^2.0.4",