@goodtek/vibeops 0.3.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to VibeOps are documented here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.4.0 - 2026-05-13
8
+
9
+ ### Changed
10
+
11
+ - **Interactive plan LLM (`questionType`)**: system prompt prefers **`multi`** (checkbox, Space toggles) whenever several options can apply; reserve **`single`** for mutually exclusive choices. **`multi` vs `single` terminal behavior** is spelled out for the model.
12
+ - **Plan JSON parsing**: if `questionType` is missing or invalid and **two or more** `options` are present, default to **`multi`** so users get multi-select instead of a hard error or accidental single-only flow.
13
+
7
14
  ## 0.3.0 - 2026-05-13
8
15
 
9
16
  ### Changed
@@ -102,16 +102,27 @@ export function parsePlanLlmTurn(jsonText) {
102
102
  }
103
103
  if (turn === "question") {
104
104
  const message = typeof raw.message === "string" ? raw.message : "";
105
- const questionType = raw.questionType;
106
105
  if (message.length === 0) {
107
106
  throw new Error('Invalid JSON: "question" turn needs non-empty "message".');
108
107
  }
109
- if (questionType !== "single" && questionType !== "multi" && questionType !== "text") {
110
- throw new Error('Invalid JSON: questionType must be "single", "multi", or "text".');
111
- }
112
108
  const options = Array.isArray(raw.options)
113
109
  ? raw.options.filter((x) => typeof x === "string" && x.trim().length > 0)
114
110
  : [];
111
+ const rawQt = raw.questionType;
112
+ let questionType;
113
+ if (rawQt === "single" || rawQt === "multi" || rawQt === "text") {
114
+ questionType = rawQt;
115
+ }
116
+ else if (options.length >= 2) {
117
+ /** Model often omits or mistypes questionType — multi is the safer default when lists are offered. */
118
+ questionType = "multi";
119
+ }
120
+ else if (options.length === 1) {
121
+ questionType = "single";
122
+ }
123
+ else {
124
+ questionType = "text";
125
+ }
115
126
  return {
116
127
  turn: "question",
117
128
  message,
@@ -11,14 +11,15 @@ import { extractJsonObject, openAiChatCompletionJson, parsePlanLlmTurn } from ".
11
11
  import { normalizeLlmProjectBrief } from "./plan-llm-normalize.js";
12
12
  import { VERSION } from "../version.js";
13
13
  const MAX_LLM_TURNS = 48;
14
- const PLAN_JSON_PROTOCOL_CORE = `You are VibeOps' planning assistant. Learn about a software project through a short dialogue, infer the next best single question from the user's last answer, then produce a structured ProjectBrief.
14
+ const PLAN_JSON_PROTOCOL_CORE = `You are VibeOps' planning assistant. Learn about a software project through a short dialogue, infer the next best question from the user's last answer, then produce a structured ProjectBrief.
15
15
 
16
16
  You MUST reply with a single JSON object only (no markdown fences). Allowed "turn" values: "question", "confirm", "done".
17
17
 
18
18
  1) While discovering:
19
19
  {"turn":"question","message":"<markdown allowed>","questionType":"single"|"multi"|"text","options":["..."]}
20
20
  - **One primary ask per turn** (see conversation rules below).
21
- - For "single" or "multi", include "options" (3–12 short labels) as **suggested answers only**. The terminal may show a picker (arrow keys / Space) but the user can always choose Other or type a custom reply.
21
+ - **questionType — critical:** Prefer **"multi"** whenever more than one option can legitimately apply (e.g. target users, MVP features, integrations, deployment targets, risks, auth methods, “which concerns apply”, stacks that can combine). Use **"single"** only when choices are **mutually exclusive** (exactly one can be true: e.g. one primary package manager, one hosting model when alternatives exclude each other, a single primary language for the codebase). When in doubt, use **"multi"** so the user can toggle several options with Space.
22
+ - For "single" or "multi", include "options" (3–12 short labels) as **suggested answers only**. **"multi"** uses a checkbox (Space toggles, Enter submits). **"single"** uses a one-line picker (Enter picks one). The user can always pick Other or type a custom reply.
22
23
  - For "text", omit "options" or use an empty array.
23
24
 
24
25
  2) When information is enough for a solid ProjectBrief and task breakdown, **before** "done", emit exactly one approval step:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodtek/vibeops",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Workflow rails for Cursor-based vibe coding projects.",
5
5
  "type": "module",
6
6
  "author": "VibeOps contributors",