@ghl-ai/aw 0.1.36-beta.32 → 0.1.36-beta.33

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/pull.mjs CHANGED
@@ -7,7 +7,7 @@ import { execSync } from 'node:child_process';
7
7
  import * as config from '../config.mjs';
8
8
  import * as fmt from '../fmt.mjs';
9
9
  import { chalk } from '../fmt.mjs';
10
- import { fetchAndMerge, addToSparseCheckout, isValidClone, isWorktree, rebaseOntoOriginMain } from '../git.mjs';
10
+ import { fetchAndMerge, addToSparseCheckout, isValidClone, findNearestWorktree, rebaseOntoOriginMain } from '../git.mjs';
11
11
  import { REGISTRY_DIR, REGISTRY_REPO, REGISTRY_URL, DOCS_SOURCE_DIR } from '../constants.mjs';
12
12
  import { linkWorkspace } from '../link.mjs';
13
13
  import { generateCommands, copyInstructions } from '../integrate.mjs';
@@ -76,8 +76,8 @@ export async function pullCommand(args) {
76
76
  }
77
77
 
78
78
  // Always rebase project worktree's current branch onto origin/main
79
- const localAw = join(cwd, '.aw');
80
- if (cwd !== HOME && isWorktree(localAw)) {
79
+ const localAw = cwd !== HOME ? findNearestWorktree(cwd, HOME) : null;
80
+ if (localAw) {
81
81
  const rebaseSpinner = log.spinner();
82
82
  rebaseSpinner.start('Rebasing local branch onto latest...');
83
83
  try {
package/commands/push.mjs CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  createPushBranch,
16
16
  checkoutMain,
17
17
  isValidClone,
18
- isWorktree,
18
+ findNearestWorktree,
19
19
  getLocalRegistryDir,
20
20
  commitsAheadOfMain,
21
21
  logAheadOfMain,
@@ -422,8 +422,8 @@ export function pushCommand(args) {
422
422
 
423
423
  // If the project has a local worktree (.aw/ with a .git file), use it so
424
424
  // changes made inside the project are correctly detected and committed.
425
- const localAw = join(cwd, '.aw');
426
- const hasWorktree = isWorktree(localAw);
425
+ const localAw = findNearestWorktree(cwd, HOME);
426
+ const hasWorktree = localAw !== null;
427
427
  const awHome = hasWorktree ? localAw : globalAw;
428
428
  const registrySubDir = join(awHome, REGISTRY_DIR);
429
429
  const workspaceDir = getLocalRegistryDir(cwd, join(HOME, '.aw_registry'));
@@ -5,7 +5,7 @@ import { homedir } from 'node:os';
5
5
  import * as config from '../config.mjs';
6
6
  import * as fmt from '../fmt.mjs';
7
7
  import { chalk } from '../fmt.mjs';
8
- import { detectChanges, getCurrentBranch, commitsAheadOfMain, isValidClone, isWorktree } from '../git.mjs';
8
+ import { detectChanges, getCurrentBranch, commitsAheadOfMain, isValidClone, findNearestWorktree } from '../git.mjs';
9
9
  import { REGISTRY_DIR, REGISTRY_REPO, REGISTRY_URL } from '../constants.mjs';
10
10
 
11
11
  export function statusCommand(args) {
@@ -15,12 +15,12 @@ export function statusCommand(args) {
15
15
  const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
16
16
 
17
17
  // Use local project worktree if present so changes made there are visible
18
- const localAw = join(cwd, '.aw');
19
- const AW_HOME = isWorktree(localAw) ? localAw : globalAw;
18
+ const localAw = cwd !== HOME ? findNearestWorktree(cwd, HOME) : null;
19
+ const AW_HOME = localAw ?? globalAw;
20
20
 
21
21
  fmt.intro('aw status');
22
22
 
23
- if (!isWorktree(localAw) && !isValidClone(AW_HOME, REGISTRY_URL)) {
23
+ if (!localAw && !isValidClone(AW_HOME, REGISTRY_URL)) {
24
24
  fmt.cancel('Registry not initialized. Run: aw init');
25
25
  return;
26
26
  }
package/git.mjs CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  import { execSync, exec as execCb } from 'node:child_process';
4
4
  import { mkdtempSync, existsSync, lstatSync, rmSync } from 'node:fs';
5
- import { join, basename } from 'node:path';
6
- import { tmpdir } from 'node:os';
5
+ import { join, basename, dirname } from 'node:path';
6
+ import { homedir, tmpdir } from 'node:os';
7
7
  import { promisify } from 'node:util';
8
8
  import { REGISTRY_BASE_BRANCH, REGISTRY_DIR, DOCS_SOURCE_DIR } from './constants.mjs';
9
9
 
@@ -468,10 +468,28 @@ export function rebaseOntoOriginMain(awHome) {
468
468
  * worktree), so isWorktree returns false and the global fallback is used.
469
469
  */
470
470
  export function getLocalRegistryDir(cwd, fallback) {
471
- if (isWorktree(join(cwd, '.aw'))) return join(cwd, '.aw', REGISTRY_DIR);
471
+ const wt = findNearestWorktree(cwd, homedir());
472
+ if (wt) return join(wt, REGISTRY_DIR);
472
473
  return fallback;
473
474
  }
474
475
 
476
+ /**
477
+ * Walk up from `startDir` toward `stopDir` looking for the nearest `.aw`
478
+ * linked worktree. Returns the `.aw` path if found, null otherwise.
479
+ * Stops at `stopDir` (usually homedir) so it never escapes the user's tree.
480
+ */
481
+ export function findNearestWorktree(startDir, stopDir) {
482
+ let dir = startDir;
483
+ while (dir !== stopDir) {
484
+ const candidate = join(dir, '.aw');
485
+ if (isWorktree(candidate)) return candidate;
486
+ const parent = dirname(dir);
487
+ if (parent === dir) break; // filesystem root
488
+ dir = parent;
489
+ }
490
+ return null;
491
+ }
492
+
475
493
  /**
476
494
  * Check if dir is a git linked worktree (has .git as a FILE, not a directory).
477
495
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.36-beta.32",
3
+ "version": "0.1.36-beta.33",
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",