@ghl-ai/aw 0.1.38-beta.10 → 0.1.38-beta.12

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/cli.mjs CHANGED
@@ -134,7 +134,7 @@ function printHelp() {
134
134
  cmd('aw push .aw_registry/agents/<name>.md', 'Push a single agent'),
135
135
  cmd('aw push .aw_registry/skills/<name>/', 'Push a single skill folder'),
136
136
  cmd('aw push .aw_rules', 'Auto-redirects to aw push-rules'),
137
- cmd('aw push-rules', 'Pushes .aw_rules or .aw_registry/.aw_rules'),
137
+ cmd('aw push-rules', 'Pushes .aw_rules'),
138
138
  '',
139
139
  ` ${chalk.dim('# Remove content from workspace')}`,
140
140
  cmd('aw drop <team>', 'Stop syncing a namespace (removes all files)'),
@@ -162,10 +162,12 @@ function resolveAwRegistryDir(homeDir) {
162
162
  }
163
163
 
164
164
  function resolveRulesDir(homeDir) {
165
- const awRegistryDir = resolveAwRegistryDir(homeDir);
166
- if (!awRegistryDir) return null;
167
- const rulesDir = join(awRegistryDir, '.aw_rules');
168
- return existsSync(rulesDir) ? rulesDir : null;
165
+ const candidates = [
166
+ join(homeDir, '.aw_rules'),
167
+ join(homeDir, '.aw_registry', '.aw_rules'),
168
+ join(homeDir, '.aw', '.aw_registry', '.aw_rules'),
169
+ ];
170
+ return candidates.find(existsSync) || null;
169
171
  }
170
172
 
171
173
  function findClaudePlugin(homeDir) {
@@ -471,7 +473,7 @@ function getProjectClaudeSessionStartStatus(cwd) {
471
473
  }
472
474
 
473
475
  function textHasRulesReference(text) {
474
- return text.includes('Platform Rules') && text.includes('.aw_registry/.aw_rules/platform/');
476
+ return text.includes('Platform Rules') && text.includes('.aw_rules/platform/');
475
477
  }
476
478
 
477
479
  function textHasManagedRouterBridge(text) {
@@ -484,9 +486,9 @@ function textHasManagedRouterBridge(text) {
484
486
  && text.includes('incremental-implementation');
485
487
  }
486
488
 
487
- function extractRegistryReferencePaths(text) {
489
+ function extractRuleReferencePaths(text) {
488
490
  const matches = [];
489
- const pattern = /(?:\]\(|`)([^)\n`]*\.aw_registry\/[^)\n`]+\.md)(?:\)|`)/g;
491
+ const pattern = /(?:\]\(|`)([^)\n`]*(?:\.aw_rules|\.aw_registry\/\.aw_rules)\/[^)\n`]+\.md)(?:\)|`)/g;
490
492
  for (const match of text.matchAll(pattern)) {
491
493
  if (match[1]) matches.push(match[1]);
492
494
  }
@@ -505,11 +507,11 @@ function listGeneratedRuleFiles(dirPath, extension) {
505
507
  }
506
508
  }
507
509
 
508
- function findBrokenRegistryReferences(filePaths) {
510
+ function findBrokenRuleReferences(filePaths) {
509
511
  const broken = [];
510
512
  for (const filePath of filePaths) {
511
513
  const content = readText(filePath);
512
- const refs = extractRegistryReferencePaths(content);
514
+ const refs = extractRuleReferencePaths(content);
513
515
  for (const ref of refs) {
514
516
  if (ref.includes('<domain>')) continue;
515
517
  const resolvedPath = join(dirname(filePath), ref);
@@ -565,8 +567,8 @@ function buildDoctorChecks(homeDir, cwd) {
565
567
  'aw-rules-source',
566
568
  'AW rules source',
567
569
  'fail',
568
- 'No synced .aw_rules tree found under ~/.aw_registry',
569
- 'Run `aw init` or `aw pull platform` to sync the AW rules source into ~/.aw_registry.',
570
+ 'No synced .aw_rules tree found under ~/.aw_rules',
571
+ 'Run `aw init` or `aw pull platform` to sync the AW rules source into ~/.aw_rules.',
570
572
  ));
571
573
  } else {
572
574
  const topLevelRulesAgents = join(rulesDir, 'AGENTS.md');
@@ -578,7 +580,7 @@ function buildDoctorChecks(homeDir, cwd) {
578
580
  'aw-rules-source',
579
581
  'AW rules source',
580
582
  'fail',
581
- 'Rules source is incomplete under ~/.aw_registry/.aw_rules',
583
+ 'Rules source is incomplete under ~/.aw_rules',
582
584
  'Run `aw pull platform` to refresh .aw_rules, then rerun `aw doctor`.',
583
585
  ),
584
586
  );
@@ -784,7 +786,7 @@ function buildDoctorChecks(homeDir, cwd) {
784
786
  );
785
787
 
786
788
  const claudeRuleFiles = listGeneratedRuleFiles(claudeRulesDir, '.md');
787
- const brokenClaudeRuleRefs = findBrokenRegistryReferences(claudeRuleFiles);
789
+ const brokenClaudeRuleRefs = findBrokenRuleReferences(claudeRuleFiles);
788
790
  checks.push(
789
791
  claudeRuleFiles.length === 0
790
792
  ? makeCheck(
@@ -795,13 +797,13 @@ function buildDoctorChecks(homeDir, cwd) {
795
797
  'Run `aw pull platform` or `aw init` to render Claude rules, then rerun `aw doctor`.',
796
798
  )
797
799
  : brokenClaudeRuleRefs.length === 0
798
- ? makeCheck('claude-rule-references', 'Claude rule references', 'pass', 'Claude generated rule references resolve to real files in ~/.aw_registry')
800
+ ? makeCheck('claude-rule-references', 'Claude rule references', 'pass', 'Claude generated rule references resolve to real files in ~/.aw_rules')
799
801
  : makeCheck(
800
802
  'claude-rule-references',
801
803
  'Claude rule references',
802
804
  'fail',
803
805
  `Claude rule reference is broken in ${brokenClaudeRuleRefs[0].filePath.replace(`${homeDir}/`, '~/')}: ${brokenClaudeRuleRefs[0].ref}`,
804
- 'Refresh the rendered Claude rules so embedded reference links point at real files under ~/.aw_registry/.aw_rules.',
806
+ 'Refresh the rendered Claude rules so embedded reference links point at real files under ~/.aw_rules.',
805
807
  ),
806
808
  );
807
809
 
@@ -894,7 +896,7 @@ function buildDoctorChecks(homeDir, cwd) {
894
896
  );
895
897
 
896
898
  const codexAgentsText = readText(codexAgentsPath);
897
- const codexBrokenRuleRefs = existsSync(codexAgentsPath) ? findBrokenRegistryReferences([codexAgentsPath]) : [];
899
+ const codexBrokenRuleRefs = existsSync(codexAgentsPath) ? findBrokenRuleReferences([codexAgentsPath]) : [];
898
900
  checks.push(
899
901
  existsSync(codexAgentsPath) && textHasRulesReference(codexAgentsText)
900
902
  ? codexBrokenRuleRefs.length === 0
@@ -1004,7 +1006,7 @@ function buildDoctorChecks(homeDir, cwd) {
1004
1006
 
1005
1007
  const cursorRulesDir = join(homeDir, '.cursor', 'rules');
1006
1008
  const cursorRuleFiles = listGeneratedRuleFiles(cursorRulesDir, '.mdc');
1007
- const brokenCursorRuleRefs = findBrokenRegistryReferences(cursorRuleFiles);
1009
+ const brokenCursorRuleRefs = findBrokenRuleReferences(cursorRuleFiles);
1008
1010
  checks.push(
1009
1011
  cursorRuleFiles.length === 0
1010
1012
  ? makeCheck(
@@ -1015,13 +1017,13 @@ function buildDoctorChecks(homeDir, cwd) {
1015
1017
  'Run `aw pull platform` or `aw init` to render Cursor rules, then rerun `aw doctor`.',
1016
1018
  )
1017
1019
  : brokenCursorRuleRefs.length === 0
1018
- ? makeCheck('cursor-rule-references', 'Cursor rule references', 'pass', 'Cursor generated rule references resolve to real files in ~/.aw_registry')
1020
+ ? makeCheck('cursor-rule-references', 'Cursor rule references', 'pass', 'Cursor generated rule references resolve to real files in ~/.aw_rules')
1019
1021
  : makeCheck(
1020
1022
  'cursor-rule-references',
1021
1023
  'Cursor rule references',
1022
1024
  'fail',
1023
1025
  `Cursor rule reference is broken in ${brokenCursorRuleRefs[0].filePath.replace(`${homeDir}/`, '~/')}: ${brokenCursorRuleRefs[0].ref}`,
1024
- 'Refresh the rendered Cursor rules so embedded reference links point at real files under ~/.aw_registry/.aw_rules.',
1026
+ 'Refresh the rendered Cursor rules so embedded reference links point at real files under ~/.aw_rules.',
1025
1027
  ),
1026
1028
  );
1027
1029
 
package/commands/init.mjs CHANGED
@@ -59,6 +59,21 @@ const HOME = (() => { try { return realpathSync(_rawHome); } catch { return _raw
59
59
  const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
60
60
  const AW_HOME = join(HOME, '.aw');
61
61
 
62
+ function syncRulesTargets(targetDir) {
63
+ const rulesSrc = join(AW_HOME, RULES_SOURCE_DIR);
64
+ if (!existsSync(rulesSrc)) return false;
65
+ syncFileTree(rulesSrc, join(targetDir, RULES_SOURCE_DIR));
66
+ return true;
67
+ }
68
+
69
+ function removeLegacyRegistryRules() {
70
+ try {
71
+ rmSync(join(GLOBAL_AW_DIR, RULES_SOURCE_DIR), { recursive: true, force: true });
72
+ } catch {
73
+ // best effort cleanup
74
+ }
75
+ }
76
+
62
77
  function syncInstructionsAndAwDocs(targetDir, namespace) {
63
78
  copyInstructions(targetDir, null, namespace);
64
79
  initAwDocs(targetDir);
@@ -262,9 +277,11 @@ export async function initCommand(args) {
262
277
 
263
278
  ensureAwGitignore(AW_HOME);
264
279
  const freshCfg = config.load(GLOBAL_AW_DIR);
265
- if (existsSync(GLOBAL_AW_DIR)) {
266
- syncFileTree(join(AW_HOME, RULES_SOURCE_DIR), join(GLOBAL_AW_DIR, RULES_SOURCE_DIR));
280
+ syncRulesTargets(HOME);
281
+ if (cwd !== HOME) {
282
+ syncRulesTargets(cwd);
267
283
  }
284
+ removeLegacyRegistryRules();
268
285
 
269
286
  // Ensure project worktree sparse checkout matches the global clone.
270
287
  // Covers the case where a namespace was added from HOME (or another project)
@@ -404,9 +421,11 @@ export async function initCommand(args) {
404
421
  if (folderName) {
405
422
  config.addPattern(GLOBAL_AW_DIR, folderName);
406
423
  }
407
- if (existsSync(GLOBAL_AW_DIR)) {
408
- syncFileTree(join(AW_HOME, RULES_SOURCE_DIR), join(GLOBAL_AW_DIR, RULES_SOURCE_DIR));
424
+ syncRulesTargets(HOME);
425
+ if (cwd !== HOME) {
426
+ syncRulesTargets(cwd);
409
427
  }
428
+ removeLegacyRegistryRules();
410
429
 
411
430
  // Step 3: Setup tasks, MCP, hooks
412
431
  await installAwEcc(cwd, { silent });
package/commands/pull.mjs CHANGED
@@ -3,6 +3,7 @@
3
3
  import {
4
4
  existsSync,
5
5
  lstatSync,
6
+ rmSync,
6
7
  } from 'node:fs';
7
8
  import { dirname, join, extname } from 'node:path';
8
9
  import { homedir } from 'node:os';
@@ -38,6 +39,21 @@ const HOME = homedir();
38
39
  const AW_HOME = join(HOME, '.aw');
39
40
  const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
40
41
 
42
+ function syncRulesTargets(targetDir) {
43
+ const rulesSrc = join(AW_HOME, RULES_SOURCE_DIR);
44
+ if (!existsSync(rulesSrc)) return false;
45
+ syncFileTree(rulesSrc, join(targetDir, RULES_SOURCE_DIR));
46
+ return true;
47
+ }
48
+
49
+ function removeLegacyRegistryRules() {
50
+ try {
51
+ rmSync(join(GLOBAL_AW_DIR, RULES_SOURCE_DIR), { recursive: true, force: true });
52
+ } catch {
53
+ // best effort cleanup
54
+ }
55
+ }
56
+
41
57
  export async function pullCommand(args) {
42
58
  const input = args._positional?.[0] || '';
43
59
  const cwd = process.cwd();
@@ -179,13 +195,6 @@ export async function pullCommand(args) {
179
195
  log.logWarn(`Conflicts in: ${fetchResult.conflicts.join(', ')}`);
180
196
  }
181
197
 
182
- const rulesSrc = join(AW_HOME, RULES_SOURCE_DIR);
183
- if (existsSync(rulesSrc)) {
184
- const rulesDest = join(GLOBAL_AW_DIR, RULES_SOURCE_DIR);
185
- syncFileTree(rulesSrc, rulesDest);
186
- if (!silent) log.logSuccess('Synced .aw_rules');
187
- }
188
-
189
198
  // Rebase project worktree branch onto origin/main — only for legacy git worktrees.
190
199
  // In the symlink model, <project>/.aw IS ~/.aw (same repo), so fetchAndMerge already
191
200
  // brought it up to date. Nothing to rebase.
@@ -244,6 +253,16 @@ export async function pullCommand(args) {
244
253
  }
245
254
  }
246
255
 
256
+ let rulesSynced = syncRulesTargets(HOME);
257
+ const workspaceRoot = localAw ? dirname(localAw) : (cwd !== HOME ? cwd : null);
258
+ if (workspaceRoot && workspaceRoot !== HOME) {
259
+ rulesSynced = syncRulesTargets(workspaceRoot) || rulesSynced;
260
+ }
261
+ removeLegacyRegistryRules();
262
+ if (rulesSynced && !silent) {
263
+ log.logSuccess('Synced .aw_rules');
264
+ }
265
+
247
266
  if (!args._skipIntegrate) {
248
267
  const projectRegistryDir = cwd !== HOME ? join(cwd, '.aw', REGISTRY_DIR) : null;
249
268
  const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
@@ -23,11 +23,9 @@ export function isRulesPushInput(input) {
23
23
 
24
24
  export function resolveRulesPushSource(input, cwd = process.cwd()) {
25
25
  const localRulesRoot = join(cwd, RULES_SOURCE_DIR);
26
- const syncedRulesRoot = join(cwd, '.aw_registry', RULES_SOURCE_DIR);
27
26
 
28
27
  if (!input) {
29
28
  if (existsSync(localRulesRoot)) return { sourceRoot: localRulesRoot, sourceType: 'local' };
30
- if (existsSync(syncedRulesRoot)) return { sourceRoot: syncedRulesRoot, sourceType: 'synced' };
31
29
  return null;
32
30
  }
33
31
 
@@ -39,22 +37,19 @@ export function resolveRulesPushSource(input, cwd = process.cwd()) {
39
37
  }
40
38
 
41
39
  if (normalizedInput === `.aw_registry/${RULES_SOURCE_DIR}` || normalizedInput.startsWith(`.aw_registry/${RULES_SOURCE_DIR}/`)) {
42
- if (!existsSync(syncedRulesRoot)) return null;
43
-
44
40
  const relativeRulesPath = normalizedInput.slice(`.aw_registry/${RULES_SOURCE_DIR}`.length).replace(/^\/+/, '');
45
41
  const localOverridePath = relativeRulesPath ? join(localRulesRoot, relativeRulesPath) : localRulesRoot;
46
42
  if (existsSync(localOverridePath)) {
47
43
  return { sourceRoot: localRulesRoot, sourceType: 'local' };
48
44
  }
49
-
50
- return { sourceRoot: syncedRulesRoot, sourceType: 'synced' };
45
+ return null;
51
46
  }
52
47
 
53
48
  return null;
54
49
  }
55
50
 
56
51
  export function hasRulesChanges(cwd = process.cwd()) {
57
- const candidateDirs = [RULES_SOURCE_DIR, `.aw_registry/${RULES_SOURCE_DIR}`]
52
+ const candidateDirs = [RULES_SOURCE_DIR]
58
53
  .filter(rel => existsSync(join(cwd, rel)));
59
54
 
60
55
  if (candidateDirs.length === 0) return false;
@@ -141,9 +136,7 @@ function pushRulesTree(sourceRoot, { repo, dryRun, cwd }) {
141
136
  fmt.cancel('Nothing to push — remote rules already match local content.');
142
137
  }
143
138
 
144
- const sourceType = normalize(sourceRoot).includes(normalize(join('.aw_registry', RULES_SOURCE_DIR)))
145
- ? 'synced'
146
- : 'local';
139
+ const sourceType = 'local';
147
140
  const prTitle = buildRulesPrTitle(sourceRoot, cwd);
148
141
  const prBody = buildRulesPrBody(sourceRoot, sourceType, cwd);
149
142
 
@@ -191,16 +184,12 @@ export function pushRulesCommand(args) {
191
184
  fmt.cancel([
192
185
  'Could not find a rules source to push.',
193
186
  '',
194
- ` Checked ${chalk.cyan('.aw_rules/')} and ${chalk.cyan('.aw_registry/.aw_rules/')}.`,
187
+ ` Checked ${chalk.cyan('.aw_rules/')}.`,
195
188
  '',
196
189
  ' Use `aw pull platform` first or create a local `.aw_rules/` authoring tree.',
197
190
  ].join('\n'));
198
191
  }
199
192
 
200
- if (resolved.sourceType === 'synced') {
201
- fmt.logWarn('Pushing from synced `.aw_registry/.aw_rules/`. Local `.aw_rules/` is safer for authoring.');
202
- }
203
-
204
193
  pushRulesTree(resolved.sourceRoot, { repo, dryRun, cwd });
205
194
  }
206
195
 
@@ -1,8 +1,5 @@
1
- // commands/telemetry.mjs — `aw telemetry [enable|disable|status|flush-queue]`
1
+ // commands/telemetry.mjs — `aw telemetry [enable|disable|status]`
2
2
 
3
- import { existsSync, readFileSync } from 'node:fs';
4
- import { join } from 'node:path';
5
- import { homedir } from 'node:os';
6
3
  import { enableTelemetry, disableTelemetry, getStatus } from '../telemetry.mjs';
7
4
  import * as fmt from '../fmt.mjs';
8
5
  import { chalk } from '../fmt.mjs';
@@ -22,66 +19,13 @@ export async function telemetryCommand(args) {
22
19
  return;
23
20
  }
24
21
 
25
- if (sub === 'flush-queue') {
26
- await flushQueueCommand();
27
- return;
28
- }
29
-
30
22
  // status (default)
31
23
  const status = getStatus();
32
24
  fmt.intro('aw telemetry');
33
25
  fmt.logStep(`Status: ${status.enabled ? chalk.green('enabled') : chalk.red('disabled')}`);
34
26
  fmt.logStep(`Machine ID: ${chalk.dim(status.machine_id)}`);
35
27
  fmt.logStep(`Config: ${chalk.dim(status.config_path)}`);
36
-
37
- // Show queue depth if available
38
- const queueFile = join(homedir(), '.aw', 'telemetry', 'queue.jsonl');
39
- if (existsSync(queueFile)) {
40
- try {
41
- const lines = readFileSync(queueFile, 'utf8').trim().split('\n').filter(Boolean);
42
- fmt.logStep(`Queue: ${chalk.yellow(lines.length)} pending prompt(s)`);
43
- } catch { /* best effort */ }
44
- }
45
-
46
28
  fmt.logMessage('');
47
- fmt.logMessage(` ${chalk.dim('aw telemetry disable')} — opt out of anonymous analytics`);
48
- fmt.logMessage(` ${chalk.dim('aw telemetry enable')} — re-enable analytics`);
49
- fmt.logMessage(` ${chalk.dim('aw telemetry flush-queue')} — manually flush pending queue`);
50
- }
51
-
52
- async function flushQueueCommand() {
53
- const eccBase = join(homedir(), '.aw-ecc');
54
- const libPath = join(eccBase, 'scripts', 'hooks', 'capabilities', 'telemetry', 'telemetry-lib.js');
55
-
56
- if (!existsSync(libPath)) {
57
- fmt.logWarn('Telemetry library not found. Run aw init first.');
58
- return;
59
- }
60
-
61
- const {
62
- readQueue,
63
- flushQueueToApi,
64
- getNamespace,
65
- buildTelemetryHeaders,
66
- } = await import(libPath);
67
-
68
- const entries = readQueue();
69
- if (entries.length === 0) {
70
- fmt.logSuccess('Queue is empty — nothing to flush.');
71
- return;
72
- }
73
-
74
- fmt.logStep(`Flushing ${entries.length} pending prompt(s)...`);
75
-
76
- const namespace = getNamespace();
77
- const headers = buildTelemetryHeaders(namespace);
78
- const result = await flushQueueToApi(headers);
79
-
80
- if (result.flushed > 0) {
81
- fmt.logSuccess(`Flushed ${result.flushed} prompt(s) to API.`);
82
- } else if (result.failed) {
83
- fmt.logWarn('Flush failed — entries remain in queue for retry.');
84
- } else {
85
- fmt.logSuccess('Nothing to flush.');
86
- }
29
+ fmt.logMessage(` ${chalk.dim('aw telemetry disable')} — opt out of anonymous analytics`);
30
+ fmt.logMessage(` ${chalk.dim('aw telemetry enable')} — re-enable analytics`);
87
31
  }
package/constants.mjs CHANGED
@@ -25,7 +25,7 @@ export const DOCS_SOURCE_DIR = 'content';
25
25
  /** Persistent git clone root — ~/.aw/ */
26
26
  export const AW_HOME = join(homedir(), '.aw');
27
27
 
28
- /** Directory in platform-docs repo containing platform rules (pulled into .aw_registry/.aw_rules/) */
28
+ /** Directory in platform-docs repo containing platform rules (synced into root-level .aw_rules/) */
29
29
  export const RULES_SOURCE_DIR = '.aw_rules';
30
30
  /** Telemetry endpoint — override with AW_TELEMETRY_URL env var */
31
31
  export const TELEMETRY_URL = process.env.AW_TELEMETRY_URL || 'https://services.leadconnectorhq.com/agentic-workspace/api/telemetry/events';
package/ecc.mjs CHANGED
@@ -10,7 +10,7 @@ import { applyStoredStartupPreferences } from "./startup.mjs";
10
10
 
11
11
  const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
12
12
  const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
13
- export const AW_ECC_TAG = "v1.0.6";
13
+ export const AW_ECC_TAG = "v1.4.23";
14
14
 
15
15
  const MARKETPLACE_NAME = "aw-marketplace";
16
16
  const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
@@ -241,9 +241,6 @@ export async function installAwEcc(
241
241
  try {
242
242
  cloneOrUpdate(AW_ECC_TAG, repoDir);
243
243
 
244
- // Ensure telemetry state directory exists (vendor-agnostic, shared across IDEs)
245
- mkdirSync(join(home, ".aw", "telemetry"), { recursive: true });
246
-
247
244
  // Claude Code: plugin install via marketplace CLI (proper agent dispatch)
248
245
  if (targets.includes("claude")) {
249
246
  try {
@@ -3,7 +3,6 @@ import { join } from 'node:path';
3
3
  import { getSupportedHarnessPhaseEntries } from '../hook-manifest.mjs';
4
4
  import {
5
5
  buildDelegatingPhaseScript,
6
- buildNodeSilentPhaseScript,
7
6
  buildRegistryDelegatingPhaseScript,
8
7
  buildReservedPhaseScript,
9
8
  } from './shared-phase-scripts.mjs';
@@ -111,9 +110,10 @@ const CODEX_HOME_PHASE_BLUEPRINTS = {
111
110
  scriptName: 'aw-stop.sh',
112
111
  scriptMarker: '# aw-managed: codex-global-stop',
113
112
  buildScriptContent() {
114
- return buildNodeSilentPhaseScript({
113
+ return buildReservedPhaseScript({
115
114
  marker: this.scriptMarker,
116
- targetPath: '$HOME/.aw-ecc/scripts/hooks/capabilities/telemetry/telemetry-stop.js',
115
+ phase: 'Stop',
116
+ harnessLabel: 'Codex home routing',
117
117
  });
118
118
  },
119
119
  buildEntry(command) {
@@ -54,23 +54,6 @@ exit 0
54
54
  `;
55
55
  }
56
56
 
57
- export function buildNodeSilentPhaseScript({
58
- marker,
59
- targetPath,
60
- }) {
61
- return `#!/usr/bin/env bash
62
- ${marker}
63
- set -euo pipefail
64
-
65
- TARGET="${targetPath}"
66
- if [[ -f "$TARGET" ]]; then
67
- node "$TARGET" > /dev/null
68
- fi
69
-
70
- exit 0
71
- `;
72
- }
73
-
74
57
  export function buildReservedPhaseScript({
75
58
  marker,
76
59
  phase,
package/integrate.mjs CHANGED
@@ -29,7 +29,7 @@ function generateAwRouterBridgeSection() {
29
29
  - Do not assume the previous skill stack is still active
30
30
 
31
31
  ### 2. Read Rules Before Acting (MANDATORY)
32
- - Read applicable AW rules from \`~/.aw/.aw_registry/.aw_rules/platform/<domain>/AGENTS.md\`
32
+ - Read applicable AW rules from \`~/.aw_rules/platform/<domain>/AGENTS.md\`
33
33
  - Also read \`universal\` and \`security\` rules whenever they apply
34
34
  - If repo-local instructions conflict with org-level sources of truth, follow org-level sources
35
35
 
@@ -260,12 +260,12 @@ export function syncHomeHarnessInstructions(homeDir = homedir()) {
260
260
  const codexRulesSection = rulesDir
261
261
  ? generateAgentsMdRulesSection(rulesDir, {
262
262
  outputDir: join(homeDir, '.codex'),
263
- }).replaceAll('../.aw/.aw_registry/', '../.aw_registry/')
263
+ })
264
264
  : '';
265
265
  const cursorRulesSection = rulesDir
266
266
  ? generateAgentsMdRulesSection(rulesDir, {
267
267
  outputDir: join(homeDir, '.cursor'),
268
- }).replaceAll('../.aw/.aw_registry/', '../.aw_registry/')
268
+ })
269
269
  : '';
270
270
  const claudeRulesSection = rulesDir ? generateClaudeMdRulesSection(rulesDir) : '';
271
271
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.38-beta.10",
3
+ "version": "0.1.38-beta.12",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": {
package/render-rules.mjs CHANGED
@@ -171,12 +171,14 @@ function relativeRuleLink(outputDir, targetPath) {
171
171
  export function resolveRulesSourceDir(cwd, options = {}) {
172
172
  const HOME = options.homeDir || homedir();
173
173
  const candidates = [
174
+ join(cwd, RULES_SOURCE_DIR),
174
175
  join(cwd, '.aw_registry', RULES_SOURCE_DIR),
175
176
  join(cwd, '.aw', '.aw_registry', RULES_SOURCE_DIR),
176
177
  ];
177
178
 
178
179
  if (cwd !== HOME) {
179
180
  candidates.push(
181
+ join(HOME, RULES_SOURCE_DIR),
180
182
  join(HOME, '.aw_registry', RULES_SOURCE_DIR),
181
183
  join(HOME, '.aw', '.aw_registry', RULES_SOURCE_DIR),
182
184
  );
@@ -410,7 +412,7 @@ export function generateClaudeMdRulesSection(rulesDir) {
410
412
  const lines = [
411
413
  '## Platform Rules (MUST)',
412
414
  '',
413
- '> Auto-synced from `.aw_registry/.aw_rules/`. Full details in reference files.',
415
+ '> Rendered from platform `.aw_rules/`. Full details in reference files.',
414
416
  '',
415
417
  ];
416
418
 
@@ -419,7 +421,7 @@ export function generateClaudeMdRulesSection(rulesDir) {
419
421
  }
420
422
 
421
423
  lines.push('');
422
- lines.push('See `.aw_registry/.aw_rules/rule-manifest.json` for all rules including SHOULD/MAY.');
424
+ lines.push('See `.aw_rules/rule-manifest.json` for all rules including SHOULD/MAY.');
423
425
  lines.push('');
424
426
 
425
427
  return lines.join('\n');
@@ -436,7 +438,7 @@ export function generateAgentsMdRulesSection(rulesDir, options = {}) {
436
438
  const lines = [
437
439
  '## Platform Rules — Non-Negotiables',
438
440
  '',
439
- '> Auto-synced from `.aw_registry/.aw_rules/`.',
441
+ '> Rendered from platform `.aw_rules/`.',
440
442
  '',
441
443
  topLevelAgents.trim(),
442
444
  '',
@@ -487,7 +489,7 @@ export function generateAgentsMdRulesSection(rulesDir, options = {}) {
487
489
 
488
490
  /**
489
491
  * Main render function. Call after aw pull / aw sync.
490
- * Reads .aw_registry/.aw_rules/ and renders:
492
+ * Reads root .aw_rules/ and renders:
491
493
  * 1. .cursor/rules/<scope>.mdc — at cwd AND at $HOME (global)
492
494
  * 2. Returns sections for CLAUDE.md and AGENTS.md injection
493
495
  */
package/startup.mjs CHANGED
@@ -154,7 +154,7 @@ function isLegacyCodexSessionStartEntry(entry) {
154
154
  const command = String(hook?.command || '');
155
155
  return (
156
156
  command.includes('.aw_registry/platform/core/skills/using-aw-skills/hooks/session-start.sh')
157
- || (command.includes('.codex/hooks/aw-session-start.sh') && entry?.matcher !== CODEX_HOME_HOOK_MATCHER)
157
+ || (command.includes('.codex/hooks/aw-session-start.sh') && entry?.matcher !== CODEX_HOOK_MATCHER)
158
158
  );
159
159
  });
160
160
  }