Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f0b69f3
fix(zsh): use global scope for typeset to support lazy loading
losinggeneration Apr 1, 2026
92e0937
Merge branch 'main' into fix/zsh-lazy-loading
amitksingh1490 Apr 20, 2026
2301a47
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 21, 2026
d40e633
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 21, 2026
597b1ef
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 21, 2026
91df0e7
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 22, 2026
1c3b6e7
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 22, 2026
bc03cc3
Merge branch 'main' into fix/zsh-lazy-loading
amitksingh1490 Apr 24, 2026
a155d17
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 25, 2026
7ab89ce
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 27, 2026
7d44433
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 27, 2026
7231865
Merge branch 'main' into fix/zsh-lazy-loading
losinggeneration Apr 29, 2026
2dbf124
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration Apr 29, 2026
4314934
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration May 2, 2026
e6cb2ab
Merge branch 'main' into fix/zsh-lazy-loading
losinggeneration May 2, 2026
e7499dd
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration May 6, 2026
076c406
Merge remote-tracking branch 'upstream/main' into fix/zsh-lazy-loading
losinggeneration May 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions crates/forge_main/src/zsh/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ pub fn generate_zsh_plugin() -> Result<String> {
output.push_str(&completions_str);

// Set environment variable to indicate plugin is loaded (with timestamp)
output.push_str("\n_FORGE_PLUGIN_LOADED=$(date +%s)\n");
// Use typeset -g so the variable is global even when eval'd inside a function
// (e.g. lazy-loading plugin managers like zinit, zplug, zsh-defer)
output.push_str("\ntypeset -g _FORGE_PLUGIN_LOADED=$(date +%s)\n");

Ok(output)
}
Expand All @@ -55,7 +57,9 @@ pub fn generate_zsh_theme() -> Result<String> {
super::normalize_script(include_str!("../../../../shell-plugin/forge.theme.zsh"));

// Set environment variable to indicate theme is loaded (with timestamp)
content.push_str("\n_FORGE_THEME_LOADED=$(date +%s)\n");
// Use typeset -g so the variable is global even when eval'd inside a function
// (e.g. lazy-loading plugin managers like zinit, zplug, zsh-defer)
content.push_str("\ntypeset -g _FORGE_THEME_LOADED=$(date +%s)\n");

Ok(content)
}
Expand Down
36 changes: 19 additions & 17 deletions shell-plugin/lib/config.zsh
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
#!/usr/bin/env zsh

# Configuration variables for forge plugin
# Using typeset to keep variables local to plugin scope and prevent public exposure
# Using typeset -gh (global + hidden) so variables survive lazy-loading
# from within a function scope (e.g. zinit, zplug, zsh-defer) while
# staying hidden from `typeset` listings.

typeset -h _FORGE_BIN="${FORGE_BIN:-forge}"
typeset -h _FORGE_CONVERSATION_PATTERN=":"
typeset -h _FORGE_MAX_COMMIT_DIFF="${FORGE_MAX_COMMIT_DIFF:-100000}"
typeset -gh _FORGE_BIN="${FORGE_BIN:-forge}"
typeset -gh _FORGE_CONVERSATION_PATTERN=":"
typeset -gh _FORGE_MAX_COMMIT_DIFF="${FORGE_MAX_COMMIT_DIFF:-100000}"

typeset -h _FORGE_COMMANDS=""
typeset -gh _FORGE_COMMANDS=""

# Hidden variables to be used only via the ForgeCLI
typeset -h _FORGE_CONVERSATION_ID
typeset -h _FORGE_ACTIVE_AGENT
typeset -gh _FORGE_CONVERSATION_ID
typeset -gh _FORGE_ACTIVE_AGENT

# Previous conversation ID for :conversation - (like cd -)
typeset -h _FORGE_PREVIOUS_CONVERSATION_ID
typeset -gh _FORGE_PREVIOUS_CONVERSATION_ID

# Session-scoped model and provider overrides (set via :model / :m).
# When non-empty, these are passed as --model / --provider to every forge
# invocation for the lifetime of the current shell session.
typeset -h _FORGE_SESSION_MODEL
typeset -h _FORGE_SESSION_PROVIDER
typeset -gh _FORGE_SESSION_MODEL
typeset -gh _FORGE_SESSION_PROVIDER

# Session-scoped reasoning effort override (set via :reasoning-effort / :re).
# When non-empty, exported as FORGE_REASONING__EFFORT for every forge invocation.
typeset -h _FORGE_SESSION_REASONING_EFFORT
typeset -gh _FORGE_SESSION_REASONING_EFFORT

# Terminal context capture settings
# Master switch for terminal context capture (preexec/precmd hooks)
typeset -h _FORGE_TERM="${FORGE_TERM:-true}"
typeset -gh _FORGE_TERM="${FORGE_TERM:-true}"
# Maximum number of commands to keep in the ring buffer (metadata: cmd + exit code)
typeset -h _FORGE_TERM_MAX_COMMANDS="${FORGE_TERM_MAX_COMMANDS:-5}"
typeset -gh _FORGE_TERM_MAX_COMMANDS="${FORGE_TERM_MAX_COMMANDS:-5}"
# OSC 133 semantic prompt marker emission: "auto", "on", or "off"
typeset -h _FORGE_TERM_OSC133="${FORGE_TERM_OSC133:-auto}"
typeset -gh _FORGE_TERM_OSC133="${FORGE_TERM_OSC133:-auto}"
# Ring buffer arrays for context capture
typeset -ha _FORGE_TERM_COMMANDS=()
typeset -ha _FORGE_TERM_EXIT_CODES=()
typeset -ha _FORGE_TERM_TIMESTAMPS=()
typeset -gha _FORGE_TERM_COMMANDS=()
typeset -gha _FORGE_TERM_EXIT_CODES=()
typeset -gha _FORGE_TERM_TIMESTAMPS=()
8 changes: 8 additions & 0 deletions shell-plugin/lib/highlight.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
# Syntax highlighting configuration for forge commands
# Style the conversation pattern with appropriate highlighting
# Keywords in yellow, rest in default white
#
# Use global declarations so we update the shared zsh-syntax-highlighting
# collections even when sourced from within a function (lazy-loading plugin
# managers). Patterns must remain an associative array because the pattern
# highlighter stores regex => style entries in ZSH_HIGHLIGHT_PATTERNS.

typeset -gA ZSH_HIGHLIGHT_PATTERNS
typeset -ga ZSH_HIGHLIGHT_HIGHLIGHTERS

# Style tagged files
ZSH_HIGHLIGHT_PATTERNS+=('@\[[^]]#\]' 'fg=cyan,bold')
Expand Down
Loading