@jakkrichm/create-nexus-devflow 2.8.0 → 2.9.3
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/dist/bin/create-nexus-devflow.d.ts +7 -3
- package/dist/bin/create-nexus-devflow.js +237 -4
- package/dist/bin/create-nexus-devflow.js.map +1 -1
- package/dist/lib/dashboard-page.d.ts +1 -1
- package/dist/lib/dashboard-page.js +76 -0
- package/dist/lib/dashboard-page.js.map +1 -1
- package/dist/lib/doctor.js +40 -0
- package/dist/lib/doctor.js.map +1 -1
- package/dist/lib/project-config.d.ts +1 -1
- package/dist/lib/project-config.js +4 -1
- package/dist/lib/project-config.js.map +1 -1
- package/dist/lib/run-state.d.ts +39 -0
- package/dist/lib/run-state.js +203 -0
- package/dist/lib/run-state.js.map +1 -0
- package/dist/lib/skill-manager.d.ts +73 -0
- package/dist/lib/skill-manager.js +510 -0
- package/dist/lib/skill-manager.js.map +1 -0
- package/dist/lib/status.d.ts +4 -1
- package/dist/lib/status.js +49 -3
- package/dist/lib/status.js.map +1 -1
- package/dist/lib/webview-studio.js +169 -47
- package/dist/lib/webview-studio.js.map +1 -1
- package/package.json +2 -2
- package/template/.agents/skills/adopt/SKILL.md +4 -0
- package/template/.agents/skills/audit/SKILL.md +4 -0
- package/template/.agents/skills/autopilot/SKILL.md +4 -0
- package/template/.agents/skills/check/SKILL.md +4 -0
- package/template/.agents/skills/ci/SKILL.md +4 -0
- package/template/.agents/skills/complete/SKILL.md +7 -1
- package/template/.agents/skills/continuous/SKILL.md +4 -0
- package/template/.agents/skills/debug/SKILL.md +4 -0
- package/template/.agents/skills/devflow/SKILL.md +6 -1
- package/template/.agents/skills/discovery/SKILL.md +10 -1
- package/template/.agents/skills/feature/SKILL.md +4 -0
- package/template/.agents/skills/fix/SKILL.md +4 -0
- package/template/.agents/skills/implement/SKILL.md +4 -0
- package/template/.agents/skills/onboard/SKILL.md +4 -0
- package/template/.agents/skills/overview/SKILL.md +4 -0
- package/template/.agents/skills/prototype/SKILL.md +4 -0
- package/template/.agents/skills/release/SKILL.md +4 -0
- package/template/.agents/skills/rollback/SKILL.md +18 -5
- package/template/.agents/skills/status/SKILL.md +7 -0
- package/template/.agents/skills/tests/SKILL.md +4 -0
- package/template/.claude/skills/adopt/SKILL.md +4 -0
- package/template/.claude/skills/audit/SKILL.md +4 -0
- package/template/.claude/skills/autopilot/SKILL.md +4 -0
- package/template/.claude/skills/check/SKILL.md +4 -0
- package/template/.claude/skills/ci/SKILL.md +4 -0
- package/template/.claude/skills/complete/SKILL.md +7 -1
- package/template/.claude/skills/continuous/SKILL.md +4 -0
- package/template/.claude/skills/debug/SKILL.md +4 -0
- package/template/.claude/skills/devflow/SKILL.md +6 -1
- package/template/.claude/skills/discovery/SKILL.md +10 -1
- package/template/.claude/skills/feature/SKILL.md +4 -0
- package/template/.claude/skills/fix/SKILL.md +4 -0
- package/template/.claude/skills/implement/SKILL.md +4 -0
- package/template/.claude/skills/onboard/SKILL.md +4 -0
- package/template/.claude/skills/overview/SKILL.md +4 -0
- package/template/.claude/skills/prototype/SKILL.md +4 -0
- package/template/.claude/skills/release/SKILL.md +4 -0
- package/template/.claude/skills/rollback/SKILL.md +18 -5
- package/template/.claude/skills/status/SKILL.md +7 -0
- package/template/.claude/skills/tests/SKILL.md +4 -0
- package/template/AGENTS.md +24 -5
- package/template/LICENSE +21 -21
- package/template/devflow/build-plan.md +16 -0
- package/template/devflow/context/ai-interaction.md +25 -0
- package/dist/lib/antigravity-artifacts.d.ts +0 -52
- package/dist/lib/antigravity-artifacts.js +0 -170
- package/dist/lib/antigravity-artifacts.js.map +0 -1
- package/dist/lib/antigravity-hooks.d.ts +0 -31
- package/dist/lib/antigravity-hooks.js +0 -85
- package/dist/lib/antigravity-hooks.js.map +0 -1
- package/dist/lib/antigravity-plugin.d.ts +0 -51
- package/dist/lib/antigravity-plugin.js +0 -179
- package/dist/lib/antigravity-plugin.js.map +0 -1
- package/dist/lib/antigravity-scheduler.d.ts +0 -39
- package/dist/lib/antigravity-scheduler.js +0 -95
- package/dist/lib/antigravity-scheduler.js.map +0 -1
- package/dist/lib/openai-tools.d.ts +0 -34
- package/dist/lib/openai-tools.js +0 -57
- package/dist/lib/openai-tools.js.map +0 -1
- package/dist/lib/visual-subagent.d.ts +0 -32
- package/dist/lib/visual-subagent.js +0 -98
- package/dist/lib/visual-subagent.js.map +0 -1
- package/template/.agents/skills/convert-any-to-md/scripts/__pycache__/convert_any_to_md.cpython-314.pyc +0 -0
- package/template/.claude/skills/convert-any-to-md/scripts/__pycache__/convert_any_to_md.cpython-314.pyc +0 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import fsSync from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { loadCoreSkillInventory } from "./core-skill-inventory.js";
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
10
|
+
const MANIFEST_PATH = path.join(".nexus", "nexus-devflow.json");
|
|
11
|
+
const AGENT_MANIFEST_PATH = "agent-bundle.manifest.json";
|
|
12
|
+
export function parseSkillFrontmatter(content) {
|
|
13
|
+
if (!content.startsWith("---"))
|
|
14
|
+
return {};
|
|
15
|
+
const parts = content.split("---");
|
|
16
|
+
if (parts.length < 3)
|
|
17
|
+
return {};
|
|
18
|
+
const lines = parts[1].split("\n");
|
|
19
|
+
let name;
|
|
20
|
+
let description;
|
|
21
|
+
let version;
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
if (trimmed.startsWith("name:")) {
|
|
25
|
+
name = trimmed.replace("name:", "").trim().replace(/^["']|["']$/g, "");
|
|
26
|
+
}
|
|
27
|
+
else if (trimmed.startsWith("description:")) {
|
|
28
|
+
description = trimmed.replace("description:", "").trim().replace(/^["']|["']$/g, "");
|
|
29
|
+
}
|
|
30
|
+
else if (trimmed.startsWith("version:")) {
|
|
31
|
+
version = trimmed.replace("version:", "").trim().replace(/^["']|["']$/g, "");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Also check metadata: version block
|
|
35
|
+
const metaMatch = parts[1].match(/version:\s*["']?([^"'\r\n]+)["']?/);
|
|
36
|
+
if (!version && metaMatch) {
|
|
37
|
+
version = metaMatch[1].trim();
|
|
38
|
+
}
|
|
39
|
+
return { name, description, version };
|
|
40
|
+
}
|
|
41
|
+
export async function readDevflowManifest(projectRoot) {
|
|
42
|
+
const fullPath = path.join(projectRoot, MANIFEST_PATH);
|
|
43
|
+
try {
|
|
44
|
+
const raw = await fs.readFile(fullPath, "utf8");
|
|
45
|
+
return JSON.parse(raw);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
if (err.code === "ENOENT") {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function writeDevflowManifest(projectRoot, manifest) {
|
|
55
|
+
const fullPath = path.join(projectRoot, MANIFEST_PATH);
|
|
56
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
57
|
+
await fs.writeFile(fullPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
58
|
+
}
|
|
59
|
+
export async function listInstalledSkills(projectRoot) {
|
|
60
|
+
let coreNameSet = new Set();
|
|
61
|
+
try {
|
|
62
|
+
const inventory = await loadCoreSkillInventory(path.join(projectRoot, AGENT_MANIFEST_PATH));
|
|
63
|
+
coreNameSet = inventory.nameSet;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// fallback if manifest not found
|
|
67
|
+
}
|
|
68
|
+
const manifest = await readDevflowManifest(projectRoot);
|
|
69
|
+
const recordedThirdParty = Array.isArray(manifest?.thirdPartySkills)
|
|
70
|
+
? manifest.thirdPartySkills
|
|
71
|
+
: [];
|
|
72
|
+
const thirdPartyMap = new Map();
|
|
73
|
+
for (const record of recordedThirdParty) {
|
|
74
|
+
if (record?.name) {
|
|
75
|
+
thirdPartyMap.set(record.name, record);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const agentsDir = path.join(projectRoot, ".agents", "skills");
|
|
79
|
+
const claudeDir = path.join(projectRoot, ".claude", "skills");
|
|
80
|
+
const agentsSkills = new Set();
|
|
81
|
+
const claudeSkills = new Set();
|
|
82
|
+
try {
|
|
83
|
+
const entries = await fs.readdir(agentsDir, { withFileTypes: true });
|
|
84
|
+
for (const e of entries) {
|
|
85
|
+
if (e.isDirectory())
|
|
86
|
+
agentsSkills.add(e.name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// ignore missing dir
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const entries = await fs.readdir(claudeDir, { withFileTypes: true });
|
|
94
|
+
for (const e of entries) {
|
|
95
|
+
if (e.isDirectory())
|
|
96
|
+
claudeSkills.add(e.name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// ignore missing dir
|
|
101
|
+
}
|
|
102
|
+
const allNames = new Set([...agentsSkills, ...claudeSkills, ...thirdPartyMap.keys()]);
|
|
103
|
+
const coreSkills = [];
|
|
104
|
+
const thirdPartySkills = [];
|
|
105
|
+
for (const name of [...allNames].sort()) {
|
|
106
|
+
const inAgents = agentsSkills.has(name);
|
|
107
|
+
const inClaude = claudeSkills.has(name);
|
|
108
|
+
const adapters = [];
|
|
109
|
+
if (inAgents)
|
|
110
|
+
adapters.push(".agents");
|
|
111
|
+
if (inClaude)
|
|
112
|
+
adapters.push(".claude");
|
|
113
|
+
const skillFilePath = inAgents
|
|
114
|
+
? path.join(agentsDir, name, "SKILL.md")
|
|
115
|
+
: path.join(claudeDir, name, "SKILL.md");
|
|
116
|
+
let description = "";
|
|
117
|
+
let version = "";
|
|
118
|
+
try {
|
|
119
|
+
const content = await fs.readFile(skillFilePath, "utf8");
|
|
120
|
+
const meta = parseSkillFrontmatter(content);
|
|
121
|
+
description = meta.description || "";
|
|
122
|
+
version = meta.version || "";
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// no readable SKILL.md
|
|
126
|
+
}
|
|
127
|
+
const recorded = thirdPartyMap.get(name);
|
|
128
|
+
const isCore = coreNameSet.has(name);
|
|
129
|
+
let category = "local-extension";
|
|
130
|
+
if (isCore) {
|
|
131
|
+
category = "core";
|
|
132
|
+
}
|
|
133
|
+
else if (recorded) {
|
|
134
|
+
category = "third-party";
|
|
135
|
+
}
|
|
136
|
+
const detail = {
|
|
137
|
+
name,
|
|
138
|
+
category,
|
|
139
|
+
description: description || recorded?.description || "",
|
|
140
|
+
version: version || recorded?.version,
|
|
141
|
+
source: recorded?.source,
|
|
142
|
+
adapters,
|
|
143
|
+
synced: inAgents && inClaude,
|
|
144
|
+
path: inAgents ? `.agents/skills/${name}` : `.claude/skills/${name}`
|
|
145
|
+
};
|
|
146
|
+
if (isCore) {
|
|
147
|
+
coreSkills.push(detail);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
thirdPartySkills.push(detail);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
coreSkills,
|
|
155
|
+
thirdPartySkills,
|
|
156
|
+
totalCount: coreSkills.length + thirdPartySkills.length
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export async function discoverSkillsInDirectory(rootDir, maxDepth = 5, currentDepth = 0) {
|
|
160
|
+
const results = [];
|
|
161
|
+
if (currentDepth > maxDepth)
|
|
162
|
+
return results;
|
|
163
|
+
const skillMdPath = path.join(rootDir, "SKILL.md");
|
|
164
|
+
if (fsSync.existsSync(skillMdPath)) {
|
|
165
|
+
try {
|
|
166
|
+
const content = await fs.readFile(skillMdPath, "utf8");
|
|
167
|
+
const meta = parseSkillFrontmatter(content);
|
|
168
|
+
const skillName = meta.name || path.basename(rootDir);
|
|
169
|
+
results.push({
|
|
170
|
+
sourceSkillPath: rootDir,
|
|
171
|
+
skillName,
|
|
172
|
+
meta
|
|
173
|
+
});
|
|
174
|
+
return results;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// ignore read error
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
let entries;
|
|
181
|
+
try {
|
|
182
|
+
entries = await fs.readdir(rootDir, { withFileTypes: true });
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
const IGNORED_DIRS = new Set([".git", "node_modules", "dist", ".nexus", "build", "coverage", ".turbo"]);
|
|
188
|
+
for (const entry of entries) {
|
|
189
|
+
if (entry.isDirectory() && !IGNORED_DIRS.has(entry.name)) {
|
|
190
|
+
const subDir = path.join(rootDir, entry.name);
|
|
191
|
+
const subResults = await discoverSkillsInDirectory(subDir, maxDepth, currentDepth + 1);
|
|
192
|
+
results.push(...subResults);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return results;
|
|
196
|
+
}
|
|
197
|
+
export async function findSkillSourceDirectory(sourceDir, requestedName) {
|
|
198
|
+
const discovered = await discoverSkillsInDirectory(sourceDir);
|
|
199
|
+
if (discovered.length === 0) {
|
|
200
|
+
throw new Error(`Could not find any valid skill with SKILL.md in source: ${sourceDir}`);
|
|
201
|
+
}
|
|
202
|
+
if (requestedName) {
|
|
203
|
+
const match = discovered.find((s) => s.skillName === requestedName || path.basename(s.sourceSkillPath) === requestedName);
|
|
204
|
+
if (match) {
|
|
205
|
+
return {
|
|
206
|
+
sourceSkillPath: match.sourceSkillPath,
|
|
207
|
+
skillName: requestedName,
|
|
208
|
+
meta: match.meta
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const available = discovered.map((s) => s.skillName).join(", ");
|
|
212
|
+
throw new Error(`Skill "${requestedName}" not found in source. Available skills (${discovered.length}): ${available}`);
|
|
213
|
+
}
|
|
214
|
+
if (discovered.length === 1) {
|
|
215
|
+
return {
|
|
216
|
+
sourceSkillPath: discovered[0].sourceSkillPath,
|
|
217
|
+
skillName: discovered[0].skillName,
|
|
218
|
+
meta: discovered[0].meta
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Check if one matches the sourceDir basename
|
|
222
|
+
const baseName = path.basename(sourceDir);
|
|
223
|
+
const baseMatch = discovered.find((s) => s.skillName === baseName || path.basename(s.sourceSkillPath) === baseName);
|
|
224
|
+
if (baseMatch) {
|
|
225
|
+
return {
|
|
226
|
+
sourceSkillPath: baseMatch.sourceSkillPath,
|
|
227
|
+
skillName: baseMatch.skillName,
|
|
228
|
+
meta: baseMatch.meta
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const available = discovered.map((s) => s.skillName).join(", ");
|
|
232
|
+
throw new Error(`Multiple skills found in source (${discovered.length} skills: ${available}). Please specify --name <skill-name> or use --all to install all skills.`);
|
|
233
|
+
}
|
|
234
|
+
export async function installThirdPartySkill(projectRoot, source, options) {
|
|
235
|
+
const isGitUrl = /^https?:\/\/|^git@|^ssh:\/\/|\.git$/.test(source);
|
|
236
|
+
let tempCloneDir = null;
|
|
237
|
+
let sourceDirectory = source;
|
|
238
|
+
let coreNameSet = new Set();
|
|
239
|
+
try {
|
|
240
|
+
const inventory = await loadCoreSkillInventory(path.join(projectRoot, AGENT_MANIFEST_PATH));
|
|
241
|
+
coreNameSet = inventory.nameSet;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// ignore
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
if (isGitUrl) {
|
|
248
|
+
tempCloneDir = await fs.mkdtemp(path.join(os.tmpdir(), "nexus-skill-"));
|
|
249
|
+
await execFileAsync("git", ["clone", "--depth", "1", source, tempCloneDir]);
|
|
250
|
+
sourceDirectory = tempCloneDir;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
sourceDirectory = path.isAbsolute(source) ? source : path.resolve(projectRoot, source);
|
|
254
|
+
if (!fsSync.existsSync(sourceDirectory)) {
|
|
255
|
+
throw new Error(`Source directory does not exist: ${source}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const recordedSource = options?.overrideSource || source;
|
|
259
|
+
const recordedType = isGitUrl || options?.overrideSource ? "git" : "local";
|
|
260
|
+
if (options?.all) {
|
|
261
|
+
const discovered = await discoverSkillsInDirectory(sourceDirectory);
|
|
262
|
+
if (discovered.length === 0) {
|
|
263
|
+
throw new Error(`Could not find any valid skill with SKILL.md in source: ${source}`);
|
|
264
|
+
}
|
|
265
|
+
const installedList = [];
|
|
266
|
+
const manifest = (await readDevflowManifest(projectRoot)) || {
|
|
267
|
+
schemaVersion: 1,
|
|
268
|
+
name: "nexus-devflow",
|
|
269
|
+
package: "@jakkrichm/create-nexus-devflow",
|
|
270
|
+
version: "2.9.3"
|
|
271
|
+
};
|
|
272
|
+
const existingThirdParty = Array.isArray(manifest.thirdPartySkills)
|
|
273
|
+
? manifest.thirdPartySkills
|
|
274
|
+
: [];
|
|
275
|
+
let updatedThirdParty = [...existingThirdParty];
|
|
276
|
+
for (const skill of discovered) {
|
|
277
|
+
const skillName = skill.skillName;
|
|
278
|
+
if (!SKILL_NAME_PATTERN.test(skillName)) {
|
|
279
|
+
continue; // skip invalid names in batch mode
|
|
280
|
+
}
|
|
281
|
+
if (coreNameSet.has(skillName) && !options?.force) {
|
|
282
|
+
continue; // skip core collisions in batch mode
|
|
283
|
+
}
|
|
284
|
+
const targetAgentsSkillDir = path.join(projectRoot, ".agents", "skills", skillName);
|
|
285
|
+
const targetClaudeSkillDir = path.join(projectRoot, ".claude", "skills", skillName);
|
|
286
|
+
await fs.rm(targetAgentsSkillDir, { recursive: true, force: true });
|
|
287
|
+
await fs.rm(targetClaudeSkillDir, { recursive: true, force: true });
|
|
288
|
+
await fs.mkdir(path.dirname(targetAgentsSkillDir), { recursive: true });
|
|
289
|
+
await fs.mkdir(path.dirname(targetClaudeSkillDir), { recursive: true });
|
|
290
|
+
await fs.cp(skill.sourceSkillPath, targetAgentsSkillDir, { recursive: true });
|
|
291
|
+
await fs.cp(skill.sourceSkillPath, targetClaudeSkillDir, { recursive: true });
|
|
292
|
+
updatedThirdParty = updatedThirdParty.filter((s) => s.name !== skillName);
|
|
293
|
+
updatedThirdParty.push({
|
|
294
|
+
name: skillName,
|
|
295
|
+
source: recordedSource,
|
|
296
|
+
version: skill.meta.version || "1.0.0",
|
|
297
|
+
description: skill.meta.description || "",
|
|
298
|
+
installedAt: new Date().toISOString(),
|
|
299
|
+
type: recordedType
|
|
300
|
+
});
|
|
301
|
+
installedList.push({
|
|
302
|
+
name: skillName,
|
|
303
|
+
category: "third-party",
|
|
304
|
+
description: skill.meta.description || "",
|
|
305
|
+
version: skill.meta.version || "1.0.0",
|
|
306
|
+
source: recordedSource,
|
|
307
|
+
adapters: [".agents", ".claude"],
|
|
308
|
+
synced: true,
|
|
309
|
+
path: `.agents/skills/${skillName}`
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
manifest.thirdPartySkills = updatedThirdParty;
|
|
313
|
+
await writeDevflowManifest(projectRoot, manifest);
|
|
314
|
+
return installedList;
|
|
315
|
+
}
|
|
316
|
+
const { sourceSkillPath, skillName, meta } = await findSkillSourceDirectory(sourceDirectory, options?.name);
|
|
317
|
+
if (!SKILL_NAME_PATTERN.test(skillName)) {
|
|
318
|
+
throw new Error(`Invalid skill name: "${skillName}". Must use kebab-case (e.g. "diagram-design").`);
|
|
319
|
+
}
|
|
320
|
+
if (coreNameSet.has(skillName) && !options?.force) {
|
|
321
|
+
throw new Error(`Cannot install skill with name "${skillName}" as it conflicts with a Core DevFlow Skill.`);
|
|
322
|
+
}
|
|
323
|
+
const targetAgentsSkillDir = path.join(projectRoot, ".agents", "skills", skillName);
|
|
324
|
+
const targetClaudeSkillDir = path.join(projectRoot, ".claude", "skills", skillName);
|
|
325
|
+
await fs.rm(targetAgentsSkillDir, { recursive: true, force: true });
|
|
326
|
+
await fs.rm(targetClaudeSkillDir, { recursive: true, force: true });
|
|
327
|
+
await fs.mkdir(path.dirname(targetAgentsSkillDir), { recursive: true });
|
|
328
|
+
await fs.mkdir(path.dirname(targetClaudeSkillDir), { recursive: true });
|
|
329
|
+
// Copy verbatim to .agents/skills/<name>
|
|
330
|
+
await fs.cp(sourceSkillPath, targetAgentsSkillDir, { recursive: true });
|
|
331
|
+
// Copy verbatim to .claude/skills/<name>
|
|
332
|
+
await fs.cp(sourceSkillPath, targetClaudeSkillDir, { recursive: true });
|
|
333
|
+
// Update .nexus/nexus-devflow.json
|
|
334
|
+
const manifest = (await readDevflowManifest(projectRoot)) || {
|
|
335
|
+
schemaVersion: 1,
|
|
336
|
+
name: "nexus-devflow",
|
|
337
|
+
package: "@jakkrichm/create-nexus-devflow",
|
|
338
|
+
version: "2.9.3"
|
|
339
|
+
};
|
|
340
|
+
const existingThirdParty = Array.isArray(manifest.thirdPartySkills)
|
|
341
|
+
? manifest.thirdPartySkills
|
|
342
|
+
: [];
|
|
343
|
+
const filtered = existingThirdParty.filter((s) => s.name !== skillName);
|
|
344
|
+
filtered.push({
|
|
345
|
+
name: skillName,
|
|
346
|
+
source: recordedSource,
|
|
347
|
+
version: meta.version || "1.0.0",
|
|
348
|
+
description: meta.description || "",
|
|
349
|
+
installedAt: new Date().toISOString(),
|
|
350
|
+
type: recordedType
|
|
351
|
+
});
|
|
352
|
+
manifest.thirdPartySkills = filtered;
|
|
353
|
+
await writeDevflowManifest(projectRoot, manifest);
|
|
354
|
+
return {
|
|
355
|
+
name: skillName,
|
|
356
|
+
category: "third-party",
|
|
357
|
+
description: meta.description || "",
|
|
358
|
+
version: meta.version || "1.0.0",
|
|
359
|
+
source: recordedSource,
|
|
360
|
+
adapters: [".agents", ".claude"],
|
|
361
|
+
synced: true,
|
|
362
|
+
path: `.agents/skills/${skillName}`
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
finally {
|
|
366
|
+
if (tempCloneDir) {
|
|
367
|
+
try {
|
|
368
|
+
await fs.rm(tempCloneDir, { recursive: true, force: true });
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// ignore cleanup error
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
export async function removeThirdPartySkill(projectRoot, name) {
|
|
377
|
+
let coreNameSet = new Set();
|
|
378
|
+
try {
|
|
379
|
+
const inventory = await loadCoreSkillInventory(path.join(projectRoot, AGENT_MANIFEST_PATH));
|
|
380
|
+
coreNameSet = inventory.nameSet;
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// ignore
|
|
384
|
+
}
|
|
385
|
+
if (coreNameSet.has(name)) {
|
|
386
|
+
throw new Error(`Cannot remove Core Skill: "${name}". Core skills are managed by Nexus-DevFlow.`);
|
|
387
|
+
}
|
|
388
|
+
const targetAgentsSkillDir = path.join(projectRoot, ".agents", "skills", name);
|
|
389
|
+
const targetClaudeSkillDir = path.join(projectRoot, ".claude", "skills", name);
|
|
390
|
+
let removedAny = false;
|
|
391
|
+
if (fsSync.existsSync(targetAgentsSkillDir)) {
|
|
392
|
+
await fs.rm(targetAgentsSkillDir, { recursive: true, force: true });
|
|
393
|
+
removedAny = true;
|
|
394
|
+
}
|
|
395
|
+
if (fsSync.existsSync(targetClaudeSkillDir)) {
|
|
396
|
+
await fs.rm(targetClaudeSkillDir, { recursive: true, force: true });
|
|
397
|
+
removedAny = true;
|
|
398
|
+
}
|
|
399
|
+
const manifest = await readDevflowManifest(projectRoot);
|
|
400
|
+
if (manifest && Array.isArray(manifest.thirdPartySkills)) {
|
|
401
|
+
const prevList = manifest.thirdPartySkills;
|
|
402
|
+
const nextList = prevList.filter((s) => s.name !== name);
|
|
403
|
+
if (nextList.length !== prevList.length) {
|
|
404
|
+
manifest.thirdPartySkills = nextList;
|
|
405
|
+
await writeDevflowManifest(projectRoot, manifest);
|
|
406
|
+
removedAny = true;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return removedAny;
|
|
410
|
+
}
|
|
411
|
+
export async function syncSkills(projectRoot) {
|
|
412
|
+
const agentsDir = path.join(projectRoot, ".agents", "skills");
|
|
413
|
+
const claudeDir = path.join(projectRoot, ".claude", "skills");
|
|
414
|
+
if (!fsSync.existsSync(agentsDir)) {
|
|
415
|
+
return { syncedCount: 0, skills: [] };
|
|
416
|
+
}
|
|
417
|
+
await fs.rm(claudeDir, { recursive: true, force: true });
|
|
418
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
419
|
+
const entries = await fs.readdir(agentsDir, { withFileTypes: true });
|
|
420
|
+
const syncedSkills = [];
|
|
421
|
+
for (const entry of entries) {
|
|
422
|
+
if (entry.isDirectory()) {
|
|
423
|
+
const src = path.join(agentsDir, entry.name);
|
|
424
|
+
const dst = path.join(claudeDir, entry.name);
|
|
425
|
+
await fs.cp(src, dst, { recursive: true });
|
|
426
|
+
syncedSkills.push(entry.name);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
syncedCount: syncedSkills.length,
|
|
431
|
+
skills: syncedSkills
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
export async function updateThirdPartySkills(projectRoot, targetSkillName, options) {
|
|
435
|
+
const manifest = await readDevflowManifest(projectRoot);
|
|
436
|
+
const existingThirdParty = Array.isArray(manifest?.thirdPartySkills)
|
|
437
|
+
? manifest.thirdPartySkills
|
|
438
|
+
: [];
|
|
439
|
+
if (existingThirdParty.length === 0) {
|
|
440
|
+
return { updatedSkills: [], failedSkills: [], totalUpdated: 0 };
|
|
441
|
+
}
|
|
442
|
+
let skillsToUpdate = existingThirdParty;
|
|
443
|
+
if (targetSkillName && targetSkillName !== "--all") {
|
|
444
|
+
skillsToUpdate = existingThirdParty.filter((s) => s.name === targetSkillName);
|
|
445
|
+
if (skillsToUpdate.length === 0) {
|
|
446
|
+
throw new Error(`Skill "${targetSkillName}" is not installed as a third-party skill.`);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// Group by source to avoid duplicate cloning
|
|
450
|
+
const sourceToSkillsMap = new Map();
|
|
451
|
+
for (const skill of skillsToUpdate) {
|
|
452
|
+
const list = sourceToSkillsMap.get(skill.source) || [];
|
|
453
|
+
list.push(skill);
|
|
454
|
+
sourceToSkillsMap.set(skill.source, list);
|
|
455
|
+
}
|
|
456
|
+
const updatedSkills = [];
|
|
457
|
+
const failedSkills = [];
|
|
458
|
+
for (const [source, skills] of sourceToSkillsMap) {
|
|
459
|
+
const isGit = /^https?:\/\/|^git@|^ssh:\/\/|\.git$/.test(source);
|
|
460
|
+
let tempCloneDir = null;
|
|
461
|
+
try {
|
|
462
|
+
let sourceDir = source;
|
|
463
|
+
if (isGit) {
|
|
464
|
+
tempCloneDir = await fs.mkdtemp(path.join(os.tmpdir(), "nexus-skill-update-"));
|
|
465
|
+
await execFileAsync("git", ["clone", "--depth", "1", source, tempCloneDir]);
|
|
466
|
+
sourceDir = tempCloneDir;
|
|
467
|
+
}
|
|
468
|
+
for (const skill of skills) {
|
|
469
|
+
try {
|
|
470
|
+
const detail = (await installThirdPartySkill(projectRoot, sourceDir, {
|
|
471
|
+
name: skill.name,
|
|
472
|
+
force: true,
|
|
473
|
+
overrideSource: isGit ? source : undefined
|
|
474
|
+
}));
|
|
475
|
+
updatedSkills.push(detail);
|
|
476
|
+
}
|
|
477
|
+
catch (err) {
|
|
478
|
+
failedSkills.push({
|
|
479
|
+
name: skill.name,
|
|
480
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
catch (err) {
|
|
486
|
+
for (const skill of skills) {
|
|
487
|
+
failedSkills.push({
|
|
488
|
+
name: skill.name,
|
|
489
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
finally {
|
|
494
|
+
if (tempCloneDir) {
|
|
495
|
+
try {
|
|
496
|
+
await fs.rm(tempCloneDir, { recursive: true, force: true });
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
// ignore
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
updatedSkills,
|
|
506
|
+
failedSkills,
|
|
507
|
+
totalUpdated: updatedSkills.length
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
//# sourceMappingURL=skill-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-manager.js","sourceRoot":"","sources":["../../lib/skill-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/status.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { GitStatusSummary } from "./git-status.js";
|
|
|
5
5
|
import type { ProjectAdapter } from "./project-metadata.js";
|
|
6
6
|
import type { IdeasSummary } from "./ideas.js";
|
|
7
7
|
import type { ProjectConfig, ProjectConfigState } from "./project-config.js";
|
|
8
|
+
import type { RunStateSummary } from "./run-state.js";
|
|
8
9
|
type CompletionState = "blocked" | "needs_verification" | "ready";
|
|
9
10
|
interface StatusWarning {
|
|
10
11
|
code: string;
|
|
@@ -15,6 +16,7 @@ interface StatusConfiguration {
|
|
|
15
16
|
state: ProjectConfigState;
|
|
16
17
|
values: ProjectConfig;
|
|
17
18
|
}
|
|
19
|
+
type StatusActivity = Omit<RunStateSummary, "warnings">;
|
|
18
20
|
interface StatusCurrentWork {
|
|
19
21
|
state: CurrentWorkSummary["state"];
|
|
20
22
|
type: CurrentWorkType | null;
|
|
@@ -57,6 +59,7 @@ interface ProjectStatus {
|
|
|
57
59
|
adapters: ProjectAdapter[];
|
|
58
60
|
};
|
|
59
61
|
configuration: StatusConfiguration;
|
|
62
|
+
activity: StatusActivity;
|
|
60
63
|
currentWork: StatusCurrentWork;
|
|
61
64
|
activeRuns: ActiveRunSummary[];
|
|
62
65
|
findings: StatusFindings;
|
|
@@ -70,4 +73,4 @@ declare function readProjectStatus(startPath?: string): Promise<ProjectStatus>;
|
|
|
70
73
|
declare function formatHumanStatus(status: ProjectStatus, options?: HumanStatusOptions): string;
|
|
71
74
|
declare function shouldUseColor(isTTY?: boolean | undefined, environment?: NodeJS.ProcessEnv): boolean;
|
|
72
75
|
export { formatHumanStatus, readProjectStatus, shouldUseColor };
|
|
73
|
-
export type { CompletionState, HumanStatusOptions, ProjectStatus, StatusCompletion, StatusCurrentWork, StatusFindings, StatusNextAction, StatusWarning };
|
|
76
|
+
export type { CompletionState, HumanStatusOptions, ProjectStatus, StatusActivity, StatusCompletion, StatusCurrentWork, StatusFindings, StatusNextAction, StatusWarning };
|
package/dist/lib/status.js
CHANGED
|
@@ -6,16 +6,18 @@ import { readGitStatus } from "./git-status.js";
|
|
|
6
6
|
import { readProjectMetadata } from "./project-metadata.js";
|
|
7
7
|
import { readIdeas } from "./ideas.js";
|
|
8
8
|
import { readProjectConfig } from "./project-config.js";
|
|
9
|
+
import { readRunState } from "./run-state.js";
|
|
9
10
|
async function readProjectStatus(startPath = process.cwd()) {
|
|
10
11
|
const metadata = await readProjectMetadata(startPath);
|
|
11
|
-
const [contextPaths, config, currentWork, activeRuns, findings, git, ideas] = await Promise.all([
|
|
12
|
+
const [contextPaths, config, currentWork, activeRuns, findings, git, ideas, runState] = await Promise.all([
|
|
12
13
|
resolveActiveContextPaths(metadata.project.root),
|
|
13
14
|
readProjectConfig(metadata.project.root),
|
|
14
15
|
readCurrentWork(metadata.project.root),
|
|
15
16
|
listActiveRunContexts(metadata.project.root),
|
|
16
17
|
readFindings(metadata.project.root),
|
|
17
18
|
readGitStatus(metadata.project.root),
|
|
18
|
-
readIdeas(metadata.project.root)
|
|
19
|
+
readIdeas(metadata.project.root),
|
|
20
|
+
readRunState(metadata.project.root)
|
|
19
21
|
]);
|
|
20
22
|
let stageMarkdown = "";
|
|
21
23
|
try {
|
|
@@ -27,6 +29,7 @@ async function readProjectStatus(startPath = process.cwd()) {
|
|
|
27
29
|
...config.warnings,
|
|
28
30
|
...currentWork.warnings,
|
|
29
31
|
...findings.warnings,
|
|
32
|
+
...runState.warnings,
|
|
30
33
|
...findDrift(currentWork, git)
|
|
31
34
|
];
|
|
32
35
|
const completion = selectCompletion(currentWork, findings, git, stageMarkdown);
|
|
@@ -43,6 +46,21 @@ async function readProjectStatus(startPath = process.cwd()) {
|
|
|
43
46
|
state: config.state,
|
|
44
47
|
values: config.values
|
|
45
48
|
},
|
|
49
|
+
activity: {
|
|
50
|
+
state: runState.state,
|
|
51
|
+
mode: runState.mode,
|
|
52
|
+
command: runState.command,
|
|
53
|
+
status: runState.status,
|
|
54
|
+
freshness: runState.freshness,
|
|
55
|
+
summary: runState.summary,
|
|
56
|
+
detail: runState.detail,
|
|
57
|
+
boundary: runState.boundary,
|
|
58
|
+
startedAt: runState.startedAt,
|
|
59
|
+
updatedAt: runState.updatedAt,
|
|
60
|
+
resumeCommand: runState.resumeCommand,
|
|
61
|
+
progress: runState.progress,
|
|
62
|
+
feature: runState.feature
|
|
63
|
+
},
|
|
46
64
|
currentWork: formatCurrentWork(currentWork),
|
|
47
65
|
activeRuns,
|
|
48
66
|
findings: formatFindings(findings),
|
|
@@ -69,8 +87,11 @@ function formatHumanStatus(status, options = {}) {
|
|
|
69
87
|
formatRow("Quality gates", formatQualityGates(status.configuration.values.qualityGates.regular), style),
|
|
70
88
|
"",
|
|
71
89
|
formatSection("Progress", style),
|
|
72
|
-
formatRow("
|
|
90
|
+
formatRow("Progress", formatWorkValue(status.currentWork, style), style)
|
|
73
91
|
];
|
|
92
|
+
if (status.activity && status.activity.state === "recorded" && status.activity.command) {
|
|
93
|
+
lines.push(formatRow("Activity", formatActivityValue(status.activity, style), style));
|
|
94
|
+
}
|
|
74
95
|
if (status.currentWork.state === "active") {
|
|
75
96
|
lines.push(formatRow("Steps", `${status.currentWork.completed}/${status.currentWork.total} complete`, style));
|
|
76
97
|
if (status.currentWork.nextStep) {
|
|
@@ -116,6 +137,31 @@ function formatSection(label, style) {
|
|
|
116
137
|
function formatRow(label, value, style) {
|
|
117
138
|
return ` ${style.cyan(label.padEnd(14))}${value}`;
|
|
118
139
|
}
|
|
140
|
+
function formatActivityValue(activity, style) {
|
|
141
|
+
if (activity.state !== "recorded" || !activity.command) {
|
|
142
|
+
return style.dim("none");
|
|
143
|
+
}
|
|
144
|
+
const parts = [`/${activity.command}`];
|
|
145
|
+
if (activity.status) {
|
|
146
|
+
parts.push(activity.status === "running"
|
|
147
|
+
? style.brightCyan(activity.status)
|
|
148
|
+
: activity.status === "ready"
|
|
149
|
+
? style.green(activity.status)
|
|
150
|
+
: activity.status === "blocked"
|
|
151
|
+
? style.red(activity.status)
|
|
152
|
+
: activity.status);
|
|
153
|
+
}
|
|
154
|
+
if (activity.progress) {
|
|
155
|
+
parts.push(`${activity.progress.current}/${activity.progress.total} ${activity.progress.label}`);
|
|
156
|
+
}
|
|
157
|
+
if (activity.boundary) {
|
|
158
|
+
parts.push(`(${activity.boundary})`);
|
|
159
|
+
}
|
|
160
|
+
if (activity.freshness === "stale") {
|
|
161
|
+
parts.push(style.yellow("[stale]"));
|
|
162
|
+
}
|
|
163
|
+
return parts.join(" ");
|
|
164
|
+
}
|
|
119
165
|
function formatWorkValue(work, style) {
|
|
120
166
|
if (work.state === "idle") {
|
|
121
167
|
return style.dim("none");
|