@evref-bl/dev-nexus 0.1.0-alpha.0
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 +677 -0
- package/dist/browserOpener.d.ts +9 -0
- package/dist/browserOpener.js +47 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +2374 -0
- package/dist/gitWorktreeService.d.ts +57 -0
- package/dist/gitWorktreeService.js +157 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +47 -0
- package/dist/nexusAgentMcpConfig.d.ts +30 -0
- package/dist/nexusAgentMcpConfig.js +228 -0
- package/dist/nexusAutomation.d.ts +103 -0
- package/dist/nexusAutomation.js +390 -0
- package/dist/nexusAutomationAgentLaunch.d.ts +148 -0
- package/dist/nexusAutomationAgentLaunch.js +855 -0
- package/dist/nexusAutomationAgentProfile.d.ts +39 -0
- package/dist/nexusAutomationAgentProfile.js +103 -0
- package/dist/nexusAutomationAgentSurface.d.ts +62 -0
- package/dist/nexusAutomationAgentSurface.js +90 -0
- package/dist/nexusAutomationCommandExecutor.d.ts +29 -0
- package/dist/nexusAutomationCommandExecutor.js +251 -0
- package/dist/nexusAutomationConfig.d.ts +114 -0
- package/dist/nexusAutomationConfig.js +547 -0
- package/dist/nexusAutomationEnqueue.d.ts +37 -0
- package/dist/nexusAutomationEnqueue.js +128 -0
- package/dist/nexusAutomationRunOnce.d.ts +91 -0
- package/dist/nexusAutomationRunOnce.js +586 -0
- package/dist/nexusAutomationScheduler.d.ts +50 -0
- package/dist/nexusAutomationScheduler.js +196 -0
- package/dist/nexusAutomationStatus.d.ts +55 -0
- package/dist/nexusAutomationStatus.js +462 -0
- package/dist/nexusAutomationTarget.d.ts +19 -0
- package/dist/nexusAutomationTarget.js +33 -0
- package/dist/nexusAutomationTargetCycle.d.ts +90 -0
- package/dist/nexusAutomationTargetCycle.js +282 -0
- package/dist/nexusAutomationTargetReport.d.ts +136 -0
- package/dist/nexusAutomationTargetReport.js +504 -0
- package/dist/nexusAutomationWorktreeSetup.d.ts +89 -0
- package/dist/nexusAutomationWorktreeSetup.js +661 -0
- package/dist/nexusCoordination.d.ts +198 -0
- package/dist/nexusCoordination.js +1018 -0
- package/dist/nexusExtension.d.ts +31 -0
- package/dist/nexusExtension.js +1 -0
- package/dist/nexusHomeConfig.d.ts +38 -0
- package/dist/nexusHomeConfig.js +133 -0
- package/dist/nexusMcpServer.d.ts +31 -0
- package/dist/nexusMcpServer.js +1036 -0
- package/dist/nexusPluginCapabilities.d.ts +197 -0
- package/dist/nexusPluginCapabilities.js +201 -0
- package/dist/nexusProjectConfig.d.ts +95 -0
- package/dist/nexusProjectConfig.js +880 -0
- package/dist/nexusProjectHomeService.d.ts +121 -0
- package/dist/nexusProjectHomeService.js +171 -0
- package/dist/nexusProjectLifecycle.d.ts +62 -0
- package/dist/nexusProjectLifecycle.js +205 -0
- package/dist/nexusProjectOperations.d.ts +101 -0
- package/dist/nexusProjectOperations.js +296 -0
- package/dist/nexusProjectRegistry.d.ts +42 -0
- package/dist/nexusProjectRegistry.js +91 -0
- package/dist/nexusProjectScaffold.d.ts +25 -0
- package/dist/nexusProjectScaffold.js +61 -0
- package/dist/nexusProjectTemplate.d.ts +34 -0
- package/dist/nexusProjectTemplate.js +354 -0
- package/dist/nexusSkills.d.ts +134 -0
- package/dist/nexusSkills.js +647 -0
- package/dist/nexusWorkerContextBundle.d.ts +142 -0
- package/dist/nexusWorkerContextBundle.js +375 -0
- package/dist/processSupervisor.d.ts +89 -0
- package/dist/processSupervisor.js +440 -0
- package/dist/vibeKanbanApi.d.ts +11 -0
- package/dist/vibeKanbanApi.js +14 -0
- package/dist/vibeKanbanAuth.d.ts +25 -0
- package/dist/vibeKanbanAuth.js +101 -0
- package/dist/vibeKanbanBoardAdapter.d.ts +36 -0
- package/dist/vibeKanbanBoardAdapter.js +196 -0
- package/dist/vibeKanbanMcpConfig.d.ts +36 -0
- package/dist/vibeKanbanMcpConfig.js +191 -0
- package/dist/vibeKanbanProjectAdapter.d.ts +39 -0
- package/dist/vibeKanbanProjectAdapter.js +113 -0
- package/dist/vibeKanbanWorkspaceSetup.d.ts +1 -0
- package/dist/vibeKanbanWorkspaceSetup.js +96 -0
- package/dist/workItemService.d.ts +60 -0
- package/dist/workItemService.js +163 -0
- package/dist/workTrackingGitHubProvider.d.ts +71 -0
- package/dist/workTrackingGitHubProvider.js +663 -0
- package/dist/workTrackingGitLabProvider.d.ts +62 -0
- package/dist/workTrackingGitLabProvider.js +523 -0
- package/dist/workTrackingJiraProvider.d.ts +67 -0
- package/dist/workTrackingJiraProvider.js +652 -0
- package/dist/workTrackingLocalProvider.d.ts +49 -0
- package/dist/workTrackingLocalProvider.js +463 -0
- package/dist/workTrackingProviderService.d.ts +21 -0
- package/dist/workTrackingProviderService.js +117 -0
- package/dist/workTrackingTypes.d.ts +202 -0
- package/dist/workTrackingTypes.js +1 -0
- package/dist/workTrackingVibeProvider.d.ts +35 -0
- package/dist/workTrackingVibeProvider.js +119 -0
- package/dist/worktreeExecutionMetadata.d.ts +76 -0
- package/dist/worktreeExecutionMetadata.js +239 -0
- package/package.json +37 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { devNexusProjectConfigFileName, projectWorktreesRootPath, } from "./nexusProjectConfig.js";
|
|
4
|
+
import { resolveProjectComponents } from "./nexusProjectLifecycle.js";
|
|
5
|
+
import { defaultLocalWorkTrackingStorePath } from "./workTrackingLocalProvider.js";
|
|
6
|
+
export function buildNexusProjectTemplateLayout(options) {
|
|
7
|
+
const projectRoot = path.resolve(options.projectRoot);
|
|
8
|
+
const components = resolveProjectComponents(projectRoot, options.projectConfig);
|
|
9
|
+
const automationConfig = options.projectConfig.automation;
|
|
10
|
+
const entries = [
|
|
11
|
+
{
|
|
12
|
+
area: "component_configuration",
|
|
13
|
+
owner: "user_authored",
|
|
14
|
+
path: devNexusProjectConfigFileName,
|
|
15
|
+
sourceControl: "source",
|
|
16
|
+
description: "Project, component, work-item service, automation, skills, plugins, and agent MCP configuration.",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
area: "project_state",
|
|
20
|
+
owner: "generated",
|
|
21
|
+
path: ".dev-nexus/README.md",
|
|
22
|
+
sourceControl: "support",
|
|
23
|
+
description: "Generated map of project support state, runtime state, and migration boundaries.",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
for (const component of components) {
|
|
27
|
+
entries.push({
|
|
28
|
+
area: "component_configuration",
|
|
29
|
+
owner: "user_authored",
|
|
30
|
+
path: displayPath(projectRoot, component.sourceRoot),
|
|
31
|
+
sourceControl: "source",
|
|
32
|
+
description: `Source root for component ${component.id}.`,
|
|
33
|
+
});
|
|
34
|
+
entries.push({
|
|
35
|
+
area: "project_state",
|
|
36
|
+
owner: "local_runtime",
|
|
37
|
+
path: displayPath(projectRoot, component.worktreesRoot, true),
|
|
38
|
+
sourceControl: "local",
|
|
39
|
+
description: `Generated implementation worktrees for component ${component.id}.`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (automationConfig) {
|
|
43
|
+
entries.push({
|
|
44
|
+
area: "target_state",
|
|
45
|
+
owner: "user_authored",
|
|
46
|
+
path: normalizedProjectRelativePath(automationConfig.target.statePath),
|
|
47
|
+
sourceControl: "support",
|
|
48
|
+
description: "Concise target memory maintained by humans or launched agents as current direction changes.",
|
|
49
|
+
});
|
|
50
|
+
entries.push({
|
|
51
|
+
area: "project_state",
|
|
52
|
+
owner: "local_runtime",
|
|
53
|
+
path: normalizedProjectRelativePath(automationConfig.target.cycleLedgerPath),
|
|
54
|
+
sourceControl: "local",
|
|
55
|
+
description: "Caller-reported target cycle facts used for reports and relaunch decisions.",
|
|
56
|
+
});
|
|
57
|
+
entries.push({
|
|
58
|
+
area: "project_state",
|
|
59
|
+
owner: "local_runtime",
|
|
60
|
+
path: normalizedProjectRelativePath(automationConfig.ledger.path),
|
|
61
|
+
sourceControl: "local",
|
|
62
|
+
description: "Automation run ledger written by DevNexus.",
|
|
63
|
+
});
|
|
64
|
+
entries.push({
|
|
65
|
+
area: "project_state",
|
|
66
|
+
owner: "local_runtime",
|
|
67
|
+
path: normalizedProjectRelativePath(automationConfig.lock.path),
|
|
68
|
+
sourceControl: "local",
|
|
69
|
+
description: "Automation lock file used to prevent overlapping runs.",
|
|
70
|
+
});
|
|
71
|
+
entries.push({
|
|
72
|
+
area: "project_state",
|
|
73
|
+
owner: "local_runtime",
|
|
74
|
+
path: ".dev-nexus/automation/agent-launches/",
|
|
75
|
+
sourceControl: "local",
|
|
76
|
+
description: "Per-run agent context and result files produced during agent-launch automation.",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (options.skillsConfig !== false) {
|
|
80
|
+
entries.push({
|
|
81
|
+
area: "skills",
|
|
82
|
+
owner: "generated",
|
|
83
|
+
path: ".dev-nexus/skills/",
|
|
84
|
+
sourceControl: "support",
|
|
85
|
+
description: "DevNexus-owned curated skill definitions.",
|
|
86
|
+
});
|
|
87
|
+
for (const target of resolvedSkillAgentTargets(options.skillsConfig)) {
|
|
88
|
+
entries.push({
|
|
89
|
+
area: "skills",
|
|
90
|
+
owner: "generated",
|
|
91
|
+
path: withTrailingSlash(normalizedProjectRelativePath(target.directory)),
|
|
92
|
+
sourceControl: target.sourceControl,
|
|
93
|
+
description: `Agent-native skill projection for ${target.agent}.`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (options.mcpConfig && options.mcpConfig.enabled !== false) {
|
|
98
|
+
for (const target of resolvedMcpAgentTargets(options.mcpConfig)) {
|
|
99
|
+
entries.push({
|
|
100
|
+
area: "agent_mcp_projection",
|
|
101
|
+
owner: "generated",
|
|
102
|
+
path: normalizedProjectRelativePath(target.configPath),
|
|
103
|
+
sourceControl: target.sourceControl,
|
|
104
|
+
description: `Agent MCP server projection for ${target.agent}.`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const storePath of localWorkItemStorePaths(projectRoot, options.projectConfig)) {
|
|
109
|
+
entries.push({
|
|
110
|
+
area: "project_state",
|
|
111
|
+
owner: "local_runtime",
|
|
112
|
+
path: displayPath(projectRoot, storePath),
|
|
113
|
+
sourceControl: "local",
|
|
114
|
+
description: "Local work-item store for a configured component tracker.",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
entries,
|
|
119
|
+
migrationNotes: nexusProjectTemplateMigrationNotes(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export function materializeNexusProjectTemplate(options) {
|
|
123
|
+
const projectRoot = path.resolve(options.projectRoot);
|
|
124
|
+
const layout = buildNexusProjectTemplateLayout(options);
|
|
125
|
+
const components = resolveProjectComponents(projectRoot, options.projectConfig);
|
|
126
|
+
const componentWorktreesRoots = components.map((component) => component.worktreesRoot);
|
|
127
|
+
fs.mkdirSync(options.worktreesRoot, { recursive: true });
|
|
128
|
+
for (const componentWorktreesRoot of componentWorktreesRoots) {
|
|
129
|
+
fs.mkdirSync(componentWorktreesRoot, { recursive: true });
|
|
130
|
+
}
|
|
131
|
+
const supportReadmePath = path.join(projectRoot, ".dev-nexus", "README.md");
|
|
132
|
+
fs.mkdirSync(path.dirname(supportReadmePath), { recursive: true });
|
|
133
|
+
fs.writeFileSync(supportReadmePath, renderNexusProjectSupportReadme(layout), "utf8");
|
|
134
|
+
const targetStatePath = options.projectConfig.automation
|
|
135
|
+
? path.resolve(projectRoot, options.projectConfig.automation.target.statePath)
|
|
136
|
+
: null;
|
|
137
|
+
if (targetStatePath && !fs.existsSync(targetStatePath)) {
|
|
138
|
+
fs.mkdirSync(path.dirname(targetStatePath), { recursive: true });
|
|
139
|
+
fs.writeFileSync(targetStatePath, defaultTargetStateMarkdown(), "utf8");
|
|
140
|
+
}
|
|
141
|
+
const gitExclude = options.excludeFromGit === false
|
|
142
|
+
? { gitExcludePath: null, gitExcludeEntries: [] }
|
|
143
|
+
: addGitExcludeEntries(projectRoot, templateGitExcludeEntries(projectRoot, options.projectConfig));
|
|
144
|
+
return {
|
|
145
|
+
...layout,
|
|
146
|
+
supportReadmePath,
|
|
147
|
+
targetStatePath,
|
|
148
|
+
componentWorktreesRoots,
|
|
149
|
+
gitExcludePath: gitExclude.gitExcludePath,
|
|
150
|
+
gitExcludeEntries: gitExclude.gitExcludeEntries,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function nexusProjectTemplateMigrationNotes() {
|
|
154
|
+
return [
|
|
155
|
+
"Historical staging roots are migration-only evidence; production templates must not inherit source-specific paths, tracker ids, agent launch commands, or component names from them.",
|
|
156
|
+
"Generated state can be refreshed by DevNexus and must stay separate from user-authored project config, component source, and target notes.",
|
|
157
|
+
"Local runtime state records locks, ledgers, local tracker files, and generated worktrees; keep it out of component source roots unless the project explicitly configures that boundary.",
|
|
158
|
+
];
|
|
159
|
+
}
|
|
160
|
+
function resolvedSkillAgentTargets(config) {
|
|
161
|
+
return (config?.agentTargets ?? [])
|
|
162
|
+
.filter((target) => target.enabled !== false)
|
|
163
|
+
.map((target) => ({
|
|
164
|
+
agent: target.agent,
|
|
165
|
+
directory: skillAgentTargetDirectory(target),
|
|
166
|
+
sourceControl: target.sourceControl ?? config?.sourceControl ?? "support",
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
function skillAgentTargetDirectory(target) {
|
|
170
|
+
if (target.directory) {
|
|
171
|
+
return target.directory;
|
|
172
|
+
}
|
|
173
|
+
if (target.agent === "codex") {
|
|
174
|
+
return path.join(".agents", "skills");
|
|
175
|
+
}
|
|
176
|
+
if (target.agent === "claude") {
|
|
177
|
+
return path.join(".claude", "skills");
|
|
178
|
+
}
|
|
179
|
+
return path.join(`.${target.agent}`, "skills");
|
|
180
|
+
}
|
|
181
|
+
function resolvedMcpAgentTargets(config) {
|
|
182
|
+
const targets = config.agentTargets ?? [{ agent: "codex" }];
|
|
183
|
+
return targets
|
|
184
|
+
.filter((target) => target.enabled !== false)
|
|
185
|
+
.map((target) => ({
|
|
186
|
+
agent: target.agent,
|
|
187
|
+
configPath: mcpAgentTargetConfigPath(target),
|
|
188
|
+
sourceControl: target.sourceControl ?? config.sourceControl ?? "support",
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
function mcpAgentTargetConfigPath(target) {
|
|
192
|
+
if (target.configPath) {
|
|
193
|
+
return target.configPath;
|
|
194
|
+
}
|
|
195
|
+
if (target.agent === "codex") {
|
|
196
|
+
return path.join(".codex", "config.toml");
|
|
197
|
+
}
|
|
198
|
+
if (target.agent === "claude") {
|
|
199
|
+
return ".mcp.json";
|
|
200
|
+
}
|
|
201
|
+
return path.join(`.${target.agent}`, "mcp.json");
|
|
202
|
+
}
|
|
203
|
+
function localWorkItemStorePaths(projectRoot, config) {
|
|
204
|
+
const paths = new Set();
|
|
205
|
+
collectLocalWorkTrackingPath(projectRoot, paths, config.workTracking ?? null);
|
|
206
|
+
for (const component of resolveProjectComponents(projectRoot, config)) {
|
|
207
|
+
collectLocalWorkTrackingPath(projectRoot, paths, component.workTracking ?? null);
|
|
208
|
+
}
|
|
209
|
+
return [...paths];
|
|
210
|
+
}
|
|
211
|
+
function collectLocalWorkTrackingPath(projectRoot, paths, config) {
|
|
212
|
+
if (config?.provider !== "local") {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
paths.add(config.storePath
|
|
216
|
+
? path.resolve(projectRoot, config.storePath)
|
|
217
|
+
: defaultLocalWorkTrackingStorePath(projectRoot));
|
|
218
|
+
}
|
|
219
|
+
function templateGitExcludeEntries(projectRoot, config) {
|
|
220
|
+
const entries = new Set([".dev-nexus/README.md"]);
|
|
221
|
+
const worktreesEntry = gitExcludeEntryForPath(projectRoot, projectWorktreesRootPath(projectRoot, config), true);
|
|
222
|
+
if (worktreesEntry) {
|
|
223
|
+
entries.add(worktreesEntry);
|
|
224
|
+
}
|
|
225
|
+
const automationConfig = config.automation;
|
|
226
|
+
if (automationConfig) {
|
|
227
|
+
addRelativeEntry(entries, automationConfig.ledger.path);
|
|
228
|
+
addRelativeEntry(entries, automationConfig.lock.path);
|
|
229
|
+
addRelativeEntry(entries, automationConfig.target.cycleLedgerPath);
|
|
230
|
+
entries.add(".dev-nexus/automation/agent-launches/");
|
|
231
|
+
}
|
|
232
|
+
for (const storePath of localWorkItemStorePaths(projectRoot, config)) {
|
|
233
|
+
const entry = gitExcludeEntryForPath(projectRoot, storePath, false);
|
|
234
|
+
if (entry) {
|
|
235
|
+
entries.add(entry);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return [...entries];
|
|
239
|
+
}
|
|
240
|
+
function addRelativeEntry(entries, entry) {
|
|
241
|
+
if (isProjectRelativePath(entry)) {
|
|
242
|
+
entries.add(normalizedProjectRelativePath(entry));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function renderNexusProjectSupportReadme(layout) {
|
|
246
|
+
const lines = [
|
|
247
|
+
"# DevNexus Project Support",
|
|
248
|
+
"",
|
|
249
|
+
"## Project Template Layout",
|
|
250
|
+
"",
|
|
251
|
+
"DevNexus keeps generic project support state separate from component source, target memory, curated skills, agent MCP projection, and local runtime records.",
|
|
252
|
+
"",
|
|
253
|
+
"## Ownership Classes",
|
|
254
|
+
"",
|
|
255
|
+
"- `user_authored`: Maintained by humans or launched agents as durable project intent.",
|
|
256
|
+
"- `generated`: Written or refreshed by DevNexus from project configuration.",
|
|
257
|
+
"- `local_runtime`: Machine-local state created while checking, launching, or recording work.",
|
|
258
|
+
"",
|
|
259
|
+
"## Paths",
|
|
260
|
+
"",
|
|
261
|
+
...layout.entries.map((entry) => `- \`${entry.path}\` - ${entry.area}, ${entry.owner}, ${entry.sourceControl}: ${entry.description}`),
|
|
262
|
+
"",
|
|
263
|
+
"## Migration Notes",
|
|
264
|
+
"",
|
|
265
|
+
...layout.migrationNotes.map((note) => `- ${note}`),
|
|
266
|
+
"",
|
|
267
|
+
];
|
|
268
|
+
return `${lines.join("\n")}`;
|
|
269
|
+
}
|
|
270
|
+
function defaultTargetStateMarkdown() {
|
|
271
|
+
return [
|
|
272
|
+
"# Target State",
|
|
273
|
+
"",
|
|
274
|
+
"Current direction:",
|
|
275
|
+
"- No target state recorded yet.",
|
|
276
|
+
"",
|
|
277
|
+
"Decisions:",
|
|
278
|
+
"- None recorded.",
|
|
279
|
+
"",
|
|
280
|
+
"Blockers:",
|
|
281
|
+
"- None recorded.",
|
|
282
|
+
"",
|
|
283
|
+
].join("\n");
|
|
284
|
+
}
|
|
285
|
+
function addGitExcludeEntries(projectRoot, entries) {
|
|
286
|
+
const gitInfoDir = path.join(projectRoot, ".git", "info");
|
|
287
|
+
if (!fs.existsSync(gitInfoDir) || !fs.statSync(gitInfoDir).isDirectory()) {
|
|
288
|
+
return {
|
|
289
|
+
gitExcludePath: null,
|
|
290
|
+
gitExcludeEntries: [],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const excludePath = path.join(gitInfoDir, "exclude");
|
|
294
|
+
const existing = fs.existsSync(excludePath)
|
|
295
|
+
? fs.readFileSync(excludePath, "utf8")
|
|
296
|
+
: "";
|
|
297
|
+
const existingLines = new Set(existing
|
|
298
|
+
.split(/\r?\n/u)
|
|
299
|
+
.map((line) => line.trim())
|
|
300
|
+
.filter(Boolean));
|
|
301
|
+
const appended = [];
|
|
302
|
+
for (const entry of entries) {
|
|
303
|
+
if (!existingLines.has(entry)) {
|
|
304
|
+
appended.push(entry);
|
|
305
|
+
existingLines.add(entry);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (appended.length > 0) {
|
|
309
|
+
fs.mkdirSync(gitInfoDir, { recursive: true });
|
|
310
|
+
const prefix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
311
|
+
fs.appendFileSync(excludePath, `${prefix}${appended.join("\n")}\n`, "utf8");
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
gitExcludePath: excludePath,
|
|
315
|
+
gitExcludeEntries: appended,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function displayPath(projectRoot, targetPath, directory = false) {
|
|
319
|
+
const resolved = path.resolve(projectRoot, targetPath);
|
|
320
|
+
const relative = path.relative(projectRoot, resolved);
|
|
321
|
+
if (relative === "") {
|
|
322
|
+
return directory ? "./" : ".";
|
|
323
|
+
}
|
|
324
|
+
if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) {
|
|
325
|
+
return directory
|
|
326
|
+
? withTrailingSlash(normalizedProjectRelativePath(relative))
|
|
327
|
+
: normalizedProjectRelativePath(relative);
|
|
328
|
+
}
|
|
329
|
+
return directory
|
|
330
|
+
? withTrailingSlash(path.resolve(targetPath))
|
|
331
|
+
: path.resolve(targetPath);
|
|
332
|
+
}
|
|
333
|
+
function gitExcludeEntryForPath(projectRoot, targetPath, directory) {
|
|
334
|
+
const relative = path.relative(projectRoot, path.resolve(targetPath));
|
|
335
|
+
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
const normalized = normalizedProjectRelativePath(relative);
|
|
339
|
+
return directory ? withTrailingSlash(normalized) : normalized;
|
|
340
|
+
}
|
|
341
|
+
function normalizedProjectRelativePath(value) {
|
|
342
|
+
return value.replace(/\\/gu, "/");
|
|
343
|
+
}
|
|
344
|
+
function withTrailingSlash(value) {
|
|
345
|
+
return value.endsWith("/") ? value : `${value}/`;
|
|
346
|
+
}
|
|
347
|
+
function isProjectRelativePath(value) {
|
|
348
|
+
return (value.trim().length > 0 &&
|
|
349
|
+
!path.isAbsolute(value) &&
|
|
350
|
+
!/^[A-Za-z]:/u.test(value) &&
|
|
351
|
+
!value
|
|
352
|
+
.split(/[\\/]/u)
|
|
353
|
+
.some((part) => part === ".." || part === ""));
|
|
354
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
export declare const nexusSkillSupportDirectoryName = ".dev-nexus";
|
|
2
|
+
export declare const nexusSkillsDirectoryName = "skills";
|
|
3
|
+
export declare const nexusSkillManifestFileName = "dev-nexus.skill.json";
|
|
4
|
+
export declare const nexusSkillMarkdownFileName = "SKILL.md";
|
|
5
|
+
export type NexusSkillMaterializationMode = "copy" | "symlink" | "reference";
|
|
6
|
+
export type NexusSkillSourceControl = "support" | "source";
|
|
7
|
+
export type NexusSkillAgentId = string;
|
|
8
|
+
export interface NexusProjectSkillAgentTarget {
|
|
9
|
+
agent: NexusSkillAgentId;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
directory?: string;
|
|
12
|
+
sourceControl?: NexusSkillSourceControl;
|
|
13
|
+
}
|
|
14
|
+
export interface NexusSkillSource {
|
|
15
|
+
type: "curated" | "git" | "url" | "local";
|
|
16
|
+
uri?: string;
|
|
17
|
+
commit?: string;
|
|
18
|
+
checksum?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface NexusSkillManifest {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
version: string;
|
|
25
|
+
license: string;
|
|
26
|
+
source: NexusSkillSource;
|
|
27
|
+
supportedAgents: string[];
|
|
28
|
+
materialization: NexusSkillMaterializationMode;
|
|
29
|
+
sourceControl: NexusSkillSourceControl;
|
|
30
|
+
}
|
|
31
|
+
export interface NexusSkillDefinition {
|
|
32
|
+
manifest: NexusSkillManifest;
|
|
33
|
+
files: Record<string, string>;
|
|
34
|
+
sourcePath?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface NexusProjectSkillSelection {
|
|
37
|
+
id: string;
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
version?: string;
|
|
40
|
+
materialization?: NexusSkillMaterializationMode;
|
|
41
|
+
sourceControl?: NexusSkillSourceControl;
|
|
42
|
+
}
|
|
43
|
+
export interface NexusProjectSkillsConfig {
|
|
44
|
+
defaultCorePack?: boolean;
|
|
45
|
+
materialization?: NexusSkillMaterializationMode;
|
|
46
|
+
sourceControl?: NexusSkillSourceControl;
|
|
47
|
+
agentTargets?: NexusProjectSkillAgentTarget[];
|
|
48
|
+
items?: NexusProjectSkillSelection[];
|
|
49
|
+
}
|
|
50
|
+
export interface MaterializeNexusProjectSkillsOptions {
|
|
51
|
+
projectRoot: string;
|
|
52
|
+
skillsConfig?: NexusProjectSkillsConfig;
|
|
53
|
+
skillDefinitions?: NexusSkillDefinition[];
|
|
54
|
+
excludeFromGit?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface MaterializedNexusSkill {
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
version: string;
|
|
60
|
+
materialization: NexusSkillMaterializationMode;
|
|
61
|
+
sourceControl: NexusSkillSourceControl;
|
|
62
|
+
skillRoot: string;
|
|
63
|
+
manifestPath: string;
|
|
64
|
+
skillPath: string | null;
|
|
65
|
+
}
|
|
66
|
+
export interface MaterializedNexusAgentSkill {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
version: string;
|
|
70
|
+
materialization: NexusSkillMaterializationMode;
|
|
71
|
+
skillRoot: string;
|
|
72
|
+
skillPath: string | null;
|
|
73
|
+
}
|
|
74
|
+
export interface MaterializedNexusAgentSkillTarget {
|
|
75
|
+
agent: NexusSkillAgentId;
|
|
76
|
+
skillsDirectory: string;
|
|
77
|
+
sourceControl: NexusSkillSourceControl;
|
|
78
|
+
installed: MaterializedNexusAgentSkill[];
|
|
79
|
+
}
|
|
80
|
+
export interface MaterializeNexusProjectSkillsResult {
|
|
81
|
+
skillsDirectory: string;
|
|
82
|
+
installed: MaterializedNexusSkill[];
|
|
83
|
+
agentTargets: MaterializedNexusAgentSkillTarget[];
|
|
84
|
+
gitExcludePath: string | null;
|
|
85
|
+
gitExcludeEntries: string[];
|
|
86
|
+
}
|
|
87
|
+
export type NexusProjectSkillState = "installed" | "missing" | "stale" | "unexpected" | "invalid";
|
|
88
|
+
export interface NexusProjectSkillStatus {
|
|
89
|
+
id: string;
|
|
90
|
+
state: NexusProjectSkillState;
|
|
91
|
+
expected: boolean;
|
|
92
|
+
installed: boolean;
|
|
93
|
+
name: string | null;
|
|
94
|
+
expectedVersion: string | null;
|
|
95
|
+
installedVersion: string | null;
|
|
96
|
+
materialization: NexusSkillMaterializationMode | null;
|
|
97
|
+
sourceControl: NexusSkillSourceControl | null;
|
|
98
|
+
skillRoot: string;
|
|
99
|
+
manifestPath: string;
|
|
100
|
+
skillPath: string | null;
|
|
101
|
+
reasons: string[];
|
|
102
|
+
}
|
|
103
|
+
export interface NexusProjectSkillStatusSummary {
|
|
104
|
+
expected: number;
|
|
105
|
+
installed: number;
|
|
106
|
+
missing: number;
|
|
107
|
+
stale: number;
|
|
108
|
+
unexpected: number;
|
|
109
|
+
invalid: number;
|
|
110
|
+
}
|
|
111
|
+
export interface InspectNexusProjectSkillsOptions {
|
|
112
|
+
projectRoot: string;
|
|
113
|
+
skillsConfig?: NexusProjectSkillsConfig;
|
|
114
|
+
skillDefinitions?: NexusSkillDefinition[];
|
|
115
|
+
}
|
|
116
|
+
export interface InspectNexusProjectSkillsResult {
|
|
117
|
+
skillsDirectory: string;
|
|
118
|
+
summary: NexusProjectSkillStatusSummary;
|
|
119
|
+
skills: NexusProjectSkillStatus[];
|
|
120
|
+
}
|
|
121
|
+
export interface RefreshNexusProjectSkillsOptions extends MaterializeNexusProjectSkillsOptions {
|
|
122
|
+
}
|
|
123
|
+
export interface RefreshNexusProjectSkillsResult {
|
|
124
|
+
before: InspectNexusProjectSkillsResult;
|
|
125
|
+
materialized: MaterializeNexusProjectSkillsResult;
|
|
126
|
+
after: InspectNexusProjectSkillsResult;
|
|
127
|
+
}
|
|
128
|
+
export declare class NexusSkillError extends Error {
|
|
129
|
+
constructor(message: string);
|
|
130
|
+
}
|
|
131
|
+
export declare const defaultCoreSkillPack: readonly NexusSkillDefinition[];
|
|
132
|
+
export declare function inspectNexusProjectSkills(options: InspectNexusProjectSkillsOptions): InspectNexusProjectSkillsResult;
|
|
133
|
+
export declare function materializeNexusProjectSkills(options: MaterializeNexusProjectSkillsOptions): MaterializeNexusProjectSkillsResult;
|
|
134
|
+
export declare function refreshNexusProjectSkills(options: RefreshNexusProjectSkillsOptions): RefreshNexusProjectSkillsResult;
|