@ghl-ai/aw 0.1.35-beta.6 → 0.1.35-beta.8
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 +3 -0
- package/commands/nuke.mjs +1 -1
- package/commands/push.mjs +1 -30
- package/commands/search.mjs +1 -1
- package/constants.mjs +1 -1
- package/ecc.mjs +43 -0
- package/link.mjs +1 -1
- package/package.json +3 -2
- package/paths.mjs +1 -1
- package/plan.mjs +3 -4
- package/registry.mjs +2 -2
package/commands/init.mjs
CHANGED
|
@@ -19,6 +19,7 @@ import { generateCommands, copyInstructions, initAwDocs } from '../integrate.mjs
|
|
|
19
19
|
import { setupMcp } from '../mcp.mjs';
|
|
20
20
|
import { autoUpdate, promptUpdate } from '../update.mjs';
|
|
21
21
|
import { installGlobalHooks } from '../hooks.mjs';
|
|
22
|
+
import { installAwEcc } from '../ecc.mjs';
|
|
22
23
|
|
|
23
24
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
25
|
const VERSION = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8')).version;
|
|
@@ -200,6 +201,7 @@ export async function initCommand(args) {
|
|
|
200
201
|
|
|
201
202
|
// Re-link IDE dirs + hooks (idempotent)
|
|
202
203
|
linkWorkspace(HOME);
|
|
204
|
+
await installAwEcc(cwd, { targets: ["cursor"], silent });
|
|
203
205
|
generateCommands(HOME);
|
|
204
206
|
copyInstructions(HOME, null, freshCfg?.namespace || team) || [];
|
|
205
207
|
initAwDocs(HOME);
|
|
@@ -280,6 +282,7 @@ export async function initCommand(args) {
|
|
|
280
282
|
// Step 3: Link IDE dirs + setup tasks
|
|
281
283
|
fmt.logStep('Linking IDE symlinks...');
|
|
282
284
|
linkWorkspace(HOME);
|
|
285
|
+
await installAwEcc(cwd, { targets: ["cursor"], silent });
|
|
283
286
|
generateCommands(HOME);
|
|
284
287
|
const instructionFiles = copyInstructions(HOME, null, team) || [];
|
|
285
288
|
initAwDocs(HOME);
|
package/commands/nuke.mjs
CHANGED
|
@@ -15,7 +15,7 @@ const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
|
|
|
15
15
|
const MANIFEST_PATH = join(GLOBAL_AW_DIR, '.aw-manifest.json');
|
|
16
16
|
|
|
17
17
|
const IDE_DIRS = ['.claude', '.cursor', '.codex', '.agents'];
|
|
18
|
-
const CONTENT_TYPES = ['agents', 'skills', 'commands', 'evals'
|
|
18
|
+
const CONTENT_TYPES = ['agents', 'skills', 'commands', 'evals'];
|
|
19
19
|
|
|
20
20
|
function loadManifest() {
|
|
21
21
|
if (!existsSync(MANIFEST_PATH)) return null;
|
package/commands/push.mjs
CHANGED
|
@@ -73,17 +73,12 @@ function collectBatchFiles(folderAbsPath, workspaceDir) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
* Collect all modified
|
|
77
|
-
* 1. Manifest-tracked files that are modified or template-derived (never pushed).
|
|
78
|
-
* 2. Filesystem files not in the manifest at all (newly added by user).
|
|
76
|
+
* Collect all modified files from manifest (for no-args push).
|
|
79
77
|
* Returns array of { absPath, registryTarget, type, namespace, slug, isDir }.
|
|
80
78
|
*/
|
|
81
79
|
function collectModifiedFiles(workspaceDir) {
|
|
82
80
|
const manifest = loadManifest(workspaceDir);
|
|
83
|
-
const manifestKeys = new Set(Object.keys(manifest.files || {}));
|
|
84
81
|
const files = [];
|
|
85
|
-
|
|
86
|
-
// 1. Manifest-tracked: modified or never-pushed
|
|
87
82
|
for (const [key, entry] of Object.entries(manifest.files || {})) {
|
|
88
83
|
const filePath = join(workspaceDir, key);
|
|
89
84
|
if (!existsSync(filePath)) continue;
|
|
@@ -104,30 +99,6 @@ function collectModifiedFiles(workspaceDir) {
|
|
|
104
99
|
}
|
|
105
100
|
}
|
|
106
101
|
}
|
|
107
|
-
|
|
108
|
-
// 2. Untracked: files on disk but not in manifest (e.g. manually added)
|
|
109
|
-
for (const name of readdirSync(workspaceDir, { withFileTypes: true })) {
|
|
110
|
-
if (!name.isDirectory() || name.name.startsWith('.')) continue;
|
|
111
|
-
const nsDir = join(workspaceDir, name.name);
|
|
112
|
-
const entries = walkRegistryTree(nsDir, name.name);
|
|
113
|
-
for (const entry of entries) {
|
|
114
|
-
// Build the manifest key for this file
|
|
115
|
-
const manifestKey = (entry.type === 'skills' || entry.type === 'evals')
|
|
116
|
-
? `${entry.namespacePath}/${entry.type}/${entry.slug}/${entry.skillRelPath || entry.filename}`
|
|
117
|
-
: `${entry.namespacePath}/${entry.type}/${entry.filename}`;
|
|
118
|
-
if (manifestKeys.has(manifestKey)) continue; // Already handled above
|
|
119
|
-
const registryTarget = `${REGISTRY_DIR}/${manifestKey}`;
|
|
120
|
-
files.push({
|
|
121
|
-
absPath: entry.sourcePath,
|
|
122
|
-
registryTarget,
|
|
123
|
-
type: entry.type,
|
|
124
|
-
namespace: entry.namespacePath,
|
|
125
|
-
slug: entry.slug,
|
|
126
|
-
isDir: false,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
102
|
return files;
|
|
132
103
|
}
|
|
133
104
|
|
package/commands/search.mjs
CHANGED
|
@@ -94,7 +94,7 @@ function searchLocal(workspaceDir, query) {
|
|
|
94
94
|
if (!nsEntry.isDirectory() || nsEntry.name.startsWith('.')) continue;
|
|
95
95
|
const ns = nsEntry.name;
|
|
96
96
|
|
|
97
|
-
for (const type of ['agents', 'skills', 'commands', 'evals'
|
|
97
|
+
for (const type of ['agents', 'skills', 'commands', 'evals']) {
|
|
98
98
|
const typeDir = join(workspaceDir, ns, type);
|
|
99
99
|
if (!existsSync(typeDir)) continue;
|
|
100
100
|
|
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 = 'main';
|
|
5
5
|
|
|
6
6
|
/** Default registry repository */
|
|
7
7
|
export const REGISTRY_REPO = 'GoHighLevel/platform-docs';
|
package/ecc.mjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import * as fmt from "./fmt.mjs";
|
|
5
|
+
|
|
6
|
+
const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
|
|
7
|
+
const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
|
|
8
|
+
const AW_ECC_TAG = "v1.0.0";
|
|
9
|
+
const TMP_DIR = "/tmp/aw-ecc";
|
|
10
|
+
|
|
11
|
+
function cloneRepo(tag, dest, stdio) {
|
|
12
|
+
try {
|
|
13
|
+
execSync(`git clone --depth 1 --branch ${tag} ${AW_ECC_REPO_SSH} ${dest}`, {
|
|
14
|
+
stdio,
|
|
15
|
+
});
|
|
16
|
+
} catch {
|
|
17
|
+
execSync(
|
|
18
|
+
`git clone --depth 1 --branch ${tag} ${AW_ECC_REPO_HTTPS} ${dest}`,
|
|
19
|
+
{ stdio },
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function installAwEcc(
|
|
25
|
+
cwd,
|
|
26
|
+
{ targets = ["cursor"], silent = false } = {},
|
|
27
|
+
) {
|
|
28
|
+
if (!silent) fmt.logStep("Installing aw-ecc engine...");
|
|
29
|
+
|
|
30
|
+
if (existsSync(TMP_DIR)) rmSync(TMP_DIR, { recursive: true, force: true });
|
|
31
|
+
|
|
32
|
+
cloneRepo(AW_ECC_TAG, TMP_DIR, silent ? "pipe" : "inherit");
|
|
33
|
+
|
|
34
|
+
for (const target of targets) {
|
|
35
|
+
execSync(
|
|
36
|
+
`node ${join(TMP_DIR, "scripts/install-apply.js")} --target ${target} --profile full`,
|
|
37
|
+
{ cwd, stdio: silent ? "pipe" : "inherit" },
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
rmSync(TMP_DIR, { recursive: true, force: true });
|
|
42
|
+
if (!silent) fmt.logSuccess("aw-ecc engine installed");
|
|
43
|
+
}
|
package/link.mjs
CHANGED
|
@@ -13,7 +13,7 @@ function forceSymlink(target, linkPath) {
|
|
|
13
13
|
const IDE_DIRS = ['.claude', '.cursor', '.codex'];
|
|
14
14
|
// Per-file symlink types
|
|
15
15
|
const FILE_TYPES = ['agents'];
|
|
16
|
-
const ALL_KNOWN_TYPES = new Set([...FILE_TYPES, 'skills', 'commands', 'evals', '
|
|
16
|
+
const ALL_KNOWN_TYPES = new Set([...FILE_TYPES, 'skills', 'commands', 'evals', 'docs']);
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* List namespace directories inside .aw_registry/ (skip dotfiles).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghl-ai/aw",
|
|
3
|
-
"version": "0.1.35-beta.
|
|
3
|
+
"version": "0.1.35-beta.8",
|
|
4
4
|
"description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"registry.mjs",
|
|
25
25
|
"apply.mjs",
|
|
26
26
|
"update.mjs",
|
|
27
|
-
"hooks.mjs"
|
|
27
|
+
"hooks.mjs",
|
|
28
|
+
"ecc.mjs"
|
|
28
29
|
],
|
|
29
30
|
"engines": {
|
|
30
31
|
"node": ">=18.0.0"
|
package/paths.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { existsSync, statSync, lstatSync, readlinkSync } from 'node:fs';
|
|
4
4
|
import { join, resolve, relative, basename, dirname } from 'node:path';
|
|
5
5
|
|
|
6
|
-
const VALID_TYPES = new Set(['agents', 'skills', 'commands', 'evals'
|
|
6
|
+
const VALID_TYPES = new Set(['agents', 'skills', 'commands', 'evals']);
|
|
7
7
|
|
|
8
8
|
// IDE dirs that may contain symlinks into .aw_registry/
|
|
9
9
|
const IDE_PREFIXES = ['.claude/', '.cursor/', '.codex/', '.agents/'];
|
package/plan.mjs
CHANGED
|
@@ -46,9 +46,8 @@ export function computePlan(registryDirs, workspaceDir, includePatterns = [], {
|
|
|
46
46
|
targetFilename = `${entry.namespacePath}/${entry.type}/${entry.slug}/${entry.skillRelPath}`;
|
|
47
47
|
targetPath = join(workspaceDir, entry.namespacePath, entry.type, entry.slug, entry.skillRelPath);
|
|
48
48
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
targetPath = join(workspaceDir, entry.namespacePath, entry.type, fileName);
|
|
49
|
+
targetFilename = `${entry.namespacePath}/${entry.type}/${entry.slug}.md`;
|
|
50
|
+
targetPath = join(workspaceDir, entry.namespacePath, entry.type, `${entry.slug}.md`);
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
const manifestKey = targetFilename;
|
|
@@ -114,7 +113,7 @@ export function computePlan(registryDirs, workspaceDir, includePatterns = [], {
|
|
|
114
113
|
const parts = manifestKey.split('/');
|
|
115
114
|
let typeIdx = -1;
|
|
116
115
|
for (let i = 0; i < parts.length; i++) {
|
|
117
|
-
if (['agents', 'skills', 'commands', 'evals'
|
|
116
|
+
if (['agents', 'skills', 'commands', 'evals'].includes(parts[i])) {
|
|
118
117
|
typeIdx = i;
|
|
119
118
|
break;
|
|
120
119
|
}
|
package/registry.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
|
4
4
|
import { join, relative } from 'node:path';
|
|
5
5
|
import { createHash } from 'node:crypto';
|
|
6
6
|
|
|
7
|
-
const TYPE_DIRS = new Set(['agents', 'skills', 'commands', 'evals'
|
|
7
|
+
const TYPE_DIRS = new Set(['agents', 'skills', 'commands', 'evals']);
|
|
8
8
|
const SKIP_DIRS = new Set(['docs']);
|
|
9
9
|
|
|
10
10
|
export function sha256(content) {
|
|
@@ -84,7 +84,7 @@ export function walkRegistryTree(baseDir, baseName) {
|
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
86
|
} else {
|
|
87
|
-
// Agents, commands
|
|
87
|
+
// Agents, commands — flat files
|
|
88
88
|
for (const fileEntry of readdirSync(fullPath)) {
|
|
89
89
|
if (fileEntry === '.gitkeep' || fileEntry.startsWith('.')) continue;
|
|
90
90
|
const filePath = join(fullPath, fileEntry);
|