odd-studio 3.3.9 → 3.4.1

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/bin/odd-studio.js CHANGED
@@ -15,7 +15,7 @@ import { registerUninstall } from './commands/uninstall.js';
15
15
  const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = path.dirname(__filename);
17
17
  const require = createRequire(import.meta.url);
18
- const pkg = require('../package.json'); // v3.3.9
18
+ const pkg = require('../package.json'); // v3.4.1
19
19
 
20
20
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
21
21
  const deps = { PACKAGE_ROOT, print };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odd-studio",
3
- "version": "3.3.9",
3
+ "version": "3.4.1",
4
4
  "description": "Outcome-Driven Development planning and build harness for domain experts building serious software with AI.",
5
5
  "author": {
6
6
  "name": "ODD Studio"
@@ -165,7 +165,13 @@ swarm-write)
165
165
  fi
166
166
 
167
167
  # Gate 2: Agent token must exist (short-lived, created by Task agents)
168
+ # Exception: allow the main conversation to write config/infrastructure files
169
+ # (package.json, .env, drizzle.config, tsconfig, etc.) during project setup
168
170
  if ! marker_valid ".odd/.odd-flow-agent-token" 120; then
171
+ # Allow config and infrastructure files without agent token
172
+ if echo "$FILE_PATH" | grep -qE '(package\.json|\.env|tsconfig|next\.config|postcss\.config|tailwind\.config|drizzle\.config|vitest\.config|eslint\.config|\.gitignore|docker-compose|Dockerfile|vercel\.config|vercel\.ts)'; then
173
+ exit 0
174
+ fi
169
175
  echo "ODD STUDIO [swarm-write]: Source writes blocked — no agent token." >&2
170
176
  echo "Source code must be written by Task agents, not the main conversation." >&2
171
177
  echo "Task agents run: touch .odd/.odd-flow-agent-token before writing." >&2
@@ -225,7 +231,7 @@ confirm-gate)
225
231
  NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty')
226
232
  echo "$NEW_CONTENT" | grep -qE '"briefConfirmed"\s*:\s*true' || exit 0
227
233
 
228
- if [ ! -f ".odd/.odd-flow-brief-stored" ]; then
234
+ if [ ! -f ".odd/.odd-flow-brief-stored" ] && [ ! -f ".odd/.odd-flow-state-ready" ]; then
229
235
  echo "ODD STUDIO [confirm-gate]: Brief not stored in odd-flow memory. Store it first." >&2
230
236
  exit 2
231
237
  fi
@@ -380,13 +386,20 @@ store-validate)
380
386
  [ "$CURRENT_PHASE" = "build" ] || exit 0
381
387
 
382
388
  KEY=$(echo "$INPUT" | jq -r '.tool_input.key // empty')
383
- [ "$KEY" = "odd-project-state" ] || exit 0
384
389
 
385
390
  SUCCESS=$(echo "$INPUT" | jq -r '.tool_response.success // false' 2>/dev/null || echo "false")
386
391
  [ "$SUCCESS" = "true" ] || exit 0
387
392
 
388
- touch .odd/.odd-flow-state-ready 2>/dev/null
389
- rm -f .odd/.odd-flow-state-dirty 2>/dev/null
393
+ # Create the right marker based on what was stored
394
+ case "$KEY" in
395
+ odd-project-state)
396
+ touch .odd/.odd-flow-state-ready 2>/dev/null
397
+ rm -f .odd/.odd-flow-state-dirty 2>/dev/null
398
+ ;;
399
+ odd-session-brief-*)
400
+ touch .odd/.odd-flow-brief-stored 2>/dev/null
401
+ ;;
402
+ esac
390
403
  exit 0
391
404
  ;;
392
405
 
@@ -427,9 +440,9 @@ code-quality)
427
440
  /^[[:space:]]*(export )?(async )?(function |const [a-zA-Z]+ = (\([^)]*\)|[a-zA-Z]+) =>)/ {
428
441
  name = $0; gsub(/^[[:space:]]+/, "", name); start = NR; depth = 0; started = 0
429
442
  while ((getline line) > 0) {
430
- gsub(/[^{]/, "", line); open = length(line)
431
- line2 = $0; gsub(/[^}]/, "", line2); close = length(line2)
432
- if (open > 0) started = 1; depth += open - close
443
+ gsub(/[^{]/, "", line); openc = length(line)
444
+ line2 = $0; gsub(/[^}]/, "", line2); closec = length(line2)
445
+ if (openc > 0) started = 1; depth += openc - closec
433
446
  if (started && depth <= 0) {
434
447
  len = NR - start
435
448
  if (len > 25) printf " %s (line %d, %d lines)\n", substr(name, 1, 60), start, len
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odd-studio",
3
- "version": "3.3.9",
3
+ "version": "3.4.1",
4
4
  "description": "Outcome-Driven Development for AI coding agents — a planning and build harness for domain experts building serious software with AI. Works with Claude Code, OpenCode, and Codex.",
5
5
  "keywords": [
6
6
  "claude-code",
package/skill/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: "odd"
3
- version: "3.3.9"
3
+ version: "3.4.1"
4
4
  description: "Outcome-Driven Development planning and build coach. Use /odd to start or resume an ODD project — building personas, writing outcomes, mapping contracts, creating a Master Implementation Plan, and directing a odd-flow-powered build. Designed for domain experts who are not developers. Works with Claude Code, OpenCode, and Codex."
5
5
  metadata:
6
6
  priority: 10
@@ -96,7 +96,7 @@ Display this when no existing state is found:
96
96
 
97
97
  ---
98
98
 
99
- Welcome to ODD Studio v3.3.9.
99
+ Welcome to ODD Studio v3.4.1.
100
100
 
101
101
  You are about to plan and build something real — using a methodology called Outcome-Driven Development. Before we write a single line of code, we are going to get precise about three things:
102
102
 
@@ -120,7 +120,7 @@ Display this when existing state is found. Replace the bracketed values with act
120
120
 
121
121
  ---
122
122
 
123
- Welcome back to ODD Studio v3.3.9.
123
+ Welcome back to ODD Studio v3.4.1.
124
124
 
125
125
  **Project:** [project.name]
126
126
  **Current Phase:** [state.currentPhase]