wogiflow 2.22.2 → 2.22.4
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 +60 -6
- package/lib/wogi-claude-expect.exp +73 -0
- package/package.json +2 -2
package/lib/wogi-claude
CHANGED
|
@@ -17,13 +17,63 @@
|
|
|
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
|
|
21
|
-
# WOGI_MAX_RESTARTS
|
|
22
|
-
# WOGI_WRAPPER_PID
|
|
23
|
-
# WOGI_CLAUDE_BIN
|
|
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_USE_EXPECT — (EXPERIMENTAL, v2.22.4+) set to 1 to opt IN to the
|
|
25
|
+
# expect-based auto-dismiss of the "Loading development
|
|
26
|
+
# channels" dialog. OFF BY DEFAULT because Ink's
|
|
27
|
+
# ANSI-rich output can cause expect's text match to
|
|
28
|
+
# miss, which deadlocks the dialog (user keystrokes
|
|
29
|
+
# get held by expect, not forwarded to claude). If
|
|
30
|
+
# you can confirm it works for your terminal, opt in
|
|
31
|
+
# and enjoy zero-click restarts.
|
|
32
|
+
# WOGI_NO_EXPECT — legacy opt-out from 2.22.3. Still honored (forces
|
|
33
|
+
# expect off regardless of WOGI_USE_EXPECT).
|
|
34
|
+
# WOGI_EXPECT_TIMEOUT — override the expect timeout (default 30s) for watching
|
|
35
|
+
# the dialog. After timeout we hand off to the user
|
|
36
|
+
# unconditionally.
|
|
24
37
|
|
|
25
38
|
set -u
|
|
26
39
|
|
|
40
|
+
# --- Resolve helper paths (for expect-based dialog auto-dismiss) ---
|
|
41
|
+
WOGI_CLAUDE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
42
|
+
WOGI_EXPECT_SCRIPT="$WOGI_CLAUDE_DIR/wogi-claude-expect.exp"
|
|
43
|
+
|
|
44
|
+
# Detect whether to use the expect wrapper (v2.22.4: OPT-IN only).
|
|
45
|
+
# Four conditions must all hold:
|
|
46
|
+
# 1. WOGI_USE_EXPECT=1 is explicitly set (opt-in)
|
|
47
|
+
# 2. WOGI_NO_EXPECT is NOT set (legacy escape hatch still honored)
|
|
48
|
+
# 3. `expect` is on PATH and the wogi-claude-expect.exp script exists
|
|
49
|
+
# 4. The args include --dangerously-load-development-channels (the only
|
|
50
|
+
# flag that triggers the dialog we want to auto-dismiss)
|
|
51
|
+
#
|
|
52
|
+
# 2.22.3 tried opt-out by default; in practice, expect's text match can miss
|
|
53
|
+
# Ink's ANSI-fragmented output, which deadlocks the dialog (user keystrokes
|
|
54
|
+
# get held in expect's buffer instead of reaching claude). 2.22.4 flips to
|
|
55
|
+
# opt-in so the default UX is predictable.
|
|
56
|
+
__wogi_use_expect=0
|
|
57
|
+
if [ "${WOGI_USE_EXPECT:-}" = "1" ] && [ -z "${WOGI_NO_EXPECT:-}" ] && \
|
|
58
|
+
command -v expect >/dev/null 2>&1 && [ -x "$WOGI_EXPECT_SCRIPT" ]; then
|
|
59
|
+
for arg in "$@"; do
|
|
60
|
+
if [ "$arg" = "--dangerously-load-development-channels" ]; then
|
|
61
|
+
__wogi_use_expect=1
|
|
62
|
+
break
|
|
63
|
+
fi
|
|
64
|
+
done
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# run_claude — invoke claude, routing through expect when we can auto-dismiss
|
|
68
|
+
# the dev-channels dialog. Preserves stdin/stdout/stderr exactly.
|
|
69
|
+
run_claude() {
|
|
70
|
+
if [ "$__wogi_use_expect" -eq 1 ]; then
|
|
71
|
+
expect "$WOGI_EXPECT_SCRIPT" "$CLAUDE_BIN" "$@"
|
|
72
|
+
else
|
|
73
|
+
"$CLAUDE_BIN" "$@"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
27
77
|
# --- Opt-out path: no restart loop, just exec claude once ---
|
|
28
78
|
for arg in "$@"; do
|
|
29
79
|
if [ "$arg" = "--no-wogi-restart" ]; then
|
|
@@ -31,7 +81,11 @@ for arg in "$@"; do
|
|
|
31
81
|
filtered=()
|
|
32
82
|
for a in "$@"; do [ "$a" = "--no-wogi-restart" ] || filtered+=("$a"); done
|
|
33
83
|
CLAUDE_BIN="${WOGI_CLAUDE_BIN:-claude}"
|
|
34
|
-
|
|
84
|
+
if [ "$__wogi_use_expect" -eq 1 ]; then
|
|
85
|
+
exec expect "$WOGI_EXPECT_SCRIPT" "$CLAUDE_BIN" "${filtered[@]}"
|
|
86
|
+
else
|
|
87
|
+
exec "$CLAUDE_BIN" "${filtered[@]}"
|
|
88
|
+
fi
|
|
35
89
|
fi
|
|
36
90
|
done
|
|
37
91
|
|
|
@@ -66,7 +120,7 @@ while true; do
|
|
|
66
120
|
rm -f "$FLAG_FILE"
|
|
67
121
|
fi
|
|
68
122
|
|
|
69
|
-
|
|
123
|
+
run_claude "$@"
|
|
70
124
|
inner_exit=$?
|
|
71
125
|
|
|
72
126
|
# 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.
|
|
3
|
+
"version": "2.22.4",
|
|
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",
|