@gettrace/cli 2.0.6 → 2.0.8

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.
@@ -34,8 +34,10 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
34
34
 
35
35
  // The extension IDs that are allowed to use this native host.
36
36
  const ALLOWED_EXTENSION_IDS = [
37
- // Development / unpacked extension ID
37
+ // Development / unpacked extension ID (macOS)
38
38
  'jefgjgdcelekglimbmgplkaaabdfpgfm',
39
+ // Development / unpacked extension ID (Windows)
40
+ 'fppbikhdjehmiidhjholkiaeeieoilfb',
39
41
  // Add the published CWS extension ID here when you have it:
40
42
  // 'PRODUCTION_EXTENSION_ID',
41
43
  ];
@@ -49,11 +51,18 @@ if (process.env.TRACE_EXTENSION_IDS) {
49
51
 
50
52
  const HOST_NAME = 'dev.gettrace.host';
51
53
 
52
- // Install native host files into ~/.local/share/trace/native-host/ so that
53
- // Chrome (and other browsers) can always read them. Files on ~/Desktop,
54
- // ~/Documents, ~/Downloads require explicit macOS TCC (Privacy) permission
55
- // which Chrome does not have by default. ~/.local/share/ is always accessible.
56
- const INSTALL_DIR = join(homedir(), '.local', 'share', 'trace', 'native-host');
54
+ // Install native host files into platform-specific directories
55
+ // macOS/Linux: ~/.local/share/trace/native-host/ (no TCC permission issues)
56
+ // Windows: %LOCALAPPDATA%\trace\native-host\ (standard Windows app data location)
57
+ function getInstallDir() {
58
+ if (platform() === 'win32') {
59
+ const localAppData = process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local');
60
+ return join(localAppData, 'trace', 'native-host');
61
+ }
62
+ return join(homedir(), '.local', 'share', 'trace', 'native-host');
63
+ }
64
+
65
+ const INSTALL_DIR = getInstallDir();
57
66
  const HOST_ENTRY = join(INSTALL_DIR, 'host-entry');
58
67
  const HOST_CJS_DEST = join(INSTALL_DIR, 'host.cjs');
59
68
 
@@ -96,6 +105,84 @@ function generateHostEntry() {
96
105
  writeFileSync(join(INSTALL_DIR, 'package.json'), readFileSync(pkgSrc), { mode: 0o644 });
97
106
  }
98
107
 
108
+ // On Windows, create a .bat launcher that Chrome can execute
109
+ if (platform() === 'win32') {
110
+ generateWindowsHostEntry(nodePath, tracePath);
111
+ } else {
112
+ generateUnixHostEntry(nodePath, tracePath);
113
+ }
114
+ }
115
+
116
+ function generateWindowsHostEntry(nodePath, tracePath) {
117
+ const HOST_BAT = join(INSTALL_DIR, 'host-entry.bat');
118
+ const HOST_JS = join(INSTALL_DIR, 'host-entry.js');
119
+
120
+ // Create the JavaScript loader file
121
+ const jsContent = [
122
+ `// Auto-generated by @gettrace/cli postinstall — do not edit manually`,
123
+ `// Generated: ${new Date().toISOString()}`,
124
+ `// Node: ${nodePath}`,
125
+ tracePath ? `// Trace: ${tracePath}` : `// Trace: (resolves from PATH)`,
126
+ `'use strict';`,
127
+ ``,
128
+ `// Fix PATH before anything else — Chrome launches with a minimal environment`,
129
+ tracePath
130
+ ? `process.env.PATH = '${dirname(tracePath).replace(/\\/g, '\\\\')};${dirname(nodePath).replace(/\\/g, '\\\\')};' + (process.env.PATH || 'C:\\\\Windows\\\\System32');`
131
+ : `process.env.PATH = '${dirname(nodePath).replace(/\\/g, '\\\\')};;' + (process.env.PATH || 'C:\\\\Windows\\\\System32');`,
132
+ ``,
133
+ ...(() => {
134
+ const monorepoAgent = resolve(
135
+ __dirname, '..', '..', 'packages', 'trace-agent', 'dist', 'node', 'index.js'
136
+ );
137
+ const localCli = resolve(__dirname, '..', 'dist', 'index.js');
138
+ if (existsSync(monorepoAgent) && existsSync(localCli)) {
139
+ return [
140
+ `// Dev mode: use local CLI build instead of the global npm package`,
141
+ `process.env.TRACE_DEV_MODE = '1';`,
142
+ `process.env.TRACE_CLI_PATH = '${localCli.replace(/\\/g, '\\\\')}';`,
143
+ ``,
144
+ ];
145
+ }
146
+ return [];
147
+ })(),
148
+ `// Diagnostic logging — written synchronously so we catch crashes before async`,
149
+ `const fs = require('fs');`,
150
+ `const path = require('path');`,
151
+ `const logPath = path.join('${homedir().replace(/\\/g, '\\\\')}', 'trace-native-host.log');`,
152
+ `function log(msg) {`,
153
+ ` const line = new Date().toISOString() + ' ' + msg + '\\n';`,
154
+ ` try { fs.appendFileSync(logPath, line); } catch(_) {}`,
155
+ `}`,
156
+ ``,
157
+ `log('[host-entry] started, node=' + process.version + ' pid=' + process.pid);`,
158
+ ``,
159
+ `try {`,
160
+ ` require('${HOST_CJS_DEST.replace(/\\/g, '\\\\')}');`,
161
+ ` log('[host-entry] host.cjs loaded OK');`,
162
+ `} catch (err) {`,
163
+ ` log('[host-entry] FATAL: ' + (err.stack || err));`,
164
+ ` process.exit(1);`,
165
+ `}`,
166
+ ].join('\n');
167
+
168
+ writeFileSync(HOST_JS, jsContent, { encoding: 'utf8' });
169
+
170
+ // Create the .bat launcher that Chrome will execute
171
+ const batContent = [
172
+ `@echo off`,
173
+ `REM Auto-generated by @gettrace/cli postinstall`,
174
+ `REM Node: ${nodePath}`,
175
+ `"${nodePath}" "${HOST_JS}" %*`,
176
+ ].join('\r\n');
177
+
178
+ writeFileSync(HOST_BAT, batContent, { encoding: 'utf8' });
179
+
180
+ console.log(`✓ Generated Windows native host: ${HOST_BAT}`);
181
+ console.log(` Node binary: ${nodePath}`);
182
+ if (tracePath) console.log(` Trace binary: ${tracePath}`);
183
+ }
184
+
185
+ function generateUnixHostEntry(nodePath, tracePath) {
99
186
  // Log paths — write to home dir only (always writable by Chrome)
100
187
  const logPath1 = `${homedir()}/trace-native-host.log`;
101
188
 
@@ -112,16 +199,6 @@ function generateHostEntry() {
112
199
  ? `process.env.PATH = '${dirname(tracePath)}:${dirname(nodePath)}:' + (process.env.PATH || '/usr/bin:/bin');`
113
200
  : `process.env.PATH = '${dirname(nodePath)}:/opt/homebrew/bin:/usr/local/bin:' + (process.env.PATH || '/usr/bin:/bin');`,
114
201
  ``,
115
- // Inject dev mode env vars ONLY when running from the trace monorepo
116
- // (the dev workflow). Detect that by the presence of the local agent
117
- // build that dev-mode resolution actually targets:
118
- // <repo>/packages/trace-agent/dist/node/index.js. In a published npm
119
- // install this path does not exist (the package lives under
120
- // node_modules/@gettrace/cli), so production NEVER enables dev mode.
121
- //
122
- // NOTE: do NOT key this off `<pkg>/dist/index.js` — the published CLI
123
- // ships that file too, which previously made every install spuriously
124
- // enable dev mode and fail to locate the agent.
125
202
  ...(() => {
126
203
  const monorepoAgent = resolve(
127
204
  __dirname, '..', '..', 'packages', 'trace-agent', 'dist', 'node', 'index.js'
@@ -179,10 +256,15 @@ function getNativeHostDir() {
179
256
  }
180
257
 
181
258
  function buildManifest() {
259
+ // On Windows, Chrome needs to execute a .bat file; Unix uses the shebang script
260
+ const executablePath = platform() === 'win32'
261
+ ? join(INSTALL_DIR, 'host-entry.bat')
262
+ : HOST_ENTRY;
263
+
182
264
  return JSON.stringify({
183
265
  name: HOST_NAME,
184
266
  description: 'Trace native host — spawns trace dev in the user\'s project directory',
185
- path: HOST_ENTRY, // Points to the generated entry file with hardcoded node path
267
+ path: executablePath,
186
268
  type: 'stdio',
187
269
  allowed_origins: ALLOWED_EXTENSION_IDS.map(id => `chrome-extension://${id}/`),
188
270
  }, null, 2);
@@ -190,15 +272,23 @@ function buildManifest() {
190
272
 
191
273
  function registerOnWindows() {
192
274
  const manifest = buildManifest();
193
- const manifestPath = join(homedir(), 'AppData', 'Local', 'Trace', `${HOST_NAME}.json`);
275
+ // Store manifest in the same directory as the host files for consistency
276
+ const manifestPath = join(INSTALL_DIR, `${HOST_NAME}.json`);
194
277
  mkdirSync(dirname(manifestPath), { recursive: true });
195
278
  writeFileSync(manifestPath, manifest, 'utf8');
279
+ console.log(`✓ Native host manifest: ${manifestPath}`);
280
+
196
281
  const regKey = `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${HOST_NAME}`;
197
282
  try {
198
- execSync(`reg add "${regKey}" /ve /t REG_SZ /d "${manifestPath}" /f`, { stdio: 'pipe' });
199
- console.log(`✓ Native host registered (Windows registry)`);
283
+ // Use double backslashes for Windows paths in registry
284
+ const manifestPathWin = manifestPath.replace(/\//g, '\\');
285
+ execSync(`reg add "${regKey}" /ve /t REG_SZ /d "${manifestPathWin}" /f`, { stdio: 'pipe' });
286
+ console.log(`✓ Native host registered in Windows registry`);
287
+ console.log(` Registry key: ${regKey}`);
288
+ console.log(` Manifest path: ${manifestPathWin}`);
200
289
  } catch (e) {
201
290
  console.warn('⚠ Could not register native host in Windows registry:', e.message);
291
+ console.warn(' Try running as Administrator or manually import the registry key');
202
292
  }
203
293
  }
204
294
 
package/dist/ast.d.ts DELETED
@@ -1,48 +0,0 @@
1
- export interface ClassNameEdit {
2
- /** Current className string to replace. Matched literally; partial match used as fallback. */
3
- oldValue?: string;
4
- /** New className string to write into the attribute. */
5
- newValue: string;
6
- /** Source line (1-indexed) from Fiber resolvedLine. Narrows the search strongly. */
7
- lineHint?: number;
8
- }
9
- export interface ASTEditResult {
10
- success: boolean;
11
- code?: string;
12
- error?: string;
13
- /** Which scoring strategy produced the winning match. */
14
- strategy?: 'line_exact' | 'line_proximity' | 'value_exact' | 'value_partial';
15
- /** Line number of the matched JSXOpeningElement. */
16
- matchedLine?: number;
17
- }
18
- export interface CSSRuleEdit {
19
- /** CSS selector to find (exact match). Appends new rule if not found. */
20
- selector: string;
21
- /** Properties to set. Existing properties are updated; new ones are appended. */
22
- properties: Record<string, string>;
23
- }
24
- /**
25
- * Parse JSX/TSX source and replace a className attribute value.
26
- *
27
- * Matching priority (higher score wins):
28
- * 1. Line-exact — node is within ±1 line of lineHint AND className contains oldValue (+100 line, +80 value)
29
- * 2. Line-nearby — node is within ±5 lines of lineHint (+50 line)
30
- * 3. Value-exact — className === oldValue (any line) (+80 value)
31
- * 4. Value-partial— className.includes(oldValue) (any line) (+40 value)
32
- * 5. Any — first className found (when no oldValue given) (+20)
33
- *
34
- * Returns { success: false } without modifying source if no match scores > 0.
35
- */
36
- export declare function editJSXClassName(source: string, edit: ClassNameEdit): ASTEditResult;
37
- /**
38
- * Edit CSS properties within a specific selector block.
39
- *
40
- * - If the selector exists: updates existing properties in-place, appends new ones.
41
- * - If the selector does not exist: appends a new rule at the end of the file.
42
- * - Leaves all properties not mentioned in `edit.properties` untouched.
43
- * - Strips any existing `!important` from injected values (clean code output).
44
- *
45
- * Uses a regex-based approach — a full CSS AST is overkill for targeted property
46
- * edits and would add another large dep.
47
- */
48
- export declare function editCSSRule(source: string, edit: CSSRuleEdit): ASTEditResult;
package/dist/ast.js DELETED
@@ -1,203 +0,0 @@
1
- // ============================================================
2
- // TRACE AST ENGINE
3
- // Precise, AST-based source code modification for JSX/TSX files.
4
- //
5
- // Complements fuzzyReplace (EDIT_FILE) with guaranteed-correct
6
- // structural edits that survive Prettier reformatting and
7
- // dynamic className expressions that string matching cannot handle.
8
- //
9
- // Two exported functions:
10
- // editJSXClassName — update a className attribute in JSX/TSX
11
- // editCSSRule — patch properties inside a CSS selector block
12
- //
13
- // Deps (runtime): @babel/parser, @babel/traverse, @babel/generator, @babel/types
14
- // Used by: EDIT_CLASSNAME handler in index.ts
15
- // ============================================================
16
- import { parse } from '@babel/parser';
17
- import { createRequire } from 'module';
18
- import * as t from '@babel/types';
19
- // @babel/traverse and @babel/generator ship CJS-only bundles.
20
- // Use createRequire so they work inside an ESM project (module:NodeNext).
21
- const _require = createRequire(import.meta.url);
22
- const _traverse = _require('@babel/traverse');
23
- const _generate = _require('@babel/generator');
24
- const traverse = (_traverse.default ?? _traverse);
25
- const generate = (_generate.default ?? _generate);
26
- // ── JSX className editing ─────────────────────────────────────────────────
27
- /**
28
- * Parse JSX/TSX source and replace a className attribute value.
29
- *
30
- * Matching priority (higher score wins):
31
- * 1. Line-exact — node is within ±1 line of lineHint AND className contains oldValue (+100 line, +80 value)
32
- * 2. Line-nearby — node is within ±5 lines of lineHint (+50 line)
33
- * 3. Value-exact — className === oldValue (any line) (+80 value)
34
- * 4. Value-partial— className.includes(oldValue) (any line) (+40 value)
35
- * 5. Any — first className found (when no oldValue given) (+20)
36
- *
37
- * Returns { success: false } without modifying source if no match scores > 0.
38
- */
39
- export function editJSXClassName(source, edit) {
40
- let ast;
41
- try {
42
- ast = parse(source, {
43
- sourceType: 'module',
44
- plugins: ['jsx', 'typescript'],
45
- errorRecovery: true, // tolerate minor syntax errors in source file
46
- });
47
- }
48
- catch (err) {
49
- const msg = err instanceof Error ? err.message : String(err);
50
- return { success: false, error: `Parse error: ${msg}` };
51
- }
52
- const candidates = [];
53
- traverse(ast, {
54
- JSXOpeningElement(nodePath) {
55
- for (const attr of nodePath.node.attributes) {
56
- if (!t.isJSXAttribute(attr))
57
- continue;
58
- if (!t.isJSXIdentifier(attr.name, { name: 'className' }))
59
- continue;
60
- const line = attr.loc?.start.line ?? 0;
61
- let score = 0;
62
- // ── Score by line proximity ──
63
- if (edit.lineHint && line > 0) {
64
- const dist = Math.abs(line - edit.lineHint);
65
- if (dist <= 1)
66
- score += 100;
67
- else if (dist <= 5)
68
- score += 50;
69
- else if (dist <= 15)
70
- score += 15;
71
- }
72
- // ── Score by value match ──
73
- const currentValue = _extractClassNameString(attr.value);
74
- if (edit.oldValue) {
75
- if (currentValue === edit.oldValue)
76
- score += 80;
77
- else if (currentValue?.includes(edit.oldValue))
78
- score += 40;
79
- // Dynamic expression (null) — can't verify value, give small score
80
- else if (currentValue === null && edit.lineHint)
81
- score += 20;
82
- }
83
- else {
84
- // No oldValue specified — any className is a candidate
85
- score += 20;
86
- }
87
- if (score > 0) {
88
- candidates.push({ nodePath, attrNode: attr, score, line });
89
- }
90
- }
91
- },
92
- });
93
- if (candidates.length === 0) {
94
- return { success: false, error: 'No className attribute found matching the given hints.' };
95
- }
96
- // Pick the highest-scoring candidate
97
- candidates.sort((a, b) => b.score - a.score);
98
- const best = candidates[0];
99
- // Classify strategy for caller transparency
100
- let strategy;
101
- if (best.score >= 180)
102
- strategy = 'line_exact';
103
- else if (best.score >= 100)
104
- strategy = 'line_proximity';
105
- else if (best.score >= 80)
106
- strategy = 'value_exact';
107
- else
108
- strategy = 'value_partial';
109
- // Apply the edit — replace with StringLiteral
110
- best.attrNode.value = t.stringLiteral(edit.newValue);
111
- // Generate source back. retainLines keeps line numbers stable so diffs
112
- // are minimal; jsescOption minimal avoids unnecessary unicode escaping.
113
- const output = generate(ast, { retainLines: true, jsescOption: { minimal: true } }, source);
114
- return {
115
- success: true,
116
- code: output.code,
117
- strategy,
118
- matchedLine: best.line,
119
- };
120
- }
121
- /**
122
- * Extract a plain string from a className JSXAttribute value.
123
- * Returns null for dynamic expressions (template literals with interpolations,
124
- * variables, function calls) — these cannot safely be string-replaced.
125
- */
126
- function _extractClassNameString(value) {
127
- if (!value)
128
- return '';
129
- if (t.isStringLiteral(value))
130
- return value.value;
131
- if (t.isJSXExpressionContainer(value)) {
132
- const expr = value.expression;
133
- if (t.isStringLiteral(expr))
134
- return expr.value;
135
- // Simple template literal with no expressions: `bg-red-500 p-4`
136
- if (t.isTemplateLiteral(expr) && expr.expressions.length === 0) {
137
- return expr.quasis[0]?.value.cooked ?? null;
138
- }
139
- }
140
- return null; // dynamic — caller should use EDIT_FILE fuzzy replacer instead
141
- }
142
- // ── CSS rule editing ──────────────────────────────────────────────────────
143
- /**
144
- * Edit CSS properties within a specific selector block.
145
- *
146
- * - If the selector exists: updates existing properties in-place, appends new ones.
147
- * - If the selector does not exist: appends a new rule at the end of the file.
148
- * - Leaves all properties not mentioned in `edit.properties` untouched.
149
- * - Strips any existing `!important` from injected values (clean code output).
150
- *
151
- * Uses a regex-based approach — a full CSS AST is overkill for targeted property
152
- * edits and would add another large dep.
153
- */
154
- export function editCSSRule(source, edit) {
155
- // Clean properties: strip !important (Trace injected them for browser specificity;
156
- // they don't belong in authored source files)
157
- const props = {};
158
- for (const [k, v] of Object.entries(edit.properties)) {
159
- props[k] = v.replace(/\s*!important\s*$/, '').trim();
160
- }
161
- // Escape selector for use in RegExp
162
- const escapedSel = edit.selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
163
- const ruleRegex = new RegExp(`(${escapedSel}\\s*\\{)([^}]*)(\\})`, 'ms');
164
- const match = ruleRegex.exec(source);
165
- if (!match) {
166
- // Selector not found — append new rule
167
- const newRule = _buildCSSRule(edit.selector, props);
168
- return {
169
- success: true,
170
- code: source.trimEnd() + '\n\n' + newRule + '\n',
171
- strategy: 'value_partial', // reuse field to signal "appended"
172
- };
173
- }
174
- const [full, open, body, close] = match;
175
- let patchedBody = body;
176
- for (const [prop, val] of Object.entries(props)) {
177
- // Match `prop:` with optional surrounding whitespace
178
- const propRegex = new RegExp(`([ \\t]*${prop.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*:\\s*)[^;\\n]+;?`, 'm');
179
- if (propRegex.test(patchedBody)) {
180
- patchedBody = patchedBody.replace(propRegex, `$1${val};`);
181
- }
182
- else {
183
- // Append missing property before closing brace
184
- const indent = _detectIndent(patchedBody);
185
- patchedBody = patchedBody.trimEnd() + `\n${indent}${prop}: ${val};`;
186
- }
187
- }
188
- return {
189
- success: true,
190
- code: source.replace(full, open + patchedBody + close),
191
- strategy: 'value_exact',
192
- };
193
- }
194
- function _buildCSSRule(selector, props) {
195
- const lines = Object.entries(props).map(([k, v]) => ` ${k}: ${v};`).join('\n');
196
- return `${selector} {\n${lines}\n}`;
197
- }
198
- function _detectIndent(body) {
199
- // Detect the indentation used by existing properties in this block
200
- const match = body.match(/^([ \t]+)\S/m);
201
- return match ? match[1] : ' ';
202
- }
203
- //# sourceMappingURL=ast.js.map
package/dist/ast.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Per-file async write-lock for the Trace IDE bridge.
3
- *
4
- * Problem: Node.js is single-threaded but WebSocket message handlers are
5
- * async. Two EDIT_FILE messages arriving in quick succession will both
6
- * start processing, and if a second message begins its read after the first
7
- * has written but before the first's `await autoFormat` resolves, the second
8
- * write lands on correctly-updated content. The real risk is a future where
9
- * parallelism is added — e.g., multiple WS connections dispatching concurrent
10
- * edits to the same file — where without a lock, the second write overwrites
11
- * the first silently.
12
- *
13
- * Solution: Promise-chain semaphore keyed on the absolute file path.
14
- * Each caller waits for the previous write to the same file to fully complete
15
- * (including the async autoFormat step) before starting its own write.
16
- *
17
- * Usage:
18
- * await withFileLock(filePath, async () => {
19
- * fs.writeFileSync(filePath, newContent, 'utf-8');
20
- * await autoFormat(filePath, projectPath);
21
- * });
22
- */
23
- export declare function withFileLock<T>(filePath: string, fn: () => Promise<T>): Promise<T>;
package/dist/file-lock.js DELETED
@@ -1,47 +0,0 @@
1
- /**
2
- * Per-file async write-lock for the Trace IDE bridge.
3
- *
4
- * Problem: Node.js is single-threaded but WebSocket message handlers are
5
- * async. Two EDIT_FILE messages arriving in quick succession will both
6
- * start processing, and if a second message begins its read after the first
7
- * has written but before the first's `await autoFormat` resolves, the second
8
- * write lands on correctly-updated content. The real risk is a future where
9
- * parallelism is added — e.g., multiple WS connections dispatching concurrent
10
- * edits to the same file — where without a lock, the second write overwrites
11
- * the first silently.
12
- *
13
- * Solution: Promise-chain semaphore keyed on the absolute file path.
14
- * Each caller waits for the previous write to the same file to fully complete
15
- * (including the async autoFormat step) before starting its own write.
16
- *
17
- * Usage:
18
- * await withFileLock(filePath, async () => {
19
- * fs.writeFileSync(filePath, newContent, 'utf-8');
20
- * await autoFormat(filePath, projectPath);
21
- * });
22
- */
23
- // Map: absolute filePath → the Promise representing the current (or last) write.
24
- const _locks = new Map();
25
- export async function withFileLock(filePath, fn) {
26
- // Grab any in-progress write for this file (or a resolved no-op if none).
27
- const prior = _locks.get(filePath) ?? Promise.resolve();
28
- // Create a "hold" promise that keeps this slot in the chain alive
29
- // until our fn() completes and we call release().
30
- let release;
31
- const hold = new Promise(resolve => (release = resolve));
32
- // Register this write as the current holder for this path.
33
- // Anyone queueing after us will wait on `hold`.
34
- _locks.set(filePath, hold);
35
- try {
36
- await prior; // Wait for any preceding write to finish
37
- return await fn(); // Execute our write (includes autoFormat await)
38
- }
39
- finally {
40
- release(); // Unblock the next write in the chain
41
- // Clean up the map if nothing queued behind us
42
- if (_locks.get(filePath) === hold) {
43
- _locks.delete(filePath);
44
- }
45
- }
46
- }
47
- //# sourceMappingURL=file-lock.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,iFAAiF;AACjF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,QAAgB,EAChB,EAAoB;IAEpB,0EAA0E;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAExD,kEAAkE;IAClE,kDAAkD;IAClD,IAAI,OAAoB,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAE/D,2DAA2D;IAC3D,gDAAgD;IAChD,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE3B,IAAI,CAAC;QACD,MAAM,KAAK,CAAC,CAAO,yCAAyC;QAC5D,OAAO,MAAM,EAAE,EAAE,CAAC,CAAC,gDAAgD;IACvE,CAAC;YAAS,CAAC;QACP,OAAO,EAAE,CAAC,CAAS,sCAAsC;QACzD,+CAA+C;QAC/C,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC;AACL,CAAC"}
package/dist/format.d.ts DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * Auto-format a project file after agent writes.
3
- *
4
- * Cascade: Prettier → ESLint --fix
5
- *
6
- * - Prettier handles JS/TS/CSS/HTML/JSON/Markdown formatting.
7
- * - ESLint --fix handles import ordering, unused imports, and React-specific
8
- * rules that Prettier does not enforce (runs only if Prettier is absent or
9
- * fails its own config check).
10
- *
11
- * Both are discovered from the *project's own* node_modules — not a global
12
- * install — so they respect the project's configured rules and parser options.
13
- *
14
- * Errors from either formatter are intentionally swallowed: a format failure
15
- * must never block an agent's write. The function returns:
16
- * 'prettier' — Prettier ran successfully
17
- * 'eslint' — ESLint ran successfully (Prettier was absent/failed)
18
- * null — file type is not formattable, or no formatter found
19
- */
20
- export declare function autoFormat(filePath: string, projectPath: string): Promise<string | null>;
package/dist/format.js DELETED
@@ -1,68 +0,0 @@
1
- /**
2
- * Auto-format a project file after agent writes.
3
- *
4
- * Cascade: Prettier → ESLint --fix
5
- *
6
- * - Prettier handles JS/TS/CSS/HTML/JSON/Markdown formatting.
7
- * - ESLint --fix handles import ordering, unused imports, and React-specific
8
- * rules that Prettier does not enforce (runs only if Prettier is absent or
9
- * fails its own config check).
10
- *
11
- * Both are discovered from the *project's own* node_modules — not a global
12
- * install — so they respect the project's configured rules and parser options.
13
- *
14
- * Errors from either formatter are intentionally swallowed: a format failure
15
- * must never block an agent's write. The function returns:
16
- * 'prettier' — Prettier ran successfully
17
- * 'eslint' — ESLint ran successfully (Prettier was absent/failed)
18
- * null — file type is not formattable, or no formatter found
19
- */
20
- import * as fs from 'fs';
21
- import * as path from 'path';
22
- import { exec } from 'child_process';
23
- import { promisify } from 'util';
24
- const execAsync = promisify(exec);
25
- const JS_EXTS = new Set(['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.mts', '.cts']);
26
- const CSS_EXTS = new Set(['.css', '.scss', '.less']);
27
- const HTML_EXTS = new Set(['.html', '.htm', '.vue', '.svelte']);
28
- const ALL_FORMATTABLE = new Set([
29
- ...JS_EXTS, ...CSS_EXTS, ...HTML_EXTS,
30
- '.json', '.md', '.yaml', '.yml',
31
- ]);
32
- export async function autoFormat(filePath, projectPath) {
33
- const ext = path.extname(filePath).toLowerCase();
34
- if (!ALL_FORMATTABLE.has(ext))
35
- return null;
36
- // ── 1. Prettier (first choice) ────────────────────────────────────────────
37
- // Handles JS/TS/CSS/HTML/JSON/Markdown. Respects .prettierrc / prettier.config.js.
38
- const prettierBin = path.join(projectPath, 'node_modules', '.bin', 'prettier');
39
- if (fs.existsSync(prettierBin)) {
40
- try {
41
- await execAsync(`"${prettierBin}" --write "${filePath}"`, { cwd: projectPath });
42
- return 'prettier';
43
- }
44
- catch {
45
- // Prettier config error or unparseable file — fall through to ESLint.
46
- }
47
- }
48
- // ── 2. ESLint --fix (JS/TS only) ─────────────────────────────────────────
49
- // Handles import ordering (eslint-plugin-import), unused imports
50
- // (eslint-plugin-unused-imports), and React-specific rules that Prettier
51
- // does not enforce. Runs after Prettier so lint rules don't fight formatting.
52
- if (JS_EXTS.has(ext)) {
53
- const eslintBin = path.join(projectPath, 'node_modules', '.bin', 'eslint');
54
- if (fs.existsSync(eslintBin)) {
55
- try {
56
- // --fix mutates the file; lint violations that can't be auto-fixed
57
- // are reported to stderr (ignored here) but the file is still improved.
58
- await execAsync(`"${eslintBin}" --fix "${filePath}"`, { cwd: projectPath });
59
- return 'eslint';
60
- }
61
- catch {
62
- // Lint violations are expected — fixable ones were still applied.
63
- }
64
- }
65
- }
66
- return null;
67
- }
68
- //# sourceMappingURL=format.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAChE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC5B,GAAG,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS;IACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM;CAClC,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,WAAmB;IAClE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,6EAA6E;IAC7E,mFAAmF;IACnF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/E,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACD,MAAM,SAAS,CAAC,IAAI,WAAW,cAAc,QAAQ,GAAG,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YAChF,OAAO,UAAU,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACL,sEAAsE;QAC1E,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,iEAAiE;IACjE,yEAAyE;IACzE,8EAA8E;IAC9E,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3E,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACD,mEAAmE;gBACnE,wEAAwE;gBACxE,MAAM,SAAS,CAAC,IAAI,SAAS,YAAY,QAAQ,GAAG,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC5E,OAAO,QAAQ,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACL,kEAAkE;YACtE,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};