aiblueprint-cli 1.4.98 → 1.4.100
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/README.md +17 -1
- package/agents-config/skills/agents-manager/SKILL.md +2 -2
- package/agents-config/skills/agents-manager/agents/openai.yaml +7 -0
- package/agents-config/skills/agents-manager/assets/codex-icon.svg +20 -0
- package/agents-config/skills/apex/SKILL.md +120 -118
- package/agents-config/skills/apex/agents/openai.yaml +10 -0
- package/agents-config/skills/apex/assets/codex-icon.svg +15 -0
- package/agents-config/skills/apex/scripts/apex-state.py +740 -0
- package/agents-config/skills/apex/scripts/setup-templates.sh +27 -145
- package/agents-config/skills/apex/scripts/test_apex_state.py +413 -0
- package/agents-config/skills/apex/scripts/update-progress.sh +17 -73
- package/agents-config/skills/apex/steps/step-00-init.md +85 -231
- package/agents-config/skills/apex/steps/step-00b-branch.md +10 -118
- package/agents-config/skills/apex/steps/step-00b-economy.md +12 -239
- package/agents-config/skills/apex/steps/step-00b-interactive.md +13 -162
- package/agents-config/skills/apex/steps/step-00b-save.md +13 -114
- package/agents-config/skills/apex/steps/step-01-analyze.md +40 -361
- package/agents-config/skills/apex/steps/step-02-plan.md +55 -562
- package/agents-config/skills/apex/steps/step-02b-tasks.md +15 -291
- package/agents-config/skills/apex/steps/step-03-execute-teams.md +47 -267
- package/agents-config/skills/apex/steps/step-03-execute.md +32 -212
- package/agents-config/skills/apex/steps/step-04-validate.md +42 -246
- package/agents-config/skills/apex/steps/step-05-examine.md +47 -371
- package/agents-config/skills/apex/steps/step-06-resolve.md +19 -221
- package/agents-config/skills/apex/steps/step-07-tests.md +19 -234
- package/agents-config/skills/apex/steps/step-08-run-tests.md +13 -300
- package/agents-config/skills/apex/steps/step-09-finish.md +36 -200
- package/agents-config/skills/apex/steps/step-10-verify.md +46 -264
- package/agents-config/skills/appstore-connect/agents/openai.yaml +7 -0
- package/agents-config/skills/appstore-connect/assets/codex-icon.svg +17 -0
- package/agents-config/skills/commit/agents/openai.yaml +10 -0
- package/agents-config/skills/commit/assets/codex-icon.svg +17 -0
- package/agents-config/skills/create-pr/agents/openai.yaml +10 -0
- package/agents-config/skills/create-pr/assets/codex-icon.svg +17 -0
- package/agents-config/skills/environments-manager/SKILL.md +1 -1
- package/agents-config/skills/environments-manager/agents/openai.yaml +7 -0
- package/agents-config/skills/environments-manager/assets/codex-icon.svg +16 -0
- package/agents-config/skills/environments-manager/examples/scripts/claude-worktree-remove.sh +19 -3
- package/agents-config/skills/environments-manager/examples/scripts/worktree-up.sh +1 -1
- package/agents-config/skills/environments-manager/references/claude.md +1 -1
- package/agents-config/skills/fix-pr-comments/agents/openai.yaml +10 -0
- package/agents-config/skills/fix-pr-comments/assets/codex-icon.svg +17 -0
- package/agents-config/skills/grill-me/SKILL.md +25 -4
- package/agents-config/skills/grill-me/agents/openai.yaml +8 -0
- package/agents-config/skills/grill-me/assets/codex-icon.svg +16 -0
- package/agents-config/skills/hooks-manager/SKILL.md +19 -9
- package/agents-config/skills/hooks-manager/assets/codex-icon.svg +15 -4
- package/agents-config/skills/hooks-manager/references/claude-code.md +32 -0
- package/agents-config/skills/hooks-manager/references/codex.md +23 -0
- package/agents-config/skills/hooks-manager/references/cursor.md +18 -0
- package/agents-config/skills/hooks-manager/references/hook-types.md +5 -3
- package/agents-config/skills/hooks-manager/references/input-output-schemas.md +2 -2
- package/agents-config/skills/hooks-manager/references/research-sources.md +25 -0
- package/agents-config/skills/hooks-manager/references/router.md +32 -0
- package/agents-config/skills/hooks-manager/references/troubleshooting.md +3 -3
- package/agents-config/skills/merge/agents/openai.yaml +10 -0
- package/agents-config/skills/merge/assets/codex-icon.svg +17 -0
- package/agents-config/skills/oneshot/SKILL.md +4 -0
- package/agents-config/skills/oneshot/agents/openai.yaml +10 -0
- package/agents-config/skills/oneshot/assets/codex-icon.svg +18 -0
- package/agents-config/skills/prompt-creator/agents/openai.yaml +7 -0
- package/agents-config/skills/prompt-creator/assets/codex-icon.svg +16 -0
- package/agents-config/skills/rules-manager/agents/openai.yaml +7 -0
- package/agents-config/skills/rules-manager/assets/codex-icon.svg +23 -0
- package/agents-config/skills/skill-manager/SKILL.md +45 -3
- package/agents-config/skills/skill-manager/agents/openai.yaml +7 -0
- package/agents-config/skills/skill-manager/assets/codex-icon.svg +23 -0
- package/agents-config/skills/skill-manager/references/skill-writing-glossary.md +201 -0
- package/agents-config/skills/skill-manager/scripts/setup-codex-icons.ts +143 -0
- package/agents-config/skills/ultrathink/agents/openai.yaml +10 -0
- package/agents-config/skills/ultrathink/assets/codex-icon.svg +20 -0
- package/agents-config/skills/use-artifacts/SKILL.md +102 -51
- package/agents-config/skills/use-artifacts/assets/local-runtime.js +299 -0
- package/agents-config/skills/use-artifacts/scripts/create_artifact.py +1 -1
- package/agents-config/skills/use-delegate/SKILL.md +4 -0
- package/agents-config/skills/use-delegate/agents/openai.yaml +10 -0
- package/agents-config/skills/use-delegate/assets/codex-icon.svg +20 -0
- package/agents-config/skills/use-goal/SKILL.md +70 -9
- package/agents-config/skills/use-goal/agents/openai.yaml +1 -1
- package/agents-config/skills/use-goal/assets/codex-icon.svg +17 -3
- package/agents-config/skills/use-goal/references/claude-code-goal.md +54 -6
- package/agents-config/skills/use-goal/references/codex-goal.md +59 -4
- package/agents-config/skills/use-goal/references/verification-harnesses.md +104 -3
- package/dist/cli.js +264 -12
- package/package.json +1 -1
- package/agents-config/skills/apex/templates/00-context.md +0 -55
- package/agents-config/skills/apex/templates/01-analyze.md +0 -10
- package/agents-config/skills/apex/templates/02-plan.md +0 -10
- package/agents-config/skills/apex/templates/03-execute.md +0 -10
- package/agents-config/skills/apex/templates/04-validate.md +0 -10
- package/agents-config/skills/apex/templates/05-examine.md +0 -10
- package/agents-config/skills/apex/templates/06-resolve.md +0 -10
- package/agents-config/skills/apex/templates/07-tests.md +0 -10
- package/agents-config/skills/apex/templates/08-run-tests.md +0 -10
- package/agents-config/skills/apex/templates/09-finish.md +0 -10
- package/agents-config/skills/apex/templates/10-verify.md +0 -9
- package/agents-config/skills/apex/templates/README.md +0 -195
- package/agents-config/skills/apex/templates/step-complete.md +0 -7
|
@@ -1,7 +1,108 @@
|
|
|
1
1
|
# Verification Harnesses For Refactors
|
|
2
2
|
|
|
3
|
-
Use this reference when a Goal involves refactoring, deletion, migration, moving files, eliminating a pattern, or reducing a code smell.
|
|
3
|
+
Use this reference when a Goal involves refactoring, deletion, migration, moving files, eliminating a pattern, or reducing a code smell. The core tactic is to create a small measurable harness before the main work, then make the Goal continue until the harness reaches the target.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Principle
|
|
6
6
|
|
|
7
|
-
For
|
|
7
|
+
For broad changes, do not rely only on subjective review. Convert the desired end state into a number, list, or deterministic command result.
|
|
8
|
+
|
|
9
|
+
Examples:
|
|
10
|
+
|
|
11
|
+
- Remove all explicit TypeScript `any` -> count explicit `any` occurrences and require `0`.
|
|
12
|
+
- Delete dead files -> scan imports/references and require no references to removed paths.
|
|
13
|
+
- Move a module -> scan imports and require all imports use the new path.
|
|
14
|
+
- Rename an API -> count old symbol references and require `0`, then run tests/typecheck.
|
|
15
|
+
- Remove a dependency -> scan package manifests and lockfiles, then run install/typecheck/test.
|
|
16
|
+
- Split a large file -> check file size or exported symbol boundaries, then run typecheck/test.
|
|
17
|
+
|
|
18
|
+
The harness should make progress visible after every iteration.
|
|
19
|
+
|
|
20
|
+
## Harness Rules
|
|
21
|
+
|
|
22
|
+
1. First establish the baseline count or failure list before editing.
|
|
23
|
+
2. Prefer existing repo tooling: tests, lint rules, typecheck, dependency analyzers, codemods, static analyzers.
|
|
24
|
+
3. If no existing command measures the target, create a narrow validation script.
|
|
25
|
+
4. Make the script deterministic and fast enough to run repeatedly.
|
|
26
|
+
5. Exclude generated, vendored, build output, lockfiles, snapshots, and irrelevant binary assets unless the task explicitly includes them.
|
|
27
|
+
6. Print actionable output: total count, grouped files, and the top remaining offenders.
|
|
28
|
+
7. Exit with code `0` only when the target condition is met. Exit non-zero while work remains.
|
|
29
|
+
8. Keep the harness scoped to the Goal. Remove temporary harnesses before completion unless they are useful project validation and the user or repo conventions support keeping them.
|
|
30
|
+
|
|
31
|
+
## Goal Pattern
|
|
32
|
+
|
|
33
|
+
Use this shape for count-based refactor Goals:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
<desired refactor>, verified by `<validation command>` returning success with <target count/list condition>, while preserving <tests/typecheck/public behavior>. First establish the baseline with `<validation command>` and inspect the highest-signal offenders. Work in checkpoints: after each batch, rerun `<validation command>`, record the count/list delta, run the narrowest relevant tests, and continue until the validation command exits 0. If the target cannot be reached safely, stop with the remaining offenders, attempted paths, failing output, and the decision needed.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
Remove all explicit TypeScript `any` from the codebase, verified by `node scripts/check-explicit-any.mjs` exiting 0 with count 0, while keeping `pnpm typecheck` and relevant tests green. First run the checker to record the baseline and prioritize files with the most occurrences. Work in checkpoints: after each batch, rerun the checker, record the remaining count, and run the narrowest relevant typecheck/tests. Continue until the checker exits 0. If some `any` cannot be removed safely, stop with the remaining locations, attempted replacements, compiler/test output, and the type information needed.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Script Patterns
|
|
46
|
+
|
|
47
|
+
Use structured parsers when reasonable. For TypeScript, prefer the TypeScript compiler API, `ts-morph`, ESLint, or an existing lint rule over raw text search when false positives matter.
|
|
48
|
+
|
|
49
|
+
For a quick bootstrap harness, a text scanner is acceptable if the Goal explicitly treats it as an approximate first pass and follows up with typecheck/lint.
|
|
50
|
+
|
|
51
|
+
Example quick scanner:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
#!/usr/bin/env node
|
|
55
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
56
|
+
import { join } from "node:path";
|
|
57
|
+
|
|
58
|
+
const root = process.cwd();
|
|
59
|
+
const ignoredDirs = new Set([".git", "node_modules", "dist", "build", ".next", "coverage"]);
|
|
60
|
+
const extensions = new Set([".ts", ".tsx"]);
|
|
61
|
+
const matches = [];
|
|
62
|
+
|
|
63
|
+
function walk(dir) {
|
|
64
|
+
for (const entry of readdirSync(dir)) {
|
|
65
|
+
const path = join(dir, entry);
|
|
66
|
+
const stat = statSync(path);
|
|
67
|
+
if (stat.isDirectory()) {
|
|
68
|
+
if (!ignoredDirs.has(entry)) walk(path);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (![...extensions].some((ext) => path.endsWith(ext))) continue;
|
|
72
|
+
const text = readFileSync(path, "utf8");
|
|
73
|
+
const lines = text.split("\n");
|
|
74
|
+
lines.forEach((line, index) => {
|
|
75
|
+
if (/\bany\b/.test(line)) matches.push(`${path.replace(`${root}/`, "")}:${index + 1}: ${line.trim()}`);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
walk(root);
|
|
81
|
+
|
|
82
|
+
console.log(`explicit_any_count=${matches.length}`);
|
|
83
|
+
for (const match of matches.slice(0, 50)) console.log(match);
|
|
84
|
+
if (matches.length > 50) console.log(`...and ${matches.length - 50} more`);
|
|
85
|
+
process.exit(matches.length === 0 ? 0 : 1);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Refactor Targets
|
|
89
|
+
|
|
90
|
+
For deletion Goals, verify both absence and behavior:
|
|
91
|
+
|
|
92
|
+
- target files or symbols are gone
|
|
93
|
+
- no imports, string references, routes, config entries, docs links, or tests point to them
|
|
94
|
+
- typecheck/build/test still passes
|
|
95
|
+
|
|
96
|
+
For moving Goals, verify all call sites:
|
|
97
|
+
|
|
98
|
+
- old import path count is `0`
|
|
99
|
+
- new import path exists where expected
|
|
100
|
+
- public exports remain compatible unless changing them is part of the Goal
|
|
101
|
+
- typecheck/build/test still passes
|
|
102
|
+
|
|
103
|
+
For migration Goals, verify old surface removal and new surface behavior:
|
|
104
|
+
|
|
105
|
+
- old package/API/pattern count reaches `0` or the explicitly allowed exception list
|
|
106
|
+
- new package/API/pattern is used consistently
|
|
107
|
+
- tests/typecheck/build pass
|
|
108
|
+
- manual or browser verification is included when behavior is visual or interactive
|
package/dist/cli.js
CHANGED
|
@@ -37539,11 +37539,14 @@ import path21 from "path";
|
|
|
37539
37539
|
var import_fs_extra15 = __toESM(require_lib4(), 1);
|
|
37540
37540
|
import os17 from "os";
|
|
37541
37541
|
import path19 from "path";
|
|
37542
|
-
import { exec as exec3 } from "child_process";
|
|
37542
|
+
import { exec as exec3, execFile } from "child_process";
|
|
37543
37543
|
import { promisify as promisify2 } from "util";
|
|
37544
37544
|
var execAsync2 = promisify2(exec3);
|
|
37545
|
+
var execFileAsync = promisify2(execFile);
|
|
37545
37546
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
37546
37547
|
var PREMIUM_BRANCH = "main";
|
|
37548
|
+
var ASSISTANT_PRO_REPO = "Melvynx/assistant-pro-skills";
|
|
37549
|
+
var ASSISTANT_PRO_BRANCH = "main";
|
|
37547
37550
|
var CONFIG_FOLDER_CANDIDATES2 = ["agents-config", "ai-coding", "claude-code-config", "ai-config"];
|
|
37548
37551
|
function routePath(relativePath) {
|
|
37549
37552
|
const segments = relativePath.split(path19.sep);
|
|
@@ -37771,6 +37774,164 @@ async function syncAllAgentSymlinks(agentsDir, claudeDir) {
|
|
|
37771
37774
|
await syncCategorySymlinks(category, agentsDir, claudeDir, undefined, true);
|
|
37772
37775
|
}
|
|
37773
37776
|
}
|
|
37777
|
+
function getAssistantProCacheDir() {
|
|
37778
|
+
return path19.join(os17.homedir(), ".config", "aiblueprint", "pro-repos", "assistant-pro-skills");
|
|
37779
|
+
}
|
|
37780
|
+
async function runAuthenticatedGit(args, token, cwd) {
|
|
37781
|
+
const authorization = Buffer.from(`x-access-token:${token}`).toString("base64");
|
|
37782
|
+
try {
|
|
37783
|
+
await execFileAsync("git", ["-c", `http.extraHeader=Authorization: Basic ${authorization}`, ...args], { cwd, timeout: 120000 });
|
|
37784
|
+
} catch {
|
|
37785
|
+
throw new Error("Unable to download the latest Assistant Pro skills from GitHub");
|
|
37786
|
+
}
|
|
37787
|
+
}
|
|
37788
|
+
async function cloneOrUpdateAssistantProRepo(githubToken) {
|
|
37789
|
+
const cacheDir = getAssistantProCacheDir();
|
|
37790
|
+
const repoUrl = `https://github.com/${ASSISTANT_PRO_REPO}.git`;
|
|
37791
|
+
if (await import_fs_extra15.default.pathExists(path19.join(cacheDir, ".git"))) {
|
|
37792
|
+
await runAuthenticatedGit(["fetch", "origin", ASSISTANT_PRO_BRANCH], githubToken, cacheDir);
|
|
37793
|
+
await runAuthenticatedGit(["merge", "--ff-only", "FETCH_HEAD"], githubToken, cacheDir);
|
|
37794
|
+
return cacheDir;
|
|
37795
|
+
}
|
|
37796
|
+
if (await import_fs_extra15.default.pathExists(cacheDir)) {
|
|
37797
|
+
throw new Error(`Assistant Pro cache is not a Git repository: ${cacheDir}`);
|
|
37798
|
+
}
|
|
37799
|
+
await import_fs_extra15.default.ensureDir(path19.dirname(cacheDir));
|
|
37800
|
+
await runAuthenticatedGit([
|
|
37801
|
+
"clone",
|
|
37802
|
+
"--branch",
|
|
37803
|
+
ASSISTANT_PRO_BRANCH,
|
|
37804
|
+
"--single-branch",
|
|
37805
|
+
repoUrl,
|
|
37806
|
+
cacheDir
|
|
37807
|
+
], githubToken);
|
|
37808
|
+
return cacheDir;
|
|
37809
|
+
}
|
|
37810
|
+
async function installAssistantProSkills(options) {
|
|
37811
|
+
const cacheDir = await cloneOrUpdateAssistantProRepo(options.githubToken);
|
|
37812
|
+
const installerPath = path19.join(cacheDir, "ap_skills.py");
|
|
37813
|
+
const manifestPath = path19.join(cacheDir, "manifest.json");
|
|
37814
|
+
if (!await import_fs_extra15.default.pathExists(installerPath) || !await import_fs_extra15.default.pathExists(manifestPath)) {
|
|
37815
|
+
throw new Error("Assistant Pro repository is missing ap_skills.py or manifest.json");
|
|
37816
|
+
}
|
|
37817
|
+
try {
|
|
37818
|
+
await execFileAsync("python3", [
|
|
37819
|
+
installerPath,
|
|
37820
|
+
"--home",
|
|
37821
|
+
options.rootDir,
|
|
37822
|
+
"--json",
|
|
37823
|
+
"install",
|
|
37824
|
+
"--bundle",
|
|
37825
|
+
"all",
|
|
37826
|
+
"--target",
|
|
37827
|
+
"codex"
|
|
37828
|
+
], { cwd: cacheDir, timeout: 120000 });
|
|
37829
|
+
} catch (error) {
|
|
37830
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
37831
|
+
throw new Error(`Assistant Pro skill installation failed: ${message}`);
|
|
37832
|
+
}
|
|
37833
|
+
const manifest = await import_fs_extra15.default.readJson(manifestPath);
|
|
37834
|
+
return {
|
|
37835
|
+
version: manifest.version ?? "unknown",
|
|
37836
|
+
skillCount: manifest.bundles?.all?.length ?? 0
|
|
37837
|
+
};
|
|
37838
|
+
}
|
|
37839
|
+
function countLeadingSpaces(line) {
|
|
37840
|
+
return line.length - line.trimStart().length;
|
|
37841
|
+
}
|
|
37842
|
+
function isYamlContentLine(line) {
|
|
37843
|
+
const trimmed = line.trim();
|
|
37844
|
+
return trimmed.length > 0 && !trimmed.startsWith("#");
|
|
37845
|
+
}
|
|
37846
|
+
async function ensureHermesExternalSkillsDir(hermesDir, agentsSkillsDir) {
|
|
37847
|
+
const configPath = path19.join(hermesDir, "config.yaml");
|
|
37848
|
+
const resolvedSkillsDir = path19.resolve(agentsSkillsDir);
|
|
37849
|
+
const defaultSkillsDir = path19.join(os17.homedir(), ".agents", "skills");
|
|
37850
|
+
const configuredPath = resolvedSkillsDir === defaultSkillsDir ? "~/.agents/skills" : resolvedSkillsDir;
|
|
37851
|
+
const yamlEntry = ` - ${JSON.stringify(configuredPath)}`;
|
|
37852
|
+
await import_fs_extra15.default.ensureDir(hermesDir);
|
|
37853
|
+
if (!await import_fs_extra15.default.pathExists(configPath)) {
|
|
37854
|
+
await import_fs_extra15.default.writeFile(configPath, `skills:
|
|
37855
|
+
external_dirs:
|
|
37856
|
+
${yamlEntry}
|
|
37857
|
+
`, "utf-8");
|
|
37858
|
+
return true;
|
|
37859
|
+
}
|
|
37860
|
+
const original = await import_fs_extra15.default.readFile(configPath, "utf-8");
|
|
37861
|
+
const lines = original.split(/\r?\n/);
|
|
37862
|
+
let skillsIndex = lines.findIndex((line) => /^skills:\s*(?:#.*)?$/.test(line));
|
|
37863
|
+
if (skillsIndex === -1) {
|
|
37864
|
+
const inlineSkillsIndex = lines.findIndex((line) => /^skills:\s*\S+/.test(line));
|
|
37865
|
+
if (inlineSkillsIndex !== -1) {
|
|
37866
|
+
const inlineValue = lines[inlineSkillsIndex].replace(/^skills:\s*/, "").replace(/\s+#.*$/, "").trim();
|
|
37867
|
+
if (inlineValue === "{}" || inlineValue === "null" || inlineValue === "~") {
|
|
37868
|
+
lines[inlineSkillsIndex] = "skills:";
|
|
37869
|
+
skillsIndex = inlineSkillsIndex;
|
|
37870
|
+
} else {
|
|
37871
|
+
throw new Error(`Hermes skills uses an inline value in ${configPath}; add ${configuredPath} manually`);
|
|
37872
|
+
}
|
|
37873
|
+
}
|
|
37874
|
+
}
|
|
37875
|
+
if (skillsIndex === -1) {
|
|
37876
|
+
const separator = original.length > 0 && !original.endsWith(`
|
|
37877
|
+
`) ? `
|
|
37878
|
+
` : "";
|
|
37879
|
+
await import_fs_extra15.default.writeFile(configPath, `${original}${separator}skills:
|
|
37880
|
+
external_dirs:
|
|
37881
|
+
${yamlEntry}
|
|
37882
|
+
`, "utf-8");
|
|
37883
|
+
return true;
|
|
37884
|
+
}
|
|
37885
|
+
let skillsEnd = lines.length;
|
|
37886
|
+
for (let index = skillsIndex + 1;index < lines.length; index += 1) {
|
|
37887
|
+
if (isYamlContentLine(lines[index]) && countLeadingSpaces(lines[index]) === 0) {
|
|
37888
|
+
skillsEnd = index;
|
|
37889
|
+
break;
|
|
37890
|
+
}
|
|
37891
|
+
}
|
|
37892
|
+
const externalIndex = lines.findIndex((line, index) => {
|
|
37893
|
+
return index > skillsIndex && index < skillsEnd && /^\s+external_dirs:\s*/.test(line);
|
|
37894
|
+
});
|
|
37895
|
+
if (externalIndex === -1) {
|
|
37896
|
+
lines.splice(skillsIndex + 1, 0, " external_dirs:", yamlEntry);
|
|
37897
|
+
} else {
|
|
37898
|
+
const match = lines[externalIndex].match(/^(\s+)external_dirs:\s*(.*)$/);
|
|
37899
|
+
let inlineValue = match?.[2]?.replace(/\s+#.*$/, "").trim() ?? "";
|
|
37900
|
+
if (inlineValue === "[]") {
|
|
37901
|
+
lines[externalIndex] = `${match?.[1] ?? " "}external_dirs:`;
|
|
37902
|
+
inlineValue = "";
|
|
37903
|
+
}
|
|
37904
|
+
if (inlineValue) {
|
|
37905
|
+
if (inlineValue.includes(configuredPath) || inlineValue.includes(resolvedSkillsDir)) {
|
|
37906
|
+
return false;
|
|
37907
|
+
}
|
|
37908
|
+
throw new Error(`Hermes external_dirs uses an inline value in ${configPath}; add ${configuredPath} manually`);
|
|
37909
|
+
}
|
|
37910
|
+
const externalIndent = match?.[1].length ?? 2;
|
|
37911
|
+
let externalEnd = skillsEnd;
|
|
37912
|
+
for (let index = externalIndex + 1;index < skillsEnd; index += 1) {
|
|
37913
|
+
if (isYamlContentLine(lines[index]) && countLeadingSpaces(lines[index]) <= externalIndent) {
|
|
37914
|
+
externalEnd = index;
|
|
37915
|
+
break;
|
|
37916
|
+
}
|
|
37917
|
+
}
|
|
37918
|
+
const existingValues = lines.slice(externalIndex + 1, externalEnd).map((line) => line.trim().replace(/^-\s*/, "").replace(/^['"]|['"]$/g, ""));
|
|
37919
|
+
if (existingValues.includes(configuredPath) || existingValues.includes(resolvedSkillsDir)) {
|
|
37920
|
+
return false;
|
|
37921
|
+
}
|
|
37922
|
+
const listIndent = " ".repeat(externalIndent + 2);
|
|
37923
|
+
lines.splice(externalEnd, 0, `${listIndent}- ${JSON.stringify(configuredPath)}`);
|
|
37924
|
+
}
|
|
37925
|
+
await import_fs_extra15.default.writeFile(configPath, `${lines.join(`
|
|
37926
|
+
`).replace(/\n+$/, "")}
|
|
37927
|
+
`, "utf-8");
|
|
37928
|
+
return true;
|
|
37929
|
+
}
|
|
37930
|
+
async function configureAssistantProConsumers(options) {
|
|
37931
|
+
await syncCategorySymlinks("skills", options.agentsDir, options.claudeDir, undefined, true);
|
|
37932
|
+
await syncCategorySymlinks("skills", options.agentsDir, options.codexDir, undefined, true);
|
|
37933
|
+
await ensureHermesExternalSkillsDir(options.hermesDir, path19.join(options.agentsDir, "skills"));
|
|
37934
|
+
}
|
|
37774
37935
|
|
|
37775
37936
|
// src/lib/token-storage.ts
|
|
37776
37937
|
var import_fs_extra16 = __toESM(require_lib4(), 1);
|
|
@@ -37789,6 +37950,9 @@ function getConfigDir() {
|
|
|
37789
37950
|
function getTokenFilePath2() {
|
|
37790
37951
|
return path20.join(getConfigDir(), "token.txt");
|
|
37791
37952
|
}
|
|
37953
|
+
function getAssistantProTokenFilePath() {
|
|
37954
|
+
return path20.join(getConfigDir(), "assistant-pro-token.txt");
|
|
37955
|
+
}
|
|
37792
37956
|
async function saveToken(githubToken) {
|
|
37793
37957
|
const tokenFile = getTokenFilePath2();
|
|
37794
37958
|
const configDir = path20.dirname(tokenFile);
|
|
@@ -37803,6 +37967,11 @@ async function saveToken(githubToken) {
|
|
|
37803
37967
|
}
|
|
37804
37968
|
await import_fs_extra16.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
37805
37969
|
}
|
|
37970
|
+
async function saveAssistantProToken(githubToken) {
|
|
37971
|
+
const tokenFile = getAssistantProTokenFilePath();
|
|
37972
|
+
await import_fs_extra16.default.ensureDir(path20.dirname(tokenFile));
|
|
37973
|
+
await import_fs_extra16.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
37974
|
+
}
|
|
37806
37975
|
async function getToken() {
|
|
37807
37976
|
const tokenFile = getTokenFilePath2();
|
|
37808
37977
|
if (!await import_fs_extra16.default.pathExists(tokenFile)) {
|
|
@@ -37815,17 +37984,36 @@ async function getToken() {
|
|
|
37815
37984
|
return null;
|
|
37816
37985
|
}
|
|
37817
37986
|
}
|
|
37987
|
+
async function getAssistantProToken() {
|
|
37988
|
+
const tokenFile = getAssistantProTokenFilePath();
|
|
37989
|
+
if (!await import_fs_extra16.default.pathExists(tokenFile)) {
|
|
37990
|
+
return null;
|
|
37991
|
+
}
|
|
37992
|
+
try {
|
|
37993
|
+
const token = await import_fs_extra16.default.readFile(tokenFile, "utf-8");
|
|
37994
|
+
return token.trim();
|
|
37995
|
+
} catch {
|
|
37996
|
+
return null;
|
|
37997
|
+
}
|
|
37998
|
+
}
|
|
37818
37999
|
function getTokenInfo() {
|
|
37819
38000
|
return {
|
|
37820
38001
|
path: getTokenFilePath2(),
|
|
37821
38002
|
platform: os18.platform()
|
|
37822
38003
|
};
|
|
37823
38004
|
}
|
|
38005
|
+
function getAssistantProTokenInfo() {
|
|
38006
|
+
return {
|
|
38007
|
+
path: getAssistantProTokenFilePath(),
|
|
38008
|
+
platform: os18.platform()
|
|
38009
|
+
};
|
|
38010
|
+
}
|
|
37824
38011
|
|
|
37825
38012
|
// src/commands/pro.ts
|
|
37826
38013
|
var import_fs_extra17 = __toESM(require_lib4(), 1);
|
|
37827
38014
|
var API_URL = "https://codeline.app/api/products";
|
|
37828
38015
|
var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
|
|
38016
|
+
var ASSISTANT_PRO_PRODUCT_ID = "prd_t2GRwX3aH1";
|
|
37829
38017
|
|
|
37830
38018
|
class PremiumActivationError extends Error {
|
|
37831
38019
|
code;
|
|
@@ -37844,9 +38032,9 @@ function logPremiumActivationError(error) {
|
|
|
37844
38032
|
M2.info("\uD83D\uDC8E Get AIBlueprint CLI Premium at: https://mlv.sh/claude-cli");
|
|
37845
38033
|
}
|
|
37846
38034
|
}
|
|
37847
|
-
async function promptForPremiumToken() {
|
|
38035
|
+
async function promptForPremiumToken(message = "Enter your Premium access token:", cancelMessage = "Premium activation cancelled") {
|
|
37848
38036
|
const result = await he({
|
|
37849
|
-
message
|
|
38037
|
+
message,
|
|
37850
38038
|
placeholder: "Your ProductsOnUsers ID from codeline.app",
|
|
37851
38039
|
validate: (value) => {
|
|
37852
38040
|
if (!value)
|
|
@@ -37857,14 +38045,14 @@ async function promptForPremiumToken() {
|
|
|
37857
38045
|
}
|
|
37858
38046
|
});
|
|
37859
38047
|
if (pD(result)) {
|
|
37860
|
-
xe(
|
|
38048
|
+
xe(cancelMessage);
|
|
37861
38049
|
process.exit(0);
|
|
37862
38050
|
}
|
|
37863
38051
|
return result;
|
|
37864
38052
|
}
|
|
37865
|
-
async function fetchPremiumActivationData(userToken) {
|
|
38053
|
+
async function fetchPremiumActivationData(userToken, productIds = PRODUCT_IDS) {
|
|
37866
38054
|
const encodedToken = encodeURIComponent(userToken);
|
|
37867
|
-
for (const productId of
|
|
38055
|
+
for (const productId of productIds) {
|
|
37868
38056
|
const response = await fetch(`${API_URL}/${productId}/have-access?token=${encodedToken}`);
|
|
37869
38057
|
if (response.ok) {
|
|
37870
38058
|
const responseData = await response.json();
|
|
@@ -37875,14 +38063,14 @@ async function fetchPremiumActivationData(userToken) {
|
|
|
37875
38063
|
}
|
|
37876
38064
|
return null;
|
|
37877
38065
|
}
|
|
37878
|
-
async function activatePremiumToken(userToken) {
|
|
37879
|
-
const premiumToken = userToken ?? await promptForPremiumToken();
|
|
38066
|
+
async function activatePremiumToken(userToken, options = {}) {
|
|
38067
|
+
const premiumToken = userToken ?? await promptForPremiumToken(options.promptMessage, options.cancelMessage);
|
|
37880
38068
|
const spinner = Y2();
|
|
37881
|
-
spinner.start("Validating token against premium products...");
|
|
37882
|
-
const data = await fetchPremiumActivationData(premiumToken);
|
|
38069
|
+
spinner.start(options.validationMessage ?? "Validating token against premium products...");
|
|
38070
|
+
const data = await fetchPremiumActivationData(premiumToken, options.productIds);
|
|
37883
38071
|
if (!data) {
|
|
37884
38072
|
spinner.stop("Token validation failed");
|
|
37885
|
-
throw new PremiumActivationError("invalid-token", "Invalid token or no access to premium products");
|
|
38073
|
+
throw new PremiumActivationError("invalid-token", options.invalidMessage ?? "Invalid token or no access to premium products");
|
|
37886
38074
|
}
|
|
37887
38075
|
spinner.stop("Token validated");
|
|
37888
38076
|
const githubToken = data.product?.metadata?.["cli-github-token"];
|
|
@@ -37890,7 +38078,7 @@ async function activatePremiumToken(userToken) {
|
|
|
37890
38078
|
throw new PremiumActivationError("missing-github-token", "No GitHub token found in product metadata. Please contact support.");
|
|
37891
38079
|
}
|
|
37892
38080
|
spinner.start("Saving token...");
|
|
37893
|
-
await saveToken(githubToken);
|
|
38081
|
+
await (options.saveGithubToken ?? saveToken)(githubToken);
|
|
37894
38082
|
spinner.stop("Token saved");
|
|
37895
38083
|
return { githubToken, data };
|
|
37896
38084
|
}
|
|
@@ -38043,6 +38231,65 @@ async function proSetupCommand(options = {}) {
|
|
|
38043
38231
|
process.exit(1);
|
|
38044
38232
|
}
|
|
38045
38233
|
}
|
|
38234
|
+
async function assistantProSetupCommand(options = {}) {
|
|
38235
|
+
Ie(source_default.blue(`\uD83E\uDD16 Setup Assistant Pro ${source_default.gray(`v${getVersion()}`)}`));
|
|
38236
|
+
try {
|
|
38237
|
+
let githubToken = await getAssistantProToken();
|
|
38238
|
+
if (!githubToken) {
|
|
38239
|
+
M2.info("Enter your Assistant Pro access key to activate and continue setup.");
|
|
38240
|
+
const activation = await activatePremiumToken(undefined, {
|
|
38241
|
+
productIds: [ASSISTANT_PRO_PRODUCT_ID],
|
|
38242
|
+
promptMessage: "Enter your Assistant Pro access key:",
|
|
38243
|
+
validationMessage: "Validating Assistant Pro access key...",
|
|
38244
|
+
invalidMessage: "Invalid key or no access to AssistantPro",
|
|
38245
|
+
cancelMessage: "Assistant Pro setup cancelled",
|
|
38246
|
+
saveGithubToken: saveAssistantProToken
|
|
38247
|
+
});
|
|
38248
|
+
githubToken = activation.githubToken;
|
|
38249
|
+
M2.success("✅ Assistant Pro key activated. Continuing setup...");
|
|
38250
|
+
}
|
|
38251
|
+
const { rootDir, claudeDir, codexDir, agentsDir } = resolveFolders(options);
|
|
38252
|
+
const hermesDir = options.hermesFolder ? path21.resolve(options.hermesFolder) : path21.join(rootDir, ".hermes");
|
|
38253
|
+
const spinner = Y2();
|
|
38254
|
+
spinner.start("Installing the latest Assistant Pro skills...");
|
|
38255
|
+
const result = await installAssistantProSkills({
|
|
38256
|
+
githubToken,
|
|
38257
|
+
rootDir
|
|
38258
|
+
});
|
|
38259
|
+
spinner.stop(`Assistant Pro ${result.version} installed`);
|
|
38260
|
+
spinner.start("Configuring Claude Code, Codex, Hermes, and OpenClaw...");
|
|
38261
|
+
await configureAssistantProConsumers({
|
|
38262
|
+
agentsDir,
|
|
38263
|
+
claudeDir,
|
|
38264
|
+
codexDir,
|
|
38265
|
+
hermesDir
|
|
38266
|
+
});
|
|
38267
|
+
spinner.stop("Assistant integrations configured");
|
|
38268
|
+
trackEvent("assistant-pro-setup", {
|
|
38269
|
+
skills: result.skillCount,
|
|
38270
|
+
version: result.version
|
|
38271
|
+
});
|
|
38272
|
+
M2.success("✅ Assistant Pro setup complete!");
|
|
38273
|
+
M2.info(` • ${result.skillCount} skills from assistant-pro-skills ${result.version}`);
|
|
38274
|
+
M2.info(` • Codex source: ${path21.join(agentsDir, "skills")}`);
|
|
38275
|
+
M2.info(` • Claude Code symlinks: ${path21.join(claudeDir, "skills")}`);
|
|
38276
|
+
M2.info(` • Hermes external skills: ${path21.join(hermesDir, "config.yaml")}`);
|
|
38277
|
+
M2.info(" • OpenClaw: native ~/.agents/skills discovery");
|
|
38278
|
+
M2.info(` • Access key saved to: ${getAssistantProTokenInfo().path}`);
|
|
38279
|
+
Se(source_default.green("\uD83D\uDE80 Assistant Pro is ready! Start a new assistant session."));
|
|
38280
|
+
} catch (error) {
|
|
38281
|
+
trackError(error, { command: "assistant-pro-setup" });
|
|
38282
|
+
await flushTelemetry();
|
|
38283
|
+
if (isPremiumActivationError(error)) {
|
|
38284
|
+
M2.error(error.message);
|
|
38285
|
+
M2.info("Get Assistant Pro at: https://codeline.app");
|
|
38286
|
+
} else if (error instanceof Error) {
|
|
38287
|
+
M2.error(error.message);
|
|
38288
|
+
}
|
|
38289
|
+
Se(source_default.red("❌ Assistant Pro setup failed"));
|
|
38290
|
+
process.exit(1);
|
|
38291
|
+
}
|
|
38292
|
+
}
|
|
38046
38293
|
async function proUpdateCommand(options = {}) {
|
|
38047
38294
|
Ie(source_default.blue(`\uD83D\uDD04 Update Premium Configs ${source_default.gray(`v${getVersion()}`)}`));
|
|
38048
38295
|
try {
|
|
@@ -39631,6 +39878,11 @@ addConfigFolderOptions(configsBackupsCmd.command("clean").description("Delete ol
|
|
|
39631
39878
|
includeManual: options.includeManual
|
|
39632
39879
|
});
|
|
39633
39880
|
});
|
|
39881
|
+
var assistantsCmd = program2.command("assistants").description("Configure skills shared by Claude Code, Codex, Hermes, and OpenClaw");
|
|
39882
|
+
var assistantsProCmd = assistantsCmd.command("pro").description("Manage Assistant Pro skills");
|
|
39883
|
+
assistantsProCmd.command("setup").description("Install the latest Assistant Pro skills and configure supported assistants").action(() => {
|
|
39884
|
+
return assistantProSetupCommand();
|
|
39885
|
+
});
|
|
39634
39886
|
var openclawCmd = program2.command("openclaw").description("OpenClaw configuration commands").option("-f, --folder <path>", "Specify custom OpenClaw folder path (default: ~/.openclaw)");
|
|
39635
39887
|
var openclawProCmd = openclawCmd.command("pro").description("Manage OpenClaw Pro features");
|
|
39636
39888
|
openclawProCmd.command("activate [token]").description("Activate OpenClaw Pro with your access token").action((token) => {
|
package/package.json
CHANGED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# APEX Task: {{task_id}}
|
|
2
|
-
|
|
3
|
-
**Created:** {{timestamp}}
|
|
4
|
-
**Task:** {{task_description}}
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Configuration
|
|
9
|
-
|
|
10
|
-
| Flag | Value |
|
|
11
|
-
|------|-------|
|
|
12
|
-
| Auto mode (`-a`) | {{auto_mode}} |
|
|
13
|
-
| Examine mode (`-x`) | {{examine_mode}} |
|
|
14
|
-
| Save mode (`-s`) | {{save_mode}} |
|
|
15
|
-
| Test mode (`-t`) | {{test_mode}} |
|
|
16
|
-
| Economy mode (`-e`) | {{economy_mode}} |
|
|
17
|
-
| Branch mode (`-b`) | {{branch_mode}} |
|
|
18
|
-
| PR mode (`-pr`) | {{pr_mode}} |
|
|
19
|
-
| Interactive mode (`-i`) | {{interactive_mode}} |
|
|
20
|
-
| Tasks mode (`-k`) | {{tasks_mode}} |
|
|
21
|
-
| Verify mode (`-v`) | {{verify_mode}} |
|
|
22
|
-
| Branch name | {{branch_name}} |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## User Request
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
{{original_input}}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Acceptance Criteria
|
|
35
|
-
|
|
36
|
-
_To be defined in step-01-analyze.md_
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Progress
|
|
41
|
-
|
|
42
|
-
| Step | Status | Timestamp |
|
|
43
|
-
|------|--------|-----------|
|
|
44
|
-
| 00-init | ⏸ Pending | |
|
|
45
|
-
| 01-analyze | ⏸ Pending | |
|
|
46
|
-
| 02-plan | ⏸ Pending | |
|
|
47
|
-
| 02b-tasks | {{tasks_status}} | |
|
|
48
|
-
| 03-execute | ⏸ Pending | |
|
|
49
|
-
| 04-validate | ⏸ Pending | |
|
|
50
|
-
| 05-examine | {{examine_status}} | |
|
|
51
|
-
| 06-resolve | {{examine_status}} | |
|
|
52
|
-
| 07-tests | {{test_status}} | |
|
|
53
|
-
| 08-run-tests | {{test_status}} | |
|
|
54
|
-
| 10-verify | {{verify_status}} | |
|
|
55
|
-
| 09-finish | {{pr_status}} | |
|