@jvittechs/j 1.0.49 → 1.0.51

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/dist/cli.js CHANGED
@@ -149,7 +149,7 @@ import { basename as basename5 } from "path";
149
149
  // package.json
150
150
  var package_default = {
151
151
  name: "@jvittechs/j",
152
- version: "1.0.49",
152
+ version: "1.0.51",
153
153
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Supports both `j` and `jai1` commands. Please contact TeamAI for usage instructions.",
154
154
  type: "module",
155
155
  bin: {
@@ -3642,19 +3642,31 @@ var IdeDetectionService = class {
3642
3642
  }
3643
3643
  }
3644
3644
  /**
3645
- * Count files with specific extension in a directory
3645
+ * Count files with specific extension in a directory (recursive)
3646
+ * Supports both flat files and files in subdirectories
3646
3647
  */
3647
3648
  async countFiles(dirPath, extension, excludeKeywords = []) {
3648
3649
  try {
3649
3650
  const entries = await fs7.readdir(dirPath, { withFileTypes: true });
3650
- return entries.filter((entry) => {
3651
- if (!entry.isFile() || !entry.name.endsWith(extension)) return false;
3652
- if (excludeKeywords.length > 0) {
3653
- const nameLower = entry.name.toLowerCase();
3654
- return !excludeKeywords.some((kw) => nameLower.includes(kw));
3651
+ let count = 0;
3652
+ for (const entry of entries) {
3653
+ if (entry.isDirectory()) {
3654
+ count += await this.countFiles(
3655
+ join4(dirPath, entry.name),
3656
+ extension,
3657
+ excludeKeywords
3658
+ );
3659
+ } else if (entry.isFile() && entry.name.endsWith(extension)) {
3660
+ if (excludeKeywords.length > 0) {
3661
+ const nameLower = entry.name.toLowerCase();
3662
+ if (excludeKeywords.some((kw) => nameLower.includes(kw))) {
3663
+ continue;
3664
+ }
3665
+ }
3666
+ count++;
3655
3667
  }
3656
- return true;
3657
- }).length;
3668
+ }
3669
+ return count;
3658
3670
  } catch {
3659
3671
  return 0;
3660
3672
  }
@@ -3992,20 +4004,9 @@ import { Command as Command14 } from "commander";
3992
4004
  import chalk10 from "chalk";
3993
4005
  import { promises as fs8 } from "fs";
3994
4006
  import { join as join5 } from "path";
3995
- var CORE_FILES = [
3996
- "workflows/gen-project-overview.md",
4007
+ var CORE_FILES_FALLBACK = [
3997
4008
  "context/jv-it-context.md",
3998
- "rules/jai1.md",
3999
- "workflows/commit-it.md",
4000
- "workflows/develop-feature.md",
4001
- "workflows/develop-feature-from-conversation.md",
4002
- "workflows/plan.md",
4003
- "workflows/plan-from-conversation.md",
4004
- "workflows/fix-bug.md",
4005
- "workflows/analyze-impact.md",
4006
- "workflows/feedback.md",
4007
- "skills/gen-commit-message",
4008
- "skills/latest-version"
4009
+ "rules/jai1.md"
4009
4010
  ];
4010
4011
  function createDoctorCommand() {
4011
4012
  const cmd = new Command14("doctor").description("Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i").option("--json", "Output as JSON").action(async (options) => {
@@ -4121,9 +4122,20 @@ async function checkCoreFiles(cliName) {
4121
4122
  suggestion: `Ch\u1EA1y "${cliName} apply core" \u0111\u1EC3 c\xE0i \u0111\u1EB7t core package.`
4122
4123
  };
4123
4124
  }
4125
+ let coreFiles = CORE_FILES_FALLBACK;
4126
+ try {
4127
+ const manifestPath = join5(jai1Dir, "manifest.json");
4128
+ const manifestContent = await fs8.readFile(manifestPath, "utf-8");
4129
+ const manifest = JSON.parse(manifestContent);
4130
+ const manifestFiles = Object.keys(manifest);
4131
+ if (manifestFiles.length > 0) {
4132
+ coreFiles = manifestFiles;
4133
+ }
4134
+ } catch {
4135
+ }
4124
4136
  const missing = [];
4125
4137
  const found = [];
4126
- for (const file of CORE_FILES) {
4138
+ for (const file of coreFiles) {
4127
4139
  const filePath = join5(jai1Dir, file);
4128
4140
  try {
4129
4141
  await fs8.access(filePath);
@@ -4136,21 +4148,21 @@ async function checkCoreFiles(cliName) {
4136
4148
  return {
4137
4149
  name: "Core Package",
4138
4150
  passed: true,
4139
- message: `\u0110\u1EA7y \u0111\u1EE7 ${CORE_FILES.length} core files`
4151
+ message: `\u0110\u1EA7y \u0111\u1EE7 ${coreFiles.length} core files`
4140
4152
  };
4141
4153
  }
4142
4154
  if (found.length === 0) {
4143
4155
  return {
4144
4156
  name: "Core Package",
4145
4157
  passed: false,
4146
- message: `Kh\xF4ng c\xF3 core file n\xE0o (0/${CORE_FILES.length})`,
4158
+ message: `Kh\xF4ng c\xF3 core file n\xE0o (0/${coreFiles.length})`,
4147
4159
  suggestion: `Ch\u1EA1y "${cliName} apply core" \u0111\u1EC3 c\xE0i \u0111\u1EB7t core package.`
4148
4160
  };
4149
4161
  }
4150
4162
  return {
4151
4163
  name: "Core Package",
4152
4164
  passed: false,
4153
- message: `Thi\u1EBFu ${missing.length}/${CORE_FILES.length} core files`,
4165
+ message: `Thi\u1EBFu ${missing.length}/${coreFiles.length} core files`,
4154
4166
  details: missing.map((f) => `Thi\u1EBFu: ${f}`),
4155
4167
  suggestion: `Ch\u1EA1y "${cliName} update" \u0111\u1EC3 c\u1EADp nh\u1EADt, ho\u1EB7c "${cliName} apply core" \u0111\u1EC3 c\xE0i l\u1EA1i.`
4156
4168
  };