mkctx 5.0.0 ā 6.0.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 +46 -9
- package/bin/mkctx.js +77 -16
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ A powerful command-line tool that generates comprehensive context files from you
|
|
|
24
24
|
- šØ **Syntax Highlighting** ā Proper language detection for code blocks
|
|
25
25
|
- š **Dual Mode** ā Interactive menu or fully non-interactive via CLI flags
|
|
26
26
|
- š **Context Statistics** ā Token estimation and file analysis
|
|
27
|
+
- šļø **ZIP Export** ā Bundle original files preserving the full directory structure
|
|
27
28
|
|
|
28
29
|
## Installation
|
|
29
30
|
|
|
@@ -76,11 +77,12 @@ After scanning, you choose a format and optionally a filename:
|
|
|
76
77
|
Size: 156.23 KB
|
|
77
78
|
|
|
78
79
|
? Select output format:
|
|
79
|
-
⯠š¦ All formats (MD, JSON, TOON, XML)
|
|
80
|
+
⯠š¦ All formats (MD, JSON, TOON, XML, ZIP)
|
|
80
81
|
š Markdown (.md)
|
|
81
82
|
š§ JSON (.json) - Simple array
|
|
82
83
|
š TOON (.toon) - Token-optimized
|
|
83
84
|
š XML (.xml)
|
|
85
|
+
šļø ZIP (.zip) - Original files bundled
|
|
84
86
|
|
|
85
87
|
? Enter a name for the output files: (context)
|
|
86
88
|
```
|
|
@@ -99,7 +101,7 @@ When any of the following flags are passed, mkctx skips all prompts and runs dir
|
|
|
99
101
|
| `--first-comment <text>` | | Override the first comment header | |
|
|
100
102
|
| `--last-comment <text>` | | Override the last comment footer | |
|
|
101
103
|
|
|
102
|
-
**Format values:** `md`, `json`, `toon`, `xml`, `all`, or comma-separated combinations.
|
|
104
|
+
**Format values:** `md`, `json`, `toon`, `xml`, `zip`, `all`, or comma-separated combinations.
|
|
103
105
|
|
|
104
106
|
```bash
|
|
105
107
|
# Single format
|
|
@@ -111,6 +113,12 @@ mkctx --src . --format md,json --name snapshot
|
|
|
111
113
|
# All formats with custom output directory
|
|
112
114
|
mkctx --src . --format all --name my-project --output ./docs
|
|
113
115
|
|
|
116
|
+
# ZIP only ā bundle original files
|
|
117
|
+
mkctx --src ./app --format zip --name snapshot
|
|
118
|
+
|
|
119
|
+
# ZIP combined with markdown
|
|
120
|
+
mkctx --src . --format md,zip --name my-project
|
|
121
|
+
|
|
114
122
|
# Using short aliases
|
|
115
123
|
mkctx -s ./src -f toon -n snapshot
|
|
116
124
|
|
|
@@ -164,32 +172,33 @@ The following are always ignored automatically: `.git`, `.svn`, `.hg`, `node_mod
|
|
|
164
172
|
| `json` | `.json` | Simple JSON array of file objects |
|
|
165
173
|
| `toon` | `.toon` | Token-Oriented Object Notation ā compact, LLM-optimized |
|
|
166
174
|
| `xml` | `.xml` | XML with CDATA sections |
|
|
175
|
+
| `zip` | `.zip` | Original files bundled, preserving directory structure |
|
|
167
176
|
|
|
168
177
|
### Markdown output example
|
|
169
178
|
|
|
170
179
|
````markdown
|
|
171
|
-
|
|
180
|
+
/* Project Context */
|
|
172
181
|
|
|
173
182
|
## Project Structure
|
|
174
183
|
|
|
175
|
-
|
|
184
|
+
```
|
|
176
185
|
š src/
|
|
177
186
|
š src/components/
|
|
178
187
|
|
|
179
188
|
42 files total
|
|
180
|
-
|
|
189
|
+
```
|
|
181
190
|
|
|
182
191
|
## Source Files
|
|
183
192
|
|
|
184
193
|
### src/index.ts
|
|
185
194
|
|
|
186
|
-
|
|
195
|
+
```typescript
|
|
187
196
|
import { App } from './app';
|
|
188
197
|
const app = new App();
|
|
189
198
|
app.start();
|
|
190
|
-
|
|
199
|
+
```
|
|
191
200
|
|
|
192
|
-
|
|
201
|
+
/* End of Context */
|
|
193
202
|
````
|
|
194
203
|
|
|
195
204
|
### JSON output example
|
|
@@ -208,6 +217,27 @@ app.start();
|
|
|
208
217
|
]
|
|
209
218
|
```
|
|
210
219
|
|
|
220
|
+
### ZIP output
|
|
221
|
+
|
|
222
|
+
The `zip` format bundles every scanned file into a `.zip` archive, preserving the full relative directory structure. This is useful for sharing a clean snapshot of your project or feeding files directly to tools that accept archives.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
context.zip
|
|
226
|
+
āāā src/
|
|
227
|
+
ā āāā index.ts
|
|
228
|
+
ā āāā components/
|
|
229
|
+
ā āāā App.tsx
|
|
230
|
+
āāā package.json
|
|
231
|
+
āāā README.md
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
The ZIP format can be combined freely with other formats in the same run:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
mkctx --src . --format md,zip --name my-project
|
|
238
|
+
# Outputs: my-project.md + my-project.zip
|
|
239
|
+
```
|
|
240
|
+
|
|
211
241
|
## Supported languages
|
|
212
242
|
|
|
213
243
|
| Category | Extensions |
|
|
@@ -232,6 +262,7 @@ app.start();
|
|
|
232
262
|
- **Onboarding** ā Help new developers get oriented quickly
|
|
233
263
|
- **Documentation** ā Generate a versioned snapshot of your codebase
|
|
234
264
|
- **CI/CD pipelines** ā Use non-interactive flags to automate context generation
|
|
265
|
+
- **Project sharing** ā Use the `zip` format to hand off a clean copy of your source files
|
|
235
266
|
|
|
236
267
|
## Platform support
|
|
237
268
|
|
|
@@ -259,6 +290,12 @@ Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-erro
|
|
|
259
290
|
|
|
260
291
|
## Changelog
|
|
261
292
|
|
|
293
|
+
### v6.0.0
|
|
294
|
+
|
|
295
|
+
- šļø Added `zip` output format ā bundles original files preserving directory structure
|
|
296
|
+
- š¦ `--format all` now includes `zip`
|
|
297
|
+
- ā New dependency: [`archiver`](https://www.npmjs.com/package/archiver) (pure JS, OS-agnostic)
|
|
298
|
+
|
|
262
299
|
### v5.0.0
|
|
263
300
|
|
|
264
301
|
- ⨠Added non-interactive CLI flags (`--src`, `--format`, `--output`, `--name`, `--ignore`, etc.)
|
|
@@ -291,4 +328,4 @@ Contributions are welcome! Feel free to open issues or submit pull requests.
|
|
|
291
328
|
|
|
292
329
|
## License
|
|
293
330
|
|
|
294
|
-
MIT License ā see [LICENSE](LICENSE) for details.
|
|
331
|
+
MIT License ā see [LICENSE](LICENSE) for details.
|
package/bin/mkctx.js
CHANGED
|
@@ -9,7 +9,7 @@ const path = require('path');
|
|
|
9
9
|
// LAZY-LOADED DEPENDENCIES
|
|
10
10
|
// ============================================
|
|
11
11
|
|
|
12
|
-
let inquirer, chalk, ora;
|
|
12
|
+
let inquirer, chalk, ora, archiver;
|
|
13
13
|
|
|
14
14
|
function loadDependencies() {
|
|
15
15
|
if (inquirer) return;
|
|
@@ -18,6 +18,11 @@ function loadDependencies() {
|
|
|
18
18
|
ora = require('ora');
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
function loadArchiver() {
|
|
22
|
+
if (archiver) return;
|
|
23
|
+
archiver = require('archiver');
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
// ============================================
|
|
22
27
|
// CONSTANTS
|
|
23
28
|
// ============================================
|
|
@@ -32,7 +37,7 @@ const DEFAULT_CONFIG = {
|
|
|
32
37
|
last_comment: '/* End of Context */',
|
|
33
38
|
};
|
|
34
39
|
|
|
35
|
-
const VALID_FORMATS = ['json', 'md', 'toon', 'xml'];
|
|
40
|
+
const VALID_FORMATS = ['json', 'md', 'toon', 'xml', 'zip'];
|
|
36
41
|
|
|
37
42
|
const LANG_MAP = {
|
|
38
43
|
js: 'javascript', ts: 'typescript', jsx: 'jsx', tsx: 'tsx',
|
|
@@ -388,8 +393,8 @@ function toMarkdown(files, config) {
|
|
|
388
393
|
|
|
389
394
|
const sources = files.map(file => {
|
|
390
395
|
const body = file.content.endsWith('\n') ? file.content : file.content + '\n';
|
|
391
|
-
return `### ${file.path}\n\n\`\`\`${file.language}\n${body}\`\`\`\n`;
|
|
392
|
-
}).join('\n');
|
|
396
|
+
return `### ${file.path}\n<!-- ${file.lines} lines -->\n\n\`\`\`${file.language}\n${body}\`\`\`\n`;
|
|
397
|
+
}).join('\n---\n');
|
|
393
398
|
|
|
394
399
|
return [
|
|
395
400
|
config.first_comment,
|
|
@@ -449,7 +454,7 @@ function toXml(files) {
|
|
|
449
454
|
const fileEntries = files.map(f => [
|
|
450
455
|
' <file>',
|
|
451
456
|
` <path>${escapeXml(f.path)}</path>`,
|
|
452
|
-
` <
|
|
457
|
+
` <n>${escapeXml(f.name)}</n>`,
|
|
453
458
|
` <extension>${escapeXml(f.extension || '')}</extension>`,
|
|
454
459
|
` <language>${escapeXml(f.language)}</language>`,
|
|
455
460
|
` <lines>${f.lines}</lines>`,
|
|
@@ -510,6 +515,46 @@ function printSummary(stats) {
|
|
|
510
515
|
console.log(chalk.white(` Size: ${formatSize(stats.totalSize)}`));
|
|
511
516
|
}
|
|
512
517
|
|
|
518
|
+
// ============================================
|
|
519
|
+
// SAVE AS ZIP
|
|
520
|
+
// ============================================
|
|
521
|
+
|
|
522
|
+
async function saveAsZip(result, fileName) {
|
|
523
|
+
loadArchiver();
|
|
524
|
+
|
|
525
|
+
const outputDir = result.config.output || './mkctx';
|
|
526
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
527
|
+
|
|
528
|
+
const zipPath = path.join(outputDir, `${fileName}.zip`);
|
|
529
|
+
const output = fs.createWriteStream(zipPath);
|
|
530
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
531
|
+
|
|
532
|
+
return new Promise((resolve, reject) => {
|
|
533
|
+
output.on('close', () => {
|
|
534
|
+
const size = archive.pointer();
|
|
535
|
+
console.log(chalk.green('\nā
ZIP saved:\n'));
|
|
536
|
+
console.log(chalk.white(` ${chalk.cyan('ZIP ')} ā ${chalk.yellow(zipPath)}`));
|
|
537
|
+
console.log(chalk.gray(` ${formatSize(size)} | ${result.files.length} files\n`));
|
|
538
|
+
resolve({ format: 'zip', file: zipPath, size, tokens: 0 });
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
archive.on('warning', err => {
|
|
542
|
+
if (err.code !== 'ENOENT') reject(err);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
archive.on('error', reject);
|
|
546
|
+
|
|
547
|
+
archive.pipe(output);
|
|
548
|
+
|
|
549
|
+
// Each scanned file is added at its relative path, preserving directory structure
|
|
550
|
+
for (const file of result.files) {
|
|
551
|
+
archive.append(file.content, { name: file.path });
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
archive.finalize();
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
513
558
|
// ============================================
|
|
514
559
|
// SAVE CONTEXT
|
|
515
560
|
// ============================================
|
|
@@ -531,7 +576,12 @@ async function saveContext(result, formats, fileName) {
|
|
|
531
576
|
|
|
532
577
|
const savedFiles = [];
|
|
533
578
|
|
|
534
|
-
|
|
579
|
+
// Separate zip from the rest of the formats
|
|
580
|
+
const zipRequested = formats.includes('zip');
|
|
581
|
+
const regularFormats = formats.filter(f => f !== 'zip');
|
|
582
|
+
|
|
583
|
+
// Handle regular text-based formats
|
|
584
|
+
for (const format of regularFormats) {
|
|
535
585
|
const { content, ext } = renderFormat(format, result.files, result.stats, result.config);
|
|
536
586
|
const outputPath = path.join(outputDir, `${fileName}.${ext}`);
|
|
537
587
|
fs.writeFileSync(outputPath, content);
|
|
@@ -543,10 +593,18 @@ async function saveContext(result, formats, fileName) {
|
|
|
543
593
|
});
|
|
544
594
|
}
|
|
545
595
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
596
|
+
if (savedFiles.length > 0) {
|
|
597
|
+
console.log(chalk.green('\nā
Context saved:\n'));
|
|
598
|
+
for (const { format, file, size, tokens } of savedFiles) {
|
|
599
|
+
console.log(chalk.white(` ${chalk.cyan(format.toUpperCase().padEnd(4))} ā ${chalk.yellow(file)}`));
|
|
600
|
+
console.log(chalk.gray(` ${formatSize(size)} | ~${tokens.toLocaleString()} tokens\n`));
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Handle zip format
|
|
605
|
+
if (zipRequested) {
|
|
606
|
+
const zipEntry = await saveAsZip(result, fileName);
|
|
607
|
+
savedFiles.push(zipEntry);
|
|
550
608
|
}
|
|
551
609
|
|
|
552
610
|
return savedFiles;
|
|
@@ -572,12 +630,13 @@ async function promptFormat() {
|
|
|
572
630
|
message: 'Select output format:',
|
|
573
631
|
default: 'all',
|
|
574
632
|
choices: [
|
|
575
|
-
{ name: chalk.magenta('š¦ All formats (MD, JSON, TOON, XML)'), value: 'all' },
|
|
633
|
+
{ name: chalk.magenta('š¦ All formats (MD, JSON, TOON, XML, ZIP)'), value: 'all' },
|
|
576
634
|
new inquirer.Separator(),
|
|
577
|
-
{ name: chalk.blue('š Markdown (.md)'),
|
|
578
|
-
{ name: chalk.green('š§ JSON (.json) - Simple array'),
|
|
579
|
-
{ name: chalk.yellow('š TOON (.toon) - Token-optimized'),
|
|
580
|
-
{ name: chalk.red('š XML (.xml)'),
|
|
635
|
+
{ name: chalk.blue('š Markdown (.md)'), value: 'md' },
|
|
636
|
+
{ name: chalk.green('š§ JSON (.json) - Simple array'), value: 'json' },
|
|
637
|
+
{ name: chalk.yellow('š TOON (.toon) - Token-optimized'), value: 'toon' },
|
|
638
|
+
{ name: chalk.red('š XML (.xml)'), value: 'xml' },
|
|
639
|
+
{ name: chalk.cyan('šļø ZIP (.zip) - Original files bundled'), value: 'zip' },
|
|
581
640
|
],
|
|
582
641
|
}]);
|
|
583
642
|
return resolveFormats(format);
|
|
@@ -716,7 +775,7 @@ function showHelp() {
|
|
|
716
775
|
${chalk.yellow('Non-interactive flags (skip all prompts):')}
|
|
717
776
|
--src <path> Source directory (default: .)
|
|
718
777
|
--output <path> Output directory (default: ./mkctx)
|
|
719
|
-
--format <fmt> md, json, toon, xml, all, or comma-separated
|
|
778
|
+
--format <fmt> md, json, toon, xml, zip, all, or comma-separated
|
|
720
779
|
--name <filename> Output file base name (default: context)
|
|
721
780
|
--ignore <patterns> Comma-separated ignore patterns
|
|
722
781
|
--first-comment <text> Override first comment header
|
|
@@ -729,6 +788,7 @@ function showHelp() {
|
|
|
729
788
|
mkctx --src ./src
|
|
730
789
|
mkctx --src . --format all --name my-project --output ./docs
|
|
731
790
|
mkctx --src ./app --format md,json --ignore "*.test.ts,__tests__/"
|
|
791
|
+
mkctx --src ./app --format zip --name snapshot
|
|
732
792
|
mkctx -s ./src -f toon -n snapshot
|
|
733
793
|
|
|
734
794
|
${chalk.yellow('Output Formats:')}
|
|
@@ -736,6 +796,7 @@ function showHelp() {
|
|
|
736
796
|
${chalk.blue('MD')} Markdown with code blocks
|
|
737
797
|
${chalk.yellow('TOON')} Token-Oriented Object Notation (LLM optimized)
|
|
738
798
|
${chalk.red('XML')} XML with CDATA sections
|
|
799
|
+
${chalk.cyan('ZIP')} Original files bundled, preserving directory structure
|
|
739
800
|
|
|
740
801
|
${chalk.gray('More info: https://github.com/pnkkzero/mkctx')}
|
|
741
802
|
`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mkctx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Generate markdown context files from your project code and chat with AI using Ollama",
|
|
5
5
|
"main": "bin/mkctx.js",
|
|
6
6
|
"bin": {
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"win32"
|
|
59
59
|
],
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"archiver": "^7.0.1",
|
|
61
62
|
"chalk": "^4.1.2",
|
|
62
63
|
"conf": "^10.2.0",
|
|
63
64
|
"inquirer": "^8.2.6",
|