@ghl-ai/aw 0.1.48-beta.1 → 0.1.48
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/cli.mjs +4 -0
- package/commands/push.mjs +91 -22
- package/ecc.mjs +1 -1
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -50,6 +50,9 @@ function parseArgs(argv) {
|
|
|
50
50
|
if (arg === '--dry-run') {
|
|
51
51
|
args['--dry-run'] = true;
|
|
52
52
|
i++;
|
|
53
|
+
} else if (arg === '--aw-docs-only' || arg === '--docs-only') {
|
|
54
|
+
args[arg] = true;
|
|
55
|
+
i++;
|
|
53
56
|
} else if (arg === '-v' || arg === '--verbose') {
|
|
54
57
|
args['-v'] = true;
|
|
55
58
|
i++;
|
|
@@ -99,6 +102,7 @@ function printHelp() {
|
|
|
99
102
|
sec('Upload'),
|
|
100
103
|
cmd('aw push', 'Push all modified files (creates one PR)'),
|
|
101
104
|
cmd('aw push --aw-docs-only', 'Publish generated .aw_docs companions and print share links'),
|
|
105
|
+
cmd('aw push --aw-docs-only --feature <slug>', 'Publish one .aw_docs feature folder and print share links'),
|
|
102
106
|
cmd('aw push <path>', 'Push file, folder, or namespace to registry'),
|
|
103
107
|
cmd('aw push-rules [path]', 'Push platform rules to platform-docs'),
|
|
104
108
|
cmd('aw push --dry-run [path]', 'Preview what would be pushed'),
|
package/commands/push.mjs
CHANGED
|
@@ -144,13 +144,71 @@ function collectFiles(root, base = root) {
|
|
|
144
144
|
return files;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
function
|
|
147
|
+
function normalizeRelPath(value) {
|
|
148
|
+
return String(value || '')
|
|
149
|
+
.trim()
|
|
150
|
+
.replace(/\\/g, '/')
|
|
151
|
+
.replace(/^\.\//, '')
|
|
152
|
+
.replace(/\/+$/, '');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function featureScopeFromInput(input) {
|
|
156
|
+
const value = normalizeRelPath(input);
|
|
157
|
+
if (!value) return null;
|
|
158
|
+
|
|
159
|
+
const match = value.match(/^(?:\.aw_docs\/)?features\/([^/]+)$/);
|
|
160
|
+
if (!match) {
|
|
161
|
+
throw new Error('Docs-only publish path must be .aw_docs/features/<feature-slug> or use --feature <feature-slug>.');
|
|
162
|
+
}
|
|
163
|
+
return awDocsFeatureScope(match[1]);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function awDocsFeatureScope(featureSlug) {
|
|
167
|
+
const slug = String(featureSlug || '').trim();
|
|
168
|
+
if (!slug || slug === 'true') {
|
|
169
|
+
throw new Error('Missing feature slug. Use: aw push --aw-docs-only --feature <feature-slug>');
|
|
170
|
+
}
|
|
171
|
+
if (!/^[A-Za-z0-9._-]+$/.test(slug)) {
|
|
172
|
+
throw new Error(`Invalid feature slug "${slug}". Feature slugs may contain letters, numbers, dot, underscore, and dash only.`);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
type: 'feature',
|
|
176
|
+
slug,
|
|
177
|
+
relPrefix: `features/${slug}`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function resolveAwDocsScope(input, featureFlag) {
|
|
182
|
+
const inputScope = featureScopeFromInput(input);
|
|
183
|
+
const flagScope = featureFlag ? awDocsFeatureScope(featureFlag) : null;
|
|
184
|
+
if (inputScope && flagScope && inputScope.relPrefix !== flagScope.relPrefix) {
|
|
185
|
+
throw new Error(`Docs-only publish received conflicting scopes: ${inputScope.relPrefix} and ${flagScope.relPrefix}.`);
|
|
186
|
+
}
|
|
187
|
+
return flagScope || inputScope;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function collectProjectAwDocs(cwd, home, scope = null) {
|
|
148
191
|
const projectRoot = getProjectRoot(cwd, home);
|
|
149
192
|
const source = join(projectRoot, AW_DOCS_DIR);
|
|
150
193
|
|
|
151
194
|
if (!existsSync(source)) return { projectRoot, files: [] };
|
|
152
195
|
|
|
153
196
|
const files = [];
|
|
197
|
+
if (scope) {
|
|
198
|
+
const sourceRoot = join(source, scope.relPrefix);
|
|
199
|
+
if (!existsSync(sourceRoot) || !statSync(sourceRoot).isDirectory()) {
|
|
200
|
+
throw new Error(`No publishable AW docs found under ${AW_DOCS_DIR}/${scope.relPrefix}.`);
|
|
201
|
+
}
|
|
202
|
+
for (const relFromRoot of collectFiles(sourceRoot)) {
|
|
203
|
+
const relPath = `${scope.relPrefix}/${relFromRoot}`.replace(/\\/g, '/');
|
|
204
|
+
files.push({
|
|
205
|
+
relPath,
|
|
206
|
+
absPath: join(source, relPath),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return { projectRoot, files };
|
|
210
|
+
}
|
|
211
|
+
|
|
154
212
|
for (const root of PROJECT_AW_DOCS_AUTO_ROOTS) {
|
|
155
213
|
const sourceRoot = join(source, root);
|
|
156
214
|
if (!existsSync(sourceRoot)) continue;
|
|
@@ -480,7 +538,7 @@ function titleForAwDoc(relPath) {
|
|
|
480
538
|
return `${label} ${ext}`;
|
|
481
539
|
}
|
|
482
540
|
|
|
483
|
-
function updateAwDocsManifest(docsRepoDir, { repoSlug, sourceRepo, githubUsername, docs, publishConfig }) {
|
|
541
|
+
function updateAwDocsManifest(docsRepoDir, { repoSlug, sourceRepo, githubUsername, docs, publishConfig, scope = null }) {
|
|
484
542
|
const manifestPath = join(docsRepoDir, 'manifest.json');
|
|
485
543
|
const manifest = existsSync(manifestPath)
|
|
486
544
|
? JSON.parse(readFileSync(manifestPath, 'utf8'))
|
|
@@ -494,25 +552,32 @@ function updateAwDocsManifest(docsRepoDir, { repoSlug, sourceRepo, githubUsernam
|
|
|
494
552
|
repoEntry.slug = repoSlug;
|
|
495
553
|
repoEntry.sourceRepo = sourceRepo;
|
|
496
554
|
repoEntry.users ||= {};
|
|
555
|
+
const existingUser = repoEntry.users[githubUsername] || {};
|
|
556
|
+
const nextDocs = docs.map(doc => ({
|
|
557
|
+
relPath: doc.relPath,
|
|
558
|
+
publishedPath: doc.publishedPath,
|
|
559
|
+
remoteUrl: awDocsRemoteUrl(doc.publishedPath, publishConfig),
|
|
560
|
+
repositoryUrl: awDocsRepositoryUrl(doc.publishedPath, publishConfig),
|
|
561
|
+
sha: createHash('sha256').update(readFileSync(join(docsRepoDir, doc.publishedPath))).digest('hex'),
|
|
562
|
+
syncedAt: now,
|
|
563
|
+
title: titleForAwDoc(doc.relPath),
|
|
564
|
+
}));
|
|
565
|
+
const preservedDocs = scope?.relPrefix
|
|
566
|
+
? (existingUser.docs || []).filter(doc => !String(doc.relPath || '').startsWith(`${scope.relPrefix}/`))
|
|
567
|
+
: [];
|
|
568
|
+
|
|
497
569
|
repoEntry.users[githubUsername] = {
|
|
570
|
+
...existingUser,
|
|
498
571
|
githubUsername,
|
|
499
|
-
docs:
|
|
500
|
-
relPath: doc.relPath,
|
|
501
|
-
publishedPath: doc.publishedPath,
|
|
502
|
-
remoteUrl: awDocsRemoteUrl(doc.publishedPath, publishConfig),
|
|
503
|
-
repositoryUrl: awDocsRepositoryUrl(doc.publishedPath, publishConfig),
|
|
504
|
-
sha: createHash('sha256').update(readFileSync(join(docsRepoDir, doc.publishedPath))).digest('hex'),
|
|
505
|
-
syncedAt: now,
|
|
506
|
-
title: titleForAwDoc(doc.relPath),
|
|
507
|
-
})),
|
|
572
|
+
docs: scope?.relPrefix ? [...preservedDocs, ...nextDocs] : nextDocs,
|
|
508
573
|
};
|
|
509
574
|
manifest.awDocs.repos[repoSlug] = repoEntry;
|
|
510
575
|
|
|
511
576
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
512
577
|
}
|
|
513
578
|
|
|
514
|
-
async function publishProjectAwDocs(cwd, home, dryRun) {
|
|
515
|
-
const { projectRoot, files } = collectProjectAwDocs(cwd, home);
|
|
579
|
+
async function publishProjectAwDocs(cwd, home, dryRun, scope = null) {
|
|
580
|
+
const { projectRoot, files } = collectProjectAwDocs(cwd, home, scope);
|
|
516
581
|
if (files.length === 0) return { hasDocs: false, publishedPaths: [] };
|
|
517
582
|
|
|
518
583
|
const publishConfig = resolveAwDocsPublishConfig(projectRoot);
|
|
@@ -551,7 +616,10 @@ async function publishProjectAwDocs(cwd, home, dryRun) {
|
|
|
551
616
|
s.start(`Publishing ${files.length} AW doc${files.length > 1 ? 's' : ''} to ${publishConfig.repo}...`);
|
|
552
617
|
try {
|
|
553
618
|
const docsRepoDir = await ensureAwDocsRepoClone(home, publishConfig);
|
|
554
|
-
|
|
619
|
+
const deleteTarget = scope?.relPrefix
|
|
620
|
+
? join(docsRepoDir, publishConfig.dest, repoSlug, githubUsername, scope.relPrefix)
|
|
621
|
+
: join(docsRepoDir, publishConfig.dest, repoSlug, githubUsername);
|
|
622
|
+
rmSync(deleteTarget, {
|
|
555
623
|
recursive: true,
|
|
556
624
|
force: true,
|
|
557
625
|
});
|
|
@@ -560,7 +628,7 @@ async function publishProjectAwDocs(cwd, home, dryRun) {
|
|
|
560
628
|
mkdirSync(dirname(dest), { recursive: true });
|
|
561
629
|
copyFileSync(doc.absPath, dest);
|
|
562
630
|
}
|
|
563
|
-
updateAwDocsManifest(docsRepoDir, { repoSlug, sourceRepo, githubUsername, docs, publishConfig });
|
|
631
|
+
updateAwDocsManifest(docsRepoDir, { repoSlug, sourceRepo, githubUsername, docs, publishConfig, scope });
|
|
564
632
|
|
|
565
633
|
const { stdout: status } = await execFile('git', ['status', '--porcelain'], {
|
|
566
634
|
cwd: docsRepoDir,
|
|
@@ -574,7 +642,9 @@ async function publishProjectAwDocs(cwd, home, dryRun) {
|
|
|
574
642
|
}
|
|
575
643
|
|
|
576
644
|
await commitAndPushAwDocsRepo(docsRepoDir, {
|
|
577
|
-
message:
|
|
645
|
+
message: scope?.relPrefix
|
|
646
|
+
? `docs(aw): sync ${repoSlug}/${githubUsername} ${scope.relPrefix}`
|
|
647
|
+
: `docs(aw): sync ${repoSlug}/${githubUsername} AW docs`,
|
|
578
648
|
branch: publishConfig.branch,
|
|
579
649
|
});
|
|
580
650
|
writeAwDocsLinkSummary(projectRoot, links, publishConfig);
|
|
@@ -1074,14 +1144,13 @@ export async function pushCommand(args) {
|
|
|
1074
1144
|
}
|
|
1075
1145
|
|
|
1076
1146
|
if (docsOnly) {
|
|
1077
|
-
if (input) {
|
|
1078
|
-
fmt.cancel('Docs-only publish does not accept a path. Run: aw push --aw-docs-only');
|
|
1079
|
-
return;
|
|
1080
|
-
}
|
|
1081
1147
|
try {
|
|
1082
|
-
const
|
|
1148
|
+
const scope = resolveAwDocsScope(input, args['--feature']);
|
|
1149
|
+
const result = await publishProjectAwDocs(cwd, HOME, dryRun, scope);
|
|
1083
1150
|
if (!result.hasDocs) {
|
|
1084
|
-
fmt.cancel(
|
|
1151
|
+
fmt.cancel(scope
|
|
1152
|
+
? `No publishable AW docs found under ${AW_DOCS_DIR}/${scope.relPrefix}.`
|
|
1153
|
+
: 'No publishable AW docs found under .aw_docs/features or .aw_docs/html.');
|
|
1085
1154
|
return;
|
|
1086
1155
|
}
|
|
1087
1156
|
if (dryRun) fmt.outro(chalk.dim('Remove --dry-run to publish AW docs'));
|
package/ecc.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { applyStoredStartupPreferences } from "./startup.mjs";
|
|
|
12
12
|
|
|
13
13
|
const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
|
|
14
14
|
const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
|
|
15
|
-
export const AW_ECC_TAG = "v1.4.
|
|
15
|
+
export const AW_ECC_TAG = "v1.4.61";
|
|
16
16
|
|
|
17
17
|
const MARKETPLACE_NAME = "aw-marketplace";
|
|
18
18
|
const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
|