@ghl-ai/aw 0.1.34-beta.1 → 0.1.34-beta.2
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/pull.mjs +2 -2
- package/commands/push.mjs +23 -8
- package/commands/status.mjs +23 -1
- package/constants.mjs +1 -1
- package/manifest.mjs +4 -2
- package/package.json +1 -1
- package/plan.mjs +4 -1
package/commands/pull.mjs
CHANGED
|
@@ -178,7 +178,7 @@ export async function pullCommand(args) {
|
|
|
178
178
|
const s2 = log.spinner();
|
|
179
179
|
s2.start('Applying changes...');
|
|
180
180
|
const conflictCount = applyActions(actions, { teamNS: teamNSOverride || renameNamespace || undefined });
|
|
181
|
-
updateManifest(workspaceDir, actions, cfg.namespace);
|
|
181
|
+
updateManifest(workspaceDir, actions, cfg.namespace, { fromTemplate: !!renameNamespace });
|
|
182
182
|
s2.stop('Changes applied');
|
|
183
183
|
|
|
184
184
|
// Copy root-level registry files (e.g. AW-PROTOCOL.md) that are fetched via
|
|
@@ -282,7 +282,7 @@ export async function pullAsync(args) {
|
|
|
282
282
|
const { actions: rawActions } = computePlan(registryDirs, workspaceDir, [pattern], { skipOrphans: true });
|
|
283
283
|
const actions = filterActions(rawActions, pattern);
|
|
284
284
|
const conflictCount = applyActions(actions, { teamNS: teamNSOverride || renameNamespace || undefined });
|
|
285
|
-
updateManifest(workspaceDir, actions, cfg.namespace);
|
|
285
|
+
updateManifest(workspaceDir, actions, cfg.namespace, { fromTemplate: !!renameNamespace });
|
|
286
286
|
|
|
287
287
|
const ROOT_REGISTRY_FILES = ['AW-PROTOCOL.md'];
|
|
288
288
|
for (const fname of ROOT_REGISTRY_FILES) {
|
package/commands/push.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import * as fmt from '../fmt.mjs';
|
|
|
8
8
|
import { chalk } from '../fmt.mjs';
|
|
9
9
|
import { REGISTRY_REPO, REGISTRY_BASE_BRANCH, REGISTRY_DIR } from '../constants.mjs';
|
|
10
10
|
import { resolveInput } from '../paths.mjs';
|
|
11
|
-
import { load as loadManifest } from '../manifest.mjs';
|
|
11
|
+
import { load as loadManifest, save as saveManifest } from '../manifest.mjs';
|
|
12
12
|
import { hashFile, walkRegistryTree } from '../registry.mjs';
|
|
13
13
|
|
|
14
14
|
const PUSHABLE_TYPES = ['agents', 'skills', 'commands', 'evals'];
|
|
@@ -53,7 +53,9 @@ function collectModifiedFiles(workspaceDir) {
|
|
|
53
53
|
const filePath = join(workspaceDir, key);
|
|
54
54
|
if (!existsSync(filePath)) continue;
|
|
55
55
|
const currentHash = hashFile(filePath);
|
|
56
|
-
|
|
56
|
+
const isModified = currentHash !== entry.sha256;
|
|
57
|
+
const isNew = !entry.registry_sha256; // Template-derived, never pushed to remote
|
|
58
|
+
if (isModified || isNew) {
|
|
57
59
|
const meta = parseManifestKey(key);
|
|
58
60
|
if (meta) {
|
|
59
61
|
files.push({
|
|
@@ -170,7 +172,7 @@ function generatePrBody(files, newNamespaces) {
|
|
|
170
172
|
|
|
171
173
|
// ── Git pipeline (works for single file or batch) ────────────────────
|
|
172
174
|
|
|
173
|
-
function pushFiles(files, { repo, dryRun }) {
|
|
175
|
+
function pushFiles(files, { repo, dryRun, workspaceDir }) {
|
|
174
176
|
// Summary
|
|
175
177
|
const counts = {};
|
|
176
178
|
for (const f of files) {
|
|
@@ -289,6 +291,19 @@ function pushFiles(files, { repo, dryRun }) {
|
|
|
289
291
|
fmt.logSuccess(`${items.length} ${type} pushed`);
|
|
290
292
|
}
|
|
291
293
|
}
|
|
294
|
+
// Update manifest — mark pushed files as synced (set registry_sha256 = sha256)
|
|
295
|
+
if (workspaceDir) {
|
|
296
|
+
const manifest = loadManifest(workspaceDir);
|
|
297
|
+
for (const file of files) {
|
|
298
|
+
// Convert registryTarget back to manifest key (strip REGISTRY_DIR/ prefix)
|
|
299
|
+
const manifestKey = file.registryTarget.replace(`${REGISTRY_DIR}/`, '');
|
|
300
|
+
if (manifest.files[manifestKey]) {
|
|
301
|
+
manifest.files[manifestKey].registry_sha256 = manifest.files[manifestKey].sha256;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
saveManifest(workspaceDir, manifest);
|
|
305
|
+
}
|
|
306
|
+
|
|
292
307
|
fmt.logSuccess(`PR: ${chalk.cyan(prUrl)}`);
|
|
293
308
|
fmt.outro('Push complete');
|
|
294
309
|
} catch (e) {
|
|
@@ -319,13 +334,13 @@ export function pushCommand(args) {
|
|
|
319
334
|
|
|
320
335
|
fmt.intro('aw push');
|
|
321
336
|
|
|
322
|
-
// No args = push all modified files
|
|
337
|
+
// No args = push all modified + new (unpushed) files
|
|
323
338
|
if (!input) {
|
|
324
339
|
const files = collectModifiedFiles(workspaceDir);
|
|
325
340
|
if (files.length === 0) {
|
|
326
|
-
fmt.cancel('Nothing to push — no modified files.\n\n Use `aw status` to see synced files.');
|
|
341
|
+
fmt.cancel('Nothing to push — no modified or new files.\n\n Use `aw status` to see synced files.');
|
|
327
342
|
}
|
|
328
|
-
pushFiles(files, { repo, dryRun });
|
|
343
|
+
pushFiles(files, { repo, dryRun, workspaceDir });
|
|
329
344
|
return;
|
|
330
345
|
}
|
|
331
346
|
|
|
@@ -354,7 +369,7 @@ export function pushCommand(args) {
|
|
|
354
369
|
if (files.length === 0) {
|
|
355
370
|
fmt.cancel(`Nothing to push in ${chalk.cyan(input)} — no agents, skills, commands, or evals found.`);
|
|
356
371
|
}
|
|
357
|
-
pushFiles(files, { repo, dryRun });
|
|
372
|
+
pushFiles(files, { repo, dryRun, workspaceDir });
|
|
358
373
|
return;
|
|
359
374
|
}
|
|
360
375
|
|
|
@@ -394,7 +409,7 @@ export function pushCommand(args) {
|
|
|
394
409
|
namespace: namespacePath,
|
|
395
410
|
slug,
|
|
396
411
|
isDir,
|
|
397
|
-
}], { repo, dryRun });
|
|
412
|
+
}], { repo, dryRun, workspaceDir });
|
|
398
413
|
}
|
|
399
414
|
|
|
400
415
|
// ── Helpers ──────────────────────────────────────────────────────────
|
package/commands/status.mjs
CHANGED
|
@@ -39,6 +39,7 @@ export function statusCommand(args) {
|
|
|
39
39
|
|
|
40
40
|
const files = Object.entries(manifest.files || {});
|
|
41
41
|
const modified = [];
|
|
42
|
+
const unpushed = [];
|
|
42
43
|
const missing = [];
|
|
43
44
|
const conflicts = [];
|
|
44
45
|
|
|
@@ -51,6 +52,12 @@ export function statusCommand(args) {
|
|
|
51
52
|
|
|
52
53
|
const currentHash = hashFile(filePath);
|
|
53
54
|
|
|
55
|
+
// Template-derived files that were never pushed to the remote registry
|
|
56
|
+
if (!entry.registry_sha256) {
|
|
57
|
+
unpushed.push(key);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
if (currentHash !== entry.sha256) {
|
|
55
62
|
const content = readFileSync(filePath, 'utf8');
|
|
56
63
|
if (content.includes('<<<<<<<')) {
|
|
@@ -64,6 +71,7 @@ export function statusCommand(args) {
|
|
|
64
71
|
// Summary line
|
|
65
72
|
const summaryParts = [
|
|
66
73
|
`${files.length} synced`,
|
|
74
|
+
unpushed.length > 0 ? chalk.green(`${unpushed.length} new (unpushed)`) : null,
|
|
67
75
|
modified.length > 0 ? chalk.yellow(`${modified.length} modified`) : null,
|
|
68
76
|
conflicts.length > 0 ? chalk.red(`${conflicts.length} conflicts`) : null,
|
|
69
77
|
missing.length > 0 ? chalk.dim(`${missing.length} missing`) : null,
|
|
@@ -78,6 +86,17 @@ export function statusCommand(args) {
|
|
|
78
86
|
);
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
if (unpushed.length > 0) {
|
|
90
|
+
// Group by namespace for cleaner display
|
|
91
|
+
const nsCounts = {};
|
|
92
|
+
for (const key of unpushed) {
|
|
93
|
+
const ns = key.split('/').slice(0, 2).join('/');
|
|
94
|
+
nsCounts[ns] = (nsCounts[ns] || 0) + 1;
|
|
95
|
+
}
|
|
96
|
+
const nsLines = Object.entries(nsCounts).map(([ns, count]) => chalk.green(` ${ns}: ${count} files`)).join('\n');
|
|
97
|
+
fmt.note(nsLines, chalk.green('New (unpushed)'));
|
|
98
|
+
}
|
|
99
|
+
|
|
81
100
|
if (modified.length > 0) {
|
|
82
101
|
fmt.note(
|
|
83
102
|
modified.map(m => chalk.yellow(m)).join('\n'),
|
|
@@ -92,7 +111,7 @@ export function statusCommand(args) {
|
|
|
92
111
|
);
|
|
93
112
|
}
|
|
94
113
|
|
|
95
|
-
if (modified.length === 0 && conflicts.length === 0 && missing.length === 0) {
|
|
114
|
+
if (modified.length === 0 && conflicts.length === 0 && missing.length === 0 && unpushed.length === 0) {
|
|
96
115
|
fmt.logSuccess('Workspace is clean');
|
|
97
116
|
}
|
|
98
117
|
|
|
@@ -100,6 +119,9 @@ export function statusCommand(args) {
|
|
|
100
119
|
if (conflicts.length > 0) {
|
|
101
120
|
fmt.logWarn(`Fix conflicts: ${chalk.dim('grep -r "<<<<<<< " .aw_registry/')}`);
|
|
102
121
|
}
|
|
122
|
+
if (unpushed.length > 0) {
|
|
123
|
+
fmt.logInfo(`Push new files: ${chalk.dim('aw push')} or ${chalk.dim('aw push <namespace>')}`);
|
|
124
|
+
}
|
|
103
125
|
if (modified.length > 0) {
|
|
104
126
|
fmt.logInfo(`Push changes: ${chalk.dim('aw push <path>')}`);
|
|
105
127
|
}
|
package/constants.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// constants.mjs — Single source of truth for registry settings.
|
|
2
2
|
|
|
3
3
|
/** Base branch for PRs and sync checkout */
|
|
4
|
-
export const REGISTRY_BASE_BRANCH = '
|
|
4
|
+
export const REGISTRY_BASE_BRANCH = 'feat/aw-push-batch';
|
|
5
5
|
|
|
6
6
|
/** Default registry repository */
|
|
7
7
|
export const REGISTRY_REPO = 'GoHighLevel/platform-docs';
|
package/manifest.mjs
CHANGED
|
@@ -24,7 +24,7 @@ export function save(workspaceDir, manifest) {
|
|
|
24
24
|
writeFileSync(manifestPath(workspaceDir), JSON.stringify(manifest, null, 2) + '\n');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function update(workspaceDir, actions, namespaceName) {
|
|
27
|
+
export function update(workspaceDir, actions, namespaceName, opts = {}) {
|
|
28
28
|
const manifest = load(workspaceDir);
|
|
29
29
|
manifest.synced_at = new Date().toISOString();
|
|
30
30
|
manifest.namespace = namespaceName || manifest.namespace;
|
|
@@ -38,7 +38,9 @@ export function update(workspaceDir, actions, namespaceName) {
|
|
|
38
38
|
manifest.files[manifestKey] = {
|
|
39
39
|
sha256: hashFile(act.targetPath),
|
|
40
40
|
source: act.source,
|
|
41
|
-
|
|
41
|
+
// When pulled from template (renamed namespace), these files don't exist
|
|
42
|
+
// in the remote registry yet — mark as null so push detects them as new.
|
|
43
|
+
registry_sha256: opts.fromTemplate ? null : act.registryHash,
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
46
|
} else if (act.action === 'CONFLICT') {
|
package/package.json
CHANGED
package/plan.mjs
CHANGED
|
@@ -68,7 +68,10 @@ export function computePlan(registryDirs, workspaceDir, includePatterns = [], {
|
|
|
68
68
|
action = 'UPDATE';
|
|
69
69
|
} else {
|
|
70
70
|
const localChanged = localHash !== manifestEntry.sha256;
|
|
71
|
-
|
|
71
|
+
// registry_sha256 is null for template-derived files (never pushed).
|
|
72
|
+
// Treat null as "no known registry version" — can't conflict with unknown.
|
|
73
|
+
const registryChanged = manifestEntry.registry_sha256 != null
|
|
74
|
+
&& registryHash !== manifestEntry.registry_sha256;
|
|
72
75
|
if (localChanged && registryChanged) {
|
|
73
76
|
action = 'CONFLICT';
|
|
74
77
|
} else if (localChanged) {
|