@ghl-ai/aw 0.1.50-beta.1 → 0.1.50

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.
@@ -4,8 +4,6 @@ import { join } from 'node:path';
4
4
  import * as fmt from '../fmt.mjs';
5
5
  import { chalk } from '../fmt.mjs';
6
6
  import { removeWorkspaceHookDefaults } from '../codex.mjs';
7
- import { syncHomeHarnessInstructions } from '../integrate.mjs';
8
- import { renderRules } from '../render-rules.mjs';
9
7
  import {
10
8
  applyStoredStartupPreferences,
11
9
  getStartupStatus,
@@ -35,27 +33,19 @@ export function routingCommand(args) {
35
33
 
36
34
  saveStartupPreferences(mode, HOME);
37
35
  const updatedFiles = applyStoredStartupPreferences(HOME);
38
- const updatedHomeInstructionFiles = syncHomeHarnessInstructions(HOME);
39
- renderRules(cwd, { homeDir: HOME });
40
36
  const status = getStartupStatus(HOME);
41
- const changedFiles = [...updatedFiles, ...updatedHomeInstructionFiles];
42
- const effectiveModeLabel = status.effectiveMode === 'enabled' ? chalk.green('enabled') : chalk.yellow('disabled');
43
37
 
44
38
  fmt.outro([
45
39
  `⟁ Session routing ${action === 'disable' ? 'disabled' : 'enabled'}`,
46
40
  '',
47
41
  ` ${chalk.green('✓')} Preference saved: ${chalk.dim(status.preferencesPath.replace(`${HOME}/`, '~/'))}`,
48
- ` ${chalk.green('✓')} Default AW router/rules: ${effectiveModeLabel}`,
49
42
  ` ${chalk.green('✓')} Claude session routing: ${status.claudeDisabled ? chalk.yellow('disabled') : chalk.green('enabled')}`,
50
43
  ` ${chalk.green('✓')} Codex session routing: ${status.codexHooksEnabled && status.codexSessionStartPresent ? chalk.green('enabled') : chalk.yellow('disabled')}`,
51
44
  ` ${chalk.green('✓')} Cursor session routing: ${status.cursorSessionStartPresent ? chalk.green('enabled') : chalk.yellow('disabled')}`,
52
- updatedHomeInstructionFiles.length > 0
53
- ? ` ${chalk.green('✓')} Updated ${updatedHomeInstructionFiles.length} home instruction file${updatedHomeInstructionFiles.length > 1 ? 's' : ''}`
54
- : null,
55
45
  removedLegacyFiles.length > 0
56
46
  ? ` ${chalk.green('✓')} Removed ${removedLegacyFiles.length} legacy repo routing file${removedLegacyFiles.length > 1 ? 's' : ''} from the current project`
57
47
  : null,
58
- changedFiles.length === 0
48
+ updatedFiles.length === 0
59
49
  ? ` ${chalk.dim('Note:')} no global routing files needed changes`
60
50
  : null,
61
51
  ].filter(Boolean).join('\n'));
@@ -63,9 +53,6 @@ export function routingCommand(args) {
63
53
 
64
54
  function renderStatus() {
65
55
  const status = getStartupStatus(HOME);
66
- const modeLabel = status.envDisableDefaultRouting
67
- ? `${status.effectiveMode} (${status.envDisableDefaultRoutingName}=1 override; saved preference: ${status.mode})`
68
- : status.mode;
69
56
  const codexStatus = status.codexHooksEnabled && status.codexSessionStartPresent
70
57
  ? 'enabled'
71
58
  : status.codexSessionStartPresent && !status.codexHooksEnabled
@@ -80,20 +67,14 @@ function renderStatus() {
80
67
  : status.claudePluginEnabled && !status.claudePluginInstalled
81
68
  ? 'misconfigured (plugin enabled in settings but not installed)'
82
69
  : 'disabled (plugin not installed)';
83
- const cursorStatus = status.cursorSessionStartPresent
84
- ? 'enabled'
85
- : status.cursorAnySessionStartPresent
86
- ? 'disabled (non-AW sessionStart hook present)'
87
- : 'disabled';
88
70
 
89
71
  fmt.note([
90
- `${chalk.dim('mode:')} ${modeLabel}`,
72
+ `${chalk.dim('mode:')} ${status.mode}`,
91
73
  `${chalk.dim('prefs:')} ${status.preferencesPath.replace(`${HOME}/`, '~/')}`,
92
- `${chalk.dim('default AW router/rules:')} ${status.effectiveMode}`,
93
74
  `${chalk.dim('claude session routing:')} ${claudeStatus}`,
94
75
  `${chalk.dim('codex session routing:')} ${codexStatus}`,
95
76
  `${chalk.dim('codex runtime:')} ${status.codexSessionStartScriptInstalled ? 'installed' : 'not installed'}`,
96
- `${chalk.dim('cursor session routing:')} ${cursorStatus}`,
77
+ `${chalk.dim('cursor session routing:')} ${status.cursorSessionStartPresent ? 'enabled' : 'disabled'}`,
97
78
  `${chalk.dim('cursor runtime:')} ${status.cursorSessionStartScriptInstalled ? 'installed' : 'not installed'}`,
98
79
  process.cwd() !== HOME
99
80
  ? `${chalk.dim('current repo legacy routing files:')} ${hasLegacyRepoStartupDefaults(process.cwd()) ? 'present' : 'not detected'}`
package/constants.mjs CHANGED
@@ -22,29 +22,6 @@ export const REGISTRY_DIR = '.aw_registry';
22
22
  /** Directory in platform-docs repo containing documentation (pulled into platform/docs/) */
23
23
  export const DOCS_SOURCE_DIR = 'content';
24
24
 
25
- /** Project-local directory containing generated AW planning/spec artifacts */
26
- export const AW_DOCS_DIR = '.aw_docs';
27
-
28
- /** Generated AW docs aggregation repository */
29
- export const AW_DOCS_REPO = process.env.AW_DOCS_REPO || 'GoHighLevel/ghl-aw-docs';
30
- export const AW_DOCS_URL = process.env.AW_DOCS_REPO_URL || `https://github.com/${AW_DOCS_REPO}.git`;
31
- /** Canonical branch for all generated AW docs publishes. Intentionally not configurable per run. */
32
- export const AW_DOCS_BASE_BRANCH = 'master-sync';
33
- export const AW_DOCS_SEED_BRANCH = process.env.AW_DOCS_SEED_BRANCH || 'scaffold';
34
- export const AW_DOCS_PUBLISH_DIR = 'aw_docs';
35
- export const AW_DOCS_PUBLIC_BASE_URL = process.env.AW_DOCS_PUBLIC_BASE_URL || `https://github.com/${AW_DOCS_REPO}/blob/${AW_DOCS_BASE_BRANCH}`;
36
- export const AW_DOCS_TEAMOFONE_ORIGIN = process.env.AW_DOCS_TEAMOFONE_ORIGIN || 'https://teamofone.msgsndr.net';
37
- export const AW_DOCS_TEAMOFONE_BASE_URL = process.env.AW_DOCS_TEAMOFONE_BASE_URL || `${AW_DOCS_TEAMOFONE_ORIGIN}/too/docs/GoHighLevel/ghl-aw-docs`;
38
-
39
- export function defaultAwDocsGithubDocsConfig() {
40
- return {
41
- enabled: true,
42
- repo: AW_DOCS_REPO,
43
- dest: AW_DOCS_PUBLISH_DIR,
44
- teamofone_base_url: AW_DOCS_TEAMOFONE_BASE_URL,
45
- };
46
- }
47
-
48
25
  /** Persistent git clone root — ~/.aw/ */
49
26
  export const AW_HOME = join(homedir(), '.aw');
50
27
 
package/ecc.mjs CHANGED
@@ -12,7 +12,7 @@ import { applyStoredStartupPreferences } from "./startup.mjs";
12
12
 
13
13
  const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
14
14
  const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
15
- export const AW_ECC_TAG = "v1.4.61";
15
+ export const AW_ECC_TAG = "v1.4.57";
16
16
 
17
17
  const MARKETPLACE_NAME = "aw-marketplace";
18
18
  const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
package/git.mjs CHANGED
@@ -5,7 +5,7 @@ import { mkdtempSync, existsSync, lstatSync, rmSync, readFileSync, symlinkSync,
5
5
  import { join, basename, dirname } from 'node:path';
6
6
  import { homedir, tmpdir } from 'node:os';
7
7
  import { promisify } from 'node:util';
8
- import { REGISTRY_BASE_BRANCH, REGISTRY_DIR, DOCS_SOURCE_DIR, AW_DOCS_DIR, RULES_SOURCE_DIR } from './constants.mjs';
8
+ import { REGISTRY_BASE_BRANCH, REGISTRY_DIR, DOCS_SOURCE_DIR, RULES_SOURCE_DIR } from './constants.mjs';
9
9
 
10
10
  const exec = promisify(execCb);
11
11
 
@@ -145,8 +145,7 @@ export function cleanup(tempDir) {
145
145
  * e.g., ["platform", "dev/agents/debugger"] -> [".aw_registry/platform", ".aw_registry/dev/agents/debugger"]
146
146
  *
147
147
  * When "platform" is in the paths, also includes the repo's docs source
148
- * directory (content/) and generated AW docs (.aw_docs/) so docs are pulled
149
- * on-the-fly into platform/docs/ and the local AW docs cache.
148
+ * directory (content/) so docs are pulled on-the-fly into platform/docs/.
150
149
  */
151
150
  export function includeToSparsePaths(paths) {
152
151
  const result = new Set();
@@ -156,7 +155,6 @@ export function includeToSparsePaths(paths) {
156
155
  result.add(`${REGISTRY_DIR}/AW-PROTOCOL.md`);
157
156
  if (paths.includes('platform')) {
158
157
  result.add(DOCS_SOURCE_DIR);
159
- result.add(AW_DOCS_DIR);
160
158
  result.add(RULES_SOURCE_DIR);
161
159
  }
162
160
  return [...result];
@@ -251,19 +249,6 @@ export function addToSparseCheckout(awHome, newPaths) {
251
249
  }
252
250
  }
253
251
 
254
- /**
255
- * Replace the current sparse checkout with an exact path set.
256
- */
257
- export function setSparseCheckout(awHome, sparsePaths) {
258
- try {
259
- execSync('git sparse-checkout init --no-cone', { cwd: awHome, stdio: 'pipe' });
260
- execSync(`git sparse-checkout set ${sparsePaths.map(p => `"${p}"`).join(' ')}`, { cwd: awHome, stdio: 'pipe' });
261
- execSync(`git checkout ${REGISTRY_BASE_BRANCH}`, { cwd: awHome, stdio: 'pipe' });
262
- } catch (e) {
263
- throw new Error(`Failed to set sparse checkout: ${e.message}`);
264
- }
265
- }
266
-
267
252
  /**
268
253
  * Mirror the main clone's sparse-checkout paths into a project worktree.
269
254
  * The worktree stays on its own branch — only the checked-out file set is updated.
@@ -512,7 +497,7 @@ export function commitToCurrentBranch(awHome, files, commitMsg, preStaged = fals
512
497
  if (!preStaged) {
513
498
  try {
514
499
  const quotedFiles = files.map(f => `"${f}"`).join(' ');
515
- execSync(`git -C "${awHome}" add --sparse -f ${quotedFiles}`, { stdio: 'pipe' });
500
+ execSync(`git -C "${awHome}" add ${quotedFiles}`, { stdio: 'pipe' });
516
501
  } catch (e) {
517
502
  throw new Error(`Failed to stage files: ${e.message}`);
518
503
  }
@@ -568,7 +553,7 @@ export async function createPushBranch(awHome, branchName, files, commitMsg, pre
568
553
  if (!preStaged) {
569
554
  try {
570
555
  const quotedFiles = files.map(f => `"${f}"`).join(' ');
571
- await exec(`git -C "${awHome}" add --sparse -f ${quotedFiles}`);
556
+ await exec(`git -C "${awHome}" add ${quotedFiles}`);
572
557
  } catch (e) {
573
558
  throw new Error(`Failed to stage files: ${e.message}`);
574
559
  }
package/integrate.mjs CHANGED
@@ -12,11 +12,6 @@ import {
12
12
  renderRules,
13
13
  resolveRulesSourceDir,
14
14
  } from './render-rules.mjs';
15
- import { isDefaultRoutingEnabled } from './startup.mjs';
16
- import {
17
- AW_DOCS_DIR,
18
- defaultAwDocsGithubDocsConfig,
19
- } from './constants.mjs';
20
15
 
21
16
  const AW_ROUTER_BRIDGE_HEADER = 'AW Router Bridge';
22
17
  const AW_ROUTER_BRIDGE_START_MARKER = '<!-- aw-managed:start router-bridge -->';
@@ -151,13 +146,11 @@ function applyManagedInstructionSections(content, file, rulesSections = {}, opti
151
146
  const rulesHeader = file === 'CLAUDE.md' ? CLAUDE_RULES_HEADER : AGENTS_RULES_HEADER;
152
147
  const rulesSection = file === 'CLAUDE.md' ? rulesSections.claudeSection : rulesSections.agentsSection;
153
148
  const includeBridge = options.includeBridge !== false;
154
- const managedBoundary = '<!-- aw-managed: content below is regenerated by `aw init` — put your own content above this line -->';
155
149
 
156
150
  let next = stripLegacyRepoInstructionContent(content, file);
157
151
  next = stripManagedBlock(next, AW_ROUTER_BRIDGE_START_MARKER, AW_ROUTER_BRIDGE_END_MARKER);
158
152
  next = stripManagedSection(next, AW_ROUTER_BRIDGE_HEADER, [rulesHeader]);
159
153
  next = stripManagedSection(next, rulesHeader);
160
- next = next.split('\n').filter(line => line.trim() !== managedBoundary).join('\n');
161
154
  next = next.trimEnd();
162
155
 
163
156
  const sections = [includeBridge ? generateAwRouterBridgeSection() : null, rulesSection].filter(Boolean);
@@ -168,8 +161,12 @@ function applyManagedInstructionSections(content, file, rulesSections = {}, opti
168
161
  // Marker tells users (and aw init) where the managed section starts.
169
162
  // Everything BEFORE this marker is repo-owned and never touched by aw.
170
163
  // Everything AFTER is managed by aw — re-rendered on every aw init.
164
+ const managedBoundary = '<!-- aw-managed: content below is regenerated by `aw init` — put your own content above this line -->';
171
165
  const appended = [managedBoundary, ...sections].join('\n\n').trim();
172
- return next ? `${next}\n\n${appended}\n` : `${appended}\n`;
166
+ // Strip any prior managedBoundary line from `next` so we don't accumulate them
167
+ // when re-running aw init.
168
+ const cleaned = next.split('\n').filter(line => line.trim() !== managedBoundary).join('\n').trimEnd();
169
+ return cleaned ? `${cleaned}\n\n${appended}\n` : `${appended}\n`;
173
170
  }
174
171
 
175
172
  /**
@@ -279,33 +276,7 @@ function syncHomeInstructionFile(destPath, file, rulesSection) {
279
276
  return destPath;
280
277
  }
281
278
 
282
- function stripManagedHomeInstructionFile(destPath, file) {
283
- if (!existsSync(destPath)) return null;
284
-
285
- const existing = readFileSync(destPath, 'utf8');
286
- const updated = applyManagedInstructionSections(existing, file, {}, { includeBridge: false });
287
- const emptyDefault = defaultInstructionPreamble(file).trim();
288
-
289
- if (updated.trim() === '' || updated.trim() === emptyDefault) {
290
- rmSync(destPath, { force: true });
291
- return destPath;
292
- }
293
-
294
- if (updated === existing) return null;
295
-
296
- writeFileSync(destPath, updated);
297
- return destPath;
298
- }
299
-
300
279
  export function syncHomeHarnessInstructions(homeDir = homedir()) {
301
- if (!isDefaultRoutingEnabled(homeDir)) {
302
- return [
303
- stripManagedHomeInstructionFile(join(homeDir, '.codex', 'AGENTS.md'), 'AGENTS.md'),
304
- stripManagedHomeInstructionFile(join(homeDir, '.claude', 'CLAUDE.md'), 'CLAUDE.md'),
305
- stripManagedHomeInstructionFile(join(homeDir, '.cursor', 'AGENTS.md'), 'AGENTS.md'),
306
- ].filter(Boolean);
307
- }
308
-
309
280
  const rulesDir = resolveRulesSourceDir(homeDir, { homeDir });
310
281
  const codexRulesSection = rulesDir
311
282
  ? generateAgentsMdRulesSection(rulesDir, {
@@ -614,14 +585,14 @@ Run with: \`/platform:eval agent:<slug>\` or \`/platform:eval skill:<slug>\`
614
585
  * Creates run tracking, learnings, task board, and cache directories.
615
586
  */
616
587
  export function initAwDocs(cwd) {
617
- const awDocsDir = join(cwd, AW_DOCS_DIR);
618
- const alreadyInitialized = existsSync(awDocsDir);
588
+ const awDocsDir = join(cwd, '.aw_docs');
589
+ if (existsSync(awDocsDir)) return; // Already initialized
619
590
 
620
591
  const dirs = [
621
- `${AW_DOCS_DIR}/runs`,
622
- `${AW_DOCS_DIR}/learnings`,
623
- `${AW_DOCS_DIR}/tasks`,
624
- `${AW_DOCS_DIR}/cache`,
592
+ '.aw_docs/runs',
593
+ '.aw_docs/learnings',
594
+ '.aw_docs/tasks',
595
+ '.aw_docs/cache',
625
596
  ];
626
597
 
627
598
  for (const dir of dirs) {
@@ -629,9 +600,7 @@ export function initAwDocs(cwd) {
629
600
  }
630
601
 
631
602
  // STATE.md — workspace state
632
- const statePath = join(awDocsDir, 'STATE.md');
633
- if (!existsSync(statePath)) {
634
- writeFileSync(statePath, `---
603
+ writeFileSync(join(awDocsDir, 'STATE.md'), `---
635
604
  active_run: null
636
605
  last_run: null
637
606
  last_workflow: null
@@ -644,60 +613,24 @@ pending_sync_count: 0
644
613
 
645
614
  No active runs. Use \`/aw:<team>-<command>\` to start a workflow.
646
615
  `);
647
- }
648
616
 
649
617
  // config.json — registry paths, sync settings
650
- const configPath = join(awDocsDir, 'config.json');
651
- const defaultConfig = {
618
+ writeFileSync(join(awDocsDir, 'config.json'), JSON.stringify({
652
619
  sync: {
653
620
  eager: true,
654
621
  batch_threshold: 10,
655
622
  mcp_memory_enabled: true,
656
- github_docs: defaultAwDocsGithubDocsConfig(),
657
623
  },
658
624
  paths: {
659
- runs: `${AW_DOCS_DIR}/runs`,
660
- learnings: `${AW_DOCS_DIR}/learnings`,
661
- tasks: `${AW_DOCS_DIR}/tasks`,
662
- cache: `${AW_DOCS_DIR}/cache`,
625
+ runs: '.aw_docs/runs',
626
+ learnings: '.aw_docs/learnings',
627
+ tasks: '.aw_docs/tasks',
628
+ cache: '.aw_docs/cache',
663
629
  },
664
- };
665
- let nextConfig = defaultConfig;
666
- if (existsSync(configPath)) {
667
- try {
668
- const existing = JSON.parse(readFileSync(configPath, 'utf8'));
669
- nextConfig = {
670
- ...existing,
671
- sync: {
672
- ...defaultConfig.sync,
673
- ...(existing.sync || {}),
674
- github_docs: {
675
- ...defaultConfig.sync.github_docs,
676
- ...(existing.sync?.github_docs || {}),
677
- },
678
- },
679
- paths: {
680
- ...defaultConfig.paths,
681
- ...(existing.paths || {}),
682
- },
683
- };
684
- } catch (e) {
685
- fmt.logWarn(`Could not migrate ${AW_DOCS_DIR}/config.json: ${e.message}`);
686
- nextConfig = null;
687
- }
688
- }
689
- if (nextConfig) {
690
- const nextConfigText = JSON.stringify(nextConfig, null, 2) + '\n';
691
- const existingText = existsSync(configPath) ? readFileSync(configPath, 'utf8') : '';
692
- if (existingText !== nextConfigText) {
693
- writeFileSync(configPath, nextConfigText);
694
- }
695
- }
630
+ }, null, 2) + '\n');
696
631
 
697
632
  // BOARD.md — task board
698
- const boardPath = join(awDocsDir, 'tasks', 'BOARD.md');
699
- if (!existsSync(boardPath)) {
700
- writeFileSync(boardPath, `---
633
+ writeFileSync(join(awDocsDir, 'tasks', 'BOARD.md'), `---
701
634
  tasks: []
702
635
  updated_at: null
703
636
  ---
@@ -706,17 +639,11 @@ updated_at: null
706
639
 
707
640
  No active tasks. Tasks are created during workflow execution.
708
641
  `);
709
- }
710
642
 
711
643
  // _pending-sync.jsonl — sync queue (empty)
712
- const pendingSyncPath = join(awDocsDir, 'learnings', '_pending-sync.jsonl');
713
- if (!existsSync(pendingSyncPath)) {
714
- writeFileSync(pendingSyncPath, '');
715
- }
644
+ writeFileSync(join(awDocsDir, 'learnings', '_pending-sync.jsonl'), '');
716
645
 
717
- if (!alreadyInitialized) {
718
- fmt.logSuccess('Orchestration state ready');
719
- }
646
+ fmt.logSuccess('Orchestration state ready');
720
647
  }
721
648
 
722
649
  /**