@ghl-ai/aw 0.1.36-beta.93 → 0.1.36-beta.95

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
@@ -205,7 +205,15 @@ export async function initCommand(args) {
205
205
  // ── Re-init path: already set up with native git clone ────────────────
206
206
 
207
207
  if (isGitNative) {
208
- const cfg = config.load(GLOBAL_AW_DIR);
208
+ let cfg = config.load(GLOBAL_AW_DIR);
209
+
210
+ // Migration: create minimal config if it's missing (older installs may not have it)
211
+ if (!cfg) {
212
+ try {
213
+ config.create(GLOBAL_AW_DIR, { namespace: team || null, user: '' });
214
+ cfg = config.load(GLOBAL_AW_DIR);
215
+ } catch { /* GLOBAL_AW_DIR may not exist yet — full-init path will create it below */ }
216
+ }
209
217
 
210
218
  const isNewSubTeam = folderName && cfg && !cfg.include.includes(folderName);
211
219
  if (isNewSubTeam) {
package/commands/pull.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  import { mkdirSync, existsSync, readdirSync, copyFileSync, unlinkSync, rmdirSync, lstatSync } from 'node:fs';
4
4
  import { join, relative, extname } from 'node:path';
5
5
  import { homedir } from 'node:os';
6
- import { exec as execCb } from 'node:child_process';
6
+ import { exec as execCb, execSync } from 'node:child_process';
7
7
  import { promisify } from 'node:util';
8
8
 
9
9
  const exec = promisify(execCb);
@@ -11,7 +11,7 @@ import * as config from '../config.mjs';
11
11
  import * as fmt from '../fmt.mjs';
12
12
  import { chalk } from '../fmt.mjs';
13
13
  import { fetchAndMerge, addToSparseCheckout, removeFromSparseCheckout, syncWorktreeSparseCheckout, isValidClone, findNearestWorktree, rebaseOntoOriginMain } from '../git.mjs';
14
- import { REGISTRY_DIR, REGISTRY_REPO, REGISTRY_URL, DOCS_SOURCE_DIR } from '../constants.mjs';
14
+ import { REGISTRY_DIR, REGISTRY_URL, DOCS_SOURCE_DIR } from '../constants.mjs';
15
15
  import { linkWorkspace } from '../link.mjs';
16
16
  import { generateCommands, copyInstructions } from '../integrate.mjs';
17
17
 
@@ -89,7 +89,7 @@ export async function pullCommand(args) {
89
89
  s.start('Fetching latest from registry...');
90
90
  let fetchResult = { updated: false, conflicts: [] };
91
91
  try {
92
- fetchResult = await fetchAndMerge(AW_HOME);
92
+ fetchResult = await fetchAndMerge(AW_HOME, { silent });
93
93
  s.stop(fetchResult.updated ? 'Registry updated' : 'Already up to date');
94
94
  } catch (e) {
95
95
  s.stop(chalk.yellow('Fetch failed'));
@@ -113,14 +113,24 @@ export async function pullCommand(args) {
113
113
 
114
114
  if (fetchResult.conflicts.length > 0) {
115
115
  if (!silent) {
116
- // Interactive mode: abort the merge so the working tree is clean again
117
- try { await exec(`git -C "${AW_HOME}" merge --abort`); } catch { /* best effort */ }
118
- log.logWarn(`Merge conflict in: ${fetchResult.conflicts.join(', ')}`);
119
- log.logWarn('Merge aborted your branch is unchanged. Resolve conflicts and run `aw pull` again.');
116
+ // Interactive: fetchAndMerge left the rebase in-progress with conflict markers.
117
+ // Do NOT touch git here the user needs to resolve the markers in their IDE.
118
+ // Skipping syncDocs and IDE re-linking intentionally: working tree is partially
119
+ // applied (conflict markers in files) and must not be synced in this state.
120
+ log.logWarn('Conflicts detected. Open the files in your IDE and resolve the markers:');
121
+ for (const f of fetchResult.conflicts) {
122
+ log.logMessage(` ${chalk.red('✗')} ${f}`);
123
+ }
124
+ log.logWarn('After resolving, run:');
125
+ log.logMessage(` git -C "${AW_HOME}" rebase --continue`);
126
+ log.logWarn('Then run `aw pull` again to complete the sync.');
127
+ log.logWarn('(On a push branch: also run `aw push` after to update your PR.)');
128
+ log.outro(chalk.yellow('Pull paused — resolve conflicts to continue'));
120
129
  return;
121
130
  }
122
- // Silent mode: leave conflict markers in place for IDE to show
123
- log.logWarn(`Conflicts in: ${fetchResult.conflicts.join(', ')}`);
131
+ // Silent: fetchAndMerge already ran rebase --abort. Repo is clean. Warn and continue
132
+ // so syncDocs and IDE re-linking still run against the clean (pre-conflict) state.
133
+ log.logWarn(`Conflicts detected and aborted: ${fetchResult.conflicts.join(', ')}`);
124
134
  }
125
135
 
126
136
  // Rebase project worktree branch onto origin/main — only for legacy git worktrees.
package/git.mjs CHANGED
@@ -255,11 +255,15 @@ export async function fetchAndMerge(awHome, { silent = true } = {}) {
255
255
  const isDrift = !isBaseBranch && !isPushBranch && currentBranch !== 'HEAD';
256
256
 
257
257
  if (isDrift) {
258
- // Re-enable sparse checkout (may have been disabled by an old --no-edit merge)
258
+ // Re-enable sparse checkout (may have been disabled by an old --no-edit merge).
259
+ // After `git sparse-checkout init --no-cone`, git resets paths to `/*` + `!/*/`
260
+ // (root files only, no subdirectories) — which excludes .aw_registry/.
261
+ // We must explicitly set the registry path so files materialise on checkout.
259
262
  try {
260
263
  await exec(`git -C "${awHome}" sparse-checkout init --no-cone`);
261
264
  const { stdout: listOut } = await exec(`git -C "${awHome}" sparse-checkout list`);
262
- if (!listOut.trim()) {
265
+ const hasPaths = listOut.trim().split('\n').filter(Boolean).some(p => p.includes(REGISTRY_DIR));
266
+ if (!hasPaths) {
263
267
  await exec(`git -C "${awHome}" sparse-checkout set "${REGISTRY_DIR}/"`);
264
268
  }
265
269
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.36-beta.93",
3
+ "version": "0.1.36-beta.95",
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",