@ghl-ai/aw 0.1.36-beta.86 → 0.1.36-beta.88
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 +26 -1
- package/git.mjs +57 -15
- package/package.json +1 -1
package/commands/init.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Uses core.hooksPath (git-lfs pattern) for system-wide hook interception.
|
|
5
5
|
// Uses IDE tasks for auto-pull on workspace open.
|
|
6
6
|
|
|
7
|
-
import { existsSync, writeFileSync, symlinkSync, lstatSync, readdirSync, readFileSync, rmSync, realpathSync, appendFileSync } from 'node:fs';
|
|
7
|
+
import { existsSync, mkdirSync, writeFileSync, symlinkSync, lstatSync, readdirSync, readFileSync, rmSync, realpathSync, appendFileSync } from 'node:fs';
|
|
8
8
|
import { execSync } from 'node:child_process';
|
|
9
9
|
import { join, dirname, sep } from 'node:path';
|
|
10
10
|
import { homedir } from 'node:os';
|
|
@@ -103,6 +103,29 @@ function installIdeTasks() {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Write .vscode/settings.json so Cursor/VS Code always treats .aw/ as a git
|
|
108
|
+
* repository — even on first load before the symlink existed at scan time.
|
|
109
|
+
* Without this, the git panel is blank until the user reloads the IDE.
|
|
110
|
+
*/
|
|
111
|
+
function installVscodeGitSettings(projectDir) {
|
|
112
|
+
if (!projectDir || projectDir === HOME) return;
|
|
113
|
+
try {
|
|
114
|
+
const vscodeDir = join(projectDir, '.vscode');
|
|
115
|
+
mkdirSync(vscodeDir, { recursive: true });
|
|
116
|
+
const settingsPath = join(vscodeDir, 'settings.json');
|
|
117
|
+
let settings = {};
|
|
118
|
+
if (existsSync(settingsPath)) {
|
|
119
|
+
try { settings = JSON.parse(readFileSync(settingsPath, 'utf8')); } catch { /* corrupted — overwrite */ }
|
|
120
|
+
}
|
|
121
|
+
const repos = settings['git.additionalRepositories'] || [];
|
|
122
|
+
if (!repos.includes('.aw')) {
|
|
123
|
+
settings['git.additionalRepositories'] = [...repos, '.aw'];
|
|
124
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
125
|
+
}
|
|
126
|
+
} catch { /* best effort */ }
|
|
127
|
+
}
|
|
128
|
+
|
|
106
129
|
const ALLOWED_NAMESPACES = ['platform', 'revex', 'mobile', 'commerce', 'leadgen', 'crm', 'marketplace', 'ai'];
|
|
107
130
|
|
|
108
131
|
export async function initCommand(args) {
|
|
@@ -272,6 +295,7 @@ export async function initCommand(args) {
|
|
|
272
295
|
if (!silent) fmt.logStep('Linked current project');
|
|
273
296
|
} catch { /* best effort */ }
|
|
274
297
|
}
|
|
298
|
+
installVscodeGitSettings(cwd !== HOME ? cwd : null);
|
|
275
299
|
|
|
276
300
|
// Wire ~/.claude/.cursor/.codex to the project's registry when in a project,
|
|
277
301
|
// so edits to project/.aw/.aw_registry/ are instantly visible in global IDE dirs.
|
|
@@ -398,6 +422,7 @@ export async function initCommand(args) {
|
|
|
398
422
|
fmt.logStep('Linked current project');
|
|
399
423
|
} catch { /* best effort */ }
|
|
400
424
|
}
|
|
425
|
+
installVscodeGitSettings(cwd !== HOME ? cwd : null);
|
|
401
426
|
|
|
402
427
|
// Step 5: Wire ~/.claude/.cursor/.codex to the project's registry when in a project,
|
|
403
428
|
// so edits to project/.aw/.aw_registry/ are instantly visible in global IDE dirs.
|
package/git.mjs
CHANGED
|
@@ -231,32 +231,74 @@ export function removeFromSparseCheckout(awHome, removePaths) {
|
|
|
231
231
|
*/
|
|
232
232
|
export async function fetchAndMerge(awHome, { silent = true } = {}) {
|
|
233
233
|
// ── 1. Branch guard ──────────────────────────────────────────────────────
|
|
234
|
-
// If ~/.aw
|
|
235
|
-
// `
|
|
236
|
-
//
|
|
234
|
+
// If ~/.aw drifted off REGISTRY_BASE_BRANCH (e.g. partial init left it on
|
|
235
|
+
// `main`), repair the sparse checkout and switch back — then RETURN EARLY.
|
|
236
|
+
// We never run fetch/rebase on a wrong-branch run: a --no-edit merge or a
|
|
237
|
+
// rebase between unrelated histories can disable sparse checkout and wipe
|
|
238
|
+
// the working tree. The NEXT aw init call (hook/IDE/user) will do the sync.
|
|
237
239
|
try {
|
|
238
240
|
const { stdout: branchOut } = await exec(
|
|
239
241
|
`git -C "${awHome}" rev-parse --abbrev-ref HEAD`,
|
|
240
242
|
);
|
|
241
243
|
const currentBranch = branchOut.trim();
|
|
244
|
+
|
|
242
245
|
if (currentBranch !== REGISTRY_BASE_BRANCH && currentBranch !== 'HEAD') {
|
|
243
|
-
|
|
246
|
+
// Re-enable sparse checkout before switching branches.
|
|
247
|
+
// If sparse-checkout was disabled (e.g. by an old --no-edit merge),
|
|
248
|
+
// `init --no-cone` restores it from the existing sparse-checkout file.
|
|
249
|
+
// If the file is also empty/gone we set a safe fallback covering the
|
|
250
|
+
// whole registry so the checkout materialises *something*.
|
|
244
251
|
try {
|
|
245
|
-
|
|
246
|
-
|
|
252
|
+
await exec(`git -C "${awHome}" sparse-checkout init --no-cone`);
|
|
253
|
+
const { stdout: listOut } = await exec(
|
|
254
|
+
`git -C "${awHome}" sparse-checkout list`,
|
|
247
255
|
);
|
|
248
|
-
|
|
249
|
-
|
|
256
|
+
if (!listOut.trim()) {
|
|
257
|
+
// Paths were cleared — restore a safe default (full registry tree)
|
|
258
|
+
await exec(
|
|
259
|
+
`git -C "${awHome}" sparse-checkout set "${REGISTRY_DIR}/"`,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
} catch {
|
|
263
|
+
// Completely broken sparse config — force a safe default
|
|
264
|
+
try {
|
|
265
|
+
await exec(`git -C "${awHome}" sparse-checkout init --no-cone`);
|
|
266
|
+
await exec(
|
|
267
|
+
`git -C "${awHome}" sparse-checkout set "${REGISTRY_DIR}/"`,
|
|
268
|
+
);
|
|
269
|
+
} catch { /* best effort */ }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Switch to the correct branch; this materialises files via lazy fetch.
|
|
250
273
|
try {
|
|
251
274
|
await exec(`git -C "${awHome}" checkout ${REGISTRY_BASE_BRANCH}`);
|
|
252
|
-
} catch {
|
|
253
|
-
|
|
254
|
-
|
|
275
|
+
} catch {
|
|
276
|
+
// checkout failed — repo is in a bad state we cannot repair here.
|
|
277
|
+
// Return without touching anything; the user can run `aw init` to
|
|
278
|
+
// trigger a full re-clone via initPersistentClone.
|
|
279
|
+
return { updated: false, conflicts: [] };
|
|
255
280
|
}
|
|
281
|
+
|
|
282
|
+
// Branch repaired. Do NOT continue to fetch/rebase on this same run —
|
|
283
|
+
// that combination is what caused the original wipe.
|
|
284
|
+
return { updated: false, conflicts: [] };
|
|
256
285
|
}
|
|
257
|
-
} catch { /*
|
|
286
|
+
} catch { /* branch detection failed — proceed with normal sync */ }
|
|
287
|
+
|
|
288
|
+
// ── 2. Repair sparse checkout if disabled on correct branch ──────────────
|
|
289
|
+
// Guard: if something disabled sparse checkout while on the right branch
|
|
290
|
+
// (should be rare), re-enable before fetch so the working tree stays intact.
|
|
291
|
+
try {
|
|
292
|
+
await exec(`git -C "${awHome}" sparse-checkout list`);
|
|
293
|
+
} catch {
|
|
294
|
+
try {
|
|
295
|
+
await exec(`git -C "${awHome}" sparse-checkout init --no-cone`);
|
|
296
|
+
// Re-checkout to materialise files according to restored sparse config
|
|
297
|
+
await exec(`git -C "${awHome}" checkout ${REGISTRY_BASE_BRANCH}`);
|
|
298
|
+
} catch { /* best effort */ }
|
|
299
|
+
}
|
|
258
300
|
|
|
259
|
-
// ──
|
|
301
|
+
// ── 3. Fetch ──────────────────────────────────────────────────────────────
|
|
260
302
|
try {
|
|
261
303
|
await exec(`git -C "${awHome}" fetch origin ${REGISTRY_BASE_BRANCH}`);
|
|
262
304
|
} catch (e) {
|
|
@@ -266,7 +308,7 @@ export async function fetchAndMerge(awHome, { silent = true } = {}) {
|
|
|
266
308
|
let updated = false;
|
|
267
309
|
const conflicts = [];
|
|
268
310
|
|
|
269
|
-
// ──
|
|
311
|
+
// ── 4. Fast-forward (clean case — no local commits ahead of remote) ──────
|
|
270
312
|
try {
|
|
271
313
|
const { stdout } = await exec(
|
|
272
314
|
`git -C "${awHome}" merge origin/${REGISTRY_BASE_BRANCH} --ff-only`,
|
|
@@ -275,7 +317,7 @@ export async function fetchAndMerge(awHome, { silent = true } = {}) {
|
|
|
275
317
|
return { updated, conflicts };
|
|
276
318
|
} catch { /* ff-only failed — local commits exist, fall through to rebase */ }
|
|
277
319
|
|
|
278
|
-
// ──
|
|
320
|
+
// ── 5. Rebase local commits onto remote ───────────────────────────────────
|
|
279
321
|
// Rebase keeps history linear and never disables sparse checkout.
|
|
280
322
|
try {
|
|
281
323
|
await exec(`git -C "${awHome}" rebase origin/${REGISTRY_BASE_BRANCH}`);
|