prodex 1.4.9 → 1.4.11

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.
@@ -75,12 +75,19 @@ function parseCliInput(argv = process.argv) {
75
75
  }
76
76
  function registerFlags(program) {
77
77
  for (const [key, meta] of Object.entries(flags_1.FLAG_MAP)) {
78
- const short = meta.short ? `-${meta.short},` : "";
78
+ const short = meta.short ? `-${meta.short}, ` : "";
79
79
  const defaultVal = meta.type === "boolean" ? false : undefined;
80
80
  program.option(`${short}--${key}`, meta.description, defaultVal);
81
81
  }
82
82
  }
83
83
  function normalizeFlags(flags, warnings, errors) {
84
+ // Remap short aliases (-i/-f/-d) to long keys (include/files/debug)
85
+ for (const [short, longKey] of Object.entries(flags_1.FLAG_SHORT_MAP)) {
86
+ if (flags[longKey] === undefined && flags[short] !== undefined) {
87
+ flags[longKey] = flags[short];
88
+ delete flags[short];
89
+ }
90
+ }
84
91
  for (const [key, meta] of Object.entries(flags_1.FLAG_MAP)) {
85
92
  const raw = flags[key];
86
93
  if (raw === undefined)
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MD_HEADER = exports.MD_FOOTER = exports.TEXT_HEADERS = exports.LANG_MAP = void 0;
6
+ exports.LLM_NOTE = exports.INDEX_RANGE_PLACEHOLDER = exports.MD_HEADER = exports.MD_FOOTER = exports.TEXT_HEADERS = exports.LANG_MAP = void 0;
7
7
  const package_json_1 = __importDefault(require("../../package.json"));
8
8
  exports.LANG_MAP = {
9
9
  "": "js",
@@ -23,3 +23,5 @@ exports.TEXT_HEADERS = {
23
23
  };
24
24
  exports.MD_FOOTER = ["\n---", "*Generated with [Prodex](https://github.com/emxhive/prodex) — Codebase decoded.*", `<!-- PRODEx v${package_json_1.default.version} | ${new Date().toISOString()} -->`].join("\n");
25
25
  exports.MD_HEADER = "*Generated by [Prodex](https://github.com/emxhive/prodex#readme)*";
26
+ exports.INDEX_RANGE_PLACEHOLDER = "L?-L?";
27
+ exports.LLM_NOTE = "> Note for LLMs: `Lx-Ly` ranges refer to lines in this Prodex trace file, not the original source files. Index metadata is provided via the HTML comment markers in this section.";
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ConfigManager = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
- const default_config_1 = require("../../constants/default-config");
9
+ const constants_1 = require("../../constants");
10
10
  const utils_1 = require("../../lib/utils");
11
11
  const flags_1 = require("../../constants/flags");
12
12
  const store_1 = require("../../store");
@@ -19,7 +19,7 @@ class ConfigManager {
19
19
  static load(cwd = process.cwd()) {
20
20
  const file = path_1.default.join(cwd, "prodex.json");
21
21
  if (!fs_1.default.existsSync(file))
22
- return default_config_1.DEFAULT_PRODEX_CONFIG;
22
+ return constants_1.DEFAULT_PRODEX_CONFIG;
23
23
  try {
24
24
  const parsed = JSON.parse(fs_1.default.readFileSync(file, "utf8"));
25
25
  this.rawFile = parsed; // <-- SAVE RAW COPY
@@ -27,20 +27,20 @@ class ConfigManager {
27
27
  }
28
28
  catch {
29
29
  console.warn("⚠️ Invalid prodex.json — using defaults.");
30
- return default_config_1.DEFAULT_PRODEX_CONFIG;
30
+ return constants_1.DEFAULT_PRODEX_CONFIG;
31
31
  }
32
32
  }
33
33
  static merge(user, flags, cwd = process.cwd()) {
34
34
  const merged = {
35
35
  // ...rest,
36
36
  ...user,
37
- output: { ...default_config_1.DEFAULT_PRODEX_CONFIG.output, ...user.output },
37
+ output: { ...constants_1.DEFAULT_PRODEX_CONFIG.output, ...user.output },
38
38
  entry: {
39
- ...default_config_1.DEFAULT_PRODEX_CONFIG.entry,
39
+ ...constants_1.DEFAULT_PRODEX_CONFIG.entry,
40
40
  ...user.entry,
41
- ui: { ...default_config_1.DEFAULT_PRODEX_CONFIG.entry.ui, ...user.entry?.ui },
41
+ ui: { ...constants_1.DEFAULT_PRODEX_CONFIG.entry.ui, ...user.entry?.ui },
42
42
  },
43
- resolve: { ...default_config_1.DEFAULT_PRODEX_CONFIG.resolve, ...user.resolve },
43
+ resolve: { ...constants_1.DEFAULT_PRODEX_CONFIG.resolve, ...user.resolve },
44
44
  root: cwd,
45
45
  name: flags?.name ?? null,
46
46
  };
@@ -11,7 +11,7 @@ const renderers_1 = require("./renderers");
11
11
  const logger_1 = require("../lib/logger");
12
12
  const utils_1 = require("../lib/utils");
13
13
  const questions_1 = require("../lib/questions");
14
- const config_1 = require("../constants/config");
14
+ const constants_1 = require("../constants");
15
15
  /**
16
16
  * 🧩 produceOutput()
17
17
  * Handles rendering and writing of the final trace file.
@@ -27,7 +27,7 @@ async function produceOutput({ name, files, cfg, showUi }) {
27
27
  outputBase = result.outputBase;
28
28
  }
29
29
  // 2️⃣ Prefix timestamp if versioned
30
- outputBase = `${outputBase}-${config_1.SUFFIX}`;
30
+ outputBase = `${outputBase}-${constants_1.SUFFIX}`;
31
31
  if (versioned)
32
32
  outputBase = `${outputBase}_${(0, utils_1.shortTimestamp)()}`;
33
33
  // 3️⃣ Ensure output directory
@@ -10,18 +10,17 @@ exports.tocTxt = tocTxt;
10
10
  exports.renderTxt = renderTxt;
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const shared_1 = require("../shared");
13
- const shared_2 = require("../shared");
14
13
  const constants_1 = require("../constants");
15
14
  /**
16
15
  * renderTraceMd()
17
- * Builds the full markdown document AND computes:
16
+ * Builds the full Markdown document AND computes:
18
17
  * - listing start/end lines
19
18
  * - each file section start/end lines (in the final output)
20
19
  */
21
20
  // src/core/renderers.ts
22
21
  function renderTraceMd(files) {
23
22
  const count = files.length;
24
- // Render sections once (content of each file)
23
+ // Render sections at once (content of each file)
25
24
  const sections = files.map((f, i) => renderMd(f, i));
26
25
  // 1) Build a FIRST PASS doc with placeholder TOC (no line ranges)
27
26
  const pass1Toc = buildToc({
@@ -59,23 +58,26 @@ function renderTraceMd(files) {
59
58
  const rangeText = (start, end) => ` L${start}-L${end}`;
60
59
  function buildToc(opts) {
61
60
  const { files, count, listingStart, listingEnd, trace, withRanges } = opts;
61
+ const indexRange = withRanges && listingStart && listingEnd
62
+ ? `L${listingStart}-L${listingEnd}`
63
+ : constants_1.INDEX_RANGE_PLACEHOLDER;
62
64
  const tocHead = [
63
- `# Index ${withRanges ? rangeText(listingStart, listingEnd) : ""} `,
64
- "",
65
- "> Note for LLMs: `Lx-Ly` ranges refer to lines in this Prodex trace file, not the original source files.",
66
- "",
67
65
  constants_1.MD_HEADER,
66
+ constants_1.LLM_NOTE,
68
67
  "",
69
- `Included Source Files: ${count}`,
68
+ "# Index",
69
+ `<!-- PRODEX_INDEX_RANGE: ${indexRange} -->`,
70
+ `<!-- PRODEX_FILE_COUNT: ${count} -->`,
71
+ "<!-- PRODEX_INDEX_LIST_START -->",
70
72
  ];
71
73
  const items = files.map((f, i) => {
72
- const rp = (0, shared_2.rel)(f);
74
+ const rp = (0, shared_1.rel)(f);
73
75
  if (!withRanges || !trace)
74
76
  return `- [${rp}](#${i + 1})`;
75
77
  const t = trace[i];
76
78
  return `- [${rp}](#${i + 1}) ${rangeText(t.startLine, t.endLine)}`;
77
79
  });
78
- const tocTail = ["", "---"];
80
+ const tocTail = ["<!-- PRODEX_INDEX_LIST_END -->", "", "---"];
79
81
  return [...tocHead, ...items, ...tocTail].join("\n");
80
82
  }
81
83
  /**
@@ -88,10 +90,28 @@ function buildToc(opts) {
88
90
  function analyzeTrace(content, count) {
89
91
  const lines = content.split("\n");
90
92
  // --- Listing range ---
91
- const includedIdx = lines.findIndex((l) => /^Included Source Files\b/.test(l.trim()));
92
- // listing begins on the next line after the header
93
- const listingStart = includedIdx >= 0 ? includedIdx + 2 : 0; // 1-based
94
- const listingEnd = count ? listingStart + count - 1 : listingStart;
93
+ const startMarkerIdx = lines.findIndex((l) => l.trim() === "<!-- PRODEX_INDEX_LIST_START -->");
94
+ const endMarkerIdx = lines.findIndex((l) => l.trim() === "<!-- PRODEX_INDEX_LIST_END -->");
95
+ let listingStart = 0;
96
+ let listingEnd = 0;
97
+ if (startMarkerIdx >= 0 && endMarkerIdx > startMarkerIdx) {
98
+ const itemIdxs = [];
99
+ for (let i = startMarkerIdx + 1; i < endMarkerIdx; i++) {
100
+ if (lines[i].trim().startsWith("- "))
101
+ itemIdxs.push(i);
102
+ }
103
+ if (itemIdxs.length) {
104
+ listingStart = itemIdxs[0] + 1; // 1-based
105
+ // count is zero during the first (placeholder) pass; cap to the requested count when provided, otherwise use the discovered items
106
+ const cappedCount = count > 0 ? Math.min(itemIdxs.length, count) : itemIdxs.length;
107
+ const lastItemIdx = itemIdxs[cappedCount - 1];
108
+ listingEnd = lastItemIdx + 1;
109
+ }
110
+ else {
111
+ listingStart = startMarkerIdx + 2; // move past the marker line (0-based) and convert to 1-based line numbers
112
+ listingEnd = listingStart;
113
+ }
114
+ }
95
115
  // --- Footer start (exclude footer from last file range) ---
96
116
  let footerMarkerIdx = lines.findIndex((l) => l.includes("<!-- PRODEx v"));
97
117
  if (footerMarkerIdx < 0)
@@ -147,11 +167,23 @@ function analyzeTrace(content, count) {
147
167
  */
148
168
  function tocMd(files) {
149
169
  const count = files.length;
150
- const items = files.map((f, i) => `- [${(0, shared_2.rel)(f)}](#${i + 1})`).join("\n");
151
- return ["# Index ", `\nIncluded Source Files (${count})`, items, "", "---"].join("\n");
170
+ const items = files.map((f, i) => `- [${(0, shared_1.rel)(f)}](#${i + 1})`);
171
+ return [
172
+ constants_1.MD_HEADER,
173
+ constants_1.LLM_NOTE,
174
+ "",
175
+ "# Index",
176
+ `<!-- PRODEX_INDEX_RANGE: ${constants_1.INDEX_RANGE_PLACEHOLDER} -->`,
177
+ `<!-- PRODEX_FILE_COUNT: ${count} -->`,
178
+ "<!-- PRODEX_INDEX_LIST_START -->",
179
+ ...items,
180
+ "<!-- PRODEX_INDEX_LIST_END -->",
181
+ "",
182
+ "---",
183
+ ].join("\n");
152
184
  }
153
185
  function renderMd(p, i) {
154
- const rp = (0, shared_2.rel)(p);
186
+ const rp = (0, shared_1.rel)(p);
155
187
  const ext = path_1.default.extname(p).toLowerCase();
156
188
  const lang = constants_1.LANG_MAP[ext] || "txt";
157
189
  const code = (0, shared_1.readFileSafe)(p).trimEnd();
@@ -169,10 +201,10 @@ function renderMd(p, i) {
169
201
  // TXT versions unchanged
170
202
  function tocTxt(files) {
171
203
  const sorted = [...files].sort((a, b) => a.localeCompare(b));
172
- return ["##==== Combined Scope ====", ...sorted.map((f) => "## - " + (0, shared_2.rel)(f))].join("\n") + "\n\n";
204
+ return ["##==== Combined Scope ====", ...sorted.map((f) => "## - " + (0, shared_1.rel)(f))].join("\n") + "\n\n";
173
205
  }
174
206
  function renderTxt(p) {
175
- const relPath = (0, shared_2.rel)(p);
207
+ const relPath = (0, shared_1.rel)(p);
176
208
  const code = (0, shared_1.readFileSafe)(p);
177
209
  return ["##==== path: " + relPath + " ====", "##region " + relPath, code, "##endregion", ""].join("\n");
178
210
  }
package/dist/debug.js CHANGED
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const index_1 = __importDefault(require("./index"));
7
7
  require("source-map-support/register");
8
8
  (async () => {
9
- const mockArgs = ["node", "prodex", "@web", "-cd"];
9
+ const mockArgs = ["node", "prodex", "-i", "src/**", "-d"];
10
10
  process.argv = mockArgs;
11
11
  //"-f", "**/(dashboard|accounts).tsx",
12
12
  console.log("🧩 Debug runner starting...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prodex",
3
- "version": "1.4.9",
3
+ "version": "1.4.11",
4
4
  "description": "Unified Project Indexer & Dependency Extractor for Laravel + React + Node stacks.",
5
5
  "type": "commonjs",
6
6
  "bin": {