@sumant.pathak/devjar 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sumnt Pathak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # devjar
2
+
3
+ Scan your project into a Claude-ready knowledge map. Rewrite vague prompts into structured ones. Use 60–70% fewer tokens on any AI coding tool.
4
+
5
+ ---
6
+
7
+ Every Claude Code session starts blind. You re-explain the same context, re-read the same files, burn tokens on clarification. devjar fixes both.
8
+
9
+ ---
10
+
11
+ ## Quick start
12
+
13
+ ```bash
14
+ npm install -g devjar
15
+ cd your-project
16
+ devjar init
17
+ ```
18
+
19
+ Your project is now mapped. Claude reads `CLAUDE.md` at session start and never re-reads your files again.
20
+
21
+ For prompt normalization, pick a provider once:
22
+
23
+ ```bash
24
+ ollama pull llama3.2 # free, runs locally
25
+ devjar config --provider ollama --model llama3.2
26
+ devjar prompt "fix login bug"
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Commands
32
+
33
+ | Command | What it does |
34
+ |---|---|
35
+ | `devjar init` | Scan project → generate `CLAUDE.md` (stack, file map, rules) |
36
+ | `devjar prompt "text"` | Rewrite vague input into STAR-C format, copy to clipboard |
37
+ | `devjar update` | Regenerate `CLAUDE.md` after major changes |
38
+ | `devjar update --watch` | Live watcher — updates file map on every save |
39
+ | `devjar stats` | Token savings estimate, streak, per-project breakdown |
40
+ | `devjar config` | Set AI provider, or run setup wizard |
41
+
42
+ ---
43
+
44
+ ## Provider setup
45
+
46
+ **Ollama — free, local, no account needed (recommended)**
47
+
48
+ ```bash
49
+ # Install from https://ollama.com, then:
50
+ ollama pull llama3.2
51
+ devjar config --provider ollama --model llama3.2
52
+ ```
53
+
54
+ **Cloud providers**
55
+
56
+ ```bash
57
+ devjar config --provider gemini --key AIza... # free tier at aistudio.google.com
58
+ devjar config --provider anthropic --key sk-ant-...
59
+ devjar config --provider openai --key sk-...
60
+ ```
61
+
62
+ First time you run `devjar prompt` with no config, the setup wizard runs automatically.
63
+
64
+ ---
65
+
66
+ ## What it looks like
67
+
68
+ ```
69
+ $ devjar init
70
+ ⬡ devjar init → /your-project
71
+ ────────────────────────────────────────────────────
72
+ Phase 1 Scanning project structure...
73
+ ✓ 115 files | Stack: React + Vite
74
+ Phase 2 Pattern extraction via Haiku...
75
+ ✓ 5 rules extracted from 4 key files
76
+ Phase 3 Writing CLAUDE.md...
77
+ ────────────────────────────────────────────────────
78
+ ✓ CLAUDE.md generated — 115 files scanned, 5 rules extracted
79
+ → /your-project/CLAUDE.md
80
+ ```
81
+
82
+ ```
83
+ $ devjar prompt "login not working after deploy"
84
+ ⬡ devjar prompt
85
+ ────────────────────────────────────────────────────
86
+ Provider: ollama/llama3.2
87
+ Input: login not working after deploy
88
+ ✓ CLAUDE.md loaded (7236 chars)
89
+
90
+ ─── STAR-C Prompt ───────────────────────────────────
91
+ S — care-home — React + Vite, auth via httpOnly cookie
92
+ T — Debug login failure introduced after deployment
93
+ A — Check src/routes/auth.js COOKIE_OPTIONS (SameSite attr)
94
+ Verify KV session creation on login success
95
+ R — Login succeeds, sc_token cookie set, /api/auth/me returns user
96
+ C — Don't change PBKDF2 iterations (CF Workers hard cap: 100k)
97
+ Don't rotate JWT_SECRET without flushing KV sessions
98
+ ────────────────────────────────────────────────────
99
+
100
+ Copy to clipboard? (Y/n) y
101
+ ✓ Copied
102
+ ```
103
+
104
+ ---
105
+
106
+ ## How it works
107
+
108
+ `devjar init` walks your project, reads `package.json` + config files, then sends 3–5 key files to your AI provider and extracts naming conventions, patterns, and 5 unbreakable rules. Writes everything to `CLAUDE.md`.
109
+
110
+ `devjar prompt` sends your vague input + your `CLAUDE.md` to your provider. Gets back a structured prompt with the exact files to check, expected result, and constraints inferred from your codebase. One provider call ≈ $0.00 with Ollama.
111
+
112
+ ---
113
+
114
+ ## Requirements
115
+
116
+ - Node.js 18+
117
+ - `devjar init` — fully offline, no provider needed
118
+ - `devjar prompt` — Ollama (free) or any cloud API key
119
+ - `devjar stats` / `devjar update` — fully offline
120
+
121
+ ---
122
+
123
+ ## License
124
+
125
+ MIT
package/bin/devjar.js ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { init } from '../src/init.js';
4
+ import { prompt } from '../src/prompt.js';
5
+ import { update } from '../src/update.js';
6
+ import { stats } from '../src/stats.js';
7
+ import { configCommand } from '../src/config.js';
8
+
9
+ const program = new Command();
10
+
11
+ program
12
+ .name('devjar')
13
+ .description('Jarvis CLI — scan projects, normalize prompts, watch files, track tokens')
14
+ .version('0.1.0');
15
+
16
+ program
17
+ .command('init [dir]')
18
+ .description('Scan project and build Jarvis knowledge map')
19
+ .option('-o, --output <file>', 'output map file', 'jarvis-map.txt')
20
+ .option('--depth <n>', 'max directory depth to scan', '4')
21
+ .action(init);
22
+
23
+ program
24
+ .command('prompt <text...>')
25
+ .description('Normalize a prompt into STAR-C format')
26
+ .option('--copy', 'copy result to clipboard')
27
+ .option('--inject', 'inject into Claude Code session context')
28
+ .action(prompt);
29
+
30
+ program
31
+ .command('update [dir]')
32
+ .description('Regenerate CLAUDE.md, or watch for live updates with --watch')
33
+ .option('--watch', 'watch for file changes and update live')
34
+ .option('--depth <n>', 'max directory depth to scan', '2')
35
+ .option('--debounce <ms>', 'debounce delay in ms for watch mode', '500')
36
+ .action(update);
37
+
38
+ program
39
+ .command('stats')
40
+ .description('Show prompt history and estimated token savings')
41
+ .option('--reset', 'clear all history')
42
+ .option('--json', 'output raw JSON')
43
+ .action(stats);
44
+
45
+ program
46
+ .command('config')
47
+ .description('Set AI provider (ollama/anthropic/gemini/openai) or run setup wizard')
48
+ .option('--provider <name>', 'provider name: ollama, anthropic, gemini, openai')
49
+ .option('--model <name>', 'model name (e.g. llama3.2, gpt-4o-mini)')
50
+ .option('--key <apikey>', 'API key for cloud providers')
51
+ .option('--url <url>', 'custom Ollama base URL (default: http://localhost:11434)')
52
+ .option('--show', 'show current config')
53
+ .action(configCommand);
54
+
55
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@sumant.pathak/devjar",
3
+ "version": "1.0.0",
4
+ "description": "Scan your project into a Claude-ready knowledge map. Use 60-70% fewer tokens on any AI coding tool.",
5
+ "type": "module",
6
+ "bin": {
7
+ "devjar": "bin/devjar.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/devjar.js"
11
+ },
12
+ "dependencies": {
13
+ "@anthropic-ai/sdk": "^0.39.0",
14
+ "chalk": "^5.6.2",
15
+ "chokidar": "^5.0.0",
16
+ "clipboardy": "^5.3.1",
17
+ "commander": "^12.1.0"
18
+ },
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "keywords": [
23
+ "claude",
24
+ "ai",
25
+ "prompt",
26
+ "developer-tools",
27
+ "ollama",
28
+ "token",
29
+ "cli",
30
+ "jarvis",
31
+ "star-c",
32
+ "token-tracker"
33
+ ],
34
+ "license": "MIT"
35
+ }
package/src/config.js ADDED
@@ -0,0 +1,103 @@
1
+ // devjar config — provider setup, wizard, config display
2
+
3
+ import readline from 'readline';
4
+ import chalk from 'chalk';
5
+ import { loadConfig, saveConfig } from './providers/index.js';
6
+
7
+ const PROVIDERS = {
8
+ 1: { name: 'ollama', label: 'Ollama (free, local, recommended)', defaultModel: 'llama3.2', needsKey: false },
9
+ 2: { name: 'anthropic', label: 'Anthropic (API key required)', defaultModel: 'claude-haiku-4-5-20251001', needsKey: true },
10
+ 3: { name: 'gemini', label: 'Gemini (free tier available)', defaultModel: 'gemini-2.0-flash', needsKey: true },
11
+ 4: { name: 'openai', label: 'OpenAI (API key required)', defaultModel: 'gpt-4o-mini', needsKey: true },
12
+ };
13
+
14
+ function ask(rl, question) {
15
+ return new Promise(resolve => rl.question(question, ans => resolve(ans.trim())));
16
+ }
17
+
18
+ export async function runWizard() {
19
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
20
+
21
+ console.log(chalk.bold.blue('⬡ devjar') + chalk.gray(' — first run setup'));
22
+ console.log(chalk.gray('─'.repeat(52)));
23
+ console.log(chalk.white('Which AI provider do you want to use?\n'));
24
+
25
+ for (const [num, p] of Object.entries(PROVIDERS)) {
26
+ const tag = num === '1' ? chalk.green(' ← default') : '';
27
+ console.log(` ${chalk.cyan(num + '.')} ${p.label}${tag}`);
28
+ }
29
+
30
+ console.log();
31
+ const choice = await ask(rl, chalk.bold('Enter number') + chalk.gray(' [1]: ')) || '1';
32
+ const provider = PROVIDERS[choice] || PROVIDERS[1];
33
+
34
+ let apiKey = '';
35
+ if (provider.needsKey) {
36
+ console.log(chalk.gray(`\n ${provider.name} requires an API key.`));
37
+ apiKey = await ask(rl, chalk.bold(' Paste API key: '));
38
+ if (!apiKey) {
39
+ console.log(chalk.yellow(' No key entered — switching to Ollama.'));
40
+ rl.close();
41
+ return runWizard(); // restart with ollama default path
42
+ }
43
+ }
44
+
45
+ rl.close();
46
+
47
+ const cfg = { provider: provider.name, model: provider.defaultModel, ...(apiKey && { apiKey }) };
48
+ saveConfig(cfg);
49
+
50
+ console.log();
51
+ console.log(chalk.green('✓ Configured: ') + chalk.white(`${provider.name} / ${provider.defaultModel}`));
52
+ if (provider.name === 'ollama') {
53
+ console.log(chalk.gray(' Make sure Ollama is running: ') + chalk.cyan('ollama serve'));
54
+ console.log(chalk.gray(' Pull model if needed: ') + chalk.cyan(`ollama pull ${provider.defaultModel}`));
55
+ }
56
+ console.log();
57
+
58
+ return cfg;
59
+ }
60
+
61
+ export async function configCommand(options) {
62
+ // devjar config --show
63
+ if (options.show) {
64
+ const cfg = loadConfig();
65
+ if (!cfg) {
66
+ console.log(chalk.yellow('No config found.') + chalk.gray(' Run `devjar config` to set up.'));
67
+ return;
68
+ }
69
+ console.log(chalk.bold.blue('⬡ devjar') + chalk.gray(' config'));
70
+ console.log(chalk.gray('─'.repeat(52)));
71
+ console.log(chalk.gray(' Provider: ') + chalk.cyan(cfg.provider));
72
+ console.log(chalk.gray(' Model: ') + chalk.white(cfg.model));
73
+ if (cfg.apiKey) console.log(chalk.gray(' API Key: ') + chalk.white(cfg.apiKey.slice(0, 8) + '••••••••'));
74
+ if (cfg.ollamaUrl) console.log(chalk.gray(' Ollama: ') + chalk.white(cfg.ollamaUrl));
75
+ return;
76
+ }
77
+
78
+ // devjar config --provider X --model Y --key Z
79
+ if (options.provider) {
80
+ const known = Object.values(PROVIDERS).map(p => p.name);
81
+ if (!known.includes(options.provider)) {
82
+ console.log(chalk.red(`Unknown provider "${options.provider}".`) + chalk.gray(` Choose: ${known.join(', ')}`));
83
+ process.exit(1);
84
+ }
85
+
86
+ const existing = loadConfig() || {};
87
+ const defaultModel = Object.values(PROVIDERS).find(p => p.name === options.provider)?.defaultModel;
88
+ const cfg = {
89
+ ...existing,
90
+ provider: options.provider,
91
+ model: options.model || existing.model || defaultModel,
92
+ ...(options.key && { apiKey: options.key }),
93
+ ...(options.url && { ollamaUrl: options.url }),
94
+ };
95
+ saveConfig(cfg);
96
+
97
+ console.log(chalk.green('✓ Saved: ') + chalk.white(`${cfg.provider} / ${cfg.model}`));
98
+ return;
99
+ }
100
+
101
+ // No flags — run wizard
102
+ await runWizard();
103
+ }