From 2e16c70519e5d0cc1a8d1804b8dbda21bd08dc88 Mon Sep 17 00:00:00 2001 From: Lakshman Patel Date: Sat, 4 Jul 2026 21:50:02 +0530 Subject: [PATCH 1/3] fix(ci): lint + checkout-eyrie fallback + marketplace sync --- .github/actions/checkout-eyrie/action.yml | 12 +++++++++++- cmd/chat.go | 2 +- cmd/chat_scrollbar.go | 2 -- cmd/chat_stream.go | 6 ------ external/sight | 2 +- internal/engine/safety/permission.go | 4 ---- internal/engine/stream_tool_exec.go | 12 ------------ .../plugin/bundled_skills/idea-refine/SKILL.md | 6 +++--- .../plugin/bundled_skills/idea-refine/examples.md | 1 + .../performance-optimization/SKILL.md | 1 - spec/agent-skills/docs/antigravity-setup.md | 14 +++++++------- spec/agent-skills/skills/idea-refine/SKILL.md | 6 +++--- spec/agent-skills/skills/idea-refine/examples.md | 1 + .../skills/performance-optimization/SKILL.md | 1 - spec/openspec/docs/examples.md | 14 +++++++------- spec/openspec/docs/existing-projects.md | 8 ++++---- spec/openspec/docs/opsx.md | 4 ++-- .../specs/cli-update/spec.md | 1 - spec/spec-kit/commands/analyze.md | 2 +- 19 files changed, 42 insertions(+), 57 deletions(-) diff --git a/.github/actions/checkout-eyrie/action.yml b/.github/actions/checkout-eyrie/action.yml index dc7a2dd6..8f58d77d 100644 --- a/.github/actions/checkout-eyrie/action.yml +++ b/.github/actions/checkout-eyrie/action.yml @@ -29,7 +29,17 @@ runs: # (e.g. by a squash-merge). A depth-1 clone can't check # out older commits and fails with "unable to read tree". git clone "https://github.com/GrayCodeAI/${repo}.git" "$dest" - (cd "$dest" && git checkout --quiet "$commit") + if ! (cd "$dest" && git checkout --quiet "$commit" 2>/dev/null); then + echo "Submodule commit $commit not reachable, falling back to ref" + ref="${{ inputs.ref }}" + if [ "$ref" = "main" ]; then + rm -rf "$dest" + git clone --depth=1 --branch main \ + "https://github.com/GrayCodeAI/${repo}.git" "$dest" + else + (cd "$dest" && git fetch --depth=1 "origin" "$ref" && git checkout --quiet "$ref") + fi + fi else ref="${{ inputs.ref }}" # Fall back to main if the branch doesn't exist on the dependency repo. diff --git a/cmd/chat.go b/cmd/chat.go index fe2287b8..883c0bb9 100644 --- a/cmd/chat.go +++ b/cmd/chat.go @@ -578,7 +578,7 @@ func runChat() error { } systemPrompt := promptRes.text settings := settingsRes.settings - m, err := newChatModelWithRegistry(ref, systemPrompt, settings, registryRes.registry) + m, err := newChatModel(ref, systemPrompt, settings) if err != nil { return err } diff --git a/cmd/chat_scrollbar.go b/cmd/chat_scrollbar.go index c505f9c6..2906a0f0 100644 --- a/cmd/chat_scrollbar.go +++ b/cmd/chat_scrollbar.go @@ -20,8 +20,6 @@ const ( var ( // scrollbarThumbStyle — brand orange thumb so it pops. scrollbarThumbStyle = lipgloss.NewStyle().Foreground(hawkColor) - // scrollbarTrackStyle — very dim grey track so it doesn't distract. - scrollbarTrackStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#3A3A3A")) ) // chatHasOverflow reports whether chat content exceeds the viewport height. diff --git a/cmd/chat_stream.go b/cmd/chat_stream.go index fbac86c2..5b9253b3 100644 --- a/cmd/chat_stream.go +++ b/cmd/chat_stream.go @@ -26,12 +26,6 @@ func (m *chatModel) startPromptCommand(display, prompt string) (tea.Model, tea.C return m, nil } -// dispatchStreamEvent maps one engine event to TUI messages. Returns true when -// the pump should stop (error or done). -func dispatchStreamEvent(ref *progRef, ev engine.StreamEvent) bool { - return dispatchStreamEventWithFlush(ref, ev, nil) -} - func dispatchStreamEventWithFlush(ref *progRef, ev engine.StreamEvent, flush func()) bool { if ev.Type != "content" && flush != nil { flush() diff --git a/external/sight b/external/sight index f7cb9903..faddabcd 160000 --- a/external/sight +++ b/external/sight @@ -1 +1 @@ -Subproject commit f7cb99035fe988edafc042e0a7cea19917d8c10a +Subproject commit faddabcd01a3b38ccfd252f5f4d9164e613007af diff --git a/internal/engine/safety/permission.go b/internal/engine/safety/permission.go index f0ea3cb8..4c233aa2 100644 --- a/internal/engine/safety/permission.go +++ b/internal/engine/safety/permission.go @@ -161,10 +161,6 @@ func ToolSummary(name string, args map[string]interface{}) string { return name } -func boolPtr(v bool) *bool { - return &v -} - func pathArgument(args map[string]interface{}) (string, bool) { if p, ok := args["path"].(string); ok && p != "" { return p, true diff --git a/internal/engine/stream_tool_exec.go b/internal/engine/stream_tool_exec.go index 4b371f19..c6cef6d8 100644 --- a/internal/engine/stream_tool_exec.go +++ b/internal/engine/stream_tool_exec.go @@ -25,18 +25,6 @@ type toolExecResult struct { isErr bool } -// classifyToolCalls splits tool calls into concurrent (read-only) and sequential (write) batches. -func classifyToolCalls(calls []types.ToolCall) (concurrent, sequential []types.ToolCall) { - for _, tc := range calls { - if tool.IsReadOnly(tc.Name) { - concurrent = append(concurrent, tc) - } else { - sequential = append(sequential, tc) - } - } - return -} - // filePathArgKeys is the list of argument names that are conventionally // file paths. Tools with non-standard names silently fall through and // extractTargets returns an empty list. For a more robust extraction, see diff --git a/internal/plugin/bundled_skills/idea-refine/SKILL.md b/internal/plugin/bundled_skills/idea-refine/SKILL.md index 38955e89..e017f80c 100644 --- a/internal/plugin/bundled_skills/idea-refine/SKILL.md +++ b/internal/plugin/bundled_skills/idea-refine/SKILL.md @@ -9,9 +9,9 @@ Refines raw ideas into sharp, actionable concepts worth building through structu ## How It Works -1. **Understand & Expand (Divergent):** Restate the idea, ask sharpening questions, and generate variations. -2. **Evaluate & Converge:** Cluster ideas, stress-test them, and surface hidden assumptions. -3. **Sharpen & Ship:** Produce a concrete markdown one-pager moving work forward. +1. **Understand & Expand (Divergent):** Restate the idea, ask sharpening questions, and generate variations. +2. **Evaluate & Converge:** Cluster ideas, stress-test them, and surface hidden assumptions. +3. **Sharpen & Ship:** Produce a concrete markdown one-pager moving work forward. ## Usage diff --git a/internal/plugin/bundled_skills/idea-refine/examples.md b/internal/plugin/bundled_skills/idea-refine/examples.md index a797d22c..ba1f1ddf 100644 --- a/internal/plugin/bundled_skills/idea-refine/examples.md +++ b/internal/plugin/bundled_skills/idea-refine/examples.md @@ -87,6 +87,7 @@ One thing I want to push back on: you said variation 1 feels "necessary but bori **Skill produces:** + # ReOrder: Keep Your Regulars Ordering Direct ## Problem Statement diff --git a/internal/plugin/bundled_skills/performance-optimization/SKILL.md b/internal/plugin/bundled_skills/performance-optimization/SKILL.md index dcc37e04..0afd6e64 100644 --- a/internal/plugin/bundled_skills/performance-optimization/SKILL.md +++ b/internal/plugin/bundled_skills/performance-optimization/SKILL.md @@ -316,7 +316,6 @@ npx lhci autorun For detailed performance checklists, optimization commands, and anti-pattern reference, see `references/performance-checklist.md`. - ## Common Rationalizations | Rationalization | Reality | diff --git a/spec/agent-skills/docs/antigravity-setup.md b/spec/agent-skills/docs/antigravity-setup.md index a0762a27..018bd3a3 100644 --- a/spec/agent-skills/docs/antigravity-setup.md +++ b/spec/agent-skills/docs/antigravity-setup.md @@ -64,7 +64,7 @@ Each command automatically invokes the corresponding skill and guides the agent ## Skills & Discovery -Antigravity automatically discovers skills inside the plugin's `skills/` directory. +Antigravity automatically discovers skills inside the plugin's `skills/` directory. * Antigravity matches user tasks and intents to relevant skills on-demand. * If a task matches a skill, the agent will load the skill and prompt you for permission before executing. @@ -85,15 +85,15 @@ agy plugin validate /path/to/agent-skills Antigravity CLI automatically discovers the `SKILL.md` files located in the `skills/` directory of the installed plugin. Using the trigger descriptions in each skill's frontmatter, the agent will dynamically activate the appropriate workflow when it detects matching developer intent. For example, when you ask the agent to: -- **Design a new system** → It will suggest/activate `spec-driven-development`. -- **Implement a feature** → It will activate `incremental-implementation` and `test-driven-development`. -- **Fix a bug** → It will activate `debugging-and-error-recovery`. +* **Design a new system** → It will suggest/activate `spec-driven-development`. +* **Implement a feature** → It will activate `incremental-implementation` and `test-driven-development`. +* **Fix a bug** → It will activate `debugging-and-error-recovery`. ### 2. Specialized Agent Personas The plugin registers reusable subagent definitions from the `agents/` directory: -- `code-reviewer.md` -- `security-auditor.md` -- `test-engineer.md` +\* `code-reviewer.md` +\* `security-auditor.md` +\* `test-engineer.md` You can invoke these personas directly within your session or when delegating tasks using subagents. diff --git a/spec/agent-skills/skills/idea-refine/SKILL.md b/spec/agent-skills/skills/idea-refine/SKILL.md index 38955e89..27f83ccc 100644 --- a/spec/agent-skills/skills/idea-refine/SKILL.md +++ b/spec/agent-skills/skills/idea-refine/SKILL.md @@ -9,9 +9,9 @@ Refines raw ideas into sharp, actionable concepts worth building through structu ## How It Works -1. **Understand & Expand (Divergent):** Restate the idea, ask sharpening questions, and generate variations. -2. **Evaluate & Converge:** Cluster ideas, stress-test them, and surface hidden assumptions. -3. **Sharpen & Ship:** Produce a concrete markdown one-pager moving work forward. +\* **Understand & Expand (Divergent):** Restate the idea, ask sharpening questions, and generate variations. +\* **Evaluate & Converge:** Cluster ideas, stress-test them, and surface hidden assumptions. +\* **Sharpen & Ship:** Produce a concrete markdown one-pager moving work forward. ## Usage diff --git a/spec/agent-skills/skills/idea-refine/examples.md b/spec/agent-skills/skills/idea-refine/examples.md index a797d22c..ba1f1ddf 100644 --- a/spec/agent-skills/skills/idea-refine/examples.md +++ b/spec/agent-skills/skills/idea-refine/examples.md @@ -87,6 +87,7 @@ One thing I want to push back on: you said variation 1 feels "necessary but bori **Skill produces:** + # ReOrder: Keep Your Regulars Ordering Direct ## Problem Statement diff --git a/spec/agent-skills/skills/performance-optimization/SKILL.md b/spec/agent-skills/skills/performance-optimization/SKILL.md index dcc37e04..0afd6e64 100644 --- a/spec/agent-skills/skills/performance-optimization/SKILL.md +++ b/spec/agent-skills/skills/performance-optimization/SKILL.md @@ -316,7 +316,6 @@ npx lhci autorun For detailed performance checklists, optimization commands, and anti-pattern reference, see `references/performance-checklist.md`. - ## Common Rationalizations | Rationalization | Reality | diff --git a/spec/openspec/docs/examples.md b/spec/openspec/docs/examples.md index cedf85c3..166d62a3 100644 --- a/spec/openspec/docs/examples.md +++ b/spec/openspec/docs/examples.md @@ -143,7 +143,7 @@ AI: Created the change. The proposal states the goal (split the When you archive a change that doesn't touch specs, you can tell the terminal command to skip the spec step: ```bash -$ openspec archive refactor-payment-module --skip-specs +openspec archive refactor-payment-module --skip-specs ``` The same flag is handy for tooling, CI, and docs-only changes. The principle: specs describe behavior, so if behavior didn't change, the spec shouldn't either. See [Concepts](concepts.md#what-a-spec-is-and-is-not). @@ -155,8 +155,8 @@ The same flag is handy for tooling, CI, and docs-only changes. The principle: sp The core `/opsx:propose` drafts everything at once. When you'd rather go one step at a time, turn on the expanded commands: ```bash -$ openspec config profile # select the expanded workflows -$ openspec update # apply them to this project +openspec config profile # select the expanded workflows +openspec update # apply them to this project ``` Now you can scaffold and build incrementally: @@ -198,10 +198,10 @@ AI: Welcome to OpenSpec! I'll walk you through a complete change Any time, from your terminal, you can inspect the state of things: ```bash -$ openspec list # active changes -$ openspec show add-dark-mode # one change in detail -$ openspec validate add-dark-mode # check structure -$ openspec view # interactive dashboard +openspec list # active changes +openspec show add-dark-mode # one change in detail +openspec validate add-dark-mode # check structure +openspec view # interactive dashboard ``` These are read-and-inspect tools. The proposing and building still happen through slash commands in chat. Full details in the [CLI reference](cli.md). diff --git a/spec/openspec/docs/existing-projects.md b/spec/openspec/docs/existing-projects.md index 8e879d44..3ff76636 100644 --- a/spec/openspec/docs/existing-projects.md +++ b/spec/openspec/docs/existing-projects.md @@ -9,8 +9,8 @@ This guide shows how to start on day one without boiling the ocean. ## The thirty-second version ```bash -$ cd your-existing-project -$ openspec init # adds openspec/ and your AI tool's commands +cd your-existing-project +openspec init # adds openspec/ and your AI tool's commands ``` Then, in your AI chat: @@ -71,8 +71,8 @@ If you'd rather watch the whole loop happen on your own code with narration, the Turn on the expanded commands first: ```bash -$ openspec config profile # select the expanded workflows -$ openspec update # apply them to this project +openspec config profile # select the expanded workflows +openspec update # apply them to this project ``` Then in chat: diff --git a/spec/openspec/docs/opsx.md b/spec/openspec/docs/opsx.md index bebe0a51..9b14e95a 100644 --- a/spec/openspec/docs/opsx.md +++ b/spec/openspec/docs/opsx.md @@ -226,7 +226,7 @@ A proposal defines three things: The question is: which changed, and by how much? -### Update the Existing Change When: +### Update the Existing Change When **Same intent, refined execution** - You discover edge cases you didn't consider @@ -242,7 +242,7 @@ The question is: which changed, and by how much? - A dependency doesn't work as expected - "Use CSS variables" → "Use Tailwind's dark: prefix instead" -### Start a New Change When: +### Start a New Change When **Intent fundamentally changed** - The problem itself is different now diff --git a/spec/openspec/examples/add-tool-command-surface-capabilities/specs/cli-update/spec.md b/spec/openspec/examples/add-tool-command-surface-capabilities/specs/cli-update/spec.md index c8d9a8d2..07eecafa 100644 --- a/spec/openspec/examples/add-tool-command-surface-capabilities/specs/cli-update/spec.md +++ b/spec/openspec/examples/add-tool-command-surface-capabilities/specs/cli-update/spec.md @@ -45,4 +45,3 @@ The update command SHALL report effective artifact behavior when delivery intent - **AND** at least one updated tool is `skills-invocable` - **THEN** output SHALL include a clear note that those tools use skills as their command surface - **AND** output SHALL avoid implying that command generation was skipped due to an error - diff --git a/spec/spec-kit/commands/analyze.md b/spec/spec-kit/commands/analyze.md index e4ba8f7d..245b473c 100644 --- a/spec/spec-kit/commands/analyze.md +++ b/spec/spec-kit/commands/analyze.md @@ -194,7 +194,7 @@ At end of report, output a concise Next Actions block: - If CRITICAL issues exist: Recommend resolving before `__SPECKIT_COMMAND_IMPLEMENT__` - If only LOW/MEDIUM: User may proceed, but provide improvement suggestions -- Provide explicit command suggestions: e.g., "Run __SPECKIT_COMMAND_SPECIFY__ with refinement", "Run __SPECKIT_COMMAND_PLAN__ to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'" +- Provide explicit command suggestions: e.g., "Run **SPECKIT_COMMAND_SPECIFY** with refinement", "Run **SPECKIT_COMMAND_PLAN** to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'" ### 8. Offer Remediation From bbcd47addbdc039624f842970b0cb3c11a48aa40 Mon Sep 17 00:00:00 2001 From: Lakshman Patel Date: Sat, 4 Jul 2026 21:57:14 +0530 Subject: [PATCH 2/3] style: fix gofumpt formatting in chat_scrollbar.go --- cmd/chat_scrollbar.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/chat_scrollbar.go b/cmd/chat_scrollbar.go index 2906a0f0..e6e0c283 100644 --- a/cmd/chat_scrollbar.go +++ b/cmd/chat_scrollbar.go @@ -17,10 +17,8 @@ const ( scrollbarBottomGlyph = "╵" // cap at the very bottom of the track ) -var ( - // scrollbarThumbStyle — brand orange thumb so it pops. - scrollbarThumbStyle = lipgloss.NewStyle().Foreground(hawkColor) -) +// scrollbarThumbStyle — brand orange thumb so it pops. +var scrollbarThumbStyle = lipgloss.NewStyle().Foreground(hawkColor) // chatHasOverflow reports whether chat content exceeds the viewport height. func (m chatModel) chatHasOverflow() bool { From 3d9145a521f630358d5cc066b93dedf78b0cf66f Mon Sep 17 00:00:00 2001 From: Lakshman Patel Date: Sat, 4 Jul 2026 22:23:35 +0530 Subject: [PATCH 3/3] fix(ci): add sync.Mutex to fix race in executeToolCalls --- internal/engine/stream_tool_exec.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/engine/stream_tool_exec.go b/internal/engine/stream_tool_exec.go index c6cef6d8..27cb57b5 100644 --- a/internal/engine/stream_tool_exec.go +++ b/internal/engine/stream_tool_exec.go @@ -191,6 +191,7 @@ func (s *Session) executeToolCalls(ctx context.Context, toolCalls []types.ToolCa readOnlySem := make(chan struct{}, maxConcurrentReadOnlyToolCalls) networkSem := make(chan struct{}, maxConcurrentNetworkReadOnlyToolCalls) var wg sync.WaitGroup + var mu sync.Mutex for _, item := range concurrentCalls { wg.Add(1) @@ -202,13 +203,17 @@ func (s *Session) executeToolCalls(ctx context.Context, toolCalls []types.ToolCa networkSem <- struct{}{} defer func() { <-networkSem }() } + mu.Lock() results[item.index] = s.executeSingleTool(ctx, item.tc, ch, turnCount, intentText) + mu.Unlock() }(item) } wg.Wait() for _, item := range sequentialCalls { + mu.Lock() results[item.index] = s.executeSingleTool(ctx, item.tc, ch, turnCount, intentText) + mu.Unlock() } return results