wogiflow 2.22.2 → 2.22.3

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/lib/wogi-claude CHANGED
@@ -17,13 +17,52 @@
17
17
  # Opt-out: pass --no-wogi-restart to run claude once without the restart loop
18
18
  #
19
19
  # Environment:
20
- # WOGI_RESTART_FLAG — path to restart-flag file (default: <cwd>/.workflow/state/restart-requested)
21
- # WOGI_MAX_RESTARTS — safety cap, default 50 (prevents runaway restart storms)
22
- # WOGI_WRAPPER_PID — exported to child; hook checks this to confirm wrapper is present
23
- # WOGI_CLAUDE_BIN — override path to claude binary (default: found via PATH)
20
+ # WOGI_RESTART_FLAG — path to restart-flag file (default: <cwd>/.workflow/state/restart-requested)
21
+ # WOGI_MAX_RESTARTS — safety cap, default 50 (prevents runaway restart storms)
22
+ # WOGI_WRAPPER_PID — exported to child; hook checks this to confirm wrapper is present
23
+ # WOGI_CLAUDE_BIN — override path to claude binary (default: found via PATH)
24
+ # WOGI_NO_EXPECT — set to 1 to disable expect-based auto-dismiss of the
25
+ # "Loading development channels" dialog (v2.22.3+).
26
+ # With expect enabled (default when expect is on PATH
27
+ # and --dangerously-load-development-channels is in args),
28
+ # the dialog is auto-accepted so workspace worker
29
+ # restarts require zero manual interaction.
30
+ # WOGI_EXPECT_TIMEOUT — override the expect timeout (default 30s) for watching
31
+ # the dialog. After timeout we hand off to the user
32
+ # unconditionally.
24
33
 
25
34
  set -u
26
35
 
36
+ # --- Resolve helper paths (for expect-based dialog auto-dismiss) ---
37
+ WOGI_CLAUDE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
38
+ WOGI_EXPECT_SCRIPT="$WOGI_CLAUDE_DIR/wogi-claude-expect.exp"
39
+
40
+ # Detect whether to use the expect wrapper. Two conditions must hold:
41
+ # 1. `expect` is on PATH and the wogi-claude-expect.exp script exists
42
+ # 2. The args include --dangerously-load-development-channels (which is the
43
+ # only flag that triggers the "Loading development channels" dialog we
44
+ # want to auto-dismiss)
45
+ # AND WOGI_NO_EXPECT is NOT set (escape hatch).
46
+ __wogi_use_expect=0
47
+ if [ -z "${WOGI_NO_EXPECT:-}" ] && command -v expect >/dev/null 2>&1 && [ -x "$WOGI_EXPECT_SCRIPT" ]; then
48
+ for arg in "$@"; do
49
+ if [ "$arg" = "--dangerously-load-development-channels" ]; then
50
+ __wogi_use_expect=1
51
+ break
52
+ fi
53
+ done
54
+ fi
55
+
56
+ # run_claude — invoke claude, routing through expect when we can auto-dismiss
57
+ # the dev-channels dialog. Preserves stdin/stdout/stderr exactly.
58
+ run_claude() {
59
+ if [ "$__wogi_use_expect" -eq 1 ]; then
60
+ expect "$WOGI_EXPECT_SCRIPT" "$CLAUDE_BIN" "$@"
61
+ else
62
+ "$CLAUDE_BIN" "$@"
63
+ fi
64
+ }
65
+
27
66
  # --- Opt-out path: no restart loop, just exec claude once ---
28
67
  for arg in "$@"; do
29
68
  if [ "$arg" = "--no-wogi-restart" ]; then
@@ -31,7 +70,11 @@ for arg in "$@"; do
31
70
  filtered=()
32
71
  for a in "$@"; do [ "$a" = "--no-wogi-restart" ] || filtered+=("$a"); done
33
72
  CLAUDE_BIN="${WOGI_CLAUDE_BIN:-claude}"
34
- exec "$CLAUDE_BIN" "${filtered[@]}"
73
+ if [ "$__wogi_use_expect" -eq 1 ]; then
74
+ exec expect "$WOGI_EXPECT_SCRIPT" "$CLAUDE_BIN" "${filtered[@]}"
75
+ else
76
+ exec "$CLAUDE_BIN" "${filtered[@]}"
77
+ fi
35
78
  fi
36
79
  done
37
80
 
@@ -66,7 +109,7 @@ while true; do
66
109
  rm -f "$FLAG_FILE"
67
110
  fi
68
111
 
69
- "$CLAUDE_BIN" "$@"
112
+ run_claude "$@"
70
113
  inner_exit=$?
71
114
 
72
115
  # If the user hit Ctrl+C (INT/TERM reached us), don't restart
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env expect
2
+ #
3
+ # wogi-claude-expect.exp — Auto-dismiss Claude Code's "Loading development
4
+ # channels" dialog so workspace worker restarts are truly seamless.
5
+ #
6
+ # Claude Code fires an interactive Ink dialog EVERY session when:
7
+ # - User is OAuth-authenticated to claude.ai
8
+ # - The CLI is launched with --dangerously-load-development-channels
9
+ #
10
+ # There's no Claude Code setting that persists an "accepted" state
11
+ # (verified via decompiled source 2026-04-17). So we intercept the dialog
12
+ # at the wrapper level: spawn claude in an expect-managed PTY, watch for
13
+ # the dialog title text, send Enter to accept the already-highlighted
14
+ # "I am using this for local development" option, then hand off control
15
+ # to the user via `interact`.
16
+ #
17
+ # Usage (invoked from lib/wogi-claude):
18
+ # expect wogi-claude-expect.exp /absolute/path/to/claude [args...]
19
+ #
20
+ # Disable at runtime: set WOGI_NO_EXPECT=1. The wrapper then execs claude
21
+ # directly and the user sees the dialog as before (manual single-click).
22
+
23
+ set timeout 30
24
+
25
+ # Allow WOGI_EXPECT_TIMEOUT override (rarely needed)
26
+ if {[info exists env(WOGI_EXPECT_TIMEOUT)]} {
27
+ set timeout $env(WOGI_EXPECT_TIMEOUT)
28
+ }
29
+
30
+ # Mirror claude's output to the user's terminal during dialog watch
31
+ log_user 1
32
+
33
+ # argv[0] is the claude binary path; rest are claude's args
34
+ if {[llength $argv] < 1} {
35
+ puts stderr "wogi-claude-expect.exp: missing claude binary path"
36
+ exit 2
37
+ }
38
+
39
+ set claude_bin [lindex $argv 0]
40
+ set claude_args [lrange $argv 1 end]
41
+
42
+ # Spawn claude in a pseudo-TTY so its Ink UI renders normally.
43
+ # eval is needed because claude_args is a list and spawn expects a
44
+ # flattened command line.
45
+ eval spawn $claude_bin $claude_args
46
+
47
+ # Watch for the DevChannels dialog title, then press Enter to accept
48
+ # the default-highlighted "I am using this for local development" option.
49
+ #
50
+ # On timeout or EOF: fall through to `interact`. If the dialog appears
51
+ # AFTER our timeout window, the user can still answer it manually —
52
+ # same failure mode as running claude directly.
53
+ expect {
54
+ -re "Loading development channels" {
55
+ # Let Ink finish rendering the dialog before sending Enter.
56
+ # Without this, the select-input component may not have bound
57
+ # its keyboard listener yet and the keystroke is dropped.
58
+ after 250
59
+ send "\r"
60
+ }
61
+ timeout { }
62
+ eof { exit }
63
+ }
64
+
65
+ # Hand off: user's keystrokes flow to claude, claude's output flows
66
+ # to the user's terminal. interact blocks until claude exits.
67
+ interact
68
+
69
+ # After claude exits, let the bash wrapper decide whether to restart.
70
+ # Pass through claude's exit status (expect sets it in $expect_out(-code)
71
+ # after `interact`, but a plain exit is sufficient since the wrapper
72
+ # only cares about the restart flag file, not exit code).
73
+ exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wogiflow",
3
- "version": "2.22.2",
3
+ "version": "2.22.3",
4
4
  "description": "AI-powered development workflow management system with multi-model support",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "scripts": {
12
12
  "flow": "./scripts/flow",
13
- "test": "NODE_ENV=test node --test tests/auto-compact-prompt.test.js tests/flow-paths.test.js tests/flow-io.test.js tests/flow-config-loader.test.js tests/flow-damage-control.test.js tests/flow-output.test.js tests/flow-constants.test.js tests/flow-session-state.test.js tests/flow-hooks-integration.test.js tests/flow-utils.test.js tests/flow-security.test.js tests/flow-memory-db.test.js tests/flow-durable-session.test.js tests/flow-skill-matcher.test.js tests/flow-bridge.test.js tests/flow-proactive-compact.test.js tests/flow-cascade-completion.test.js tests/flow-capture-gate.test.js tests/flow-correction-detector-hybrid.test.js tests/flow-promote.test.js tests/flow-archive-runs.test.js tests/flow-memory.test.js tests/flow-hooks-pre-tool-helpers.test.js tests/flow-hooks-bugfix-scope-gate.test.js tests/flow-hooks-routing-gate.test.js tests/flow-hooks-phase-read-gate.test.js tests/flow-hooks-commit-log-gate.test.js tests/flow-hooks-deploy-gate.test.js tests/flow-hooks-todowrite-gate.test.js tests/flow-hooks-git-safety-gate.test.js tests/flow-hooks-scope-mutation-gate.test.js tests/flow-hooks-strike-gate.test.js tests/flow-hooks-component-check.test.js tests/flow-hooks-scope-gate.test.js tests/flow-hooks-implementation-gate.test.js tests/flow-hooks-research-gate.test.js tests/flow-hooks-loop-check.test.js tests/flow-hooks-manager-boundary-gate.test.js tests/flow-hooks-phase-gate.test.js tests/flow-hooks-pre-tool-orchestrator.test.js tests/flow-hooks-observation-capture.test.js tests/flow-hooks-task-gate.test.js tests/flow-durable-session-suspension.test.js tests/flow-health-mcp-scopes.test.js tests/flow-lean-config.test.js tests/flow-workspace-autopickup.test.js tests/flow-worker-boundary-gate.test.js tests/flow-worker-question-classifier.test.js tests/flow-completion-truth-gate-contradictions.test.js tests/flow-structure-sensor.test.js tests/flow-workspace-dispatch-tracking.test.js tests/flow-story-gates.test.js tests/flow-workspace-restart-handoff.test.js && NODE_ENV=test node tests/run-quality-gates.test.js",
13
+ "test": "NODE_ENV=test node --test tests/auto-compact-prompt.test.js tests/flow-paths.test.js tests/flow-io.test.js tests/flow-config-loader.test.js tests/flow-damage-control.test.js tests/flow-output.test.js tests/flow-constants.test.js tests/flow-session-state.test.js tests/flow-hooks-integration.test.js tests/flow-utils.test.js tests/flow-security.test.js tests/flow-memory-db.test.js tests/flow-durable-session.test.js tests/flow-skill-matcher.test.js tests/flow-bridge.test.js tests/flow-proactive-compact.test.js tests/flow-cascade-completion.test.js tests/flow-capture-gate.test.js tests/flow-correction-detector-hybrid.test.js tests/flow-promote.test.js tests/flow-archive-runs.test.js tests/flow-memory.test.js tests/flow-hooks-pre-tool-helpers.test.js tests/flow-hooks-bugfix-scope-gate.test.js tests/flow-hooks-routing-gate.test.js tests/flow-hooks-phase-read-gate.test.js tests/flow-hooks-commit-log-gate.test.js tests/flow-hooks-deploy-gate.test.js tests/flow-hooks-todowrite-gate.test.js tests/flow-hooks-git-safety-gate.test.js tests/flow-hooks-scope-mutation-gate.test.js tests/flow-hooks-strike-gate.test.js tests/flow-hooks-component-check.test.js tests/flow-hooks-scope-gate.test.js tests/flow-hooks-implementation-gate.test.js tests/flow-hooks-research-gate.test.js tests/flow-hooks-loop-check.test.js tests/flow-hooks-manager-boundary-gate.test.js tests/flow-hooks-phase-gate.test.js tests/flow-hooks-pre-tool-orchestrator.test.js tests/flow-hooks-observation-capture.test.js tests/flow-hooks-task-gate.test.js tests/flow-durable-session-suspension.test.js tests/flow-health-mcp-scopes.test.js tests/flow-lean-config.test.js tests/flow-workspace-autopickup.test.js tests/flow-worker-boundary-gate.test.js tests/flow-worker-question-classifier.test.js tests/flow-completion-truth-gate-contradictions.test.js tests/flow-structure-sensor.test.js tests/flow-workspace-dispatch-tracking.test.js tests/flow-story-gates.test.js tests/flow-workspace-restart-handoff.test.js tests/flow-wogi-claude-wrapper.test.js && NODE_ENV=test node tests/run-quality-gates.test.js",
14
14
  "test:syntax": "find scripts/ lib/ -name '*.js' -not -path '*/node_modules/*' -exec node --check {} +",
15
15
  "lint": "eslint scripts/ lib/ tests/",
16
16
  "lint:ci": "eslint scripts/ lib/ tests/ --max-warnings 0",