@ghl-ai/aw 0.1.37-beta.25 → 0.1.37-beta.26

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/commands/init.mjs CHANGED
@@ -25,7 +25,7 @@ import { chalk } from '../fmt.mjs';
25
25
  import { linkWorkspace } from '../link.mjs';
26
26
  import { generateCommands, copyInstructions, initAwDocs } from '../integrate.mjs';
27
27
  import { setupMcp } from '../mcp.mjs';
28
- import { installLocalCommitHook } from '../hooks.mjs';
28
+ import { installLocalCommitHook, syncCursorHooks } from '../hooks.mjs';
29
29
  import { autoUpdate, promptUpdate } from '../update.mjs';
30
30
  import { installGlobalHooks } from '../hooks.mjs';
31
31
  import { installAwEcc } from '../ecc.mjs';
@@ -294,7 +294,7 @@ export async function initCommand(args) {
294
294
  const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
295
295
  const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
296
296
  const commands = generateCommands(HOME, { silent: true });
297
- if (cwd !== HOME) installLocalCommitHook(cwd);
297
+ if (cwd !== HOME) { installLocalCommitHook(cwd); syncCursorHooks(cwd); }
298
298
 
299
299
  if (silent) {
300
300
  autoUpdate(await args._updateCheck);
@@ -425,7 +425,7 @@ export async function initCommand(args) {
425
425
  const projectRegistryDir = cwd !== HOME ? join(cwd, '.aw', REGISTRY_DIR) : null;
426
426
  const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
427
427
  const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
428
- if (cwd !== HOME) installLocalCommitHook(cwd);
428
+ if (cwd !== HOME) { installLocalCommitHook(cwd); syncCursorHooks(cwd); }
429
429
  ideSpinner.message('Generating commands...');
430
430
  const commands = generateCommands(HOME, { silent: true });
431
431
  ideSpinner.stop(`IDE wired — ${chalk.bold(symlinks)} symlinks · ${chalk.bold(commands)} commands`);
@@ -9,7 +9,7 @@ import { addProjectWorktree, isWorktree, isValidClone } from '../git.mjs';
9
9
  import { REGISTRY_DIR, REGISTRY_URL } from '../constants.mjs';
10
10
  import { linkWorkspace } from '../link.mjs';
11
11
  import { generateCommands } from '../integrate.mjs';
12
- import { installLocalCommitHook } from '../hooks.mjs';
12
+ import { installLocalCommitHook, syncCursorHooks } from '../hooks.mjs';
13
13
 
14
14
  const HOME = homedir();
15
15
  const AW_HOME = join(HOME, '.aw');
@@ -42,6 +42,7 @@ export function linkProjectCommand(args) {
42
42
  const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
43
43
  const commands = generateCommands(HOME, { silent: true });
44
44
  installLocalCommitHook(cwd);
45
+ syncCursorHooks(cwd);
45
46
  fmt.logSuccess(`Already linked — refreshed ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`);
46
47
  return;
47
48
  }
@@ -53,6 +54,7 @@ export function linkProjectCommand(args) {
53
54
  const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
54
55
  const commands = generateCommands(HOME, { silent: true });
55
56
  installLocalCommitHook(cwd);
57
+ syncCursorHooks(cwd);
56
58
  fmt.logSuccess([
57
59
  `Project linked — ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`,
58
60
  '',
package/hooks.mjs CHANGED
@@ -289,3 +289,40 @@ export function installLocalCommitHook(projectDir) {
289
289
  chmodSync(hookPath, '755');
290
290
  } catch { /* best effort */ }
291
291
  }
292
+
293
+ /**
294
+ * Ensure the project has a .cursor/hooks.json that points to the global
295
+ * aw-ecc hooks via absolute paths. Cursor resolves hook commands relative
296
+ * to the workspace root, so a project-level hooks.json with absolute paths
297
+ * is the simplest way to make hooks work everywhere.
298
+ *
299
+ * @param {string} projectDir — root of the project
300
+ */
301
+ export function syncCursorHooks(projectDir) {
302
+ try {
303
+ const eccHooksJson = join(HOME, '.aw-ecc', '.cursor', 'hooks.json');
304
+ if (!existsSync(eccHooksJson)) return;
305
+
306
+ const projectCursorDir = join(projectDir, '.cursor');
307
+ if (!existsSync(projectCursorDir)) return;
308
+
309
+ const destHooksJson = join(projectCursorDir, 'hooks.json');
310
+
311
+ // Read the ecc hooks.json and rewrite relative paths to absolute
312
+ const hooksConfig = JSON.parse(readFileSync(eccHooksJson, 'utf8'));
313
+ const eccHooksDir = join(HOME, '.aw-ecc', '.cursor', 'hooks');
314
+
315
+ for (const [, entries] of Object.entries(hooksConfig.hooks || {})) {
316
+ for (const entry of entries) {
317
+ if (entry.command && entry.command.startsWith('node .cursor/hooks/')) {
318
+ entry.command = entry.command.replace(
319
+ 'node .cursor/hooks/',
320
+ `node ${eccHooksDir}/`,
321
+ );
322
+ }
323
+ }
324
+ }
325
+
326
+ writeFileSync(destHooksJson, JSON.stringify(hooksConfig, null, 2) + '\n');
327
+ } catch { /* best effort */ }
328
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.37-beta.25",
3
+ "version": "0.1.37-beta.26",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": "bin.js",