@ghl-ai/aw 0.1.82 → 0.1.84
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/push.mjs +34 -12
- package/package.json +1 -1
package/commands/push.mjs
CHANGED
|
@@ -416,26 +416,28 @@ function resolveAwDocsPublishConfig(projectRoot) {
|
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
async function removeTrackedAwSymlink(cloneDir) {
|
|
419
|
+
const awPath = join(cloneDir, '.aw');
|
|
420
|
+
// Only ever touch a STRAY on-disk `.aw` symlink (e.g. one the IDE/worktree
|
|
421
|
+
// `aw link` hook drops into the cache clone). Remove it from the WORKTREE
|
|
422
|
+
// ONLY, with a filesystem unlink — never a git command.
|
|
423
|
+
//
|
|
424
|
+
// The docs repo may track a real `.aw/` tree (ghl-aw-docs tracks
|
|
425
|
+
// `.aw/.aw_rules/**`). A `git rm .aw` here would stage a deletion of that
|
|
426
|
+
// committed content and push it away (this is exactly what corrupted
|
|
427
|
+
// master-sync). A plain unlink cannot stage anything, so it can never delete
|
|
428
|
+
// the committed tree — and since `.aw` is kept out of the sparse cone, the
|
|
429
|
+
// tracked tree is SKIP_WORKTREE and unaffected by removing the disk symlink.
|
|
419
430
|
try {
|
|
420
|
-
if (!lstatSync(
|
|
431
|
+
if (!lstatSync(awPath).isSymbolicLink()) return false;
|
|
421
432
|
} catch {
|
|
422
433
|
return false;
|
|
423
434
|
}
|
|
424
|
-
|
|
425
435
|
try {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
encoding: 'utf8',
|
|
429
|
-
});
|
|
436
|
+
rmSync(awPath, { force: true });
|
|
437
|
+
return true;
|
|
430
438
|
} catch {
|
|
431
439
|
return false;
|
|
432
440
|
}
|
|
433
|
-
|
|
434
|
-
await execFile('git', ['rm', '-f', '.aw'], {
|
|
435
|
-
cwd: cloneDir,
|
|
436
|
-
encoding: 'utf8',
|
|
437
|
-
});
|
|
438
|
-
return true;
|
|
439
441
|
}
|
|
440
442
|
|
|
441
443
|
function parseStatusPaths(status) {
|
|
@@ -480,9 +482,24 @@ async function selfHealManagedAwCacheDirtiness(cloneDir, status) {
|
|
|
480
482
|
});
|
|
481
483
|
|
|
482
484
|
if (await hasTrackedAwCachePaths(cloneDir)) {
|
|
485
|
+
// Restore a dirty tracked `.aw` from HEAD. In a full clone this cleans the
|
|
486
|
+
// worktree + index (the original behaviour). Best-effort (.catch): when `.aw`
|
|
487
|
+
// is sparse-excluded (out of cone) this pathspec can't match and the call is
|
|
488
|
+
// a no-op — but a sparse-excluded `.aw` is SKIP_WORKTREE and won't be dirty
|
|
489
|
+
// in the first place. This can only restore/un-stage, never delete tracked
|
|
490
|
+
// content.
|
|
483
491
|
await execFile('git', ['restore', '--staged', '--worktree', '--', '.aw'], {
|
|
484
492
|
cwd: cloneDir,
|
|
485
493
|
encoding: 'utf8',
|
|
494
|
+
}).catch((e) => {
|
|
495
|
+
const msg = (e?.stderr || e?.message || '').toString();
|
|
496
|
+
// Expected + ignorable: when `.aw` is sparse-excluded (out of cone) the
|
|
497
|
+
// pathspec cannot match, so the restore is simply a no-op.
|
|
498
|
+
if (/did not match any file|outside .*sparse-checkout/i.test(msg)) return;
|
|
499
|
+
// Anything else (permissions, index corruption, ...) is unexpected —
|
|
500
|
+
// surface it so a future `.aw` cache issue is diagnosable, but don't
|
|
501
|
+
// block the publish on a best-effort cleanup step.
|
|
502
|
+
fmt.logWarn(`AW docs cache: could not restore .aw (${msg.trim()})`);
|
|
486
503
|
});
|
|
487
504
|
}
|
|
488
505
|
|
|
@@ -579,6 +596,11 @@ async function getProjectSourceRepo(projectRoot) {
|
|
|
579
596
|
const AW_DOCS_GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: '0', GCM_INTERACTIVE: 'never' };
|
|
580
597
|
const AW_DOCS_CLONE_TIMEOUT_MS = Number(process.env.AW_DOCS_GIT_TIMEOUT_MS) || 180000;
|
|
581
598
|
const AW_DOCS_NET_TIMEOUT_MS = Number(process.env.AW_DOCS_GIT_TIMEOUT_MS) || 120000;
|
|
599
|
+
// NOTE: `.aw` is intentionally NOT added to the sparse cone. The docs repo may
|
|
600
|
+
// track a real `.aw/` tree (ghl-aw-docs tracks `.aw/.aw_rules/**`); keeping it
|
|
601
|
+
// out of the cone leaves that tree SKIP_WORKTREE so no publish can materialise
|
|
602
|
+
// or (crucially) stage a deletion of it. Any stray on-disk `.aw` symlink is
|
|
603
|
+
// removed worktree-only via a filesystem unlink (see removeTrackedAwSymlink).
|
|
582
604
|
|
|
583
605
|
async function awDocsSparseEnabled(cloneDir) {
|
|
584
606
|
try {
|