jammincms 0.1.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/dist/claude.d.ts +14 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +146 -0
- package/dist/claude.js.map +1 -0
- package/dist/editor.d.ts +4 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +74 -0
- package/dist/editor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt.d.ts +3 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +202 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
package/dist/claude.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Job } from './types.js';
|
|
2
|
+
interface ClaudeCallbacks {
|
|
3
|
+
onProgress: (output: string, phase: 'thinking' | 'editing' | 'complete') => void;
|
|
4
|
+
onComplete: (success: boolean, filesChanged?: string[], error?: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function checkClaudeAvailable(): Promise<boolean>;
|
|
7
|
+
export declare function checkGitDirty(projectPath: string): {
|
|
8
|
+
isDirty: boolean;
|
|
9
|
+
changedFiles: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare function spawnClaudeJob(job: Job, callbacks: ClaudeCallbacks): Promise<void>;
|
|
12
|
+
export declare function cancelJob(job: Job): void;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,UAAU,eAAe;IACvB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,KAAK,IAAI,CAAC;IACjF,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACjF;AAGD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO7D;AAGD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAoB/F;AAkDD,wBAAsB,cAAc,CAClC,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAYxC"}
|
package/dist/claude.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
2
|
+
import { buildPrompt } from './prompt.js';
|
|
3
|
+
// Check if Claude CLI is available
|
|
4
|
+
export async function checkClaudeAvailable() {
|
|
5
|
+
try {
|
|
6
|
+
execSync('which claude', { stdio: 'pipe' });
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// Check if git repo has uncommitted changes
|
|
14
|
+
export function checkGitDirty(projectPath) {
|
|
15
|
+
try {
|
|
16
|
+
// Check if it's a git repo
|
|
17
|
+
execSync('git rev-parse --git-dir', { cwd: projectPath, stdio: 'pipe' });
|
|
18
|
+
// Get status of changed files
|
|
19
|
+
const status = execSync('git status --porcelain', { cwd: projectPath, stdio: 'pipe' }).toString();
|
|
20
|
+
const changedFiles = status
|
|
21
|
+
.split('\n')
|
|
22
|
+
.filter(line => line.trim())
|
|
23
|
+
.map(line => line.slice(3).trim());
|
|
24
|
+
return {
|
|
25
|
+
isDirty: changedFiles.length > 0,
|
|
26
|
+
changedFiles,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Not a git repo or git not available - allow changes
|
|
31
|
+
return { isDirty: false, changedFiles: [] };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Parse file changes from Claude output
|
|
35
|
+
function parseFilesChanged(output) {
|
|
36
|
+
const files = [];
|
|
37
|
+
// Look for common patterns in Claude's output indicating file changes
|
|
38
|
+
// Pattern: "Modified: path/to/file" or "Updated: path/to/file" or "Created: path/to/file"
|
|
39
|
+
const modifiedPattern = /(?:Modified|Updated|Created|Edited|Changed|Wrote to|Writing to):\s*[`"]?([^\s`"]+)[`"]?/gi;
|
|
40
|
+
let match;
|
|
41
|
+
while ((match = modifiedPattern.exec(output)) !== null) {
|
|
42
|
+
const file = match[1].trim();
|
|
43
|
+
if (file && !files.includes(file)) {
|
|
44
|
+
files.push(file);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Also look for file paths in backticks that look like they were edited
|
|
48
|
+
const backtickPattern = /`([^`]+\.(tsx?|jsx?|mdx?|html?|css|json|yml|yaml))`/gi;
|
|
49
|
+
while ((match = backtickPattern.exec(output)) !== null) {
|
|
50
|
+
const file = match[1].trim();
|
|
51
|
+
if (file && !files.includes(file) && !file.includes(' ')) {
|
|
52
|
+
files.push(file);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
57
|
+
// Detect current phase from output
|
|
58
|
+
function detectPhase(output) {
|
|
59
|
+
const lowerOutput = output.toLowerCase();
|
|
60
|
+
if (lowerOutput.includes('complete') || lowerOutput.includes('done') || lowerOutput.includes('finished')) {
|
|
61
|
+
return 'complete';
|
|
62
|
+
}
|
|
63
|
+
if (lowerOutput.includes('editing') ||
|
|
64
|
+
lowerOutput.includes('writing') ||
|
|
65
|
+
lowerOutput.includes('updating') ||
|
|
66
|
+
lowerOutput.includes('modifying') ||
|
|
67
|
+
lowerOutput.includes('creating')) {
|
|
68
|
+
return 'editing';
|
|
69
|
+
}
|
|
70
|
+
return 'thinking';
|
|
71
|
+
}
|
|
72
|
+
export async function spawnClaudeJob(job, callbacks) {
|
|
73
|
+
const prompt = buildPrompt(job);
|
|
74
|
+
const claudePath = job.claudePath || 'claude';
|
|
75
|
+
job.status = 'running';
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
// Spawn claude CLI with the prompt via stdin
|
|
78
|
+
// Using -p for print mode and --dangerously-skip-permissions to avoid prompts
|
|
79
|
+
const proc = spawn(claudePath, [
|
|
80
|
+
'-p',
|
|
81
|
+
'--dangerously-skip-permissions',
|
|
82
|
+
], {
|
|
83
|
+
cwd: job.projectPath,
|
|
84
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
85
|
+
env: {
|
|
86
|
+
...process.env,
|
|
87
|
+
// Ensure we get clean output
|
|
88
|
+
FORCE_COLOR: '0',
|
|
89
|
+
NO_COLOR: '1',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
job.process = proc;
|
|
93
|
+
// Send prompt via stdin
|
|
94
|
+
proc.stdin?.write(prompt);
|
|
95
|
+
proc.stdin?.end();
|
|
96
|
+
let fullOutput = '';
|
|
97
|
+
let currentPhase = 'thinking';
|
|
98
|
+
const handleOutput = (data) => {
|
|
99
|
+
const text = data.toString();
|
|
100
|
+
fullOutput += text;
|
|
101
|
+
const newPhase = detectPhase(text);
|
|
102
|
+
if (newPhase !== currentPhase) {
|
|
103
|
+
currentPhase = newPhase;
|
|
104
|
+
}
|
|
105
|
+
callbacks.onProgress(text, currentPhase);
|
|
106
|
+
};
|
|
107
|
+
proc.stdout?.on('data', handleOutput);
|
|
108
|
+
proc.stderr?.on('data', handleOutput);
|
|
109
|
+
proc.on('error', (err) => {
|
|
110
|
+
job.status = 'error';
|
|
111
|
+
callbacks.onComplete(false, [], err.message);
|
|
112
|
+
reject(err);
|
|
113
|
+
});
|
|
114
|
+
proc.on('close', (code) => {
|
|
115
|
+
const filesChanged = parseFilesChanged(fullOutput);
|
|
116
|
+
if (code === 0) {
|
|
117
|
+
job.status = 'complete';
|
|
118
|
+
job.filesChanged = filesChanged;
|
|
119
|
+
callbacks.onComplete(true, filesChanged);
|
|
120
|
+
resolve();
|
|
121
|
+
}
|
|
122
|
+
else if (job.status === 'cancelled') {
|
|
123
|
+
callbacks.onComplete(false, [], 'Job cancelled');
|
|
124
|
+
resolve();
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
job.status = 'error';
|
|
128
|
+
callbacks.onComplete(false, filesChanged, `Claude exited with code ${code}`);
|
|
129
|
+
resolve();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
export function cancelJob(job) {
|
|
135
|
+
if (job.process && job.status === 'running') {
|
|
136
|
+
job.status = 'cancelled';
|
|
137
|
+
job.process.kill('SIGTERM');
|
|
138
|
+
// Force kill after 5 seconds if still running
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
if (job.process && !job.process.killed) {
|
|
141
|
+
job.process.kill('SIGKILL');
|
|
142
|
+
}
|
|
143
|
+
}, 5000);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
|
package/dist/editor.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAsC7C,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,EACb,UAAU,GAAE,UAAmB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA0Cf"}
|
package/dist/editor.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
const execAsync = promisify(exec);
|
|
5
|
+
// Check if an editor command is available
|
|
6
|
+
async function isEditorAvailable(command) {
|
|
7
|
+
try {
|
|
8
|
+
await execAsync(`which ${command}`);
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// Detect available editor
|
|
16
|
+
async function detectEditor() {
|
|
17
|
+
// Check for Cursor first (preferred)
|
|
18
|
+
if (await isEditorAvailable('cursor')) {
|
|
19
|
+
return 'cursor';
|
|
20
|
+
}
|
|
21
|
+
// Check for VS Code
|
|
22
|
+
if (await isEditorAvailable('code')) {
|
|
23
|
+
return 'code';
|
|
24
|
+
}
|
|
25
|
+
// Check for common macOS editor locations
|
|
26
|
+
const cursorMacPath = '/Applications/Cursor.app/Contents/Resources/app/bin/cursor';
|
|
27
|
+
if (existsSync(cursorMacPath)) {
|
|
28
|
+
return cursorMacPath;
|
|
29
|
+
}
|
|
30
|
+
const codeMacPath = '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code';
|
|
31
|
+
if (existsSync(codeMacPath)) {
|
|
32
|
+
return codeMacPath;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
export async function openInEditor(projectPath, file, editorType = 'auto') {
|
|
37
|
+
let editorCommand = null;
|
|
38
|
+
if (editorType === 'auto') {
|
|
39
|
+
editorCommand = await detectEditor();
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
editorCommand = editorType;
|
|
43
|
+
// Verify the specified editor is available
|
|
44
|
+
if (!(await isEditorAvailable(editorCommand))) {
|
|
45
|
+
throw new Error(`Editor '${editorCommand}' is not available`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (!editorCommand) {
|
|
49
|
+
throw new Error('No editor found. Please install Cursor or VS Code.');
|
|
50
|
+
}
|
|
51
|
+
// Build the path to open
|
|
52
|
+
const targetPath = file ? `${projectPath}/${file}` : projectPath;
|
|
53
|
+
// Verify the path exists
|
|
54
|
+
if (!existsSync(targetPath)) {
|
|
55
|
+
throw new Error(`Path does not exist: ${targetPath}`);
|
|
56
|
+
}
|
|
57
|
+
console.log(`Opening ${targetPath} in ${editorCommand}`);
|
|
58
|
+
// Open the editor
|
|
59
|
+
// Use -r to reuse existing window, -g to not focus the editor
|
|
60
|
+
const args = ['-r', targetPath];
|
|
61
|
+
try {
|
|
62
|
+
await execAsync(`"${editorCommand}" ${args.join(' ')}`);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
// Editor might return non-zero even on success (e.g., if already open)
|
|
66
|
+
// So we only throw if it's a clear failure
|
|
67
|
+
const error = err;
|
|
68
|
+
if (error.message?.includes('command not found')) {
|
|
69
|
+
throw new Error(`Editor '${editorCommand}' is not available`);
|
|
70
|
+
}
|
|
71
|
+
// Otherwise, assume success
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAIlC,0CAA0C;AAC1C,KAAK,UAAU,iBAAiB,CAAC,OAAe;IAC9C,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,0BAA0B;AAC1B,KAAK,UAAU,YAAY;IACzB,qCAAqC;IACrC,IAAI,MAAM,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,IAAI,MAAM,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,0CAA0C;IAC1C,MAAM,aAAa,GAAG,4DAA4D,CAAC;IACnF,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,WAAW,GAAG,sEAAsE,CAAC;IAC3F,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,IAAa,EACb,aAAyB,MAAM;IAE/B,IAAI,aAAa,GAAkB,IAAI,CAAC;IAExC,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,aAAa,GAAG,MAAM,YAAY,EAAE,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,UAAU,CAAC;QAC3B,2CAA2C;QAC3C,IAAI,CAAC,CAAC,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,WAAW,aAAa,oBAAoB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,yBAAyB;IACzB,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAEjE,yBAAyB;IACzB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,OAAO,aAAa,EAAE,CAAC,CAAC;IAEzD,kBAAkB;IAClB,8DAA8D;IAC9D,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,IAAI,aAAa,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uEAAuE;QACvE,2CAA2C;QAC3C,MAAM,KAAK,GAAG,GAA2B,CAAC;QAC1C,IAAI,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,WAAW,aAAa,oBAAoB,CAAC,CAAC;QAChE,CAAC;QACD,4BAA4B;IAC9B,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { startServer } from './server.js';
|
|
4
|
+
import { checkClaudeAvailable } from './claude.js';
|
|
5
|
+
const program = new Command();
|
|
6
|
+
async function start(port) {
|
|
7
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
8
|
+
console.error('Invalid port number');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
// Check if Claude CLI is available
|
|
12
|
+
const claudeAvailable = await checkClaudeAvailable();
|
|
13
|
+
if (!claudeAvailable) {
|
|
14
|
+
console.warn('Warning: Claude CLI not found in PATH');
|
|
15
|
+
console.warn('Install it with: npm install -g @anthropic-ai/claude-code');
|
|
16
|
+
console.warn('The server will start but edit jobs will fail.');
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log('Claude CLI: available');
|
|
20
|
+
}
|
|
21
|
+
// Start the server
|
|
22
|
+
const server = startServer(port);
|
|
23
|
+
// Handle graceful shutdown
|
|
24
|
+
const shutdown = () => {
|
|
25
|
+
console.log('\nShutting down...');
|
|
26
|
+
server.close(() => {
|
|
27
|
+
console.log('Server closed');
|
|
28
|
+
process.exit(0);
|
|
29
|
+
});
|
|
30
|
+
// Force exit after 5 seconds
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
console.log('Forcing exit');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}, 5000);
|
|
35
|
+
};
|
|
36
|
+
process.on('SIGINT', shutdown);
|
|
37
|
+
process.on('SIGTERM', shutdown);
|
|
38
|
+
}
|
|
39
|
+
program
|
|
40
|
+
.name('jammincms')
|
|
41
|
+
.description('Local bridge server for Jammin CMS Chrome extension')
|
|
42
|
+
.version('1.0.0')
|
|
43
|
+
.option('-p, --port <port>', 'Port to listen on', '9876')
|
|
44
|
+
.action(async (options) => {
|
|
45
|
+
const port = parseInt(options.port, 10);
|
|
46
|
+
await start(port);
|
|
47
|
+
});
|
|
48
|
+
program
|
|
49
|
+
.command('status')
|
|
50
|
+
.description('Check if the bridge server is running')
|
|
51
|
+
.option('-p, --port <port>', 'Port to check', '9876')
|
|
52
|
+
.action(async (options) => {
|
|
53
|
+
const port = parseInt(options.port, 10);
|
|
54
|
+
const WebSocket = (await import('ws')).default;
|
|
55
|
+
const ws = new WebSocket(`ws://localhost:${port}`);
|
|
56
|
+
const timeout = setTimeout(() => {
|
|
57
|
+
console.log('Bridge server: not running');
|
|
58
|
+
ws.close();
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}, 2000);
|
|
61
|
+
ws.on('open', () => {
|
|
62
|
+
ws.send(JSON.stringify({ type: 'ping' }));
|
|
63
|
+
});
|
|
64
|
+
ws.on('message', (data) => {
|
|
65
|
+
clearTimeout(timeout);
|
|
66
|
+
try {
|
|
67
|
+
const response = JSON.parse(data.toString());
|
|
68
|
+
if (response.type === 'pong') {
|
|
69
|
+
console.log(`Bridge server: running (v${response.version})`);
|
|
70
|
+
console.log(`Claude CLI: ${response.claudeAvailable ? 'available' : 'not found'}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
console.log('Bridge server: running (invalid response)');
|
|
75
|
+
}
|
|
76
|
+
ws.close();
|
|
77
|
+
process.exit(0);
|
|
78
|
+
});
|
|
79
|
+
ws.on('error', () => {
|
|
80
|
+
clearTimeout(timeout);
|
|
81
|
+
console.log('Bridge server: not running');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
program.parse();
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAc,MAAM,YAAY,CAAC;AAkBlD,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAiC5C"}
|
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function formatChange(change, index) {
|
|
2
|
+
return `### Change ${index + 1}
|
|
3
|
+
**Location**: ${change.elementPath}
|
|
4
|
+
**Selector**: ${change.selector}
|
|
5
|
+
|
|
6
|
+
**Original content:**
|
|
7
|
+
\`\`\`html
|
|
8
|
+
${change.originalContent}
|
|
9
|
+
\`\`\`
|
|
10
|
+
|
|
11
|
+
**New content (user edited):**
|
|
12
|
+
\`\`\`html
|
|
13
|
+
${change.newContent}
|
|
14
|
+
\`\`\``;
|
|
15
|
+
}
|
|
16
|
+
export function buildPrompt(job) {
|
|
17
|
+
const { siteUrl, changes, customInstructions } = job;
|
|
18
|
+
const changesSection = changes
|
|
19
|
+
.map((change, index) => formatChange(change, index))
|
|
20
|
+
.join('\n\n');
|
|
21
|
+
const instructionsSection = customInstructions
|
|
22
|
+
? `## Site-Specific Instructions
|
|
23
|
+
${customInstructions}
|
|
24
|
+
|
|
25
|
+
`
|
|
26
|
+
: '';
|
|
27
|
+
return `# Website Content Update Request
|
|
28
|
+
|
|
29
|
+
The user has made inline edits to their website at: ${siteUrl}
|
|
30
|
+
|
|
31
|
+
${instructionsSection}## Changes Made
|
|
32
|
+
|
|
33
|
+
${changesSection}
|
|
34
|
+
|
|
35
|
+
## Instructions
|
|
36
|
+
1. Find the source files that generate this content
|
|
37
|
+
2. Update the content to match the user's edits
|
|
38
|
+
3. Preserve all existing formatting, structure, and code
|
|
39
|
+
4. Briefly summarize what files were modified
|
|
40
|
+
|
|
41
|
+
Important:
|
|
42
|
+
- The content may come from markdown files, React components, or other templates
|
|
43
|
+
- Match the existing code style and patterns
|
|
44
|
+
- Only change the specific content that was edited
|
|
45
|
+
- Do not add comments or explanations to the code`;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAEA,SAAS,YAAY,CAAC,MAAkB,EAAE,KAAa;IACrD,OAAO,cAAc,KAAK,GAAG,CAAC;gBAChB,MAAM,CAAC,WAAW;gBAClB,MAAM,CAAC,QAAQ;;;;EAI7B,MAAM,CAAC,eAAe;;;;;EAKtB,MAAM,CAAC,UAAU;OACZ,CAAC;AACR,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAQ;IAClC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,GAAG,CAAC;IAErD,MAAM,cAAc,GAAG,OAAO;SAC3B,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;SACnD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,MAAM,mBAAmB,GAAG,kBAAkB;QAC5C,CAAC,CAAC;EACJ,kBAAkB;;CAEnB;QACG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;sDAE6C,OAAO;;EAE3D,mBAAmB;;EAEnB,cAAc;;;;;;;;;;;;kDAYkC,CAAC;AACnD,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
2
|
+
import type { BridgeMessage, Job } from './types.js';
|
|
3
|
+
export declare function broadcast(message: BridgeMessage): void;
|
|
4
|
+
export declare function sendToClient(client: WebSocket, message: BridgeMessage): void;
|
|
5
|
+
export declare function startServer(port?: number): WebSocketServer;
|
|
6
|
+
export declare function getJobs(): Map<string, Job>;
|
|
7
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAEV,aAAa,EAIb,GAAG,EACJ,MAAM,YAAY,CAAC;AAapB,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAOtD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAI5E;AAwKD,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAqB,GAAG,eAAe,CAwCxE;AAED,wBAAgB,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAE1C"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
2
|
+
import { spawnClaudeJob, cancelJob, checkClaudeAvailable, checkGitDirty } from './claude.js';
|
|
3
|
+
import { openInEditor } from './editor.js';
|
|
4
|
+
const VERSION = '1.0.0';
|
|
5
|
+
const DEFAULT_PORT = 9876;
|
|
6
|
+
// Active jobs tracked by job ID
|
|
7
|
+
const jobs = new Map();
|
|
8
|
+
// Connected clients
|
|
9
|
+
const clients = new Set();
|
|
10
|
+
export function broadcast(message) {
|
|
11
|
+
const data = JSON.stringify(message);
|
|
12
|
+
for (const client of clients) {
|
|
13
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
14
|
+
client.send(data);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function sendToClient(client, message) {
|
|
19
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
20
|
+
client.send(JSON.stringify(message));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function handleMessage(client, message) {
|
|
24
|
+
switch (message.type) {
|
|
25
|
+
case 'ping': {
|
|
26
|
+
const claudeAvailable = await checkClaudeAvailable();
|
|
27
|
+
sendToClient(client, {
|
|
28
|
+
type: 'pong',
|
|
29
|
+
version: VERSION,
|
|
30
|
+
claudeAvailable,
|
|
31
|
+
});
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'submit_edit': {
|
|
35
|
+
await handleSubmitEdit(client, message);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'cancel_job': {
|
|
39
|
+
handleCancelJob(client, message);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'open_editor': {
|
|
43
|
+
await handleOpenEditor(client, message);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
default: {
|
|
47
|
+
sendToClient(client, {
|
|
48
|
+
type: 'error',
|
|
49
|
+
message: `Unknown message type: ${message.type}`,
|
|
50
|
+
code: 'UNKNOWN_MESSAGE_TYPE',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function handleSubmitEdit(client, message) {
|
|
56
|
+
const { jobId, projectPath, siteUrl, changes, customInstructions, claudePath, skipGitCheck } = message;
|
|
57
|
+
// Check if job already exists
|
|
58
|
+
if (jobs.has(jobId)) {
|
|
59
|
+
sendToClient(client, {
|
|
60
|
+
type: 'error',
|
|
61
|
+
message: `Job ${jobId} already exists`,
|
|
62
|
+
code: 'JOB_EXISTS',
|
|
63
|
+
});
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Check for uncommitted git changes (unless skipped)
|
|
67
|
+
if (!skipGitCheck) {
|
|
68
|
+
const gitStatus = checkGitDirty(projectPath);
|
|
69
|
+
if (gitStatus.isDirty) {
|
|
70
|
+
sendToClient(client, {
|
|
71
|
+
type: 'git_dirty',
|
|
72
|
+
jobId,
|
|
73
|
+
changedFiles: gitStatus.changedFiles,
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Create job
|
|
79
|
+
const job = {
|
|
80
|
+
id: jobId,
|
|
81
|
+
projectPath,
|
|
82
|
+
siteUrl,
|
|
83
|
+
changes,
|
|
84
|
+
customInstructions,
|
|
85
|
+
claudePath,
|
|
86
|
+
status: 'pending',
|
|
87
|
+
output: '',
|
|
88
|
+
filesChanged: [],
|
|
89
|
+
};
|
|
90
|
+
jobs.set(jobId, job);
|
|
91
|
+
// Acknowledge job
|
|
92
|
+
sendToClient(client, {
|
|
93
|
+
type: 'job_accepted',
|
|
94
|
+
jobId,
|
|
95
|
+
});
|
|
96
|
+
// Spawn Claude process
|
|
97
|
+
try {
|
|
98
|
+
await spawnClaudeJob(job, {
|
|
99
|
+
onProgress: (output, phase) => {
|
|
100
|
+
job.output += output;
|
|
101
|
+
broadcast({
|
|
102
|
+
type: 'job_progress',
|
|
103
|
+
jobId,
|
|
104
|
+
output,
|
|
105
|
+
phase,
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
onComplete: (success, filesChanged, error) => {
|
|
109
|
+
job.status = success ? 'complete' : 'error';
|
|
110
|
+
job.filesChanged = filesChanged || [];
|
|
111
|
+
broadcast({
|
|
112
|
+
type: 'job_complete',
|
|
113
|
+
jobId,
|
|
114
|
+
success,
|
|
115
|
+
filesChanged,
|
|
116
|
+
error,
|
|
117
|
+
});
|
|
118
|
+
// Clean up job after some time
|
|
119
|
+
setTimeout(() => jobs.delete(jobId), 60000);
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
job.status = 'error';
|
|
125
|
+
sendToClient(client, {
|
|
126
|
+
type: 'job_complete',
|
|
127
|
+
jobId,
|
|
128
|
+
success: false,
|
|
129
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function handleCancelJob(client, message) {
|
|
134
|
+
const { jobId } = message;
|
|
135
|
+
const job = jobs.get(jobId);
|
|
136
|
+
if (!job) {
|
|
137
|
+
sendToClient(client, {
|
|
138
|
+
type: 'error',
|
|
139
|
+
message: `Job ${jobId} not found`,
|
|
140
|
+
code: 'JOB_NOT_FOUND',
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
cancelJob(job);
|
|
145
|
+
job.status = 'cancelled';
|
|
146
|
+
broadcast({
|
|
147
|
+
type: 'job_cancelled',
|
|
148
|
+
jobId,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async function handleOpenEditor(client, message) {
|
|
152
|
+
const { projectPath, file } = message;
|
|
153
|
+
try {
|
|
154
|
+
await openInEditor(projectPath, file);
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
sendToClient(client, {
|
|
158
|
+
type: 'error',
|
|
159
|
+
message: err instanceof Error ? err.message : 'Failed to open editor',
|
|
160
|
+
code: 'EDITOR_ERROR',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export function startServer(port = DEFAULT_PORT) {
|
|
165
|
+
const wss = new WebSocketServer({ port });
|
|
166
|
+
console.log(`Jammin CMS Bridge v${VERSION}`);
|
|
167
|
+
console.log(`WebSocket server listening on ws://localhost:${port}`);
|
|
168
|
+
wss.on('connection', (ws) => {
|
|
169
|
+
console.log('Client connected');
|
|
170
|
+
clients.add(ws);
|
|
171
|
+
ws.on('message', async (data) => {
|
|
172
|
+
try {
|
|
173
|
+
const message = JSON.parse(data.toString());
|
|
174
|
+
await handleMessage(ws, message);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
console.error('Error handling message:', err);
|
|
178
|
+
sendToClient(ws, {
|
|
179
|
+
type: 'error',
|
|
180
|
+
message: err instanceof Error ? err.message : 'Invalid message',
|
|
181
|
+
code: 'INVALID_MESSAGE',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
ws.on('close', () => {
|
|
186
|
+
console.log('Client disconnected');
|
|
187
|
+
clients.delete(ws);
|
|
188
|
+
});
|
|
189
|
+
ws.on('error', (err) => {
|
|
190
|
+
console.error('WebSocket error:', err);
|
|
191
|
+
clients.delete(ws);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
wss.on('error', (err) => {
|
|
195
|
+
console.error('Server error:', err);
|
|
196
|
+
});
|
|
197
|
+
return wss;
|
|
198
|
+
}
|
|
199
|
+
export function getJobs() {
|
|
200
|
+
return jobs;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface PingMessage {
|
|
2
|
+
type: 'ping';
|
|
3
|
+
}
|
|
4
|
+
export interface SubmitEditMessage {
|
|
5
|
+
type: 'submit_edit';
|
|
6
|
+
jobId: string;
|
|
7
|
+
projectPath: string;
|
|
8
|
+
siteUrl: string;
|
|
9
|
+
changes: EditChange[];
|
|
10
|
+
customInstructions?: string;
|
|
11
|
+
claudePath?: string;
|
|
12
|
+
skipGitCheck?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface CancelJobMessage {
|
|
15
|
+
type: 'cancel_job';
|
|
16
|
+
jobId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface OpenEditorMessage {
|
|
19
|
+
type: 'open_editor';
|
|
20
|
+
projectPath: string;
|
|
21
|
+
file?: string;
|
|
22
|
+
}
|
|
23
|
+
export type ExtensionMessage = PingMessage | SubmitEditMessage | CancelJobMessage | OpenEditorMessage;
|
|
24
|
+
export interface PongMessage {
|
|
25
|
+
type: 'pong';
|
|
26
|
+
version: string;
|
|
27
|
+
claudeAvailable: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface JobAcceptedMessage {
|
|
30
|
+
type: 'job_accepted';
|
|
31
|
+
jobId: string;
|
|
32
|
+
}
|
|
33
|
+
export interface JobProgressMessage {
|
|
34
|
+
type: 'job_progress';
|
|
35
|
+
jobId: string;
|
|
36
|
+
output: string;
|
|
37
|
+
phase: 'thinking' | 'editing' | 'complete';
|
|
38
|
+
}
|
|
39
|
+
export interface JobCompleteMessage {
|
|
40
|
+
type: 'job_complete';
|
|
41
|
+
jobId: string;
|
|
42
|
+
success: boolean;
|
|
43
|
+
filesChanged?: string[];
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface JobCancelledMessage {
|
|
47
|
+
type: 'job_cancelled';
|
|
48
|
+
jobId: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ErrorMessage {
|
|
51
|
+
type: 'error';
|
|
52
|
+
message: string;
|
|
53
|
+
code: string;
|
|
54
|
+
}
|
|
55
|
+
export interface GitDirtyMessage {
|
|
56
|
+
type: 'git_dirty';
|
|
57
|
+
jobId: string;
|
|
58
|
+
changedFiles: string[];
|
|
59
|
+
}
|
|
60
|
+
export type BridgeMessage = PongMessage | JobAcceptedMessage | JobProgressMessage | JobCompleteMessage | JobCancelledMessage | ErrorMessage | GitDirtyMessage;
|
|
61
|
+
export interface EditChange {
|
|
62
|
+
elementPath: string;
|
|
63
|
+
selector: string;
|
|
64
|
+
originalContent: string;
|
|
65
|
+
newContent: string;
|
|
66
|
+
}
|
|
67
|
+
export interface Job {
|
|
68
|
+
id: string;
|
|
69
|
+
projectPath: string;
|
|
70
|
+
siteUrl: string;
|
|
71
|
+
changes: EditChange[];
|
|
72
|
+
customInstructions?: string;
|
|
73
|
+
claudePath?: string;
|
|
74
|
+
status: 'pending' | 'running' | 'complete' | 'cancelled' | 'error';
|
|
75
|
+
process?: import('child_process').ChildProcess;
|
|
76
|
+
output: string;
|
|
77
|
+
filesChanged: string[];
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,CAAC;AAGtB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,GACnB,YAAY,GACZ,eAAe,CAAC;AAGpB,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IACnE,OAAO,CAAC,EAAE,OAAO,eAAe,EAAE,YAAY,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jammincms",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local bridge server for Jammin CMS Chrome extension - connects to Claude Code CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"jammincms": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"cms",
|
|
22
|
+
"claude",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"inline-editing",
|
|
25
|
+
"chrome-extension",
|
|
26
|
+
"ai"
|
|
27
|
+
],
|
|
28
|
+
"author": "",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"commander": "^12.1.0",
|
|
32
|
+
"ws": "^8.18.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^22.10.0",
|
|
36
|
+
"@types/ws": "^8.5.13",
|
|
37
|
+
"typescript": "^5.7.2"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|