@ghl-ai/aw 0.1.63 → 0.1.65
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 +111 -17
- package/constants.mjs +1 -1
- package/package.json +1 -1
package/commands/push.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
readdirSync,
|
|
11
11
|
copyFileSync,
|
|
12
12
|
rmSync,
|
|
13
|
+
renameSync,
|
|
13
14
|
writeFileSync,
|
|
14
15
|
} from 'node:fs';
|
|
15
16
|
import { join, dirname, basename } from 'node:path';
|
|
@@ -307,16 +308,6 @@ function resolveAwDocsPublishConfig(projectRoot) {
|
|
|
307
308
|
};
|
|
308
309
|
}
|
|
309
310
|
|
|
310
|
-
function isOnlyUntrackedAwSymlink(status, cloneDir) {
|
|
311
|
-
const lines = status.trim().split('\n').filter(Boolean);
|
|
312
|
-
if (lines.length !== 1 || !/^\?\?\s+\.aw\/?$/.test(lines[0])) return false;
|
|
313
|
-
try {
|
|
314
|
-
return lstatSync(join(cloneDir, '.aw')).isSymbolicLink();
|
|
315
|
-
} catch {
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
311
|
async function removeTrackedAwSymlink(cloneDir) {
|
|
321
312
|
try {
|
|
322
313
|
if (!lstatSync(join(cloneDir, '.aw')).isSymbolicLink()) return false;
|
|
@@ -340,6 +331,93 @@ async function removeTrackedAwSymlink(cloneDir) {
|
|
|
340
331
|
return true;
|
|
341
332
|
}
|
|
342
333
|
|
|
334
|
+
function parseStatusPaths(status) {
|
|
335
|
+
return status
|
|
336
|
+
.split('\n')
|
|
337
|
+
.filter(line => line.trim())
|
|
338
|
+
.flatMap(line => line.slice(3).trim().split(' -> '));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function isManagedAwCachePath(path) {
|
|
342
|
+
return path === '.aw' || path.startsWith('.aw/');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function isOnlyManagedAwCacheDirtiness(status) {
|
|
346
|
+
const paths = parseStatusPaths(status);
|
|
347
|
+
return paths.length > 0 && paths.every(isManagedAwCachePath);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
async function hasTrackedAwCachePaths(cloneDir) {
|
|
351
|
+
const { stdout } = await execFile('git', ['ls-files', '--', '.aw'], {
|
|
352
|
+
cwd: cloneDir,
|
|
353
|
+
encoding: 'utf8',
|
|
354
|
+
});
|
|
355
|
+
return stdout.trim().length > 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async function treeHasAwCachePaths(repoDir, treeish) {
|
|
359
|
+
const { stdout } = await execFile('git', ['ls-tree', '-r', '--name-only', treeish, '--', '.aw'], {
|
|
360
|
+
cwd: repoDir,
|
|
361
|
+
encoding: 'utf8',
|
|
362
|
+
});
|
|
363
|
+
return stdout.trim().length > 0;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async function selfHealManagedAwCacheDirtiness(cloneDir, status) {
|
|
367
|
+
if (!isOnlyManagedAwCacheDirtiness(status)) return false;
|
|
368
|
+
|
|
369
|
+
rmSync(join(cloneDir, '.aw'), { recursive: true, force: true });
|
|
370
|
+
await execFile('git', ['clean', '-fd', '--', '.aw'], {
|
|
371
|
+
cwd: cloneDir,
|
|
372
|
+
encoding: 'utf8',
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
if (await hasTrackedAwCachePaths(cloneDir)) {
|
|
376
|
+
await execFile('git', ['restore', '--staged', '--worktree', '--', '.aw'], {
|
|
377
|
+
cwd: cloneDir,
|
|
378
|
+
encoding: 'utf8',
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function moveLocalAwCachePathAside(cloneDir) {
|
|
386
|
+
const awPath = join(cloneDir, '.aw');
|
|
387
|
+
if (!existsSync(awPath)) return null;
|
|
388
|
+
|
|
389
|
+
const parentDir = dirname(cloneDir);
|
|
390
|
+
const cloneName = basename(cloneDir);
|
|
391
|
+
const stamp = new Date().toISOString().replace(/[^0-9T]/g, '').slice(0, 15);
|
|
392
|
+
let backupPath = join(parentDir, `${cloneName}.untracked-aw-backup-${stamp}`);
|
|
393
|
+
let suffix = 1;
|
|
394
|
+
while (existsSync(backupPath)) {
|
|
395
|
+
backupPath = join(parentDir, `${cloneName}.untracked-aw-backup-${stamp}-${suffix}`);
|
|
396
|
+
suffix += 1;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
renameSync(awPath, backupPath);
|
|
400
|
+
if (process.env.AW_DEBUG) {
|
|
401
|
+
fmt.logWarn(`Moved ignored AW docs cache .aw path aside: ${backupPath}`);
|
|
402
|
+
}
|
|
403
|
+
return backupPath;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
async function selfHealIgnoredAwCachePath(cloneDir) {
|
|
407
|
+
const awPath = join(cloneDir, '.aw');
|
|
408
|
+
if (!existsSync(awPath)) return null;
|
|
409
|
+
if (await hasTrackedAwCachePaths(cloneDir)) return null;
|
|
410
|
+
return moveLocalAwCachePathAside(cloneDir);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function isCheckoutOverwrittenByAwPathError(error) {
|
|
414
|
+
const text = [error?.message, error?.stderr, error?.stdout]
|
|
415
|
+
.filter(Boolean)
|
|
416
|
+
.join('\n');
|
|
417
|
+
return /untracked working tree files would be overwritten/i.test(text)
|
|
418
|
+
&& /(?:^|\s)\.aw(?:\/|$)/m.test(text);
|
|
419
|
+
}
|
|
420
|
+
|
|
343
421
|
async function getGitStatus(repoDir) {
|
|
344
422
|
const { stdout } = await execFile('git', ['status', '--porcelain'], {
|
|
345
423
|
cwd: repoDir,
|
|
@@ -397,8 +475,7 @@ async function ensureAwDocsRepoClone(home, publishConfig) {
|
|
|
397
475
|
}
|
|
398
476
|
|
|
399
477
|
let status = await getGitStatus(cloneDir);
|
|
400
|
-
if (status.trim() &&
|
|
401
|
-
rmSync(join(cloneDir, '.aw'), { force: true });
|
|
478
|
+
if (status.trim() && await selfHealManagedAwCacheDirtiness(cloneDir, status)) {
|
|
402
479
|
status = await getGitStatus(cloneDir);
|
|
403
480
|
}
|
|
404
481
|
if (status.trim()) {
|
|
@@ -419,10 +496,27 @@ async function ensureAwDocsRepoClone(home, publishConfig) {
|
|
|
419
496
|
? `origin/${publishConfig.branch}`
|
|
420
497
|
: `origin/${publishConfig.seedBranch}`;
|
|
421
498
|
|
|
422
|
-
await
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
499
|
+
if (await treeHasAwCachePaths(cloneDir, checkoutStart)) {
|
|
500
|
+
await selfHealIgnoredAwCachePath(cloneDir);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
try {
|
|
504
|
+
await execFile('git', ['checkout', '-B', publishConfig.branch, checkoutStart], {
|
|
505
|
+
cwd: cloneDir,
|
|
506
|
+
encoding: 'utf8',
|
|
507
|
+
});
|
|
508
|
+
} catch (e) {
|
|
509
|
+
const healedPath = isCheckoutOverwrittenByAwPathError(e)
|
|
510
|
+
? await selfHealIgnoredAwCachePath(cloneDir)
|
|
511
|
+
: null;
|
|
512
|
+
if (!healedPath) {
|
|
513
|
+
throw e;
|
|
514
|
+
}
|
|
515
|
+
await execFile('git', ['checkout', '-B', publishConfig.branch, checkoutStart], {
|
|
516
|
+
cwd: cloneDir,
|
|
517
|
+
encoding: 'utf8',
|
|
518
|
+
});
|
|
519
|
+
}
|
|
426
520
|
|
|
427
521
|
if (hasPublishBranch) {
|
|
428
522
|
await execFile('git', ['pull', '--ff-only', 'origin', publishConfig.branch], {
|
|
@@ -501,7 +595,7 @@ function printAwDocsLinks(links, limit = 10) {
|
|
|
501
595
|
fmt.logInfo(chalk.bold('Remote Docs'));
|
|
502
596
|
for (const link of links.slice(0, limit)) {
|
|
503
597
|
fmt.logInfo(` ${chalk.dim(link.relPath)}`);
|
|
504
|
-
fmt.logInfo(`
|
|
598
|
+
fmt.logInfo(` Devtools: ${chalk.cyan(link.remoteUrl)}`);
|
|
505
599
|
if (link.repositoryUrl && link.repositoryUrl !== link.remoteUrl) {
|
|
506
600
|
fmt.logInfo(` GitHub: ${chalk.cyan(link.repositoryUrl)}`);
|
|
507
601
|
}
|
package/constants.mjs
CHANGED
|
@@ -33,7 +33,7 @@ export const AW_DOCS_BASE_BRANCH = 'master-sync';
|
|
|
33
33
|
export const AW_DOCS_SEED_BRANCH = process.env.AW_DOCS_SEED_BRANCH || 'scaffold';
|
|
34
34
|
export const AW_DOCS_PUBLISH_DIR = 'aw_docs';
|
|
35
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://
|
|
36
|
+
export const AW_DOCS_TEAMOFONE_ORIGIN = process.env.AW_DOCS_TEAMOFONE_ORIGIN || 'https://devtools.servers.stg.msgsndr.net';
|
|
37
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
38
|
|
|
39
39
|
export function defaultAwDocsGithubDocsConfig() {
|