spectoflow 0.23.1 → 0.23.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectoflow",
3
- "version": "0.23.1",
3
+ "version": "0.23.2",
4
4
  "description": "Agent-agnostic spec-driven development framework + real-time local control plane. Markdown artifacts, intent router, workflow-by-scope.",
5
5
  "keywords": [
6
6
  "spec-driven-development",
@@ -135,8 +135,18 @@ function createHandlers(root) {
135
135
  if (p === '/api/workflow/toggle' && req.method === 'POST') {
136
136
  const { name } = await body(req); const wf = path.join(root, '.spectoflow', 'workflow.md');
137
137
  const lines = fs.readFileSync(wf, 'utf8').split('\n');
138
+ // Must strip a trailing {cap:... skill:... policy} annotation (added in D29) BEFORE stripping
139
+ // "(optional)" — same order as store.js's readWorkflow(), which is what the client's own step
140
+ // names (and so `name` here) are actually derived from. Every step in the default workflow.md
141
+ // template carries one of these annotations, so getting this order wrong breaks toggling
142
+ // every single step, not just an edge case.
143
+ const stepName = (rest) => {
144
+ const ann = rest.match(/\{([^}]*)\}\s*$/);
145
+ if (ann) rest = rest.slice(0, ann.index).trim();
146
+ return rest.replace(/\s*\(optional\)\s*$/i, '').trim();
147
+ };
138
148
  for (let i = 0; i < lines.length; i++) { const m = lines[i].match(/^(\s*- \[)( |x|X)(\]\s+)(.*)$/);
139
- if (m && m[4].replace(/\s*\(optional\)\s*$/i, '').trim() === name) lines[i] = m[1] + (m[2].trim() ? ' ' : 'x') + m[3] + m[4]; }
149
+ if (m && stepName(m[4]) === name) lines[i] = m[1] + (m[2].trim() ? ' ' : 'x') + m[3] + m[4]; }
140
150
  fs.writeFileSync(wf, lines.join('\n')); emit({ type: 'change' }); sendJSON(res, 200, { ok: true }); return true;
141
151
  }
142
152