setup-vibeflow 0.11.0 → 0.13.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.
Files changed (2) hide show
  1. package/index.js +49 -20
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -60,7 +60,8 @@ const EDITIONS = {
60
60
  },
61
61
  };
62
62
 
63
- const DUPLICATE_MARKER = 'vibeflow-architect';
63
+ const VIBEFLOW_START = '<!-- vibeflow:start -->';
64
+ const VIBEFLOW_END = '<!-- vibeflow:end -->';
64
65
 
65
66
  const GITIGNORE_MARKER = '# Vibeflow — installed + generated (remove to track in git)';
66
67
 
@@ -114,6 +115,32 @@ function extractCopilotInstructionsSnippet(fullContent) {
114
115
  return match[1].trim();
115
116
  }
116
117
 
118
+ function upsertDelimitedBlock(existing, newBlock, legacyMarker) {
119
+ const delimited = `${VIBEFLOW_START}\n${newBlock.trim()}\n${VIBEFLOW_END}`;
120
+
121
+ if (!existing) {
122
+ return { content: delimited + '\n', action: 'created' };
123
+ }
124
+
125
+ const startIdx = existing.indexOf(VIBEFLOW_START);
126
+ const endIdx = existing.indexOf(VIBEFLOW_END);
127
+
128
+ if (startIdx !== -1 && endIdx !== -1) {
129
+ const before = existing.slice(0, startIdx);
130
+ const after = existing.slice(endIdx + VIBEFLOW_END.length);
131
+ const content = before + delimited + after;
132
+ return { content, action: 'replaced' };
133
+ }
134
+
135
+ if (legacyMarker && existing.includes(legacyMarker)) {
136
+ const content = existing.trimEnd() + '\n\n' + delimited + '\n';
137
+ return { content, action: 'legacy-append', warning: true };
138
+ }
139
+
140
+ const content = existing.trimEnd() + '\n\n' + delimited + '\n';
141
+ return { content, action: 'appended' };
142
+ }
143
+
117
144
  function detectEdition() {
118
145
  const args = process.argv.slice(2);
119
146
  if (args.includes('--cursor')) return 'cursor';
@@ -215,19 +242,18 @@ async function main() {
215
242
  try {
216
243
  const agentsSource = await downloadFile(edition.baseUrl, edition.agentsSrc);
217
244
  const appendContent = extractAgentsAppendContent(agentsSource);
245
+ const existing = existsSync(agentsPath) ? readFileSync(agentsPath, 'utf-8') : null;
246
+ const result = upsertDelimitedBlock(existing, appendContent, '## Vibeflow Methodology');
247
+ writeFileSync(agentsPath, result.content, 'utf-8');
218
248
 
219
- if (existsSync(agentsPath)) {
220
- const existing = readFileSync(agentsPath, 'utf-8');
221
- if (existing.includes(DUPLICATE_MARKER) && !force) {
222
- log(pc.dim('-'), `${pc.dim('AGENTS.md')} ${pc.dim('(vibeflow block exists, skipped)')}`);
223
- } else {
224
- const updated = existing.trimEnd() + '\n\n' + appendContent;
225
- writeFileSync(agentsPath, updated, 'utf-8');
226
- log(pc.green('+'), `AGENTS.md ${pc.dim('(appended vibeflow block)')}`);
227
- }
228
- } else {
229
- writeFileSync(agentsPath, appendContent, 'utf-8');
249
+ if (result.action === 'created') {
230
250
  log(pc.green('+'), `AGENTS.md ${pc.dim('(created)')}`);
251
+ } else if (result.action === 'replaced') {
252
+ log(pc.green('+'), `AGENTS.md ${pc.dim('(vibeflow block updated)')}`);
253
+ } else if (result.action === 'appended') {
254
+ log(pc.green('+'), `AGENTS.md ${pc.dim('(appended vibeflow block)')}`);
255
+ } else if (result.warning) {
256
+ log(pc.yellow('!'), `AGENTS.md ${pc.dim('(new delimited block appended — please remove the old vibeflow block manually)')}`);
231
257
  }
232
258
  } catch (err) {
233
259
  log(pc.red('x'), `AGENTS.md — ${err.message}`);
@@ -239,15 +265,18 @@ async function main() {
239
265
  try {
240
266
  if (existsSync(copilotInstrPath)) {
241
267
  const existing = readFileSync(copilotInstrPath, 'utf-8');
242
- if (existing.includes('vibeflow') && !force) {
243
- log(pc.dim('-'), `${pc.dim('.github/copilot-instructions.md')} ${pc.dim('(vibeflow snippet exists, skipped)')}`);
244
- } else {
245
- const snippetSource = await downloadFile(edition.baseUrl, 'copilot-instructions.md');
246
- const snippet = extractCopilotInstructionsSnippet(snippetSource);
247
- if (snippet) {
248
- const updated = existing.trimEnd() + '\n\n' + snippet + '\n';
249
- writeFileSync(copilotInstrPath, updated, 'utf-8');
268
+ const snippetSource = await downloadFile(edition.baseUrl, 'copilot-instructions.md');
269
+ const snippet = extractCopilotInstructionsSnippet(snippetSource);
270
+ if (snippet) {
271
+ const result = upsertDelimitedBlock(existing, snippet, '## Vibeflow');
272
+ writeFileSync(copilotInstrPath, result.content, 'utf-8');
273
+
274
+ if (result.action === 'replaced') {
275
+ log(pc.green('+'), `.github/copilot-instructions.md ${pc.dim('(vibeflow snippet updated)')}`);
276
+ } else if (result.action === 'appended') {
250
277
  log(pc.green('+'), `.github/copilot-instructions.md ${pc.dim('(appended vibeflow snippet)')}`);
278
+ } else if (result.warning) {
279
+ log(pc.yellow('!'), `.github/copilot-instructions.md ${pc.dim('(new delimited snippet appended — please remove the old vibeflow block manually)')}`);
251
280
  }
252
281
  }
253
282
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "setup-vibeflow",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Install Vibeflow (spec-driven development) in your project",
5
5
  "bin": {
6
6
  "setup-vibeflow": "./index.js"