@mrpatronz/nexusflow 1.9.0 → 2.0.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/dist/agent/ProviderRegistry.d.ts +12 -1
- package/dist/agent/ProviderRegistry.d.ts.map +1 -1
- package/dist/agent/ProviderRegistry.js.map +1 -1
- package/dist/agent/ProviderRegistry.test.js +1 -0
- package/dist/agent/ProviderRegistry.test.js.map +1 -1
- package/dist/agent/adapters.d.ts +14 -0
- package/dist/agent/adapters.d.ts.map +1 -1
- package/dist/agent/adapters.js +39 -4
- package/dist/agent/adapters.js.map +1 -1
- package/dist/agent/adapters.test.d.ts +2 -0
- package/dist/agent/adapters.test.d.ts.map +1 -0
- package/dist/agent/adapters.test.js +49 -0
- package/dist/agent/adapters.test.js.map +1 -0
- package/dist/agent/cliAvailability.d.ts +48 -0
- package/dist/agent/cliAvailability.d.ts.map +1 -0
- package/dist/agent/cliAvailability.js +112 -0
- package/dist/agent/cliAvailability.js.map +1 -0
- package/dist/agent/cliAvailability.test.d.ts +2 -0
- package/dist/agent/cliAvailability.test.d.ts.map +1 -0
- package/dist/agent/cliAvailability.test.js +105 -0
- package/dist/agent/cliAvailability.test.js.map +1 -0
- package/dist/analyzers/detect-deps.d.ts.map +1 -1
- package/dist/analyzers/detect-deps.js +16 -19
- package/dist/analyzers/detect-deps.js.map +1 -1
- package/dist/analyzers/index.d.ts +0 -2
- package/dist/analyzers/index.d.ts.map +1 -1
- package/dist/analyzers/index.js +6 -9
- package/dist/analyzers/index.js.map +1 -1
- package/dist/commands/commands.test.js +4 -3
- package/dist/commands/commands.test.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/knowledge.d.ts +10 -0
- package/dist/commands/knowledge.d.ts.map +1 -1
- package/dist/commands/knowledge.js +27 -1
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/knowledge.test.d.ts +2 -0
- package/dist/commands/knowledge.test.d.ts.map +1 -0
- package/dist/commands/knowledge.test.js +77 -0
- package/dist/commands/knowledge.test.js.map +1 -0
- package/dist/commands/refresh.d.ts +2 -4
- package/dist/commands/refresh.d.ts.map +1 -1
- package/dist/commands/refresh.js +4 -20
- package/dist/commands/refresh.js.map +1 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +8 -3
- package/dist/core/adapters/registry.js.map +1 -1
- package/dist/core/adapters/storage.test.js +5 -24
- package/dist/core/adapters/storage.test.js.map +1 -1
- package/dist/core/analysis-cache.d.ts +15 -8
- package/dist/core/analysis-cache.d.ts.map +1 -1
- package/dist/core/analysis-cache.js +61 -10
- package/dist/core/analysis-cache.js.map +1 -1
- package/dist/core/analysis-cache.test.js +17 -4
- package/dist/core/analysis-cache.test.js.map +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +5 -4
- package/dist/core/config.js.map +1 -1
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +9 -5
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/knowledge.d.ts +14 -4
- package/dist/core/knowledge.d.ts.map +1 -1
- package/dist/core/knowledge.js +64 -14
- package/dist/core/knowledge.js.map +1 -1
- package/dist/core/knowledge.test.js +54 -2
- package/dist/core/knowledge.test.js.map +1 -1
- package/dist/core/locks.d.ts +43 -0
- package/dist/core/locks.d.ts.map +1 -0
- package/dist/core/locks.js +102 -0
- package/dist/core/locks.js.map +1 -0
- package/dist/core/locks.test.d.ts +2 -0
- package/dist/core/locks.test.d.ts.map +1 -0
- package/dist/core/locks.test.js +95 -0
- package/dist/core/locks.test.js.map +1 -0
- package/dist/core/ports/storage.d.ts +3 -3
- package/dist/core/ports/storage.d.ts.map +1 -1
- package/dist/core/refresh.d.ts +12 -13
- package/dist/core/refresh.d.ts.map +1 -1
- package/dist/core/refresh.js +14 -11
- package/dist/core/refresh.js.map +1 -1
- package/dist/core/refresh.test.js +17 -11
- package/dist/core/refresh.test.js.map +1 -1
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +2 -65
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/sync.js +3 -3
- package/dist/core/sync.js.map +1 -1
- package/dist/core/worktree.js +2 -2
- package/dist/core/worktree.js.map +1 -1
- package/dist/core/worktree.test.js +2 -2
- package/dist/core/worktree.test.js.map +1 -1
- package/dist/generators/base.d.ts +31 -2
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +174 -238
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/base.test.js +231 -24
- package/dist/generators/base.test.js.map +1 -1
- package/dist/generators/claude.d.ts +19 -5
- package/dist/generators/claude.d.ts.map +1 -1
- package/dist/generators/claude.js +33 -11
- package/dist/generators/claude.js.map +1 -1
- package/dist/generators/index.d.ts +10 -9
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +103 -118
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/plan-generator.d.ts.map +1 -1
- package/dist/generators/plan-generator.js +217 -193
- package/dist/generators/plan-generator.js.map +1 -1
- package/dist/generators/plan-generator.test.d.ts +2 -0
- package/dist/generators/plan-generator.test.d.ts.map +1 -0
- package/dist/generators/plan-generator.test.js +217 -0
- package/dist/generators/plan-generator.test.js.map +1 -0
- package/dist/gui/assets/{DashboardPage-C3NH97y2.js → DashboardPage-HNC3-OP0.js} +1 -1
- package/dist/gui/assets/{GettingStartedPage-og-Kv7Sm.js → GettingStartedPage-Dguoya_Z.js} +1 -1
- package/dist/gui/assets/{ProjectsPage-COqqadEr.js → ProjectsPage-DVR4j4sw.js} +1 -1
- package/dist/gui/assets/{ScaffoldRepoInline-DRipQsos.js → ScaffoldRepoInline-D-2ZeuDK.js} +1 -1
- package/dist/gui/assets/{SettingsPage-CpU3V9oU.js → SettingsPage-Bauo77q3.js} +1 -1
- package/dist/gui/assets/{StartWorkPage-DIND0hJy.js → StartWorkPage-DvuFEa5Y.js} +1 -1
- package/dist/gui/assets/{StrategiesPage-6LWOnKdk.js → StrategiesPage-Cizm0GWk.js} +1 -1
- package/dist/gui/assets/{WorkspacesPage-BUqgOhuy.js → WorkspacesPage-DYOVfZqy.js} +1 -1
- package/dist/gui/assets/{index-CyYbQwRf.js → index-BqeoAIB1.js} +6 -6
- package/dist/gui/index.html +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +11 -15
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resources/workflows/plan-implement-review.md +8 -0
- package/dist/resources/workflows/research-verify.md +6 -0
- package/dist/resources/workflows/solo-developer.md +3 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -2
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +4 -2
- package/dist/server.test.js.map +1 -1
- package/dist/types.d.ts +0 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/prompts.js +2 -2
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/resources.d.ts +28 -0
- package/dist/utils/resources.d.ts.map +1 -0
- package/dist/utils/resources.js +54 -0
- package/dist/utils/resources.js.map +1 -0
- package/dist/utils/workflow-advisor.d.ts.map +1 -1
- package/dist/utils/workflow-advisor.js +17 -27
- package/dist/utils/workflow-advisor.js.map +1 -1
- package/dist/utils/workflows.d.ts.map +1 -1
- package/dist/utils/workflows.js +6 -2
- package/dist/utils/workflows.js.map +1 -1
- package/package.json +5 -3
- package/resources/workflows/plan-implement-review.md +8 -0
- package/resources/workflows/research-verify.md +6 -0
- package/resources/workflows/solo-developer.md +3 -0
- package/dist/analyzers/detect-apis.d.ts +0 -19
- package/dist/analyzers/detect-apis.d.ts.map +0 -1
- package/dist/analyzers/detect-apis.js +0 -250
- package/dist/analyzers/detect-apis.js.map +0 -1
- package/dist/analyzers/messaging-analyzer.d.ts +0 -17
- package/dist/analyzers/messaging-analyzer.d.ts.map +0 -1
- package/dist/analyzers/messaging-analyzer.js +0 -229
- package/dist/analyzers/messaging-analyzer.js.map +0 -1
- package/dist/core/adapters/vault-storage.d.ts +0 -16
- package/dist/core/adapters/vault-storage.d.ts.map +0 -1
- package/dist/core/adapters/vault-storage.js +0 -77
- package/dist/core/adapters/vault-storage.js.map +0 -1
- package/dist/core/graph.d.ts +0 -35
- package/dist/core/graph.d.ts.map +0 -1
- package/dist/core/graph.js +0 -281
- package/dist/core/graph.js.map +0 -1
- package/dist/generators/diff-context.d.ts +0 -6
- package/dist/generators/diff-context.d.ts.map +0 -1
- package/dist/generators/diff-context.js +0 -70
- package/dist/generators/diff-context.js.map +0 -1
- package/dist/generators/map-generator.d.ts +0 -15
- package/dist/generators/map-generator.d.ts.map +0 -1
- package/dist/generators/map-generator.js +0 -514
- package/dist/generators/map-generator.js.map +0 -1
- package/dist/generators/map-generator.test.d.ts +0 -2
- package/dist/generators/map-generator.test.d.ts.map +0 -1
- package/dist/generators/map-generator.test.js +0 -147
- package/dist/generators/map-generator.test.js.map +0 -1
package/dist/generators/base.js
CHANGED
|
@@ -1,266 +1,202 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module generators/base
|
|
3
|
-
* Builds the
|
|
4
|
-
*
|
|
3
|
+
* Builds the small markdown context every AI assistant generator starts from:
|
|
4
|
+
* the task, the repos and how they relate, how to verify each one, and pointers
|
|
5
|
+
* to everything else.
|
|
5
6
|
*/
|
|
6
|
-
import
|
|
7
|
-
import { resolveBaseFileUrl, resolveWorkspaceFileUrl } from '../core/storage.js';
|
|
7
|
+
import { findInterRepoDependencies } from '../analyzers/detect-deps.js';
|
|
8
8
|
import { isInPlace } from '../utils/feature.js';
|
|
9
9
|
import { getConventionalTestCommand } from '../utils/test-command.js';
|
|
10
|
-
import { detectServiceConfig } from '../orchestration/detect.js';
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
11
|
+
* Works out how each repo relates to its siblings.
|
|
12
|
+
*
|
|
13
|
+
* The data was already being computed — `findInterRepoDependencies` has existed
|
|
14
|
+
* and been exported all along — it simply never reached the assistant-facing
|
|
15
|
+
* context, which is the one place it matters most.
|
|
13
16
|
*/
|
|
14
|
-
function
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
lines.push(`- **Languages**: ${langStr}`);
|
|
29
|
-
lines.push(`- **Frameworks**: ${fwStr}`);
|
|
30
|
-
lines.push(`- **Build tools**: ${buildStr}`);
|
|
31
|
-
}
|
|
32
|
-
// README summary
|
|
33
|
-
if (analysis.readmeSummary) {
|
|
34
|
-
// Take first 200 chars of README summary as purpose
|
|
35
|
-
const purpose = analysis.readmeSummary
|
|
36
|
-
.replace(/^#\s+.+\n?/, '') // Remove h1 title
|
|
37
|
-
.trim()
|
|
38
|
-
.slice(0, 200)
|
|
39
|
-
.trim();
|
|
40
|
-
if (purpose) {
|
|
41
|
-
lines.push(`- **Purpose**: ${purpose}`);
|
|
17
|
+
function computeRepoRelations(ctx) {
|
|
18
|
+
const relations = new Map();
|
|
19
|
+
const { repos, analysis, feature } = ctx;
|
|
20
|
+
if (!analysis)
|
|
21
|
+
return relations;
|
|
22
|
+
const repoNames = new Map();
|
|
23
|
+
for (const repo of repos)
|
|
24
|
+
repoNames.set(repo.path, repo.name);
|
|
25
|
+
const dependsOn = findInterRepoDependencies(analysis, repoNames);
|
|
26
|
+
// Invert it, so each repo can also state who would break if it changed.
|
|
27
|
+
const consumedBy = new Map();
|
|
28
|
+
for (const [consumer, providers] of dependsOn) {
|
|
29
|
+
for (const provider of providers) {
|
|
30
|
+
consumedBy.set(provider, [...(consumedBy.get(provider) ?? []), consumer]);
|
|
42
31
|
}
|
|
43
32
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const portStr = analysis.ports.map((p) => `${p.port} (${p.protocol}, from ${p.source})`).join(', ');
|
|
51
|
-
lines.push(`- **Ports**: ${portStr}`);
|
|
33
|
+
for (const repo of repos) {
|
|
34
|
+
relations.set(repo.name, {
|
|
35
|
+
dependsOn: dependsOn.get(repo.name) ?? [],
|
|
36
|
+
consumedBy: consumedBy.get(repo.name) ?? [],
|
|
37
|
+
branch: feature.repoBranches?.[repo.name] ?? repo.defaultBranch,
|
|
38
|
+
});
|
|
52
39
|
}
|
|
53
|
-
|
|
54
|
-
lines.push(`- **Path**: \`${analysis.path}\``);
|
|
55
|
-
return lines.join('\n');
|
|
40
|
+
return relations;
|
|
56
41
|
}
|
|
57
42
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
43
|
+
* Orders repos so anything depended upon comes before its consumers. Falls back
|
|
44
|
+
* to the given order for anything a cycle makes unorderable, rather than
|
|
45
|
+
* dropping it.
|
|
60
46
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
* test command derived from the detected tech stack, and the detected service
|
|
67
|
-
* run command. Old manifests that still carry hand-entered `resumption`
|
|
68
|
-
* commands get those appended (custom commands beat conventions); the
|
|
69
|
-
* standard-command filter applies to that legacy path only.
|
|
47
|
+
* Keyed on the repo objects, not their names. Two repos can share a basename —
|
|
48
|
+
* `/org1/api` and `/org2/api` in an in-place workspace — and keying the visited
|
|
49
|
+
* set by name collapsed them, so one was silently missing from the caller's
|
|
50
|
+
* output. Dependencies are still resolved by name, which is all a manifest
|
|
51
|
+
* gives, so an ambiguous name visits every repo bearing it.
|
|
70
52
|
*/
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
const
|
|
53
|
+
function orderReposByDependency(repos, relations) {
|
|
54
|
+
const placed = new Set();
|
|
55
|
+
const ordered = [];
|
|
56
|
+
const byName = new Map();
|
|
74
57
|
for (const repo of repos) {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (service)
|
|
81
|
-
runCommand = [service.command, ...service.args].join(' ').trim();
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// Detection is best-effort; a repo without a runnable service gets '—'.
|
|
85
|
-
}
|
|
86
|
-
rows.push(`| ${repo.name} | \`${testCommand}\` | ${runCommand ? `\`${runCommand}\`` : '—'} |`);
|
|
58
|
+
const sameName = byName.get(repo.name);
|
|
59
|
+
if (sameName)
|
|
60
|
+
sameName.push(repo);
|
|
61
|
+
else
|
|
62
|
+
byName.set(repo.name, [repo]);
|
|
87
63
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
legacy.push(`- **Start/Run Command**: \`${startCommand}\``);
|
|
96
|
-
const standardCommands = [
|
|
97
|
-
'npm run test', 'npm test', 'npm t', 'yarn test', 'yarn t', 'pnpm test', 'pnpm t', 'bun test',
|
|
98
|
-
'dotnet test',
|
|
99
|
-
'pytest', 'python -m unittest', 'python -m pytest',
|
|
100
|
-
'go test', 'go test ./...',
|
|
101
|
-
'cargo test',
|
|
102
|
-
];
|
|
103
|
-
if (testCommand) {
|
|
104
|
-
const normalized = testCommand.trim().toLowerCase();
|
|
105
|
-
const isStandard = standardCommands.some((cmd) => normalized === cmd || normalized.startsWith(cmd + ' '));
|
|
106
|
-
if (!isStandard) {
|
|
107
|
-
legacy.push(`- **Verification/Test Command**: \`${testCommand}\``);
|
|
108
|
-
}
|
|
64
|
+
const visit = (repo, seen) => {
|
|
65
|
+
if (placed.has(repo) || seen.has(repo))
|
|
66
|
+
return;
|
|
67
|
+
seen.add(repo);
|
|
68
|
+
for (const dependency of relations.get(repo.name)?.dependsOn ?? []) {
|
|
69
|
+
for (const target of byName.get(dependency) ?? [])
|
|
70
|
+
visit(target, seen);
|
|
109
71
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
${legacy.length > 0 ? `\nCustom workspace commands:\n\n${legacy.join('\n')}\n` : ''}`;
|
|
72
|
+
if (!placed.has(repo)) {
|
|
73
|
+
placed.add(repo);
|
|
74
|
+
ordered.push(repo);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
for (const repo of repos)
|
|
78
|
+
visit(repo, new Set());
|
|
79
|
+
// Every repo is placed by the loop above; this only guarantees the caller
|
|
80
|
+
// never receives fewer rows than it passed in.
|
|
81
|
+
for (const repo of repos)
|
|
82
|
+
if (!placed.has(repo))
|
|
83
|
+
ordered.push(repo);
|
|
84
|
+
return ordered;
|
|
124
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Builds the workspace context an assistant loads at session start.
|
|
88
|
+
*
|
|
89
|
+
* Kept deliberately small. It carries only what an assistant cannot cheaply
|
|
90
|
+
* work out for itself, and links to the rest:
|
|
91
|
+
*
|
|
92
|
+
* - what to build
|
|
93
|
+
* - where each repo is, and how the repos relate to each other
|
|
94
|
+
* - how to verify each repo
|
|
95
|
+
* - the one structural rule that is not inferable (worktree isolation)
|
|
96
|
+
*
|
|
97
|
+
* Everything else is a pointer. Per-repo language, framework, build tool, port
|
|
98
|
+
* and purpose used to be listed here; two independent agents evaluating a
|
|
99
|
+
* generated workspace used none of it — they needed code-level facts instead,
|
|
100
|
+
* like a module's exports — while that same block is where a wrong claim
|
|
101
|
+
* appeared ("Build tools: none detected" for a repo whose package.json has
|
|
102
|
+
* "build": "tsc"). Anything derivable from a manifest is better read from the
|
|
103
|
+
* manifest, where it cannot go stale.
|
|
104
|
+
*/
|
|
125
105
|
export async function buildContextContent(ctx) {
|
|
126
106
|
const { feature, repos, analysis } = ctx;
|
|
127
|
-
const workspacePath = feature.workspacePath;
|
|
128
|
-
// Build project sections — rich if analysis is available, simple if not
|
|
129
|
-
let projectSections;
|
|
130
|
-
if (analysis && analysis.size > 0) {
|
|
131
|
-
const sections = repos.map((r) => {
|
|
132
|
-
const a = analysis.get(r.path);
|
|
133
|
-
if (a)
|
|
134
|
-
return formatProjectSection(a, workspacePath);
|
|
135
|
-
return `### ${r.name}\n- **Path**: \`${r.path}\``;
|
|
136
|
-
});
|
|
137
|
-
projectSections = sections.join('\n\n');
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
projectSections = repos
|
|
141
|
-
.map((r) => `- **${r.name}** — \`${r.path}\` (default branch: \`${r.defaultBranch}\`)`)
|
|
142
|
-
.join('\n');
|
|
143
|
-
}
|
|
144
|
-
// Build existing AI configs section
|
|
145
|
-
let existingConfigsSection = '';
|
|
146
|
-
if (analysis && analysis.size > 0) {
|
|
147
|
-
const allConfigs = [];
|
|
148
|
-
for (const [, a] of analysis) {
|
|
149
|
-
for (const config of a.existingAIConfigs) {
|
|
150
|
-
allConfigs.push(`- **${a.name}** has \`${config.relativePath}\` (${config.assistant})`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (allConfigs.length > 0) {
|
|
154
|
-
existingConfigsSection = `
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Existing AI Configurations
|
|
158
|
-
|
|
159
|
-
The following repos already have AI assistant configuration files.
|
|
160
|
-
Incorporate their instructions when working in those repos:
|
|
161
|
-
|
|
162
|
-
${allConfigs.join('\n')}
|
|
163
|
-
`;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// Verification & services section — auto-derived; legacy manifests may
|
|
167
|
-
// contribute stored custom commands on top.
|
|
168
|
-
const verificationSection = await buildVerificationSection(ctx);
|
|
169
|
-
const knowledgePath = resolveWorkspaceFileUrl(workspacePath, feature.id, 'nexusflow-knowledge.md').replace(/\\/g, '/');
|
|
170
|
-
let setupDone = false;
|
|
171
|
-
try {
|
|
172
|
-
if (fs.existsSync(knowledgePath)) {
|
|
173
|
-
const content = fs.readFileSync(knowledgePath, 'utf-8');
|
|
174
|
-
if (!content.includes('No assumptions recorded yet') && !content.includes('AI assistant to populate')) {
|
|
175
|
-
setupDone = true;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
catch { }
|
|
180
|
-
// Teamwork strategy section
|
|
181
|
-
let teamworkSection = '';
|
|
182
|
-
if (feature.teamworkInstructions) {
|
|
183
|
-
teamworkSection = `
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## Team Collaboration Strategy
|
|
187
|
-
|
|
188
|
-
${feature.teamworkInstructions}
|
|
189
|
-
`;
|
|
190
|
-
}
|
|
191
|
-
// The structural rules differ fundamentally by mode: worktree workspaces
|
|
192
|
-
// isolate agents inside checked-out subdirectories, while in-place
|
|
193
|
-
// workspaces point at the original source repositories — telling an agent
|
|
194
|
-
// "never touch the original repos" there would forbid the only correct
|
|
195
|
-
// behavior.
|
|
196
107
|
const inPlace = isInPlace(feature);
|
|
197
|
-
const
|
|
198
|
-
?
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
${
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
108
|
+
const relations = analysis && analysis.size > 0
|
|
109
|
+
? computeRepoRelations(ctx)
|
|
110
|
+
: new Map();
|
|
111
|
+
const ordered = orderReposByDependency(repos, relations);
|
|
112
|
+
// One row per repo: where it is, how to check it, and who it is tied to.
|
|
113
|
+
const rows = ordered.map((repo) => {
|
|
114
|
+
const a = analysis?.get(repo.path);
|
|
115
|
+
const rel = relations.get(repo.name);
|
|
116
|
+
const verify = a ? getConventionalTestCommand(a) : '';
|
|
117
|
+
// In-place repos can each sit on a different branch, which is worth stating.
|
|
118
|
+
// In worktree mode they are all on the feature branch named just below, so
|
|
119
|
+
// repeating it per row would be noise.
|
|
120
|
+
const branch = rel?.branch;
|
|
121
|
+
const location = inPlace
|
|
122
|
+
? `${repo.path}${branch ? ` (on ${branch})` : ''}`
|
|
123
|
+
: repo.name;
|
|
124
|
+
const ties = [];
|
|
125
|
+
if (rel?.dependsOn.length)
|
|
126
|
+
ties.push(`needs ${rel.dependsOn.map((n) => '`' + n + '`').join(', ')}`);
|
|
127
|
+
if (rel?.consumedBy.length)
|
|
128
|
+
ties.push(`used by ${rel.consumedBy.map((n) => '`' + n + '`').join(', ')}`);
|
|
129
|
+
return `| \`${repo.name}\` | \`${location}\` | ${verify ? '`' + verify + '`' : '—'} | ${ties.join('; ') || '—'} |`;
|
|
130
|
+
});
|
|
131
|
+
// The earliest repo something actually builds on — and it names what. The
|
|
132
|
+
// previous test was "does any repo anywhere have a dependency", which pointed
|
|
133
|
+
// at `ordered[0]` regardless: a workspace of [alpha (independent), lib, web]
|
|
134
|
+
// where only web needs lib produced "Start with `alpha` — the others build on
|
|
135
|
+
// it" directly above alpha's own row showing no ties at all. Since `ordered` is
|
|
136
|
+
// already dependency-ordered, the first entry with consumers is the real
|
|
137
|
+
// starting point, and if nothing has consumers there is no order to give.
|
|
138
|
+
const startsWith = ordered.find((repo) => (relations.get(repo.name)?.consumedBy.length ?? 0) > 0);
|
|
139
|
+
const consumers = startsWith ? relations.get(startsWith.name).consumedBy : [];
|
|
140
|
+
const startHint = startsWith
|
|
141
|
+
? `\n\nStart with \`${startsWith.name}\` — ${consumers.map((n) => '`' + n + '`').join(', ')} ${consumers.length === 1 ? 'builds' : 'build'} on it.`
|
|
142
|
+
: '';
|
|
143
|
+
// Only the rule an assistant cannot infer. Which directory to run a command
|
|
144
|
+
// in, and how git works, are not worth the tokens.
|
|
145
|
+
const structureRule = inPlace
|
|
146
|
+
? 'These are the original repositories, on whatever branch each has checked out — NexusFlow does not manage branches here, so check before you commit.'
|
|
147
|
+
: `Each repo above is a separate git worktree on \`${feature.branchName}\`. **Do not edit the original repositories elsewhere on disk** — that is a different checkout and changes there are not part of this feature.`;
|
|
148
|
+
// Repos that already ship their own assistant instructions; those override
|
|
149
|
+
// anything here for that repo, so it is worth naming them. Walked via `repos`
|
|
150
|
+
// rather than the analysis map, so an analysis entry for a repo that is not in
|
|
151
|
+
// this workspace cannot put a name in the list — the same scoping the plan's
|
|
152
|
+
// contract table needed.
|
|
153
|
+
const existing = ordered
|
|
154
|
+
.map((repo) => analysis?.get(repo.path))
|
|
155
|
+
.filter((a) => !!a && a.existingAIConfigs.length > 0)
|
|
156
|
+
.map((a) => `\`${a.name}\` (${a.existingAIConfigs.map((c) => c.relativePath).join(', ')})`);
|
|
157
|
+
const teamwork = feature.teamworkInstructions
|
|
158
|
+
? `\n## How to work together\n\n${feature.teamworkInstructions}\n`
|
|
159
|
+
: '';
|
|
160
|
+
const ownInstructions = existing.length > 0
|
|
161
|
+
? `- These repos carry their own assistant instructions, which take precedence inside them: ${existing.join(', ')}\n`
|
|
162
|
+
: '';
|
|
163
|
+
// Commands the person who created this workspace typed in by hand. Exactly the
|
|
164
|
+
// kind of thing an assistant cannot derive: a mock/seed step, a non-standard
|
|
165
|
+
// start command, a test command that differs from the convention. The API still
|
|
166
|
+
// accepts and persists these, and for a while nothing read them — deleting the
|
|
167
|
+
// only reader as "dead code" silently dropped them from every generated file.
|
|
168
|
+
const custom = [];
|
|
169
|
+
if (feature.resumption?.testCommand)
|
|
170
|
+
custom.push(`- Verify with \`${feature.resumption.testCommand}\` — this overrides the per-repo commands above.`);
|
|
171
|
+
if (feature.resumption?.mockCommand)
|
|
172
|
+
custom.push(`- Set up dependencies first with \`${feature.resumption.mockCommand}\`.`);
|
|
173
|
+
if (feature.resumption?.startCommand)
|
|
174
|
+
custom.push(`- Start the services with \`${feature.resumption.startCommand}\`.`);
|
|
175
|
+
const customCommands = custom.length > 0
|
|
176
|
+
? `\n## Commands recorded for this workspace\n\nThese were entered by hand and are not derivable from any manifest.\n\n${custom.join('\n')}\n`
|
|
177
|
+
: '';
|
|
178
|
+
// A table header over no rows, followed by "Each repo above is a separate git
|
|
179
|
+
// worktree", describes nothing. `create` should never produce this, but the
|
|
180
|
+
// writer had no guard, so say the true thing instead.
|
|
181
|
+
const reposSection = rows.length > 0
|
|
182
|
+
? `## Repos
|
|
183
|
+
|
|
184
|
+
| Repo | ${inPlace ? 'Path' : 'Directory'} | Verify | Cross-repo |
|
|
185
|
+
|---|---|---|---|
|
|
186
|
+
${rows.join('\n')}
|
|
252
187
|
|
|
253
|
-
${
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
- Read each project's existing \`README.md\` and any doc files before proposing changes.
|
|
257
|
-
- When modifying a shared library, check every downstream consumer for breakage.
|
|
258
|
-
- Prefer small, focused commits that touch one repo at a time when possible.
|
|
259
|
-
- If a change must span repos, describe the ordering and any migration steps.
|
|
188
|
+
${structureRule}${startHint}`
|
|
189
|
+
: `This workspace has no repositories yet — add one with \`nexusflow add-repo\`.`;
|
|
190
|
+
return `# ${feature.id}
|
|
260
191
|
|
|
192
|
+
${feature.description}
|
|
261
193
|
|
|
194
|
+
${reposSection}
|
|
262
195
|
|
|
196
|
+
## Where to look
|
|
263
197
|
|
|
264
|
-
|
|
198
|
+
- \`nexusflow-knowledge.md\` — decisions and gotchas from earlier sessions, one per \`###\` heading. It grows every session and is often long, so search the headings for your topic and read only those entries, not the whole file. Add with \`nexusflow knowledge add -t decision|gotcha -m "..."\`, keeping each entry to a rule and its reason
|
|
199
|
+
- \`nexusflow-plan.md\` — phase order when a change spans repos
|
|
200
|
+
${ownInstructions}${customCommands}${teamwork}`;
|
|
265
201
|
}
|
|
266
202
|
//# sourceMappingURL=base.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/generators/base.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/generators/base.ts"],"names":[],"mappings":"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"}
|